imx6 GPIO1 interrupts

3 messages, 3 authors, 2015-06-25 · open the first message on its own page

imx6 GPIO1 interrupts

From: Joshua Clayton <hidden>
Date: 2015-02-19 18:09:40

Freescale imx6 has gpios use shared irqs that trigger across 16 pins
at a time. These are supported in the mainline kernel.

The first 8 pins on GPIO1 also have their own interrupts on the GIC.
I have a kluge sort of working,  and am wondering what it would take
for me to fully support these in a way that might be mainlined.

What I am doing:
(error checking removed for brevity)

        /* request the shared gpio irq to set the correct edge bits */
        gpiod = gpiod_get(my->dev, "diffirq");
        ret = gpiod_direction_input(gpiod);
        fake_irq = gpiod_to_irq(gpiod);
        ret = request_irq(fake_irq, no_action, 0, "gpio irq", mydev);

        /* Use the ARM GPIO4 irq */
        mydev->irq = irq_of_parse_and_map(mydev->dev->of_node, 0);

        ret = request_irq(mydev->irq, my_irq_handler, 0, "my fpga", mydev);

        disable_irq(mydev->irq);
        enable_irq(mydev->irq);

This seems to work, but both irq appear in /proc/interrupts, and if I
try to change the affinity of the hard irq the gpio irq gets all the
traffic (or something)

Looking at the code in drivers/gpio/gpio-mxc.c, it seems like almost
all the code for full hardware irq support is already there, but just
out of reach to my brain. I think I just need the hardware irq to call
gpio_set_irq_type() for its set_type function.

What is the proper way to do this? Do I need another virtual irq_chip
for the 8 gpio1 irqs? Can something like that be set up in the gpio
probe, or do I need to catch it earlier when the GIC is being
probed/initialized?

...or am I way off base here?

Joshua Clayton

imx6 GPIO1 interrupts

From: Uwe Kleine-König <hidden>
Date: 2015-06-25 09:08:28

Hello,

probably not helpful for your original question, but ...

On Thu, Feb 19, 2015 at 10:09:40AM -0800, Joshua Clayton wrote:
Freescale imx6 has gpios use shared irqs that trigger across 16 pins
at a time. These are supported in the mainline kernel.

The first 8 pins on GPIO1 also have their own interrupts on the GIC.
I have a kluge sort of working,  and am wondering what it would take
for me to fully support these in a way that might be mainlined.

What I am doing:
(error checking removed for brevity)

        /* request the shared gpio irq to set the correct edge bits */
        gpiod = gpiod_get(my->dev, "diffirq");
        ret = gpiod_direction_input(gpiod);
... you should make this read:

	gpiod = gpiod_get(my->dev, "diffirq", GPIOD_IN);

instead. It's easier and gpiod_get with only two parameters will go away
soon.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

imx6 GPIO1 interrupts

From: Marc Zyngier <hidden>
Date: 2015-06-25 09:39:02

[I only saw this thanks to Uwe who just replied...]
On 19/02/15 18:09, Joshua Clayton wrote:
Freescale imx6 has gpios use shared irqs that trigger across 16 pins
at a time. These are supported in the mainline kernel.

The first 8 pins on GPIO1 also have their own interrupts on the GIC.
I have a kluge sort of working,  and am wondering what it would take
for me to fully support these in a way that might be mainlined.

What I am doing:
(error checking removed for brevity)

        /* request the shared gpio irq to set the correct edge bits */
        gpiod = gpiod_get(my->dev, "diffirq");
        ret = gpiod_direction_input(gpiod);
        fake_irq = gpiod_to_irq(gpiod);
        ret = request_irq(fake_irq, no_action, 0, "gpio irq", mydev);

        /* Use the ARM GPIO4 irq */
        mydev->irq = irq_of_parse_and_map(mydev->dev->of_node, 0);

        ret = request_irq(mydev->irq, my_irq_handler, 0, "my fpga", mydev);

        disable_irq(mydev->irq);
        enable_irq(mydev->irq);

This seems to work, but both irq appear in /proc/interrupts, and if I
try to change the affinity of the hard irq the gpio irq gets all the
traffic (or something)

Looking at the code in drivers/gpio/gpio-mxc.c, it seems like almost
all the code for full hardware irq support is already there, but just
out of reach to my brain. I think I just need the hardware irq to call
gpio_set_irq_type() for its set_type function.

What is the proper way to do this? Do I need another virtual irq_chip
for the 8 gpio1 irqs? Can something like that be set up in the gpio
probe, or do I need to catch it earlier when the GIC is being
probed/initialized?

...or am I way off base here?
This looks like something very similar to drivers/irqchip/irq-mtk-sysirq.c.

You may have to adapt your DT to make the devices point to the GPIO
block as an interrupt controller though.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help