Implement named GPIOs on the Device layer. Listifies the existing GPIOs
stuff using string keys. Legacy un-named GPIOs are preserved by using
a NULL name string - they are just a single matchable element in the
name list.
Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com
---
hw/core/qdev.c | 82 ++
include/hw/qdev-core.h | 25 ---
qdev-monitor.c | 14 ++---
qtest.c| 15 ++---
4 files changed, 110 insertions(+), 26 deletions(-)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index ce7588b..90dcb8c 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -312,36 +312,94 @@ BusState *qdev_get_parent_bus(DeviceState *dev)
return dev-parent_bus;
}
+static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
+ const char *name)
+{
+NamedGPIOList *ngl = dev-gpios;
+
+while (ngl) {
+if (ngl-name == name ||
+(name ngl-name !strcmp(name, ngl-name))) {
+return ngl;
+}
+ngl = ngl-next;
+}
+
+ngl = g_malloc0(sizeof(*ngl));
+ngl-next = dev-gpios;
+ngl-name = g_strdup(name);
+dev-gpios = ngl;
+return ngl;
+}
+
+void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, int n,
+ const char *name)
+{
+NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
+
+gpio_list-in = qemu_extend_irqs(gpio_list-in, gpio_list-num_in, handler,
+ dev, n);
+gpio_list-num_in += n;
+}
+
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
-dev-gpio_in = qemu_extend_irqs(dev-gpio_in, dev-num_gpio_in, handler,
-dev, n);
-dev-num_gpio_in += n;
+qdev_init_gpio_in_named(dev, handler, n, NULL);
+}
+
+void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, int n,
+ const char *name)
+{
+NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
+
+assert(gpio_list-num_out == 0);
+gpio_list-num_out = n;
+gpio_list-out = pins;
}
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
{
-assert(dev-num_gpio_out == 0);
-dev-num_gpio_out = n;
-dev-gpio_out = pins;
+qdev_init_gpio_out_named(dev, pins, n, NULL);
+}
+
+qemu_irq qdev_get_gpio_in_named(DeviceState *dev, int n, const char *name)
+{
+NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
+
+assert(n = 0 n gpio_list-num_in);
+return gpio_list-in[n];
}
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
{
-assert(n = 0 n dev-num_gpio_in);
-return dev-gpio_in[n];
+return qdev_get_gpio_in_named(dev, n, NULL);
+}
+
+qemu_irq qdev_get_gpio_out_named(DeviceState *dev, int n, const char *name)
+{
+NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
+
+assert(n = 0 n gpio_list-num_out);
+return gpio_list-out[n];
}
qemu_irq qdev_get_gpio_out(DeviceState *dev, int n)
{
-assert(n = 0 n dev-num_gpio_out);
-return dev-gpio_out[n];
+return qdev_get_gpio_out_named(dev, n, NULL);
+}
+
+void qdev_connect_gpio_out_named(DeviceState *dev, int n, qemu_irq pin,
+ const char *name)
+{
+NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
+
+assert(n = 0 n gpio_list-num_out);
+gpio_list-out[n] = pin;
}
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
{
-assert(n = 0 n dev-num_gpio_out);
-dev-gpio_out[n] = pin;
+qdev_connect_gpio_out_named(dev, n, pin, NULL);
}
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index ed3a628..1018765 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -131,6 +131,17 @@ typedef struct DeviceClass {
const char *bus_type;
} DeviceClass;
+typedef struct NamedGPIOList NamedGPIOList;
+
+struct NamedGPIOList {
+const char *name;
+int num_in;
+qemu_irq *in;
+qemu_irq *out;
+int num_out;
+struct NamedGPIOList *next;
+};
+
/**
* DeviceState:
* @realized: Indicates whether the device has been fully constructed.
@@ -148,10 +159,7 @@ struct DeviceState {
QemuOpts *opts;
int hotplugged;
BusState *parent_bus;
-int num_gpio_out;
-qemu_irq *gpio_out;
-int num_gpio_in;
-qemu_irq *gpio_in;
+NamedGPIOList *gpios;
QLIST_HEAD(, BusState) child_bus;
int num_child_bus;
int instance_id_alias;
@@ -253,7 +261,12 @@ bool qdev_machine_modified(void);
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
qemu_irq qdev_get_gpio_out(DeviceState *dev, int n);
+qemu_irq qdev_get_gpio_in_named(DeviceState *dev, int n, const char *name);
+qemu_irq qdev_get_gpio_out_named(DeviceState *dev, int n, const char *name);
+
void