Prepare for the move to dynamically allocated IRQ objects by
introducing qemu_irq_new / qemu_irq_new_child / qemu_irq_new_array
functions which call through to object_new instead of object_initialize.

Signed-off-by: Daniel P. Berrangé <[email protected]>
---
 hw/core/irq.c         | 35 ++++++++++++++++++++
 include/hw/core/irq.h | 75 ++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 106 insertions(+), 4 deletions(-)

diff --git a/hw/core/irq.c b/hw/core/irq.c
index 106805e241..e943c87b81 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -49,6 +49,13 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, 
void *opaque,
     init_irq_fields(irq, handler, opaque, n);
 }
 
+IRQState *qemu_irq_new(qemu_irq_handler handler, void *opaque, int n)
+{
+    IRQState *irq = IRQ(object_new(TYPE_IRQ));
+    init_irq_fields(irq, handler, opaque, n);
+    return irq;
+}
+
 void qemu_init_irq_child(Object *parent, const char *propname,
                          IRQState *irq, qemu_irq_handler handler,
                          void *opaque, int n)
@@ -57,14 +64,42 @@ void qemu_init_irq_child(Object *parent, const char 
*propname,
     init_irq_fields(irq, handler, opaque, n);
 }
 
+IRQState *qemu_irq_new_child(Object *parent, const char *propname,
+                             qemu_irq_handler handler,
+                             void *opaque, int n,
+                             Error **errp)
+{
+    IRQState *irq = IRQ(object_new_with_props(TYPE_IRQ, parent, propname,
+                                              errp, NULL));
+    if (!irq) {
+        return NULL;
+    }
+    init_irq_fields(irq, handler, opaque, n);
+    return irq;
+}
+
+
 void qemu_init_irqs(IRQState irq[], size_t count,
                     qemu_irq_handler handler, void *opaque)
 {
     for (size_t i = 0; i < count; i++) {
+        QEMU_DEPRECATIONS_OFF;
         qemu_init_irq(&irq[i], handler, opaque, i);
+        QEMU_DEPRECATIONS_ON;
     }
 }
 
+IRQState **qemu_irq_new_array(size_t count,
+                              qemu_irq_handler handler, void *opaque)
+{
+    IRQState **irqs = g_new0(IRQState *, count);
+    for (size_t i = 0; i < count; i++) {
+        irqs[i] = qemu_irq_new(handler, opaque, i);
+    }
+    return irqs;
+}
+
+
 qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
                            void *opaque, int n)
 {
diff --git a/include/hw/core/irq.h b/include/hw/core/irq.h
index 291fdd67df..af9bf6fb12 100644
--- a/include/hw/core/irq.h
+++ b/include/hw/core/irq.h
@@ -34,7 +34,12 @@ static inline void qemu_irq_pulse(qemu_irq irq)
     qemu_set_irq(irq, 0);
 }
 
-/*
+/**
+ * qemu_init_irq: Initialize IRQ
+ * @handler: handler function for incoming interrupts
+ * @opaque: opaque data to pass to @handler
+ * @n: interrupt number to pass to @handler
+ *
  * Init a single IRQ. The irq is assigned with a handler, an opaque data
  * and the interrupt number. The caller must free this with qemu_free_irq().
  * If you are using this inside a device's init or realize method, then
@@ -42,7 +47,21 @@ static inline void qemu_irq_pulse(qemu_irq irq)
  * to manually clean up the IRQ.
  */
 void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
-                   int n);
+                   int n)
+    QEMU_DEPRECATED;
+/**
+ * qemu_new_irq: Allocate IRQ
+ * @handler: handler function for incoming interrupts
+ * @opaque: opaque data to pass to @handler
+ * @n: interrupt number to pass to @handler
+ *
+ * The returned IRQ will have a single reference, which is held by the
+ * caller and must be released to free the returned IRQ object when
+ * no longer required.
+ *
+ * Returns: the newly allocated IRQ
+ */
+IRQState *qemu_irq_new(qemu_irq_handler handler, void *opaque, int n);
 
 /**
  * qemu_init_irq_child: Initialize IRQ and make it a QOM child
@@ -56,10 +75,38 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, 
void *opaque,
  * Init a single IRQ and make the IRQ object a child of @parent with
  * the child-property name @propname. The IRQ object will thus be
  * automatically freed when @parent is destroyed.
+ *
+ * Use of this function is now deprecated. All IRQs must be
+ * allocated using the qemu_irq_new() family of functions and not
+ * statically embedded in a larger struct.
  */
 void qemu_init_irq_child(Object *parent, const char *propname,
                          IRQState *irq, qemu_irq_handler handler,
-                         void *opaque, int n);
+                         void *opaque, int n)
+    QEMU_DEPRECATED;
+
+/**
+ * qemu_init_irq_child: Allocate IRQ and make it a QOM child
+ * @parent: QOM object which owns this IRQ
+ * @propname: child property name
+ * @handler: handler function for incoming interrupts
+ * @opaque: opaque data to pass to @handler
+ * @n: interrupt number to pass to @handler
+ *
+ * Allocate a single IRQ and make the IRQ object a child of @parent with
+ * the child-property name @propname.
+ *
+ * The returned IRQ will have a single reference, which is held by the
+ * @owner object in the QOM composition tree. Thus in the absence of
+ * any further references being acquired, the IRQ will be freed when
+ * @owner is freed
+ *
+ * Returns: the newly allocated IRQ
+ */
+IRQState *qemu_irq_new_child(Object *parent, const char *propname,
+                             qemu_irq_handler handler,
+                             void *opaque, int n,
+                             Error **errp);
 
 
 /**
@@ -69,9 +116,29 @@ void qemu_init_irq_child(Object *parent, const char 
*propname,
  * @count: number of IRQs to initialize
  * @handler: handler to assign to each IRQ
  * @opaque: opaque data to pass to @handler
+ *
+ * Use of this function is now deprecated. All IRQs must be
+ * allocated using the qemu_irq_new() family of functions and not
+ * statically embedded in a larger struct.
  */
 void qemu_init_irqs(IRQState irq[], size_t count,
-                    qemu_irq_handler handler, void *opaque);
+                    qemu_irq_handler handler, void *opaque)
+    QEMU_DEPRECATED;
+/**
+ * qemu_irq_new_array: Allocate an array of IRQs.
+ * @count: number of IRQs to initialize
+ * @handler: handler to assign to each IRQ
+ * @opaque: opaque data to pass to @handler
+ *
+ * The returned IRQs will have a single reference, which is held by the
+ * caller and must be released to free the returned IRQs object when
+ * no longer required. The return array memory must also be freed by
+ * the caller.
+ *
+ * Returns: an array of IRQ objects
+ */
+IRQState **qemu_irq_new_array(size_t count,
+                              qemu_irq_handler handler, void *opaque);
 
 /* Returns an array of N IRQs. Each IRQ is assigned the argument handler and
  * opaque data.
-- 
2.54.0


Reply via email to