aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/core/qdev.c15
-rw-r--r--include/hw/resettable.h11
2 files changed, 25 insertions, 1 deletions
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 28fc93b107..7697f033b1 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -909,6 +909,12 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
}
}
+ /*
+ * Clear the reset state, in case the object was previously unrealized
+ * with a dirty state.
+ */
+ resettable_state_clear(&dev->reset);
+
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
object_property_set_bool(OBJECT(bus), true, "realized",
&local_err);
@@ -917,7 +923,14 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
}
}
if (dev->hotplugged) {
- device_legacy_reset(dev);
+ /*
+ * Reset the device, as well as its subtree which, at this point,
+ * should be realized too.
+ */
+ resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
+ resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
+ NULL);
+ resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
}
dev->pending_deleted_event = false;
diff --git a/include/hw/resettable.h b/include/hw/resettable.h
index 96073354fd..5e215d94e4 100644
--- a/include/hw/resettable.h
+++ b/include/hw/resettable.h
@@ -154,6 +154,17 @@ struct ResettableState {
};
/**
+ * resettable_state_clear:
+ * Clear the state. It puts the state to the initial (zeroed) state required
+ * to reuse an object. Typically used in realize step of base classes
+ * implementing the interface.
+ */
+static inline void resettable_state_clear(ResettableState *state)
+{
+ memset(state, 0, sizeof(ResettableState));
+}
+
+/**
* resettable_reset:
* Trigger a reset on an object @obj of type @type. @obj must implement
* Resettable interface.