pinctrl: sirf: add lost chained_irq_enter and exit in sirfsoc_gpio_handle_irq

This patch fixes the chained irq hang issue, tested by DM9000 driver using
GPIO0-3(irqnr=131) as the external IRQ on SiRFmarco:
   $ cat /proc/interrupts
               CPU0       CPU1
     32:       1608          0       GIC  sirfsoc_timer0
     33:          0       3197       GIC  sirfsoc_timer1
     50:      10207          0       GIC  sirfsoc-uart
     56:          2          0       GIC  cc0e0000.i2c
     70:         44          0       GIC  mmc0
    131:        333          0  sirf-gpio-irq  eth0
    ...

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Barry Song 2012-09-27 17:56:10 +08:00 коммит произвёл Linus Walleij
Родитель 1983040139
Коммит 6fd4011e16
1 изменённых файлов: 6 добавлений и 0 удалений

Просмотреть файл

@ -24,6 +24,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <asm/mach/irq.h>
#define DRIVER_NAME "pinmux-sirf" #define DRIVER_NAME "pinmux-sirf"
@ -1427,6 +1428,9 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
u32 status, ctrl; u32 status, ctrl;
int idx = 0; int idx = 0;
unsigned int first_irq; unsigned int first_irq;
struct irq_chip *chip = irq_get_chip(irq);
chained_irq_enter(chip, desc);
status = readl(bank->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id)); status = readl(bank->chip.regs + SIRFSOC_GPIO_INT_STATUS(bank->id));
if (!status) { if (!status) {
@ -1455,6 +1459,8 @@ static void sirfsoc_gpio_handle_irq(unsigned int irq, struct irq_desc *desc)
idx++; idx++;
status = status >> 1; status = status >> 1;
} }
chained_irq_exit(chip, desc);
} }
static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_bank *bank, unsigned ctrl_offset) static inline void sirfsoc_gpio_set_input(struct sirfsoc_gpio_bank *bank, unsigned ctrl_offset)