Skip to content

Commit 70f8915

Browse files
michalpiekoslinusw
authored andcommitted
pinctrl: sunxi: fix gpiochip_lock_as_irq() failure when pinmux is unknown
Fixes kernel hang during boot due to inability to set up IRQ on AXP313a. The issue is caused by gpiochip_lock_as_irq() which is failing when gpio is in uninitialized state. Solution is to set pinmux to GPIO INPUT in sunxi_pinctrl_irq_request_resources() if it wasn't initialized earlier. Tested on Orange Pi Zero 3. Fixes: 01e10d0 ("pinctrl: sunxi: Implement gpiochip::get_direction()") Reviewed-by: Andre Przywara <[email protected]> Reviewed-by: Chen-Yu Tsai <[email protected]> Signed-off-by: Michal Piekos <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent 42e0668 commit 70f8915

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

drivers/pinctrl/sunxi/pinctrl-sunxi.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,15 +1092,31 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
10921092
{
10931093
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
10941094
struct sunxi_desc_function *func;
1095+
unsigned int offset;
1096+
u32 reg, shift, mask;
1097+
u8 disabled_mux, muxval;
10951098
int ret;
10961099

10971100
func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
10981101
pctl->irq_array[d->hwirq], "irq");
10991102
if (!func)
11001103
return -EINVAL;
11011104

1102-
ret = gpiochip_lock_as_irq(pctl->chip,
1103-
pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
1105+
offset = pctl->irq_array[d->hwirq] - pctl->desc->pin_base;
1106+
sunxi_mux_reg(pctl, offset, &reg, &shift, &mask);
1107+
muxval = (readl(pctl->membase + reg) & mask) >> shift;
1108+
1109+
/* Change muxing to GPIO INPUT mode if at reset value */
1110+
if (pctl->flags & SUNXI_PINCTRL_NEW_REG_LAYOUT)
1111+
disabled_mux = SUN4I_FUNC_DISABLED_NEW;
1112+
else
1113+
disabled_mux = SUN4I_FUNC_DISABLED_OLD;
1114+
1115+
if (muxval == disabled_mux)
1116+
sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq],
1117+
SUN4I_FUNC_INPUT);
1118+
1119+
ret = gpiochip_lock_as_irq(pctl->chip, offset);
11041120
if (ret) {
11051121
dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
11061122
irqd_to_hwirq(d));

drivers/pinctrl/sunxi/pinctrl-sunxi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@
8686

8787
#define SUN4I_FUNC_INPUT 0
8888
#define SUN4I_FUNC_IRQ 6
89+
#define SUN4I_FUNC_DISABLED_OLD 7
90+
#define SUN4I_FUNC_DISABLED_NEW 15
8991

9092
#define SUNXI_PINCTRL_VARIANT_MASK GENMASK(7, 0)
9193
#define SUNXI_PINCTRL_NEW_REG_LAYOUT BIT(8)

0 commit comments

Comments
 (0)