GPIO IRQ on P1022
Hi,
I'm running kernel 3.0 on a custom board based on Freescale P1022. The interrupt line of on-board FPGA is connected to GPIO2_9. FPGA IRQ is level, active low. The GPIOs are mapped like this:
GPIOs 160-191, /soc@ffe00000/gpio-controller@f200:
GPIOs 192-223, /soc@ffe00000/gpio-controller@f100:
GPIOs 224-255, /soc@ffe00000/gpio-controller@f000:
I've verified that pin mixing is done correctly, and the FPGA IRQ line is indeed configured as GPIO.
I have the following code in my driver:
#define FPGA_IRQ_GPIO 169
err = gpio_request(FPGA_IRQ_GPIO, "FPGA IRQ");
if (err) {
printk(KERN_ERR "Failed to request FPGA IRQ GPIO, err=%d\n",
err);
goto out;
}
gpio_direction_input(FPGA_IRQ_GPIO);
irq = gpio_to_irq(FPGA_IRQ_GPIO);
if (irq < 0) {
printk(KERN_ERR "Failed to map FPGA GPIO to IRQ\n");
goto out;
}
err = request_irq(irq, gsat_interrupt,
IRQF_TRIGGER_FALLING, DRVNAME, priv);
Interrupt handler reads FPGA interrupt status register to clear interrupt
and exits.
What happens when I load my driver is single execution of
interrupt handler
followed by system freeze. Even if I call disable_irq() in
interrupt handler the
system still freezes.
I've added some prints to mpc8xxx_gpio.c driver, here's what I get:
mpc8xxx_gpio_to_irq: offset 9
mpc8xxx_gpio_irq_map: virq 31
irq: irq 9 on host /soc@ffe00000/gpio-controller@f200 mapped to
virtual irq 31
mpc8xxx_irq_set_type: virq 9 flow_type 2
mpc8xxx_irq_unmask: irq 9
mpc8xxx_gpio_irq_cascade: irq 47
mpc8xxx_irq_mask: irq 9
mpc8xxx_irq_ack: irq 9
What am I doing wrong ?
Thanks a lot.
Felix.
Quoted 6 lines · Felix Radensky
What happens when I load my driver is single execution of interrupt
handler
followed by system freeze. Even if I calldisable_irq()in interrupt
handler the
system still freezes.
I don't know anything about the GPIO layer, but I think you're going to=20 need to debug this a little more. Where exactly is the freeze? Are you=20 sure the interrupt handler is being called only once? Perhaps you're not=20 clearing the interrupt status and your handler is being called repeatedly?
--=20
Timur Tabi
Linux kernel developer at Freescale=
Hi Timur,
Quoted 11 lines · On 07/31/2011 04:59 PM, Tabi Timur-B04825 wrote:
Quoted 5 lines · Felix Radensky
What happens when I load my driver is single execution of interrupt
handler
followed by system freeze. Even if I calldisable_irq()in interrupt
handler the
system still freezes.I don't know anything about the GPIO layer, but I think you're going to need to debug this a little more. Where exactly is the freeze? Are you sure the interrupt handler is being called only once? Perhaps you're not clearing the interrupt status and your handler is being called repeatedly?
It was verified with oscilloscope that interrupt handler clears the interrupt. The interrupt line goes from low to high and stays there. I have prints in interrupt handler, they appear only once.
It's difficult to say where it freezes. I've tried magic sysrq on serial console, but got nothing.
Felix.
Hi,
Quoted 11 lines · On 07/31/2011 04:59 PM, Tabi Timur-B04825 wrote:
Quoted 5 lines · Felix Radensky
What happens when I load my driver is single execution of interrupt
handler
followed by system freeze. Even if I calldisable_irq()in interrupt
handler the
system still freezes.I don't know anything about the GPIO layer, but I think you're going to need to debug this a little more. Where exactly is the freeze? Are you sure the interrupt handler is being called only once? Perhaps you're not clearing the interrupt status and your handler is being called repeatedly?
I'm trying to debug this problem, without much luck so far. I've enabled hard and soft lock-up detection and various locking debugging options in kernel configuration but nothing shows up. I've also tried KGDB over serial line, and was able to hit the breakpoint in mpc8xxx_gpio code, but was unable to step through the code, gdb just freezes.
I'm getting the following after system locks up:
nfs: server 10.0.0.10 not responding, still trying NETDEV WATCHDOG: eth0 (fsl-gianfar): transmit queue 0 timed out
------------[ cut here ]------------ WARNING: at net/sched/sch_generic.c:255 Modules linked in: gsat hal NIP: c01a5e9c LR: c01a5e9c CTR: c01576bc REGS: dfff1e90 TRAP: 0700 Not tainted (3.0.0) MSR: 00029000 <EE,ME,CE> CR: 24044082 XER: 20000000
TASK = c02df3b8[0] 'swapper' THREAD: c02ee000
GPR00: c01a5e9c dfff1f40 c02df3b8 00000046 00003d04 ffffffff c01546e4 00003d04
GPR08: c02e0000 c02ed710 00003d04 00000002 84044042 7dcac9f0 00000000 00000000
GPR16: 1ff8c184 1ffa95e0 c0284070 c02f9dc0 c02fabec c02fa9ec c02fa7ec c02fa5ec
GPR24: 00200200 dfff1f68 c02e0000 dfff0000 c034c138 c02e0000 df011000 00000000 NIP [c01a5e9c] dev_watchdog+0x298/0x2a8
LR [c01a5e9c] dev_watchdog+0x298/0x2a8
Call Trace:
[dfff1f40] [c01a5e9c] dev_watchdog+0x298/0x2a8 (unreliable)
[dfff1f60] [c00434e8] run_timer_softirq+0x1a4/0x1e0
[dfff1fb0] [c003cf20] __do_softirq+0x9c/0x114
[dfff1ff0] [c000c8a0] call_do_softirq+0x14/0x24
[c02efe90] [c00049ec] do_softirq+0x74/0x80
[c02efeb0] [c003d174] irq_exit+0x98/0x9c
[c02efec0] [c0009944] timer_interrupt+0xb4/0x118
[c02efed0] [c000e018] ret_from_except+0x0/0x18
--- Exception: 901 at cpu_idle+0x98/0xd8
LR = cpu_idle+0x98/0xd8
[c02eff90] [c0008238] cpu_idle+0x50/0xd8 (unreliable)
[c02effb0] [c00022e4] rest_init+0x64/0x78
[c02effc0] [c02bb86c] start_kernel+0x244/0x2c0
[c02efff0] [c00003a0] skpinv+0x2b8/0x2f4
Instruction dump:
38000001 7c0903a6 4bfffe40 7fc3f378 4bfe7045 7fe6fb78 7c651b78 3c60c02a
7fc4f378 38639ac4 4cc63182 4be921dd <0fe00000> 38000001 981c0001 4bffff9c
---[ end trace 5d45e0fe33774f9c ]---What else can be done to find the problem. ?
Thanks a lot in advance.
Felix.
Quoted 37 lines · Felix Radensky
Hi,
I'm running kernel 3.0 on a custom board based on Freescale P1022. The interrupt line of on-board FPGA is connected to
GPIO2_9. FPGA IRQ is level, active low. The GPIOs are mapped like this:GPIOs 160-191, /soc@ffe00000/gpio-controller@f200:
GPIOs 192-223, /soc@ffe00000/gpio-controller@f100:
GPIOs 224-255, /soc@ffe00000/gpio-controller@f000:
I've verified that pin mixing is done correctly, and the FPGA IRQ line is indeed configured as GPIO.
I have the following code in my driver:
#define FPGA_IRQ_GPIO 169 err = gpio_request(FPGA_IRQ_GPIO, "FPGA IRQ"); if (err) { printk(KERN_ERR "Failed to request FPGA IRQ GPIO, err=%d\n", err); goto out; } gpio_direction_input(FPGA_IRQ_GPIO); irq = gpio_to_irq(FPGA_IRQ_GPIO); if (irq < 0) { printk(KERN_ERR "Failed to map FPGA GPIO to IRQ\n"); goto out; } err = request_irq(irq, gsat_interrupt, IRQF_TRIGGER_FALLING, DRVNAME, priv); Interrupt handler reads FPGA interrupt status register to clear
Quoted 8 lines
interrupt
and exits.What happens when I load my driver is single execution of interrupt
handler
followed by system freeze. Even if I calldisable_irq()in interrupt
handler the
system still freezes.
Try disable_irq_nosync() instead.
Wolfgang.
Hi Wolfgang,
Quoted 41 lines · Wolfgang Grandegger
Quoted 40 lines · Felix Radensky
Hi,
I'm running kernel 3.0 on a custom board based on Freescale P1022. The interrupt line of on-board FPGA is connected to
GPIO2_9. FPGA IRQ is level, active low. The GPIOs are mapped like this:GPIOs 160-191, /soc@ffe00000/gpio-controller@f200:
GPIOs 192-223, /soc@ffe00000/gpio-controller@f100:
GPIOs 224-255, /soc@ffe00000/gpio-controller@f000:
I've verified that pin mixing is done correctly, and the FPGA IRQ line is indeed configured as GPIO.
I have the following code in my driver:
#define FPGA_IRQ_GPIO 169 err = gpio_request(FPGA_IRQ_GPIO, "FPGA IRQ"); if (err) { printk(KERN_ERR "Failed to request FPGA IRQ GPIO, err=%d\n", err); goto out; } gpio_direction_input(FPGA_IRQ_GPIO); irq = gpio_to_irq(FPGA_IRQ_GPIO); if (irq< 0) { printk(KERN_ERR "Failed to map FPGA GPIO to IRQ\n"); goto out; } err = request_irq(irq, gsat_interrupt, IRQF_TRIGGER_FALLING, DRVNAME, priv); Interrupt handler reads FPGA interrupt status register to clearinterrupt
and exits.
Quoted 8 lines
Quoted 5 lines
What happens when I load my driver is single execution of interrupt
handler
followed by system freeze. Even if I calldisable_irq()in interrupt
handler the
system still freezes.Try
disable_irq_nosync()instead.
Thanks. However this doesn't help either.
Felix.
Hi Felix,
Quoted 9 lines · Felix Radensky
Hi Wolfgang,
Quoted 6 lines · Wolfgang Grandegger
Quoted 5 lines · Felix Radensky
Hi,
I'm running kernel 3.0 on a custom board based on Freescale P1022. The interrupt line of on-board FPGA is connected to
GPIO2_9. FPGA IRQ is level, active low. The GPIOs are mapped like this:
Here you say that it's a level sensitive interrupt but ...
Quoted 22 lines
Quoted 22 lines
Quoted 22 lines
GPIOs 160-191, /soc@ffe00000/gpio-controller@f200:
GPIOs 192-223, /soc@ffe00000/gpio-controller@f100:
GPIOs 224-255, /soc@ffe00000/gpio-controller@f000:
I've verified that pin mixing is done correctly, and the FPGA IRQ line is indeed configured as GPIO.
I have the following code in my driver:
#define FPGA_IRQ_GPIO 169 err = gpio_request(FPGA_IRQ_GPIO, "FPGA IRQ"); if (err) { printk(KERN_ERR "Failed to request FPGA IRQ GPIO, err=%d\n", err); goto out; } gpio_direction_input(FPGA_IRQ_GPIO);
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
irq = gpio_to_irq(FPGA_IRQ_GPIO); if (irq< 0) { printk(KERN_ERR "Failed to map FPGA GPIO to IRQ\n"); goto out; } err = request_irq(irq, gsat_interrupt, IRQF_TRIGGER_FALLING, DRVNAME, priv);
.. you request here an edge triggered interrupt.
Wolfgang.
Hi Wolfgang,
Quoted 42 lines · Wolfgang Grandegger
Hi Felix,
Quoted 9 lines · Felix Radensky
Hi Wolfgang,
Quoted 6 lines · Wolfgang Grandegger
Quoted 5 lines · Felix Radensky
Hi,
I'm running kernel 3.0 on a custom board based on Freescale P1022. The interrupt line of on-board FPGA is connected to
GPIO2_9. FPGA IRQ is level, active low. The GPIOs are mapped like this:Here you say that it's a level sensitive interrupt but ...
Quoted 28 lines
Quoted 28 lines
Quoted 28 lines
GPIOs 160-191, /soc@ffe00000/gpio-controller@f200:
GPIOs 192-223, /soc@ffe00000/gpio-controller@f100:
GPIOs 224-255, /soc@ffe00000/gpio-controller@f000:
I've verified that pin mixing is done correctly, and the FPGA IRQ line is indeed configured as GPIO.
I have the following code in my driver:
#define FPGA_IRQ_GPIO 169 err = gpio_request(FPGA_IRQ_GPIO, "FPGA IRQ"); if (err) { printk(KERN_ERR "Failed to request FPGA IRQ GPIO, err=%d\n", err); goto out; } gpio_direction_input(FPGA_IRQ_GPIO); irq = gpio_to_irq(FPGA_IRQ_GPIO); if (irq< 0) { printk(KERN_ERR "Failed to map FPGA GPIO to IRQ\n"); goto out; }
Quoted 3 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
err = request_irq(irq,
gsat_interrupt,
IRQF_TRIGGER_FALLING, DRVNAME, priv);.. you request here an edge triggered interrupt.
Yes, that is is correct. mpc8xxx_gpio.c driver does not allow level sensitive interrupts, so I had no choice but to specify IRQF_TRIGGER_FALLING.
Felix.