Thread (10 messages) 10 messages, 4 authors, 2026-03-19

Re: [PATCH v3] pinctrl: sunxi: fix gpiochip_lock_as_irq() failure when pinmux is unknown

From: Andre Przywara <andre.przywara@arm.com>
Date: 2026-03-16 14:37:37
Also in: linux-gpio, linux-sunxi, lkml

Hi,

On 3/14/26 09:09, Michal Piekos wrote:
quoted hunk ↗ jump to hunk
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 <redacted>
Suggested-by: Chen-Yu Tsai <wens@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 (local)

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 (local)
---
  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, &reg, &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?
quoted hunk ↗ jump to hunk
+		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,
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help