Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org> --- include/hw/qdev-core.h | 8 +++++++- hw/core/qdev.c | 21 ++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index d47536eadb..2ca33aea3b 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -101,8 +101,12 @@ typedef void (*BusUnrealize)(BusState *bus); * @props: Properties accessing state fields. * @realize: Callback function invoked when the #DeviceState:realized * property is changed to %true. + * @wire: Callback function called after @realize to connect IRQs, + * clocks and map memories. Can not fail. + * @unwire: Callback function to undo @wire. Called before @unrealize. + * Can not fail. * @unrealize: Callback function invoked when the #DeviceState:realized - * property is changed to %false. + * property is changed to %false. Can not fail. * @hotpluggable: indicates if #DeviceClass is hotpluggable, available * as readonly "hotpluggable" property of #DeviceState instance * @@ -161,6 +165,8 @@ struct DeviceClass { */ DeviceReset reset; DeviceRealize realize; + void (*wire)(DeviceState *dev); + void (*unwire)(DeviceState *dev); DeviceUnrealize unrealize; /** diff --git a/hw/core/qdev.c b/hw/core/qdev.c index c68d0f7c51..1d399aae71 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -303,6 +303,16 @@ bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp) void qdev_unrealize(DeviceState *dev) { + DeviceClass *dc = DEVICE_GET_CLASS(dev); + + if (dc->unwire) { + if (!dc->wire) { + error_report("disconnect() without connect() for type '%s'", + object_get_typename(OBJECT(dev))); + abort(); + } + dc->unwire(dev); + } object_property_set_bool(OBJECT(dev), "realized", false, &error_abort); } @@ -601,8 +611,17 @@ static void device_set_realized(Object *obj, bool value, Error **errp) dev->pending_deleted_event = true; DEVICE_LISTENER_CALL(unrealize, Reverse, dev); } - assert(local_err == NULL); + + if (dc->wire) { + if (!dc->unwire) { + warn_report_once("wire() without unwire() for type '%s'", + object_get_typename(OBJECT(dev))); + } + dc->wire(dev); + } + + /* At this point the device is "guest visible". */ return; child_realize_fail: -- 2.41.0