[RFC PATCH v2 110/137] irq: Reintroduce qemu_allocate_irq*() with a mandatory owner and name

Alexander Graf <[email protected]>
Newsgroups org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv
Message-ID <[email protected]>
Add parented variants of the IRQ allocation helpers under the
well-known names, taking (Object *owner, const char *name, ...) as
their first two arguments:

  qemu_allocate_irq(owner, name, handler, opaque, n)
  qemu_allocate_irqs(owner, name, handler, opaque, n)
  qemu_extend_irqs(owner, name, old, n_old, handler, opaque, n)
  qemu_irq_invert(owner, name, irq)

The new IRQ object is created via object_new_child() so it lands
under @owner with a stable path.  The array/extend variants suffix
"[*]" so callers pass a bare name and get name[0], name[1], ...

qemu_free_irq() is taught to unparent when the IRQ has a QOM parent,
so it works for both the *_orphan() and the parented allocation
paths during the transition.

The *_orphan() variants stay for now; later commits convert every
caller and delete them, at which point the /machine/unattached
fallback in qdev_connect_gpio_out_named() also goes away.

AI-used-for: code (refactoring)
Signed-off-by: Alexander Graf <[email protected]>
---
 hw/core/irq.c         | 45 ++++++++++++++++++++++++++++++++++++++++++-
 include/hw/core/irq.h | 15 +++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/hw/core/irq.c b/hw/core/irq.c
index f8fdeb7e02..1ae53a74d3 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -96,6 +96,38 @@ qemu_irq qemu_allocate_irq_orphan(qemu_irq_handler handler, void *opaque, int n)
     return irq;
 }
 
+qemu_irq qemu_allocate_irq(Object *owner, const char *name,
+                           qemu_irq_handler handler, void *opaque, int n)
+{
+    IRQState *irq = IRQ(object_new_child(owner, name, TYPE_IRQ));
+    init_irq_fields(irq, handler, opaque, n);
+    return irq;
+}
+
+qemu_irq *qemu_extend_irqs(Object *owner, const char *name,
+                           qemu_irq *old, int n_old,
+                           qemu_irq_handler handler, void *opaque, int n)
+{
+    qemu_irq *s;
+    int i;
+
+    if (!old) {
+        n_old = 0;
+    }
+    s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n);
+    for (i = n_old; i < n + n_old; i++) {
+        g_autofree char *propname = g_strdup_printf("%s[%d]", name, i);
+        s[i] = qemu_allocate_irq(owner, propname, handler, opaque, i);
+    }
+    return s;
+}
+
+qemu_irq *qemu_allocate_irqs(Object *owner, const char *name,
+                             qemu_irq_handler handler, void *opaque, int n)
+{
+    return qemu_extend_irqs(owner, name, NULL, 0, handler, opaque, n);
+}
+
 void qemu_free_irqs(qemu_irq *s, int n)
 {
     int i;
@@ -107,7 +139,11 @@ void qemu_free_irqs(qemu_irq *s, int n)
 
 void qemu_free_irq(qemu_irq irq)
 {
-    object_unref(OBJECT(irq));
+    if (irq && OBJECT(irq)->parent) {
+        object_unparent(OBJECT(irq));
+    } else {
+        object_unref(OBJECT(irq));
+    }
 }
 
 static void qemu_notirq(void *opaque, int line, int level)
@@ -124,6 +160,13 @@ qemu_irq qemu_irq_invert_orphan(qemu_irq irq)
     return qemu_allocate_irq_orphan(qemu_notirq, irq, 0);
 }
 
+qemu_irq qemu_irq_invert(Object *owner, const char *name, qemu_irq irq)
+{
+    /* The default state for IRQs is low, so raise the output now.  */
+    qemu_irq_raise(irq);
+    return qemu_allocate_irq(owner, name, qemu_notirq, irq, 0);
+}
+
 void qemu_irq_set_observer(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
 {
     int i;
diff --git a/include/hw/core/irq.h b/include/hw/core/irq.h
index f984c02c14..5ccccd2697 100644
--- a/include/hw/core/irq.h
+++ b/include/hw/core/irq.h
@@ -85,6 +85,20 @@ qemu_irq *qemu_allocate_irqs_orphan(qemu_irq_handler handler, void *opaque, int
  */
 qemu_irq qemu_allocate_irq_orphan(qemu_irq_handler handler, void *opaque, int n);
 
+/*
+ * Same as the *_orphan() variants above, but the new IRQ objects are
+ * parented under @owner with property name @name (or @name[*] for the
+ * array/extend variants).  The reference is held by @owner; call
+ * qemu_free_irq() to unparent and free.
+ */
+qemu_irq qemu_allocate_irq(Object *owner, const char *name,
+                           qemu_irq_handler handler, void *opaque, int n);
+qemu_irq *qemu_allocate_irqs(Object *owner, const char *name,
+                             qemu_irq_handler handler, void *opaque, int n);
+qemu_irq *qemu_extend_irqs(Object *owner, const char *name,
+                           qemu_irq *old, int n_old,
+                           qemu_irq_handler handler, void *opaque, int n);
+
 /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
  * preserved. New IRQs are assigned the argument handler and opaque data.
  */
@@ -96,6 +110,7 @@ void qemu_free_irq(qemu_irq irq);
 
 /* Returns a new IRQ with opposite polarity.  */
 qemu_irq qemu_irq_invert_orphan(qemu_irq irq);
+qemu_irq qemu_irq_invert(Object *owner, const char *name, qemu_irq irq);
 
 /* For internal use in qtest. */
 void qemu_irq_set_observer(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
-- 
2.47.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.