qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH for-2.1 v1 2/3] qdev: Implement named GPIOs


From: Peter Crosthwaite
Subject: [Qemu-devel] [PATCH for-2.1 v1 2/3] qdev: Implement named GPIOs
Date: Tue, 8 Apr 2014 16:45:36 -0700

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 <address@hidden>
---

 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 qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
+void qdev_connect_gpio_out_named(DeviceState *dev, int n, qemu_irq pin,
+                                 const char *name);
 
 BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
 
@@ -263,6 +276,10 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char 
*name);
 /* GPIO inputs also double as IRQ sinks.  */
 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
+void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, int n,
+                             const char *name);
+void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, int n,
+                              const char *name);
 
 BusState *qdev_get_parent_bus(DeviceState *dev);
 
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 9268c87..6974236 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -609,14 +609,18 @@ static void qdev_print(Monitor *mon, DeviceState *dev, 
int indent)
 {
     ObjectClass *class;
     BusState *child;
+    NamedGPIOList *ngl;
+
     qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
                 dev->id ? dev->id : "");
     indent += 2;
-    if (dev->num_gpio_in) {
-        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
-    }
-    if (dev->num_gpio_out) {
-        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
+    for (ngl = dev->gpios; ngl; ngl = ngl->next) {
+        if (ngl->num_in) {
+            qdev_printf("gpio-in \"%s\" %d\n", ngl->name, ngl->num_in);
+        }
+        if (ngl->num_out) {
+            qdev_printf("gpio-out \"%s\" %d\n", ngl->name, ngl->num_out);
+        }
     }
     class = object_get_class(OBJECT(dev));
     do {
diff --git a/qtest.c b/qtest.c
index 0ac9f42..d663675 100644
--- a/qtest.c
+++ b/qtest.c
@@ -233,7 +233,8 @@ static void qtest_process_command(CharDriverState *chr, 
gchar **words)
     g_assert(command);
     if (strcmp(words[0], "irq_intercept_out") == 0
         || strcmp(words[0], "irq_intercept_in") == 0) {
-       DeviceState *dev;
+        DeviceState *dev;
+        NamedGPIOList *ngl;
 
         g_assert(words[1]);
         dev = DEVICE(object_resolve_path(words[1], NULL));
@@ -253,10 +254,14 @@ static void qtest_process_command(CharDriverState *chr, 
gchar **words)
            return;
         }
 
-        if (words[0][14] == 'o') {
-            qemu_irq_intercept_out(&dev->gpio_out, qtest_irq_handler, 
dev->num_gpio_out);
-        } else {
-            qemu_irq_intercept_in(dev->gpio_in, qtest_irq_handler, 
dev->num_gpio_in);
+        for (ngl = dev->gpios; ngl; ngl = ngl->next) {
+            if (words[0][14] == 'o') {
+                qemu_irq_intercept_out(&ngl->out, qtest_irq_handler,
+                                       ngl->num_out);
+            } else {
+                qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
+                                      ngl->num_in);
+            }
         }
         irq_intercept_dev = dev;
         qtest_send_prefix(chr);
-- 
1.9.1.1.gbb9f595




reply via email to

[Prev in Thread] Current Thread [Next in Thread]