Re: [GIT pull] irq updates for 4.13

From: Tony Lindgren
Date: Tue Jul 11 2017 - 09:51:45 EST


* Thomas Gleixner <tglx@xxxxxxxxxxxxx> [170711 02:48]:
> On Tue, 11 Jul 2017, Thomas Gleixner wrote:
>
> So Tony actually provided the part of dmesg which shows the initial
> failure, which subsequently leads to the splat Sebastian reported.
>
> Unhandled fault: external abort on non-linefetch (0x1028) at 0xfb050034
> pgd = c0004000 [fb050034] *pgd=49011452(bad)
> Internal error: : 1028 [#1] SMP ARM
> Workqueue: events deferred_probe_work_func
> task: ce1d41c0 task.stack: ce1fc000
> PC is at omap_gpio_get_direction+0x2c/0x44
> LR is at _raw_spin_lock_irqsave+0x40/0x4c
> pc : [<c0509258>] lr : [<c08263c4>] psr: 60000093
> sp : ce1fdb78 ip : c0dce42c fp : ce22d810
> r10: ce22d800 r9 : 00000000 r8 : ce22d900
> r7 : 00000016 r6 : ce223864 r5 : fb050034 r4 : 00000020
> r3 : ce1d41c0 r2 : 00000000 r1 : a0000013 r0 : a0000013
> Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none
> Control: 10c5387d Table: 80004019 DAC: 00000051
> Process kworker/0:1 (pid: 14, stack limit = 0xce1fc218)
>
> The callstack is:
>
> omap_gpio_get_direction
> gpiochip_lock_as_irq
> gpiochip_irq_reqres
> __setup_irq
> request_threaded_irq
> smc_probe
> smc_drv_probe
> platform_drv_probe
> ....
>
> So the SMC91X network driver request an IRQ, which ends up calling into the
> GPIO interrupt setup and that fails. I have no idea why that would not fail
> with the patch reverted. Dusting off a Beaglebone board....

And "external abort on non-linefetch" means something is not clocked
in this case. The following alone makes things boot for me again, but I don't
quite follow what has now changed with the ordering.. Thomas, any ideas?

Anyways, adding Linus W and Grygorii to Cc since things now point to
gpio-omap.

Regards,

Tony

8< ---------------------
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -919,13 +919,24 @@ static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
struct gpio_bank *bank;
unsigned long flags;
void __iomem *reg;
- int dir;
+ int error, dir;

bank = gpiochip_get_data(chip);
reg = bank->base + bank->regs->direction;
+ error = pm_runtime_get_sync(bank->chip.parent);
+ if (error < 0) {
+ dev_err(bank->chip.parent,
+ "Could not enable gpio bank %p: %d\n",
+ bank, error);
+ pm_runtime_put_noidle(bank->chip.parent);
+
+ return error;
+ }
raw_spin_lock_irqsave(&bank->lock, flags);
dir = !!(readl_relaxed(reg) & BIT(offset));
raw_spin_unlock_irqrestore(&bank->lock, flags);
+ pm_runtime_put_sync(bank->chip.parent);
+
return dir;
}

--
2.13.2