Re: [PATCH] pinctrl: sunxi: dt: number the IRQ banks from the first one that has IRQs
From: Linus Walleij
Date: Thu Oct 01 2026 - 08:40:49 EST
On Tue, Sep 29, 2026 at 10:37 PM Pablo Mazzini <pmazzini@xxxxxxxxx> 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,
Why don't you add a patch to protect against that?
Something like this (completely untested, not even compiled)
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 31cd142ce0f7..c0c90d9e3215 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -1632,9 +1632,10 @@ int sunxi_pinctrl_init_with_flags(struct
platform_device *pdev,
else
pctl->pow_mod_sel_offset = PIO_POW_MOD_SEL_REG;
+ pctl->irqs = IRQ_PER_BANK * pctl->desc->irq_banks;
pctl->irq_array = devm_kcalloc(&pdev->dev,
- IRQ_PER_BANK * pctl->desc->irq_banks,
- sizeof(*pctl->irq_array),
+ pctl->irqs,
+ sizeof(unsigned int),
GFP_KERNEL);
if (!pctl->irq_array)
return -ENOMEM;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index 8bd00c6ff628..9e0ed9c0c1ee 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -176,7 +176,8 @@ struct sunxi_pinctrl {
struct sunxi_pinctrl_group *groups;
unsigned ngroups;
int *irq;
- unsigned *irq_array;
+ unsigned irq_array[] __counted_by(irqs);
+ unsigned irqs;
raw_spinlock_t lock;
/*
* Output latch shadow, one word per bank. Seeded lockless at
> and interrupts are
> looked up at the wrong offsets.
>
> Count the IRQ banks from the first bank that has interrupts.
(...)
> 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;
> + }
This looks reasonable.
Yours,
Linus Walleij