Skip to contentSkip to conversation

GPIO IRQ on P1022

DISCUSSION Felix Radensky 3 participants 8 messages Jul 31, 2011 – Aug 2, 2011

lore
Share & tools
lore
#0 lore raw

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.

#1 lore raw
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 call disable_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=

#2 lore raw

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 call disable_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.

#3 lore raw
In reply to Tabi Timur-B04825

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 call disable_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.

#4 lore raw
In reply to Felix Radensky
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 call disable_irq() in interrupt
handler the
system still freezes.

Try disable_irq_nosync() instead.

Wolfgang.

#5 lore raw

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 clear

interrupt
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 call disable_irq() in interrupt
handler the
system still freezes.

Try disable_irq_nosync() instead.

Thanks. However this doesn't help either.

Felix.

#6 lore raw

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.

#7 lore raw

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.