summary refs log tree commit diff stats
path: root/hw/qdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/qdev.c')
-rw-r--r--hw/qdev.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/hw/qdev.c b/hw/qdev.c
index 6fc9b02a38..d93a6c4bf0 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -333,6 +333,12 @@ void qbus_reset_all(BusState *bus)
     qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
 }
 
+void qbus_reset_all_fn(void *opaque)
+{
+    BusState *bus = opaque;
+    qbus_reset_all(bus);
+}
+
 /* can be used as ->unplug() callback for the simple cases */
 int qdev_simple_unplug_cb(DeviceState *dev)
 {
@@ -754,8 +760,11 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
     if (parent) {
         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
         parent->num_child_bus++;
+    } else if (bus != main_system_bus) {
+        /* TODO: once all bus devices are qdevified,
+           only reset handler for main_system_bus should be registered here. */
+        qemu_register_reset(qbus_reset_all_fn, bus);
     }
-
 }
 
 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
@@ -778,6 +787,9 @@ void qbus_free(BusState *bus)
     if (bus->parent) {
         QLIST_REMOVE(bus, sibling);
         bus->parent->num_child_bus--;
+    } else {
+        assert(bus != main_system_bus); /* main_system_bus is never freed */
+        qemu_unregister_reset(qbus_reset_all_fn, bus);
     }
     qemu_free((void*)bus->name);
     if (bus->qdev_allocated) {