summary refs log tree commit diff stats
path: root/hw/core
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/irq.c46
-rw-r--r--hw/core/qdev.c2
2 files changed, 30 insertions, 18 deletions
diff --git a/hw/core/irq.c b/hw/core/irq.c
index 03c8cb31ea..cffced040f 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -23,8 +23,13 @@
  */
 #include "qemu-common.h"
 #include "hw/irq.h"
+#include "qom/object.h"
+
+#define IRQ(obj) OBJECT_CHECK(struct IRQState, (obj), TYPE_IRQ)
 
 struct IRQState {
+    Object parent_obj;
+
     qemu_irq_handler handler;
     void *opaque;
     int n;
@@ -42,23 +47,14 @@ qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
                            void *opaque, int n)
 {
     qemu_irq *s;
-    struct IRQState *p;
     int i;
 
     if (!old) {
         n_old = 0;
     }
     s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n);
-    p = old ? g_renew(struct IRQState, s[0], n + n_old) :
-                g_new(struct IRQState, n);
-    for (i = 0; i < n + n_old; i++) {
-        if (i >= n_old) {
-            p->handler = handler;
-            p->opaque = opaque;
-            p->n = i;
-        }
-        s[i] = p;
-        p++;
+    for (i = n_old; i < n + n_old; i++) {
+        s[i] = qemu_allocate_irq(handler, opaque, i);
     }
     return s;
 }
@@ -72,7 +68,7 @@ qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
 {
     struct IRQState *irq;
 
-    irq = g_new(struct IRQState, 1);
+    irq = IRQ(object_new(TYPE_IRQ));
     irq->handler = handler;
     irq->opaque = opaque;
     irq->n = n;
@@ -80,15 +76,18 @@ qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n)
     return irq;
 }
 
-void qemu_free_irqs(qemu_irq *s)
+void qemu_free_irqs(qemu_irq *s, int n)
 {
-    g_free(s[0]);
+    int i;
+    for (i = 0; i < n; i++) {
+        qemu_free_irq(s[i]);
+    }
     g_free(s);
 }
 
 void qemu_free_irq(qemu_irq irq)
 {
-    g_free(irq);
+    object_unref(OBJECT(irq));
 }
 
 static void qemu_notirq(void *opaque, int line, int level)
@@ -102,7 +101,7 @@ qemu_irq qemu_irq_invert(qemu_irq irq)
 {
     /* The default state for IRQs is low, so raise the output now.  */
     qemu_irq_raise(irq);
-    return qemu_allocate_irqs(qemu_notirq, irq, 1)[0];
+    return qemu_allocate_irq(qemu_notirq, irq, 0);
 }
 
 static void qemu_splitirq(void *opaque, int line, int level)
@@ -117,7 +116,7 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
     qemu_irq *s = g_malloc0(2 * sizeof(qemu_irq));
     s[0] = irq1;
     s[1] = irq2;
-    return qemu_allocate_irqs(qemu_splitirq, s, 1)[0];
+    return qemu_allocate_irq(qemu_splitirq, s, 0);
 }
 
 static void proxy_irq_handler(void *opaque, int n, int level)
@@ -150,3 +149,16 @@ void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n
     qemu_irq *old_irqs = *gpio_out;
     *gpio_out = qemu_allocate_irqs(handler, old_irqs, n);
 }
+
+static const TypeInfo irq_type_info = {
+   .name = TYPE_IRQ,
+   .parent = TYPE_OBJECT,
+   .instance_size = sizeof(struct IRQState),
+};
+
+static void irq_register_types(void)
+{
+    type_register_static(&irq_type_info);
+}
+
+type_init(irq_register_types)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index c52041543d..a2feb5abfe 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -951,7 +951,7 @@ static void device_finalize(Object *obj)
 
     QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
         QLIST_REMOVE(ngl, node);
-        qemu_free_irqs(ngl->in);
+        qemu_free_irqs(ngl->in, ngl->num_in);
         g_free(ngl->name);
         g_free(ngl);
         /* ngl->out irqs are owned by the other end and should not be freed