* [Qemu-devel] [PATCH for-2.1 v1 0/3] Named GPIOs
@ 2014-04-08 23:44 Peter Crosthwaite
2014-04-08 23:45 ` [Qemu-devel] [PATCH for-2.1 v1 1/3] qdev: Define qdev_get_gpio_out Peter Crosthwaite
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Peter Crosthwaite @ 2014-04-08 23:44 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, alistai
This series implements Named GPIOs on the qdev level. Patch 2 is the
feature presentation.
First patch is a developer-centric patch I have had in my tree for a
while. I include it so it picks up the change pattern in P2.
Last patch I give a useful example of the features use (an SSI
cleanup).
Peter Crosthwaite (3):
qdev: Define qdev_get_gpio_out
qdev: Implement named GPIOs
ssi: Name the CS GPIO.
hw/arm/stellaris.c | 7 ++--
hw/arm/xilinx_zynq.c | 2 +-
hw/core/qdev.c | 84 ++++++++++++++++++++++++++++++++-----
hw/microblaze/petalogix_ml605_mmu.c | 2 +-
hw/ssi/ssi.c | 4 +-
include/hw/qdev-core.h | 26 ++++++++++--
include/hw/ssi.h | 2 +
qdev-monitor.c | 14 ++++---
qtest.c | 15 ++++---
9 files changed, 125 insertions(+), 31 deletions(-)
--
1.9.1.1.gbb9f595
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH for-2.1 v1 1/3] qdev: Define qdev_get_gpio_out
2014-04-08 23:44 [Qemu-devel] [PATCH for-2.1 v1 0/3] Named GPIOs Peter Crosthwaite
@ 2014-04-08 23:45 ` Peter Crosthwaite
2014-04-08 23:45 ` [Qemu-devel] [PATCH for-2.1 v1 2/3] qdev: Implement named GPIOs Peter Crosthwaite
2014-04-08 23:46 ` [Qemu-devel] [PATCH for-2.1 v1 3/3] ssi: Name the CS GPIO Peter Crosthwaite
2 siblings, 0 replies; 4+ messages in thread
From: Peter Crosthwaite @ 2014-04-08 23:45 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, alistai
An API similar to the existing qdev_get_gpio_in() except gets outputs.
Useful for testing or debugging code which may wish to override the
hardware generated value of of a GPIO with a user specified value
(E.G. interrupt injection).
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
hw/core/qdev.c | 6 ++++++
include/hw/qdev-core.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 60f9df1..ce7588b 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -332,6 +332,12 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
return dev->gpio_in[n];
}
+qemu_irq qdev_get_gpio_out(DeviceState *dev, int n)
+{
+ assert(n >= 0 && n < dev->num_gpio_out);
+ return dev->gpio_out[n];
+}
+
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
{
assert(n >= 0 && n < dev->num_gpio_out);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index dbe473c..ed3a628 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -252,6 +252,7 @@ void qdev_machine_creation_done(void);
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);
void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
--
1.9.1.1.gbb9f595
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH for-2.1 v1 2/3] qdev: Implement named GPIOs
2014-04-08 23:44 [Qemu-devel] [PATCH for-2.1 v1 0/3] Named GPIOs Peter Crosthwaite
2014-04-08 23:45 ` [Qemu-devel] [PATCH for-2.1 v1 1/3] qdev: Define qdev_get_gpio_out Peter Crosthwaite
@ 2014-04-08 23:45 ` Peter Crosthwaite
2014-04-08 23:46 ` [Qemu-devel] [PATCH for-2.1 v1 3/3] ssi: Name the CS GPIO Peter Crosthwaite
2 siblings, 0 replies; 4+ messages in thread
From: Peter Crosthwaite @ 2014-04-08 23:45 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, alistai
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.crosthwaite@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 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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH for-2.1 v1 3/3] ssi: Name the CS GPIO.
2014-04-08 23:44 [Qemu-devel] [PATCH for-2.1 v1 0/3] Named GPIOs Peter Crosthwaite
2014-04-08 23:45 ` [Qemu-devel] [PATCH for-2.1 v1 1/3] qdev: Define qdev_get_gpio_out Peter Crosthwaite
2014-04-08 23:45 ` [Qemu-devel] [PATCH for-2.1 v1 2/3] qdev: Implement named GPIOs Peter Crosthwaite
@ 2014-04-08 23:46 ` Peter Crosthwaite
2 siblings, 0 replies; 4+ messages in thread
From: Peter Crosthwaite @ 2014-04-08 23:46 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, alistai
To get it out of the default GPIO list. This allows child devices to
use the un-named GPIO namespace without having to be SSI aware. That
is, there is no more need for machines to know about the obscure
policy where GPIO 0 is the SSI chip-select and GPIO 1..N are the
concrete class GPIOs (defined locally as 0..N-1).
This is most notable is stellaris, which uses a device which has both
SSI and concrete level GPIOs.
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
hw/arm/stellaris.c | 7 ++++---
hw/arm/xilinx_zynq.c | 2 +-
hw/microblaze/petalogix_ml605_mmu.c | 2 +-
hw/ssi/ssi.c | 4 ++--
include/hw/ssi.h | 2 ++
5 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index d6cc77b..78607a9 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1287,9 +1287,10 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
sddev = ssi_create_slave(bus, "ssi-sd");
ssddev = ssi_create_slave(bus, "ssd0323");
- gpio_out[GPIO_D][0] = qemu_irq_split(qdev_get_gpio_in(sddev, 0),
- qdev_get_gpio_in(ssddev, 0));
- gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 1);
+ gpio_out[GPIO_D][0] = qemu_irq_split(
+ qdev_get_gpio_in_named(sddev, 0, SSI_GPIO_CS),
+ qdev_get_gpio_in_named(ssddev, 0, SSI_GPIO_CS));
+ gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
/* Make sure the select pin is high. */
qemu_irq_raise(gpio_out[GPIO_D][0]);
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 9ee21e7..2406761 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -94,7 +94,7 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
for (j = 0; j < num_ss; ++j) {
flash_dev = ssi_create_slave(spi, "n25q128");
- cs_line = qdev_get_gpio_in(flash_dev, 0);
+ cs_line = qdev_get_gpio_in_named(flash_dev, 0, SSI_GPIO_CS);
sysbus_connect_irq(busdev, i * num_ss + j + 1, cs_line);
}
}
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 40a9f5c..00ade23 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -196,7 +196,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
qemu_irq cs_line;
dev = ssi_create_slave(spi, "n25q128");
- cs_line = qdev_get_gpio_in(dev, 0);
+ cs_line = qdev_get_gpio_in_named(dev, 0, SSI_GPIO_CS);
sysbus_connect_irq(busdev, i+1, cs_line);
}
}
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 017f022..84f5237 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -60,7 +60,7 @@ static int ssi_slave_init(DeviceState *dev)
if (ssc->transfer_raw == ssi_transfer_raw_default &&
ssc->cs_polarity != SSI_CS_NONE) {
- qdev_init_gpio_in(dev, ssi_cs_default, 1);
+ qdev_init_gpio_in_named(dev, ssi_cs_default, 1, SSI_GPIO_CS);
}
return ssc->init(s);
@@ -156,7 +156,7 @@ static int ssi_auto_connect_slave(Object *child, void *opaque)
return 0;
}
- cs_line = qdev_get_gpio_in(DEVICE(dev), 0);
+ cs_line = qdev_get_gpio_in_named(DEVICE(dev), 0, SSI_GPIO_CS);
qdev_set_parent_bus(DEVICE(dev), BUS(arg->bus));
**arg->cs_linep = cs_line;
(*arg->cs_linep)++;
diff --git a/include/hw/ssi.h b/include/hw/ssi.h
index 6c13fb2..df0f838 100644
--- a/include/hw/ssi.h
+++ b/include/hw/ssi.h
@@ -23,6 +23,8 @@ typedef struct SSISlave SSISlave;
#define SSI_SLAVE_GET_CLASS(obj) \
OBJECT_GET_CLASS(SSISlaveClass, (obj), TYPE_SSI_SLAVE)
+#define SSI_GPIO_CS "ssi-gpio-cs"
+
typedef enum {
SSI_CS_NONE = 0,
SSI_CS_LOW,
--
1.9.1.1.gbb9f595
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-04-08 23:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-08 23:44 [Qemu-devel] [PATCH for-2.1 v1 0/3] Named GPIOs Peter Crosthwaite
2014-04-08 23:45 ` [Qemu-devel] [PATCH for-2.1 v1 1/3] qdev: Define qdev_get_gpio_out Peter Crosthwaite
2014-04-08 23:45 ` [Qemu-devel] [PATCH for-2.1 v1 2/3] qdev: Implement named GPIOs Peter Crosthwaite
2014-04-08 23:46 ` [Qemu-devel] [PATCH for-2.1 v1 3/3] ssi: Name the CS GPIO Peter Crosthwaite
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).