qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] i.MX: add support for lower and upper interrupt


From: Jean-Christophe DUBOIS
Subject: Re: [Qemu-devel] [PATCH] i.MX: add support for lower and upper interrupt in GPIO.
Date: Wed, 28 Oct 2015 08:10:18 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0

Le 27/10/2015 23:41, Peter Crosthwaite a écrit :


On Tue, Oct 27, 2015 at 3:32 PM, Jean-Christophe Dubois <address@hidden> wrote:
The i.MX6 GPIO device supports 2 interrupts instead of one.

* 1 for the lower 16 GPIOs.
* 1 for the upper 16 GPIOs.

i.MX31 and i.MX25 only support 1 interrupt for the 32 GPIOs.


So an architectural question, is it the case that the IP always has two outbound interrupt lines but MX31 and 25 always OR together on the SoC level?

Well, I am not part of Freescale so I just don't know anything about internal implementation details of this IP and its use inside the SOC.

What we can say is that the dual interrupt version (i.MX6) is newer than the single one (i.MX31, i.MX25). So my guess is that this is an evolution of the IP and the goal was to make GPIO interrupt handling easier, faster and prioritisable.
 

If that is the case I think it would be cleaner to do on the board level.

At the SOC level I was planning to set (or not) the new property and to assign 1 (or 2) IRQ to the device.

Regards

JC


Regards,
Peter

 
So we add a property to turn the behavior on when required.

Signed-off-by: Jean-Christophe Dubois <address@hidden>
---
 hw/gpio/imx_gpio.c         | 12 ++++++++++--
 include/hw/gpio/imx_gpio.h |  3 ++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c
index 3170585..a6d7cab 100644
--- a/hw/gpio/imx_gpio.c
+++ b/hw/gpio/imx_gpio.c
@@ -62,7 +62,12 @@ static const char *imx_gpio_reg_name(uint32_t reg)

 static void imx_gpio_update_int(IMXGPIOState *s)
 {
-    qemu_set_irq(s->irq, (s->isr & s->imr) ? 1 : 0);
+    if (s->has_upper_pin_irq) {
+        qemu_set_irq(s->irq[0], (s->isr & s->imr & 0x0000FFFF) ? 1 : 0);
+        qemu_set_irq(s->irq[1], (s->isr & s->imr & 0xFFFF0000) ? 1 : 0);
+    } else {
+        qemu_set_irq(s->irq[0], (s->isr & s->imr) ? 1 : 0);
+    }
 }

 static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level)
@@ -282,6 +287,8 @@ static const VMStateDescription vmstate_imx_gpio = {

 static Property imx_gpio_properties[] = {
     DEFINE_PROP_BOOL("has-edge-sel", IMXGPIOState, has_edge_sel, true),
+    DEFINE_PROP_BOOL("has-upper-pin-irq", IMXGPIOState, has_upper_pin_irq,
+                     false),
     DEFINE_PROP_END_OF_LIST(),
 };

@@ -311,7 +318,8 @@ static void imx_gpio_realize(DeviceState *dev, Error **errp)
     qdev_init_gpio_in(DEVICE(s), imx_gpio_set, IMX_GPIO_PIN_COUNT);
     qdev_init_gpio_out(DEVICE(s), s->output, IMX_GPIO_PIN_COUNT);

-    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[0]);
+    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[1]);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
 }

diff --git a/include/hw/gpio/imx_gpio.h b/include/hw/gpio/imx_gpio.h
index 517b261..b15a09f 100644
--- a/include/hw/gpio/imx_gpio.h
+++ b/include/hw/gpio/imx_gpio.h
@@ -54,8 +54,9 @@ typedef struct IMXGPIOState {
     uint32_t isr;
     bool has_edge_sel;
     uint32_t edge_sel;
+    bool has_upper_pin_irq;

-    qemu_irq irq;
+    qemu_irq irq[2];
     qemu_irq output[IMX_GPIO_PIN_COUNT];
 } IMXGPIOState;

--
2.5.0




reply via email to

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