[PATCH v3] pinctrl: sunxi: fix gpiochip_lock_as_irq() failure when pinmux is unknown
Andre Przywara
andre.przywara at arm.com
Mon Mar 16 07:37:32 PDT 2026
Hi,
On 3/14/26 09:09, Michal Piekos wrote:
> 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 unitialized 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.
>
> Signed-off-by: Michal Piekos <michal.piekos at mmpsystems.pl>
> Suggested-by: Chen-Yu Tsai <wens at kernel.org>
> ---
> Changes in v3:
> - Drop v2 solution which was returning input instead of error when pin
> is not initialized.
> - Add checking pinmux configuration in
> sunxi_pinctrl_irq_request_resources() and set pin to input if
> uninitialized
> - Link to v2: https://lore.kernel.org/r/20260308-rc2-boot-hang-v2-1-516fdb820953@mmpsystems.pl
>
> Changes in v2:
> - Dropped the previous faulty solution which was forcing the axp313 to
> use r_pio as interrupt controller as pointed out by Jernej Škrabec.
> - Implemented suggestion from Andrey Skvortsov to return default
> direction as input
> - Link to v1: https://lore.kernel.org/r/20260308-rc2-boot-hang-v1-0-d792d1a78dfd@mmpsystems.pl
> ---
> drivers/pinctrl/sunxi/pinctrl-sunxi.c | 13 +++++++++++++
> drivers/pinctrl/sunxi/pinctrl-sunxi.h | 1 +
> 2 files changed, 14 insertions(+)
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> index c990b6118172..7d46f7613672 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> @@ -1089,6 +1089,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 muxval;
> int ret;
>
> func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
> @@ -1096,6 +1099,16 @@ static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
> if (!func)
> return -EINVAL;
>
> + offset = pctl->irq_array[d->hwirq] - pctl->desc->pin_base;
> + sunxi_mux_reg(pctl, offset, ®, &shift, &mask);
> + muxval = (readl(pctl->membase + reg) & mask) >> shift;
> +
> + /* Change muxing to GPIO INPUT mode if at reset value */
> + if (muxval == SUN4I_FUNC_IO_DISABLE) {
The "high impedance"/reset value depends on the SoC generation: older
SoCs didn't have one, so they used 0 (GPIO_INPUT), which is the closest
to "off" you can get there. Most SoCs afterwards indeed used 0x7, as you
set below, but newer SoCs (D1/T113, A523, ...) use 0xf now.
Would it work to do:
if (muxval != SUN4I_FUNC_INPUT) {
or shall we just force SUN4I_FUNC_INPUT always, without even checking?
Or can there be other settings already (for instance the IRQ function)?
Not really familiar with the call chain here, but shouldn't the mux be
set to the IRQ function (0x6/0xe) here anyway?
> + sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq],
> + SUN4I_FUNC_INPUT);
> + }
> +
> ret = gpiochip_lock_as_irq(pctl->chip,
> pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
> if (ret) {
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> index ad26e4de16a8..22c527fc6ae2 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> @@ -86,6 +86,7 @@
>
> #define SUN4I_FUNC_INPUT 0
> #define SUN4I_FUNC_IRQ 6
> +#define SUN4I_FUNC_IO_DISABLE 7
As mentioned above, this cannot be a simple fixed define for all SoCs.
Cheers,
Andre
>
> #define SUNXI_PINCTRL_VARIANT_MASK GENMASK(7, 0)
> #define SUNXI_PINCTRL_NEW_REG_LAYOUT BIT(8)
>
> ---
> base-commit: 4ae12d8bd9a830799db335ee661d6cbc6597f838
> change-id: 20260308-rc2-boot-hang-269e8546635b
>
> Best regards,
More information about the linux-arm-kernel
mailing list