Re: [PATCH] pinctrl: sunxi: dt: number the IRQ banks from the first one that has IRQs
From: Andre Przywara
Date: Wed Sep 30 2026 - 13:15:40 EST
Hi Pablo,
thanks for sending a patch!
On 9/29/26 22:36, Pablo Mazzini wrote:
prepare_function_table() assumes the first pin is in bank 0. On the
A523, which has no PA pins, every IRQ bank is numbered one too high:
the last bank writes past the end of irq_array, and interrupts are
looked up at the wrong offsets.
Yes, this is a known issue, and I already provided a quite different fix for this[1]: the A523 manual actually lists a PortA GPIO interrupt, even though this is pretty likely not functional. But specifying this IRQ in the DT fixes the problem as well.
The DT binding does not say how the IRQs are assigned to the GPIO ports, so from that point of view my solution is similarly usable as yours - though admittedly yours looks a little better and more future proof.
I guess we now need to figure out how we want to handle this in the future, and add an explanation to the binding. The A733 has a similar problem: PortA does not exist. This time the manual does not explicitly specify a GPIO IRQ, but conspicuously leaves a gap before the PortB GPIO IRQ, so we can use that as well.
Linus, Chen-Yu, Jernej: what do you think?
Cheers,
Andre
[1] https://lore.kernel.org/linux-sunxi/20260327113006.3135663-4-andre.przywara@xxxxxxx/
Count the IRQ banks from the first bank that has interrupts.
Fixes: f5e2cd34b12f ("pinctrl: sunxi: allow reading mux values from DT")
Signed-off-by: Pablo Mazzini <pmazzini@xxxxxxxxx>
---
drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c b/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
index 50a16f3bd131..9c5eb21a86a5 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
@@ -208,7 +208,7 @@ static int prepare_function_table(struct device *dev, struct device_node *pnode,
* The extra functions will be filled in later.
*/
irq_bank = 0;
- last_bank = 0;
+ last_bank = -1;
for (i = 0; i < npins; i++) {
struct sunxi_desc_pin *pin = &pins[i];
int bank = (pin->pin.number - pin_base) / PINS_PER_BANK;
@@ -221,16 +221,14 @@ static int prepare_function_table(struct device *dev, struct device_node *pnode,
func[1].muxval = 1;
if (irq_mux) {
- if (bank > last_bank)
+ if (last_bank >= 0 && bank > last_bank)
irq_bank++;
func[lastfunc].muxval = irq_mux;
func[lastfunc].irqbank = irq_bank;
func[lastfunc].irqnum = pin->pin.number % PINS_PER_BANK;
func[lastfunc].name = "irq";
- }
-
- if (bank > last_bank)
last_bank = bank;
+ }
pin->functions = func;