* [PATCH v4 00/11] ARM: sunxi: add Allwinner B288 and the PocketBook Verse
@ 2026-10-12 10:08 Pablo Mazzini
2026-10-12 10:08 ` [PATCH v4 03/11] dt-bindings: pinctrl: sun4i-a10: add Allwinner B288 Pablo Mazzini
2026-10-12 10:08 ` [PATCH v4 04/11] pinctrl: sunxi: add Allwinner B288 pin controller driver Pablo Mazzini
0 siblings, 2 replies; 4+ messages in thread
From: Pablo Mazzini @ 2026-10-12 10:08 UTC (permalink / raw)
To: Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: Pablo Mazzini, Andre Przywara, devicetree, linux-arm-kernel,
linux-clk, linux-gpio, linux-i2c, linux-kernel, linux-rtc,
linux-sunxi, linux-watchdog
The Allwinner B288 (sun8iw10p1) is a dual Cortex-A7 SoC used in e-book
readers. This series adds the CCU and pin controller drivers, the RTC,
I2C, NMI and watchdog compatibles, the SoC .dtsi, and one board: the
PocketBook Verse (PB629), a 6" reader.
The B288 is closest to the A64: most of its PLLs are bit-identical.
The clock and pin descriptions come from Allwinner's BSP, cross-checked
against ccu-sun50i-a64.c. Tested on a PB629, boots to userspace.
The pin controller relies on "pinctrl: sunxi: dt: number the IRQ banks
from the first one that has IRQs" for correct PIO interrupt mapping.
Changes since v3:
- CCU: reference parents with clk_parent_data and clk_hw pointers,
as newer sunxi-ng drivers do; add the audio PLL's sigma-delta
settings, as on the A64; fix the PLL_24M rate and parent the PLLs
to it.
- RTC: register the 32 kHz clocks, reusing the A23 data (Sashiko).
- DTS: take osc32k from the RTC, as on the A64.
- DTS: allow the eMMC up to 150 MHz, as on the A523.
Changes since v2:
- Drop the MMC binding patch, applied by Ulf.
- Rebase onto sunxi/for-next.
- Constrain the RTC clock outputs and pinctrl interrupts in the
bindings (Sashiko).
- Add a B288 watchdog compatible (Andre).
- DTS: drop the memory node, the arch timer workaround and the
sunxi.c entry; add disable-wp and the eMMC 1.8V modes; DLDO1 no
longer always-on; mainline pin function names (Andre).
Changes since v1:
- Add this cover letter.
- Drop both new bindings; add the compatibles to the existing
allwinner,sun4i-a10-{ccu,pinctrl}.yaml instead.
- Rewrite the pinctrl driver in the DT-provided pinmux style.
Pablo Mazzini (11):
dt-bindings: clock: sun4i-a10-ccu: add Allwinner B288
clk: sunxi-ng: add Allwinner B288 CCU driver
dt-bindings: pinctrl: sun4i-a10: add Allwinner B288
pinctrl: sunxi: add Allwinner B288 pin controller driver
dt-bindings: rtc: sun6i-a31: add Allwinner B288
rtc: sun6i: add Allwinner B288 compatible
dt-bindings: i2c: mv64xxx: add Allwinner B288
dt-bindings: interrupt-controller: add Allwinner B288 NMI
dt-bindings: watchdog: sun4i-a10-wdt: add Allwinner B288
dt-bindings: arm: sunxi: add PocketBook Verse
ARM: dts: allwinner: add B288 and the PocketBook Verse
.../devicetree/bindings/arm/sunxi.yaml | 5 +
.../clock/allwinner,sun4i-a10-ccu.yaml | 1 +
.../bindings/i2c/marvell,mv64xxx-i2c.yaml | 1 +
.../allwinner,sun7i-a20-sc-nmi.yaml | 1 +
.../pinctrl/allwinner,sun4i-a10-pinctrl.yaml | 22 +
.../bindings/rtc/allwinner,sun6i-a31-rtc.yaml | 3 +
.../watchdog/allwinner,sun4i-a10-wdt.yaml | 1 +
arch/arm/boot/dts/allwinner/Makefile | 1 +
.../allwinner/sun8i-b288-pocketbook-verse.dts | 114 +++
arch/arm/boot/dts/allwinner/sun8i-b288.dtsi | 292 +++++++
drivers/clk/sunxi-ng/Kconfig | 5 +
drivers/clk/sunxi-ng/Makefile | 1 +
drivers/clk/sunxi-ng/ccu-sun8i-b288.c | 749 ++++++++++++++++++
drivers/clk/sunxi-ng/ccu-sun8i-b288.h | 10 +
drivers/pinctrl/sunxi/Kconfig | 10 +
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c | 49 ++
drivers/rtc/rtc-sun6i.c | 5 +
include/dt-bindings/clock/sun8i-b288-ccu.h | 82 ++
include/dt-bindings/reset/sun8i-b288-ccu.h | 45 ++
20 files changed, 1398 insertions(+)
create mode 100644 arch/arm/boot/dts/allwinner/sun8i-b288-pocketbook-verse.dts
create mode 100644 arch/arm/boot/dts/allwinner/sun8i-b288.dtsi
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-b288.c
create mode 100644 drivers/clk/sunxi-ng/ccu-sun8i-b288.h
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c
create mode 100644 include/dt-bindings/clock/sun8i-b288-ccu.h
create mode 100644 include/dt-bindings/reset/sun8i-b288-ccu.h
--
2.52.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v4 03/11] dt-bindings: pinctrl: sun4i-a10: add Allwinner B288
2026-10-12 10:08 [PATCH v4 00/11] ARM: sunxi: add Allwinner B288 and the PocketBook Verse Pablo Mazzini
@ 2026-10-12 10:08 ` Pablo Mazzini
2026-10-12 10:08 ` [PATCH v4 04/11] pinctrl: sunxi: add Allwinner B288 pin controller driver Pablo Mazzini
1 sibling, 0 replies; 4+ messages in thread
From: Pablo Mazzini @ 2026-10-12 10:08 UTC (permalink / raw)
To: Chen-Yu Tsai, Conor Dooley, Jernej Skrabec, Krzysztof Kozlowski,
Linus Walleij, Maxime Ripard, Rob Herring, Samuel Holland
Cc: Pablo Mazzini, Andre Przywara, devicetree, linux-arm-kernel,
linux-gpio, linux-kernel, linux-sunxi
The B288 driver takes its mux values from the DT, so allwinner,pinmux
becomes an allowed property here, required for this compatible only.
Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
.../pinctrl/allwinner,sun4i-a10-pinctrl.yaml | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
index 45b7a0b6c626..b1f093d218f5 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml
@@ -39,6 +39,7 @@ properties:
- allwinner,sun8i-a33-pinctrl
- allwinner,sun8i-a83t-pinctrl
- allwinner,sun8i-a83t-r-pinctrl
+ - allwinner,sun8i-b288-pinctrl
- allwinner,sun8i-h3-pinctrl
- allwinner,sun8i-h3-r-pinctrl
- allwinner,sun8i-r40-pinctrl
@@ -120,6 +121,15 @@ patternProperties:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [10, 20, 30, 40]
+ allwinner,pinmux:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description:
+ Pinmux selector value, for each pin. Only used by SoCs whose
+ driver takes the mux values from the DT instead of an in-driver
+ table. Almost every time this value is the same for all pins, so
+ any array shorter than the number of pins will repeat the last
+ value, to allow just specifying a single cell, for all cells.
+
required:
- pins
- function
@@ -144,6 +154,17 @@ allOf:
# warnings.
- $ref: pinctrl.yaml#
+
+ - if:
+ properties:
+ compatible:
+ const: allwinner,sun8i-b288-pinctrl
+
+ then:
+ patternProperties:
+ "^([rs]-)?(([a-z0-9]{3,}|[a-oq-z0-9][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$":
+ required:
+ - allwinner,pinmux
- if:
not:
properties:
@@ -222,6 +243,7 @@ allOf:
enum:
- allwinner,sun6i-a31-pinctrl
- allwinner,sun6i-a31s-pinctrl
+ - allwinner,sun8i-b288-pinctrl
- allwinner,sun50i-h6-pinctrl
then:
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v4 04/11] pinctrl: sunxi: add Allwinner B288 pin controller driver
2026-10-12 10:08 [PATCH v4 00/11] ARM: sunxi: add Allwinner B288 and the PocketBook Verse Pablo Mazzini
2026-10-12 10:08 ` [PATCH v4 03/11] dt-bindings: pinctrl: sun4i-a10: add Allwinner B288 Pablo Mazzini
@ 2026-10-12 10:08 ` Pablo Mazzini
2026-10-12 10:29 ` sashiko-bot
1 sibling, 1 reply; 4+ messages in thread
From: Pablo Mazzini @ 2026-10-12 10:08 UTC (permalink / raw)
To: Chen-Yu Tsai, Jernej Skrabec, Linus Walleij, Samuel Holland
Cc: Pablo Mazzini, Andre Przywara, linux-arm-kernel, linux-gpio,
linux-kernel, linux-sunxi
80 pins across ports B, C, D, F and G; the mux values come from the DT.
Port C has no external interrupts. PH0 is BSP FPGA-only and omitted.
Signed-off-by: Pablo Mazzini <pmazzini@gmail.com>
---
drivers/pinctrl/sunxi/Kconfig | 10 +++++
drivers/pinctrl/sunxi/Makefile | 1 +
drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c | 49 ++++++++++++++++++++++
3 files changed, 60 insertions(+)
create mode 100644 drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c
diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index dc62eba96348..a08186133090 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -56,6 +56,16 @@ config PINCTRL_SUN8I_A23_R
default MACH_SUN8I
select PINCTRL_SUNXI
+config PINCTRL_SUN8I_B288
+ bool "Support for the Allwinner B288 PIO"
+ default MACH_SUN8I
+ select PINCTRL_SUNXI
+ help
+ Say Y here to enable pin controller and GPIO support for the
+ Allwinner B288 (sun8iw10p1) SoC, as used in e-book readers such
+ as the PocketBook Verse. This covers ports B, C, D, F and G,
+ including the four banks of external interrupt capable pins.
+
config PINCTRL_SUN8I_H3
bool "Support for the Allwinner H3 PIO"
default MACH_SUN8I
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index 951b3f1e4b4f..5129c0f19f3e 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_PINCTRL_SUN50I_A100) += pinctrl-sun50i-a100.o
obj-$(CONFIG_PINCTRL_SUN50I_A100_R) += pinctrl-sun50i-a100-r.o
obj-$(CONFIG_PINCTRL_SUN8I_A83T) += pinctrl-sun8i-a83t.o
obj-$(CONFIG_PINCTRL_SUN8I_A83T_R) += pinctrl-sun8i-a83t-r.o
+obj-$(CONFIG_PINCTRL_SUN8I_B288) += pinctrl-sun8i-b288.o
obj-$(CONFIG_PINCTRL_SUN8I_H3) += pinctrl-sun8i-h3.o
obj-$(CONFIG_PINCTRL_SUN8I_H3_R) += pinctrl-sun8i-h3-r.o
obj-$(CONFIG_PINCTRL_SUN8I_V3S) += pinctrl-sun8i-v3s.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c
new file mode 100644
index 000000000000..f973c2b3f2eb
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Allwinner B288 (sun8iw10p1) SoC pinctrl driver.
+ *
+ * Bank sizes and the interrupt mux derived from Allwinner's BSP driver
+ * pinctrl-sun8iw10p1.c, which is:
+ * Copyright (C) 2014 Jackie Hwang <huangshr@allwinnertech.com>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+/* PH0 exists only on the BSP's FPGA platform and is omitted. */
+static const u8 b288_nr_bank_pins[SUNXI_PINCTRL_MAX_BANKS] =
+/* PA PB PC PD PE PF PG */
+ { 0, 17, 15, 29, 0, 7, 12 };
+
+static const u8 b288_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =
+/* PA PB PC PD PE PF PG */
+ { 0, 6, 0, 6, 0, 6, 6 };
+
+static struct sunxi_pinctrl_desc b288_pinctrl_data = {
+ .irq_banks = 4,
+};
+
+static int b288_pinctrl_probe(struct platform_device *pdev)
+{
+ return sunxi_pinctrl_dt_table_init(pdev, b288_nr_bank_pins,
+ b288_irq_bank_muxes,
+ &b288_pinctrl_data, 0);
+}
+
+static const struct of_device_id b288_pinctrl_match[] = {
+ { .compatible = "allwinner,sun8i-b288-pinctrl", },
+ {}
+};
+
+static struct platform_driver b288_pinctrl_driver = {
+ .probe = b288_pinctrl_probe,
+ .driver = {
+ .name = "sun8i-b288-pinctrl",
+ .of_match_table = b288_pinctrl_match,
+ },
+};
+builtin_platform_driver(b288_pinctrl_driver);
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v4 04/11] pinctrl: sunxi: add Allwinner B288 pin controller driver
2026-10-12 10:08 ` [PATCH v4 04/11] pinctrl: sunxi: add Allwinner B288 pin controller driver Pablo Mazzini
@ 2026-10-12 10:29 ` sashiko-bot
0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-10-12 10:29 UTC (permalink / raw)
To: Pablo Mazzini; +Cc: linux-sunxi, linux-gpio
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] pinctrl: sunxi: out-of-bounds write in irq_array when Bank 0 has 0 pins
- [High] pinctrl: sunxi: Missing irq_bank_map breaks B288 IRQ offsets and domain size
- [High] pinctrl: sunxi: probe deferral crash due to npins accumulation
--
commit 6057aa70ee139132fe0176fd6bf4d482c87bdc64
Author: Pablo Mazzini <pmazzini@gmail.com>
pinctrl: sunxi: add Allwinner B288 pin controller driver
This commit adds a new pin controller driver for the Allwinner B288 SoC,
supporting 80 pins across ports B, C, D, F, and G. It uses DT-provided
mux values and specifies 4 banks of external interrupts.
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c
> new file mode 100644
> index 0000000000000..f973c2b3f2eba
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-b288.c
> @@ -0,0 +1,49 @@
[ ... ]
> +/* PH0 exists only on the BSP's FPGA platform and is omitted. */
> +static const u8 b288_nr_bank_pins[SUNXI_PINCTRL_MAX_BANKS] =
> +/* PA PB PC PD PE PF PG */
> + { 0, 17, 15, 29, 0, 7, 12 };
[Severity: High]
Since Bank 0 (PA) has 0 pins, does this cause an out-of-bounds write in
the core sunxi pinctrl driver?
In drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c:prepare_function_table(),
last_bank and irq_bank are initialized to 0. When processing PB (bank 1),
the condition (bank > last_bank) evaluates to true (1 > 0), causing irq_bank
to erroneously increment to 1.
This shifts the logical IRQ bank indices for PB, PD, PF, and PG to
1, 2, 3, and 4 instead of 0, 1, 2, and 3.
Later, sunxi_pinctrl_build_state() configures the interrupts:
int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
pctl->irq_array[irqnum] = pin->pin.number;
For PG (irqbank 4), irqnum will be between 128 and 139. However, irq_array
is allocated for exactly 4 banks (128 elements) in
sunxi_pinctrl_init_with_flags(), which would result in an out-of-bounds
write past the end of the array.
> +
> +static const u8 b288_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =
> +/* PA PB PC PD PE PF PG */
> + { 0, 6, 0, 6, 0, 6, 6 };
> +
> +static struct sunxi_pinctrl_desc b288_pinctrl_data = {
> + .irq_banks = 4,
> +};
[Severity: High]
Does omitting the irq_bank_map array break external interrupts?
Without an irq_bank_map, drivers/pinctrl/sunxi/pinctrl-sunxi.h:
sunxi_irq_hw_bank_num() returns the sequential logical irqbank indices.
Because the irq_bank offset is already shifted to 1, 2, 3, and 4, these
logical indices will be used as physical hardware bank offsets.
This incorrectly maps PD, PF, and PG to hardware banks 2, 3, and 4 instead
of their actual hardware indices 3, 5, and 6.
Additionally, because PG receives irqbank 4, its out_hwirq is calculated
as 4 * 32 + irqnum (>= 128), which exceeds the bounds of the 128-entry
IRQ domain created during probe.
> +
> +static int b288_pinctrl_probe(struct platform_device *pdev)
> +{
> + return sunxi_pinctrl_dt_table_init(pdev, b288_nr_bank_pins,
> + b288_irq_bank_muxes,
> + &b288_pinctrl_data, 0);
> +}
[Severity: High]
Could this lead to a kernel panic during a probe deferral?
The driver passes the static b288_pinctrl_data descriptor to
sunxi_pinctrl_dt_table_init(), which calls init_pins_table() and
accumulates the total pin count:
desc->npins += pins_per_bank[i];
If the driver probe defers, desc->npins will double on the next attempt
(from 80 to 160) because the static descriptor is reused.
The pins array is then allocated for 160 elements, but only the first 80
will have their .pin.name populated.
During DT parsing in fill_pin_function(), if an unrecognized pin name is
encountered, the search loops over the oversized array and evaluates:
if (!strcmp(pins[pin].pin.name, name))
break;
Iterating past index 79 would call strcmp() with a NULL pointer for
.pin.name, causing a panic.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261012100816.331033-1-pmazzini@gmail.com?part=4
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-12 10:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-12 10:08 [PATCH v4 00/11] ARM: sunxi: add Allwinner B288 and the PocketBook Verse Pablo Mazzini
2026-10-12 10:08 ` [PATCH v4 03/11] dt-bindings: pinctrl: sun4i-a10: add Allwinner B288 Pablo Mazzini
2026-10-12 10:08 ` [PATCH v4 04/11] pinctrl: sunxi: add Allwinner B288 pin controller driver Pablo Mazzini
2026-10-12 10:29 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox