From nobody Fri Apr 3 22:19:48 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2D0F338838A; Mon, 23 Mar 2026 11:02:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774263737; cv=none; b=RN6q2m5yB0xUDOfMKi1viU/cXc+5amvQfwFbyJ+N6hznSmTLdsdc5BDBH01fN8ZPYRF/449nOvhAZLPUJtxnYPwPxCszpN3M5sOO1laBsT2aU7LrZGtuIUVWAhXm9GHViJJAtPEruip4Ay9bp3+6dlZuwKgONSgxKIziox7BU5Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774263737; c=relaxed/simple; bh=BdcEra9FbAB3SE5ZyznxdSUBQYhHbt1CSIJp0DdTRCo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MON7eXG8tG0y33k4kINdSplsr1mHYy0SiSBpnMZLEVvKTT38bf9fwYX28jHWHqcnrmw2bcgea9M0ePLMe7rVSOE5WGd+XDV57LRgmSi6nRajwef/NCk1NSQyAWEDTLbeYZu/XvbmfiXNJAltrzsYNpv3pwBv5uEhbEehJVd+gJU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A37F6169E; Mon, 23 Mar 2026 04:02:08 -0700 (PDT) Received: from e142021.fritz.box (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C4FD23F73B; Mon, 23 Mar 2026 04:02:11 -0700 (PDT) From: Andre Przywara To: Linus Walleij , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Michal Piekos , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH 5/5] pinctrl: sunxi: a523: add missing IRQ bank (plus old DT workaround) Date: Mon, 23 Mar 2026 12:01:51 +0100 Message-ID: <20260323110151.2352832-6-andre.przywara@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260323110151.2352832-1-andre.przywara@arm.com> References: <20260323110151.2352832-1-andre.przywara@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Allwinner A532 SoC implements 10 GPIO banks, each of which is interrupt capable. However the first bank (PortA) is skipped, so the indicies of those banks range from 1 to 10, not 0 to 9. We described the skipped bank correctly, but missed that for the IRQ banks, where we rely on the IRQ bank index to be aligned with the MMIO register offset, starting at 0x200. Correct that by increasing the number of IRQ banks to 11, to cover both the first skipped one, but also the last one (PortK). This fixes a bug where the interrupt numbers would be off-by-one, due to that mis-enumeration. The big caveat is that now old DTs break the kernel, since they only provide 10 interrupts, and the driver bails out entirely due to the last missing one. So add a workaround for this particular case, where we detect the requirement for 11 banks, but only 10 interrupts provided, and continue with 10 IRQs, albeit emitting a warning about a DT update. This would still be broken in terms of interrupt assignment, but it was broken the whole time before, so it's not a regression. Signed-off-by: Andre Przywara Reviewed-by: Chen-Yu Tsai --- drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c | 2 +- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 22 +++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c b/drivers/pinctrl/= sunxi/pinctrl-sun55i-a523.c index b6f78f1f30ac..a1d157de53d2 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c @@ -17,7 +17,7 @@ static const u8 a523_nr_bank_pins[SUNXI_PINCTRL_MAX_BANKS= ] =3D /* PA PB PC PD PE PF PG PH PI PJ PK */ { 0, 15, 17, 24, 16, 7, 15, 20, 17, 28, 24 }; =20 -static const unsigned int a523_irq_bank_map[] =3D { 0, 1, 2, 3, 4, 5, 6, 7= , 8, 9 }; +static const unsigned int a523_irq_bank_map[] =3D { 0, 1, 2, 3, 4, 5, 6, 7= , 8, 9, 10 }; =20 static const u8 a523_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =3D /* PA PB PC PD PE PF PG PH PI PJ PK */ diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/= pinctrl-sunxi.c index 6a86b7989b25..ffee79397590 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1582,6 +1583,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_dev= ice *pdev, struct sunxi_pinctrl *pctl; struct pinmux_ops *pmxops; int i, ret, last_pin, pin_idx; + int num_irq_banks; struct clk *clk; =20 pctl =3D devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); @@ -1715,16 +1717,20 @@ int sunxi_pinctrl_init_with_flags(struct platform_d= evice *pdev, goto gpiochip_error; } =20 - pctl->irq =3D devm_kcalloc(&pdev->dev, - pctl->desc->irq_banks, - sizeof(*pctl->irq), - GFP_KERNEL); + num_irq_banks =3D pctl->desc->irq_banks; + /* Workaround for old A523 DT, exposing one less interrupt. */ + if (num_irq_banks =3D=3D 11 && of_irq_count(node) < 11) { + num_irq_banks =3D 10; + pr_warn("Not enough PIO interrupts, please update your DT!\n"); + } + pctl->irq =3D devm_kcalloc(&pdev->dev, num_irq_banks, + sizeof(*pctl->irq), GFP_KERNEL); if (!pctl->irq) { ret =3D -ENOMEM; goto gpiochip_error; } =20 - for (i =3D 0; i < pctl->desc->irq_banks; i++) { + for (i =3D 0; i < num_irq_banks; i++) { pctl->irq[i] =3D platform_get_irq(pdev, i); if (pctl->irq[i] < 0) { ret =3D pctl->irq[i]; @@ -1733,7 +1739,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_dev= ice *pdev, } =20 pctl->domain =3D irq_domain_create_linear(dev_fwnode(&pdev->dev), - pctl->desc->irq_banks * IRQ_PER_BANK, + num_irq_banks * IRQ_PER_BANK, &sunxi_pinctrl_irq_domain_ops, pctl); if (!pctl->domain) { dev_err(&pdev->dev, "Couldn't register IRQ domain\n"); @@ -1741,7 +1747,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_dev= ice *pdev, goto gpiochip_error; } =20 - for (i =3D 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) { + for (i =3D 0; i < (num_irq_banks * IRQ_PER_BANK); i++) { int irqno =3D irq_create_mapping(pctl->domain, i); =20 irq_set_lockdep_class(irqno, &sunxi_pinctrl_irq_lock_class, @@ -1751,7 +1757,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_dev= ice *pdev, irq_set_chip_data(irqno, pctl); } =20 - for (i =3D 0; i < pctl->desc->irq_banks; i++) { + for (i =3D 0; i < num_irq_banks; i++) { /* Mask and clear all IRQs before registering a handler */ writel(0, pctl->membase + sunxi_irq_ctrl_reg_from_bank(pctl->desc, i)); --=20 2.43.0