From: Andreas Färber <afaer...@suse.de> As a prequel to any big Pin refactoring plans, do an in-place conversion of qemu_irq to an Object, so that we can reference it in link<> properties.
Signed-off-by: Andreas Färber <afaer...@suse.de> --- hw/core/irq.c | 44 +++++++++++++++++++++++++++++++++++++++++--- include/hw/irq.h | 2 ++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/hw/core/irq.c b/hw/core/irq.c index 03c8cb3..0bcd27b 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; @@ -38,6 +43,14 @@ void qemu_set_irq(qemu_irq irq, int level) irq->handler(irq->opaque, irq->n, level); } +static void irq_nonfirst_free(void *obj) +{ + struct IRQState *s = obj; + + /* Unreference the first IRQ in this array */ + object_unref(OBJECT(s - s->n)); +} + qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler, void *opaque, int n) { @@ -51,11 +64,23 @@ qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler, 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); + memset(p + n_old, 0, n * sizeof(*p)); for (i = 0; i < n + n_old; i++) { if (i >= n_old) { + Object *obj; + + object_initialize(p, sizeof(*p), TYPE_IRQ); p->handler = handler; p->opaque = opaque; p->n = i; + obj = OBJECT(p); + /* Let the first IRQ clean them all up */ + if (unlikely(i == 0)) { + obj->free = g_free; + } else { + object_ref(OBJECT(s[0])); + obj->free = irq_nonfirst_free; + } } s[i] = p; p++; @@ -72,7 +97,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; @@ -82,13 +107,13 @@ qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n) void qemu_free_irqs(qemu_irq *s) { - g_free(s[0]); + object_unref(OBJECT(s[0])); 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) @@ -150,3 +175,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/include/hw/irq.h b/include/hw/irq.h index d08bc02..ac76ea7 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -3,6 +3,8 @@ /* Generic IRQ/GPIO pin infrastructure. */ +#define TYPE_IRQ "irq" + typedef struct IRQState *qemu_irq; typedef void (*qemu_irq_handler)(void *opaque, int n, int level); -- 1.9.3.1.ga73a6ad