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: 01e10d0272 ("pinctrl: sunxi: Implement gpiochip::get_direction()")
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
Signed-off-by: Linus Walleij <linusw@kernel.org>
This commit is contained in:
Michal Piekos 2026-03-20 18:52:31 +01:00 committed by Linus Walleij
parent 42e06688c6
commit 70f8915ea4
2 changed files with 20 additions and 2 deletions

View File

@ -1092,6 +1092,9 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
{
struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
struct sunxi_desc_function *func;
unsigned int offset;
u32 reg, shift, mask;
u8 disabled_mux, muxval;
int ret;
func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
@ -1099,8 +1102,21 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
if (!func)
return -EINVAL;
ret = gpiochip_lock_as_irq(pctl->chip,
pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
offset = pctl->irq_array[d->hwirq] - pctl->desc->pin_base;
sunxi_mux_reg(pctl, offset, &reg, &shift, &mask);
muxval = (readl(pctl->membase + reg) & mask) >> shift;
/* Change muxing to GPIO INPUT mode if at reset value */
if (pctl->flags & SUNXI_PINCTRL_NEW_REG_LAYOUT)
disabled_mux = SUN4I_FUNC_DISABLED_NEW;
else
disabled_mux = SUN4I_FUNC_DISABLED_OLD;
if (muxval == disabled_mux)
sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq],
SUN4I_FUNC_INPUT);
ret = gpiochip_lock_as_irq(pctl->chip, offset);
if (ret) {
dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));

View File

@ -86,6 +86,8 @@
#define SUN4I_FUNC_INPUT 0
#define SUN4I_FUNC_IRQ 6
#define SUN4I_FUNC_DISABLED_OLD 7
#define SUN4I_FUNC_DISABLED_NEW 15
#define SUNXI_PINCTRL_VARIANT_MASK GENMASK(7, 0)
#define SUNXI_PINCTRL_NEW_REG_LAYOUT BIT(8)