From 02757df2ad2d5dfc96482e2cdfa046f439dafc3d Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:20:25 -0700 Subject: qdev: gpio: Re-implement qdev_connect_gpio QOM style Re-implement as a link setter. This should allow the QOM framework to keep track of ref counts properly etc. We need to add a default parent for the connecting input incase it's coming from a non-qdev source. We simply parent the IRQ to the machine in this case. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'hw/core/qdev.c') diff --git a/hw/core/qdev.c b/hw/core/qdev.c index a1e9247772..fc7860f0bb 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -440,10 +440,19 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq pin) { - NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); - - assert(n >= 0 && n < gpio_list->num_out); - gpio_list->out[n] = pin; + char *propname = g_strdup_printf("%s[%d]", + name ? name : "unnamed-gpio-out", n); + if (pin) { + /* We need a name for object_property_set_link to work. If the + * object has a parent, object_property_add_child will come back + * with an error without doing anything. If it has none, it will + * never fail. So we can just call it with a NULL Error pointer. + */ + object_property_add_child(qdev_get_machine(), "non-qdev-gpio[*]", + OBJECT(pin), NULL); + } + object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort); + g_free(propname); } void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) -- cgit 1.4.1 From 0c24db2b8c60cb578d7af6fb50c0ad60a723a02d Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:20:58 -0700 Subject: qdev: gpio: Add API for intercepting a GPIO To replace the old qemu_irq intercept API (which had users reaching into qdev private state for GPIOs). Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 25 +++++++++++++++++++++++++ include/hw/qdev-core.h | 2 ++ 2 files changed, 27 insertions(+) (limited to 'hw/core/qdev.c') diff --git a/hw/core/qdev.c b/hw/core/qdev.c index fc7860f0bb..92f88f6698 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -455,6 +455,31 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, g_free(propname); } +/* disconnect a GPIO ouput, returning the disconnected input (if any) */ + +static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev, + const char *name, int n) +{ + char *propname = g_strdup_printf("%s[%d]", + name ? name : "unnamed-gpio-out", n); + + qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname, + NULL); + if (ret) { + object_property_set_link(OBJECT(dev), NULL, propname, NULL); + } + g_free(propname); + return ret; +} + +qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt, + const char *name, int n) +{ + qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n); + qdev_connect_gpio_out_named(dev, name, n, icpt); + return disconnected; +} + void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) { qdev_connect_gpio_out_named(dev, NULL, n, pin); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 1fca75c591..cf27e6564a 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -273,6 +273,8 @@ qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n); void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq pin); +qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt, + const char *name, int n); BusState *qdev_get_child_bus(DeviceState *dev, const char *name); -- cgit 1.4.1 From 15942b65697c7016a8ca836ecbfd9777d959187c Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:22:36 -0700 Subject: qdev: gpio: delete NamedGPIOList::out All users of GPIO outputs are fully QOMified, using QOM properties to access the GPIO data. Delete. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 1 - include/hw/qdev-core.h | 1 - 2 files changed, 2 deletions(-) (limited to 'hw/core/qdev.c') diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 92f88f6698..efbaa99117 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -406,7 +406,6 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, assert(gpio_list->num_in == 0 || !name); assert(gpio_list->num_out == 0); gpio_list->num_out = n; - gpio_list->out = pins; for (i = 0; i < n; ++i) { memset(&pins[i], 0, sizeof(*pins)); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index cf27e6564a..86d341f083 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -136,7 +136,6 @@ struct NamedGPIOList { char *name; qemu_irq *in; int num_in; - qemu_irq *out; int num_out; QLIST_ENTRY(NamedGPIOList) node; }; -- cgit 1.4.1 From aef0869e8ed83ec201488020a9a1cc44d85d72bf Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:23:09 -0700 Subject: qdev: gpio: Remove qdev_init_gpio_out x1 restriction Previously this was restricted to a single call per-dev/per-name. With the conversion of the GPIO output state to QOM the implementation can now handle repeated calls. Remove the restriction. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'hw/core/qdev.c') diff --git a/hw/core/qdev.c b/hw/core/qdev.c index efbaa99117..31014e8769 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -404,8 +404,7 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-out"); assert(gpio_list->num_in == 0 || !name); - assert(gpio_list->num_out == 0); - gpio_list->num_out = n; + gpio_list->num_out += n; for (i = 0; i < n; ++i) { memset(&pins[i], 0, sizeof(*pins)); -- cgit 1.4.1 From 17a96a146cb5195ab1f6b5cf48645f9f6450539f Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Thu, 25 Sep 2014 22:23:42 -0700 Subject: qdev: gpio: Define qdev_pass_gpios() Allows a container to take ownership of GPIOs in a contained device and automatically connect them as GPIOs to the container. This prepares for deprecation of the SYSBUS IRQ functionality, which has this feature. We push it up to the device level instead of sysbus level. There's nothing sysbus specific about passing GPIOs to containers so its a legitimate device-level generic feature. Reviewed-by: Alexander Graf Signed-off-by: Peter Crosthwaite Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 26 ++++++++++++++++++++++++++ include/hw/qdev-core.h | 3 +++ 2 files changed, 29 insertions(+) (limited to 'hw/core/qdev.c') diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 31014e8769..c247fffd7f 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -483,6 +483,32 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) qdev_connect_gpio_out_named(dev, NULL, n, pin); } +void qdev_pass_gpios(DeviceState *dev, DeviceState *container, + const char *name) +{ + int i; + NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name); + + for (i = 0; i < ngl->num_in; i++) { + const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in"; + char *propname = g_strdup_printf("%s[%d]", nm, i); + + object_property_add_alias(OBJECT(container), propname, + OBJECT(dev), propname, + &error_abort); + } + for (i = 0; i < ngl->num_out; i++) { + const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out"; + char *propname = g_strdup_printf("%s[%d]", nm, i); + + object_property_add_alias(OBJECT(container), propname, + OBJECT(dev), propname, + &error_abort); + } + QLIST_REMOVE(ngl, node); + QLIST_INSERT_HEAD(&container->gpios, ngl, node); +} + BusState *qdev_get_child_bus(DeviceState *dev, const char *name) { BusState *bus; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 86d341f083..a7327fd122 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -288,6 +288,9 @@ void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, const char *name, int n); +void qdev_pass_gpios(DeviceState *dev, DeviceState *container, + const char *name); + BusState *qdev_get_parent_bus(DeviceState *dev); /*** BUS API. ***/ -- cgit 1.4.1