xref: /openbmc/qemu/hw/core/resetcontainer.c (revision 2e1cacfb)
1 /*
2  * Reset container
3  *
4  * Copyright (c) 2024 Linaro, Ltd
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7  * See the COPYING file in the top-level directory.
8  */
9 
10 /*
11  * The "reset container" is an object which implements the Resettable
12  * interface. It contains a list of arbitrary other objects which also
13  * implement Resettable. Resetting the reset container resets all the
14  * objects in it.
15  */
16 
17 #include "qemu/osdep.h"
18 #include "hw/resettable.h"
19 #include "hw/core/resetcontainer.h"
20 
21 struct ResettableContainer {
22     Object parent;
23     ResettableState reset_state;
24     GPtrArray *children;
25 };
26 
27 OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ResettableContainer, resettable_container, RESETTABLE_CONTAINER, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { })
28 
29 void resettable_container_add(ResettableContainer *rc, Object *obj)
30 {
31     INTERFACE_CHECK(void, obj, TYPE_RESETTABLE_INTERFACE);
32     g_ptr_array_add(rc->children, obj);
33 }
34 
35 void resettable_container_remove(ResettableContainer *rc, Object *obj)
36 {
37     g_ptr_array_remove(rc->children, obj);
38 }
39 
40 static ResettableState *resettable_container_get_state(Object *obj)
41 {
42     ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
43     return &rc->reset_state;
44 }
45 
46 static void resettable_container_child_foreach(Object *obj,
47                                                ResettableChildCallback cb,
48                                                void *opaque, ResetType type)
49 {
50     ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
51     unsigned int len = rc->children->len;
52 
53     for (unsigned int i = 0; i < len; i++) {
54         cb(g_ptr_array_index(rc->children, i), opaque, type);
55         /* Detect callbacks trying to unregister themselves */
56         assert(len == rc->children->len);
57     }
58 }
59 
60 static void resettable_container_init(Object *obj)
61 {
62     ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
63 
64     rc->children = g_ptr_array_new();
65 }
66 
67 static void resettable_container_finalize(Object *obj)
68 {
69 }
70 
71 static void resettable_container_class_init(ObjectClass *klass, void *data)
72 {
73     ResettableClass *rc = RESETTABLE_CLASS(klass);
74 
75     rc->get_state = resettable_container_get_state;
76     rc->child_foreach = resettable_container_child_foreach;
77 }
78