From b64cbd3f5d96b143fa9f21d84d381b1bb286339c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Apr 2026 16:35:27 +0200 Subject: [PATCH 01/20] ARM: s3c: use gpio lookup table for LEDs The crag6410 board is one of the last users of the gpio-led driver with plain gpio numbers. The driver has several ways to pass this information without using gpio numbers, using a lookup table is the easiest way. Signed-off-by: Arnd Bergmann Reviewed-by: Bartosz Golaszewski Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20260427143546.3098519-1-arnd@kernel.org Signed-off-by: Krzysztof Kozlowski --- arch/arm/mach-s3c/mach-crag6410.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-s3c/mach-crag6410.c b/arch/arm/mach-s3c/mach-crag6410.c index 028169c7debf..c4040aad1ed3 100644 --- a/arch/arm/mach-s3c/mach-crag6410.c +++ b/arch/arm/mach-s3c/mach-crag6410.c @@ -779,46 +779,53 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = { static const struct gpio_led gpio_leds[] = { { .name = "d13:green:", - .gpio = MMGPIO_GPIO_BASE + 0, .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "d14:green:", - .gpio = MMGPIO_GPIO_BASE + 1, .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "d15:green:", - .gpio = MMGPIO_GPIO_BASE + 2, .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "d16:green:", - .gpio = MMGPIO_GPIO_BASE + 3, .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "d17:green:", - .gpio = MMGPIO_GPIO_BASE + 4, .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "d18:green:", - .gpio = MMGPIO_GPIO_BASE + 5, .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "d19:green:", - .gpio = MMGPIO_GPIO_BASE + 6, .default_state = LEDS_GPIO_DEFSTATE_ON, }, { .name = "d20:green:", - .gpio = MMGPIO_GPIO_BASE + 7, .default_state = LEDS_GPIO_DEFSTATE_ON, }, }; +static struct gpiod_lookup_table crag_leds_table = { + .dev_id = "leds-gpio", + .table = { + GPIO_LOOKUP_IDX("basic-mmio-gpio", 0, "cs", 0, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("basic-mmio-gpio", 1, "cs", 1, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("basic-mmio-gpio", 2, "cs", 2, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("basic-mmio-gpio", 3, "cs", 3, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("basic-mmio-gpio", 4, "cs", 4, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("basic-mmio-gpio", 5, "cs", 5, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("basic-mmio-gpio", 6, "cs", 6, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("basic-mmio-gpio", 7, "cs", 7, GPIO_ACTIVE_LOW), + { }, + }, +}; + static const struct gpio_led_platform_data gpio_leds_pdata = { .leds = gpio_leds, .num_leds = ARRAY_SIZE(gpio_leds), @@ -875,6 +882,7 @@ static void __init crag6410_machine_init(void) platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices)); platform_device_register_full(&crag6410_mmgpio_devinfo); + gpiod_add_lookup_table(&crag_leds_table); gpio_led_register_device(-1, &gpio_leds_pdata); regulator_has_full_constraints(); From 518949e986e2b5d0f39b640dd27a19b6fc8740ea Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Apr 2026 18:27:30 +0200 Subject: [PATCH 02/20] ARM: select legacy gpiolib interfaces where used A few old machines have not been converted away from the old-style gpiolib interfaces. Make these select the new CONFIG_GPIOLIB_LEGACY symbol so the code still works where it is needed but can be left out otherwise. Acked-by: Krzysztof Kozlowski Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20260428162757.540823-1-arnd@kernel.org Signed-off-by: Arnd Bergmann --- arch/arm/mach-mv78xx0/Kconfig | 1 + arch/arm/mach-orion5x/Kconfig | 1 + arch/arm/mach-pxa/Kconfig | 1 + arch/arm/mach-s3c/Kconfig.s3c64xx | 1 + arch/arm/mach-sa1100/Kconfig | 1 + 5 files changed, 5 insertions(+) diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig index 9de3bbc09c3a..670e6587827e 100644 --- a/arch/arm/mach-mv78xx0/Kconfig +++ b/arch/arm/mach-mv78xx0/Kconfig @@ -6,6 +6,7 @@ menuconfig ARCH_MV78XX0 depends on ATAGS select CPU_FEROCEON select GPIOLIB + select GPIOLIB_LEGACY select MVEBU_MBUS select FORCE_PCI select PLAT_ORION_LEGACY diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index ee449ca032d2..cef19bea6164 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -5,6 +5,7 @@ menuconfig ARCH_ORION5X depends on CPU_LITTLE_ENDIAN select CPU_FEROCEON select GPIOLIB + select GPIOLIB_LEGACY select MVEBU_MBUS select FORCE_PCI select PCI_QUIRKS diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 10e472f4fa43..66e26990e2c8 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -10,6 +10,7 @@ menuconfig ARCH_PXA select CPU_XSCALE if !CPU_XSC3 select GPIO_PXA select GPIOLIB + select GPIOLIB_LEGACY select PLAT_PXA help Support for Intel/Marvell's PXA2xx/PXA3xx processor line. diff --git a/arch/arm/mach-s3c/Kconfig.s3c64xx b/arch/arm/mach-s3c/Kconfig.s3c64xx index 8f40af063ad6..3f97fba8e4f5 100644 --- a/arch/arm/mach-s3c/Kconfig.s3c64xx +++ b/arch/arm/mach-s3c/Kconfig.s3c64xx @@ -101,6 +101,7 @@ config MACH_WLF_CRAGG_6410 depends on ATAGS depends on I2C=y select CPU_S3C6410 + select GPIOLIB_LEGACY select LEDS_GPIO_REGISTER select S3C64XX_DEV_SPI0 select S3C64XX_SETUP_FB_24BPP diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index 0fb4c24cfad5..e23700e0d6c8 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig @@ -13,6 +13,7 @@ menuconfig ARCH_SA1100 select CPU_FREQ select CPU_SA1100 select GPIOLIB + select GPIOLIB_LEGACY select IRQ_DOMAIN select ISA select NEED_MACH_MEMORY_H From 2a7a9e20b9e8b5dc4fdef777e67d390dcb3a8ea4 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Mon, 30 Mar 2026 14:35:28 -0700 Subject: [PATCH 03/20] ARM: omap2: simplify allocation for omap_device Use a flexible array member (FAM) to combine hwmods array allocation with the omap_device structure. This reduces the number of allocations from two separate calls (one for the device, one for the array) to a single allocation, improving efficiency and reducing memory fragmentation. The FAM approach also enables bounds checking through __counted_by(), which provides runtime verification that array accesses stay within the allocated size. This improves security and helps catch bugs during development. Simplify error handling by removing the unnecessary multi-label goto pattern. The new code is more straightforward: allocate, verify, copy data, and either return success or error immediately. Also removes the now-redundant kfree(od->hwmods) in omap_device_delete() since the hwmods array is now embedded in the structure rather than separately allocated. Signed-off-by: Rosen Penev Link: https://patch.msgid.link/20260330213528.18187-1-rosenp@gmail.com Signed-off-by: Kevin Hilman (TI) --- arch/arm/mach-omap2/omap_device.c | 29 ++++++++++------------------- arch/arm/mach-omap2/omap_device.h | 4 ++-- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 79db4c49ffc9..77a75b0b9ae6 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -307,35 +307,27 @@ static struct omap_device *omap_device_alloc(struct platform_device *pdev, int ret = -ENOMEM; struct omap_device *od; int i; - struct omap_hwmod **hwmods; + struct omap_hwmod *hwmod; - od = kzalloc_obj(struct omap_device); - if (!od) - goto oda_exit1; + od = kzalloc_flex(*od, hwmods, oh_cnt); + if (!od) { + dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret); + return ERR_PTR(ret); + } od->hwmods_cnt = oh_cnt; + memcpy(od->hwmods, ohs, oh_cnt * sizeof(*od->hwmods)); - hwmods = kmemdup_array(ohs, oh_cnt, sizeof(*hwmods), GFP_KERNEL); - if (!hwmods) - goto oda_exit2; - - od->hwmods = hwmods; od->pdev = pdev; pdev->archdata.od = od; for (i = 0; i < oh_cnt; i++) { - hwmods[i]->od = od; - _add_hwmod_clocks_clkdev(od, hwmods[i]); + hwmod = od->hwmods[i]; + hwmod->od = od; + _add_hwmod_clocks_clkdev(od, hwmod); } return od; - -oda_exit2: - kfree(od); -oda_exit1: - dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret); - - return ERR_PTR(ret); } static void omap_device_delete(struct omap_device *od) @@ -344,7 +336,6 @@ static void omap_device_delete(struct omap_device *od) return; od->pdev->archdata.od = NULL; - kfree(od->hwmods); kfree(od); } diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h index aa8096ecb23c..fae09cfce137 100644 --- a/arch/arm/mach-omap2/omap_device.h +++ b/arch/arm/mach-omap2/omap_device.h @@ -37,11 +37,11 @@ /** * struct omap_device - omap_device wrapper for platform_devices * @pdev: platform_device - * @hwmods: (one .. many per omap_device) * @hwmods_cnt: ARRAY_SIZE() of @hwmods * @_state: one of OMAP_DEVICE_STATE_* (see above) * @flags: device flags * @_driver_status: one of BUS_NOTIFY_*_DRIVER from + * @hwmods: (one .. many per omap_device) * * Integrates omap_hwmod data into Linux platform_device. * @@ -51,11 +51,11 @@ */ struct omap_device { struct platform_device *pdev; - struct omap_hwmod **hwmods; unsigned long _driver_status; u8 hwmods_cnt; u8 _state; u8 flags; + struct omap_hwmod *hwmods[] __counted_by(hwmods_cnt); }; /* Device driver interface (call via platform_data fn ptrs) */ From ab0a2d7de6b8fa87a0aaa5113071d90099bf6545 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 30 Apr 2026 14:57:18 +0200 Subject: [PATCH 04/20] ARM: pxa: statify platform device definitions in spitz board file The scoop devices are not used outside of this board file so make them static. Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20260430-pxa-gpio-swnodes-v3-1-5142e95f0eca@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- arch/arm/mach-pxa/spitz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index c0b1f7e6be87..3284b9f62be9 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -165,7 +165,7 @@ static struct scoop_config spitz_scoop_1_setup = { .gpio_base = SPITZ_SCP_GPIO_BASE, }; -struct platform_device spitz_scoop_1_device = { +static struct platform_device spitz_scoop_1_device = { .name = "sharp-scoop", .id = 0, .dev = { @@ -192,7 +192,7 @@ static struct scoop_config spitz_scoop_2_setup = { .gpio_base = SPITZ_SCP2_GPIO_BASE, }; -struct platform_device spitz_scoop_2_device = { +static struct platform_device spitz_scoop_2_device = { .name = "sharp-scoop", .id = 1, .dev = { From a25463c14d9b803c8308a222d5f8ac1c55098b3c Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 30 Apr 2026 14:57:19 +0200 Subject: [PATCH 05/20] ARM: pxa: spitz: attach software nodes to their target GPIO controllers Software nodes describing the GPIO controllers for the spitz platform are currently "dangling" - they're not actually attached to the relevant controllers and don't allow real fwnode lookup. Attach them either by directly assigning them to the struct device or by using the i2c board info struct. Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20260430-pxa-gpio-swnodes-v3-2-5142e95f0eca@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- arch/arm/mach-pxa/spitz.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 3284b9f62be9..5091b601c4e1 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -204,11 +204,15 @@ static struct platform_device spitz_scoop_2_device = { static void __init spitz_scoop_init(void) { + spitz_scoop_1_device.dev.fwnode = software_node_fwnode(&spitz_scoop_1_gpiochip_node); platform_device_register(&spitz_scoop_1_device); /* Akita doesn't have the second SCOOP chip */ - if (!machine_is_akita()) + if (!machine_is_akita()) { + spitz_scoop_2_device.dev.fwnode = software_node_fwnode( + &spitz_scoop_2_gpiochip_node); platform_device_register(&spitz_scoop_2_device); + } } /* Power control is shared with between one of the CF slots and SD */ @@ -988,6 +992,7 @@ static struct i2c_board_info spitz_i2c_devs[] = { .type = "max7310", .addr = 0x18, .platform_data = &akita_pca953x_pdata, + .swnode = &akita_max7310_gpiochip_node, }, }; From af3fb0aeb7071acc471c1cb0b76e22b776934e48 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 30 Apr 2026 14:57:20 +0200 Subject: [PATCH 06/20] ARM: pxa: pxa25x: attach software node to its target GPIO controller Software node describing the GPIO controller for the pxa25x platforms is currently "dangling" - it's not actually attached to the relevant controller and doesn't allow real fwnode lookup. Attach it once it's registered as a firmware node before adding the platform device. Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20260430-pxa-gpio-swnodes-v3-3-5142e95f0eca@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- arch/arm/mach-pxa/pxa25x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 70509a599814..a4e878be004a 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -240,6 +240,9 @@ static int __init pxa25x_init(void) if (!of_have_populated_dt()) { software_node_register(&pxa2xx_gpiochip_node); + pxa25x_device_gpio.dev.fwnode = software_node_fwnode( + &pxa2xx_gpiochip_node); + pxa2xx_set_dmac_info(&pxa25x_dma_pdata); ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); From 2c450dd88161abbadf889711d0bcedd7a0504a84 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 30 Apr 2026 14:57:21 +0200 Subject: [PATCH 07/20] ARM: pxa: pxa27x: attach software node to its target GPIO controller Software node describing the GPIO controller for the pxa27x platforms is currently "dangling" - it's not actually attached to the relevant controller and doesn't allow real fwnode lookup. Attach it once it's registered as a firmware node before adding the platform device. Reviewed-by: Linus Walleij Link: https://patch.msgid.link/20260430-pxa-gpio-swnodes-v3-4-5142e95f0eca@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- arch/arm/mach-pxa/pxa27x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index ff6361979038..49c677f2dac1 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -342,6 +342,9 @@ static int __init pxa27x_init(void) if (!of_have_populated_dt()) { software_node_register(&pxa2xx_gpiochip_node); + pxa27x_device_gpio.dev.fwnode = software_node_fwnode( + &pxa2xx_gpiochip_node); + pxa2xx_set_dmac_info(&pxa27x_dma_pdata); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); From 220ae5d36dba278003d265aabd080ffa78553f5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 27 Jan 2026 20:52:08 +0300 Subject: [PATCH 08/20] ARM: zte: Add zx297520v3 platform support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This SoC is used in low end LTE-to-WiFi routers, for example some D-Link DWR 932 revisions, ZTE K10, ZLT S10 4G, but also models that are branded and sold by ISPs themselves. They are widespread in Africa, China, Russia and Eastern Europe. This SoC is a relative of the zx296702 and zx296718 that had some upstream support until commit 89d4f98ae90d ("ARM: remove zte zx platform"). Reviewed-by: Linus Walleij Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stefan Dösinger --- Patch changelog: v8: * Select ARM_PSCI_FW (Sashiko). This is an issue make defconfig pointed out in the last patch in this series. The board does not have PSCI firmware as far as I can tell, but the ARM_GIC_V3 option indirectly assumes ARM_PSCI_FW is enabled. * Include in the board file for __initdata (Sashiko), removed other includes copypasted from another platform that aren't needed. Let's see if Sashiko agrees. * Add the SoC documentation to the documentation index (Sashiko) * Add the SoC documentation to MAINTAINERS (Sashiko) * Removed redundant if ARCH_ZTE (Sashiko) * Point towards a sane (USB-Only) U-Boot and modify the example code for booting from NAND to detect already fixed GIC setups. --- Documentation/arch/arm/index.rst | 2 + Documentation/arch/arm/zte/index.rst | 10 ++ Documentation/arch/arm/zte/zx297520v3.rst | 167 ++++++++++++++++++++++ MAINTAINERS | 9 ++ arch/arm/Kconfig | 2 + arch/arm/Makefile | 1 + arch/arm/mach-zte/Kconfig | 29 ++++ arch/arm/mach-zte/Makefile | 2 + arch/arm/mach-zte/zx297520v3.c | 16 +++ 9 files changed, 238 insertions(+) create mode 100644 Documentation/arch/arm/zte/index.rst create mode 100644 Documentation/arch/arm/zte/zx297520v3.rst create mode 100644 arch/arm/mach-zte/Kconfig create mode 100644 arch/arm/mach-zte/Makefile create mode 100644 arch/arm/mach-zte/zx297520v3.c diff --git a/Documentation/arch/arm/index.rst b/Documentation/arch/arm/index.rst index afe17db294c4..b15621093f7a 100644 --- a/Documentation/arch/arm/index.rst +++ b/Documentation/arch/arm/index.rst @@ -75,3 +75,5 @@ SoC-specific documents sti/overview vfp/release-notes + + zte/index diff --git a/Documentation/arch/arm/zte/index.rst b/Documentation/arch/arm/zte/index.rst new file mode 100644 index 000000000000..0ed80b60b746 --- /dev/null +++ b/Documentation/arch/arm/zte/index.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +======= +ZTE SoC +======= + +.. toctree:: + :maxdepth: 1 + + zx297520v3 diff --git a/Documentation/arch/arm/zte/zx297520v3.rst b/Documentation/arch/arm/zte/zx297520v3.rst new file mode 100644 index 000000000000..2122887e391a --- /dev/null +++ b/Documentation/arch/arm/zte/zx297520v3.rst @@ -0,0 +1,167 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +==================================== +Booting Linux on ZTE zx297520v3 SoCs +==================================== + +............................................................................... + +Author: Stefan Dösinger + +Date : 27 Jan 2026 + +1. Hardware description +--------------------------- +Zx297520v3 SoCs use a 64 bit capable Cortex-A53 CPU and GICv3, although they +run in arm32 mode only. The CPU has support EL3, but no hypervisor (EL2) and +it seems to lack VFP and NEON. + +The SoC is used in a number of cheap LTE to WiFi routers, both battery powered +MiFis and stationary CPEs. In addition to the CPU these devices usually have +64 MB Ram (although some is shared with the LTE chip), 128 MB NAND flash, an +SDIO connected RTL8192-type Wifi chip limited to 2.4 ghz operation, USB 2, +and buttons. Devices with as low as 32 MB or as high as 128 MB ram exist, as +do devices with 8 or 16 MB of NOR flash. + +Some devices, especially the stationary ones, have 100 mbit Ethernet and an +Ethernet switch. + +Usually the devices have LEDs for status indication, although some have SPI or +I2C connected displays + +Some have an SD card slot. If it exists, it is a better choice for the root +file system because it easily outperforms the built-in NAND. + +The LTE interface runs on a separate DSP called ZSP880. It is probably derived +from LSI ZSPs and has an undocumented instruction set. The ZSP communicates +with the main CPU via SRAM and DRAM and a mailbox hardware that can generate +IRQs on either ends. + +There is also a Cortex M0 CPU, which is responsible for early HW initialization +and starting the Cortex A53 CPU. It does not have any essential purpose once +U-Boot is started. A SRAM-Based handover protocol exists to run custom code on +this CPU. + +2. Booting via USB +--------------------------- + +The Boot ROM has support for booting custom code via USB. This mode can be +entered by connecting a Boot PIN to GND or by modifying the third byte on NAND +(set it to anything other than 0x5A aka 'Z'). A free software tool to start +custom U-Boot and kernels can be found here: + +https://github.com/zx297520v3-mainline/zx297520v3-loader + +If USB download mode is entered but no boot commands are sent through USB, the +device will proceed to boot normally after a few seconds. It is therefore +possible to enable USB boot permanently and still leave the default boot files +in place. + +https://github.com/zx297520v3-mainline/u-boot-mainline + +Contains an U-Boot version that can be used with the USB loader and sets up the +CPU and interrupt controller to comply with Linux's booting requirements. + +3. Building for built-in U-Boot +--------------------------- +The devices come with an ancient U-Boot that loads legacy uImages from NAND and +boots them without a chance for the user to interrupt. The images are stored in +files ap_cpuap.bin and ap_recovery.bin on a jffs2 partition named imagefs, +usually mtd4. A file named "fotaflag" switches between the two modes. + +In addition to the uImage header, those files have a 384 byte signature header, +which is used for authenticating the images on some devices. Most devices have +this authentication disabled and it is enough to pad the uImage files with 384 +zero bytes. + +Builtin U-Boot also poorly sets up the CPU. Read the next section for details +on this. It has no support for loading DTBs, so CONFIG_ARM_APPENDED_DTB is +needed. + +So to build an image that boots from NAND the following steps are necessary: + +1) Patch the assembly code from section 3 into arch/arm/kernel/head.S. +2) make zx29_defconfig +3) make [-j x] +4) cat arch/arm/boot/zImage arch/arm/boot/dts/zte/[device].dtb > kernel+dtb +5) mkimage -A arm -O linux -T kernel -C none -a 0x20008000 -d kernel+dtb uimg +6) dd if=/dev/zero bs=1 count=384 of=ap_recovery.bin +7) cat uimg >> ap_recovery.bin +8) Place this file onto imagefs on the device. Delete ap_cpuap.bin if the +free space is not enough. +9) Create the file fotaflag: echo -n FOTA-RECOVERY > fotaflag + +For development, booting ap_recovery.bin is recommended because the normal boot +mode arms the watchdog before starting the kernel. + +4. CPU and GIC Setup +--------------------------- + +Generally CPU and GICv3 need to be set up according to the requirements spelled +out in Documentation/arch/arm64/booting.rst. For zx297520v3 this means: + +1. GICD_CTLR.DS=1 to disable GIC security +2. Enable access to ICC_SRE +3. Disable trapping IRQs into monitor mode +4. Configure EL2 and below to run in insecure mode. +5. Configure timer PPIs to active-low. + +The kernel sources provided by ZTE do not boot either (interrupts do not work +at all). They are incomplete in other aspects too, so it is assumed that there +is some workaround similar to the one described in this document somewhere in +the binary blobs. + +The assembly code below is given as an example of how to achieve this: + +``` +#include +#include +#include + +@ Detect sane bootloaders and skip the hack +ldr r3, =0xf2000000 +ldr r3, [r3] +ldr r4, =(GICD_CTLR_ARE_NS | GICD_CTLR_DS) +cmp r3, r4 +beq skip_zx_hack +@ This allows EL1 to handle ints hat are normally handled by EL2/3. +ldr r3, =0xf2000000 +str r4, [r3] + +cps #MON_MODE + +@ Work in non-secure physical address space: SCR_EL3.NS = 1. At least the UART +@ seems to respond only to non-secure addresses. I have taken insipiration from +@ Raspberry pi's armstub7.S here. +mov r3, #0x131 @ non-secure, Make F, A bits in CPSR writeable + @ Allow hypervisor call. +mcr p15, 0, r3, c1, c1, 0 + +@ AP_PPI_MODE_REG: Configure timer PPIs (10, 11, 13, 14) to active-low. +ldr r3, =0xF22020a8 +ldr r4, =0x50 +str r4, [r3] +ldr r3, =0xF22020ac +ldr r4, =0x14 +str r4, [r3] + +@ Enable EL2 access to ICC_SRE (bit 3, ICC_SRE_EL3.Enable). Enable system reg +@ access to GICv3 registers (bit 0, ICC_SRE_EL3.SRE) for EL1 and EL3. +mrc p15, 6, r3, c12, c12, 5 @ ICC_SRE_EL3 +orr r3, #0x9 @ FIXME: No defines for SRE_EL3 values? +mcr p15, 6, r3, c12, c12, 5 +mrc p15, 0, r3, c12, c12, 5 @ ICC_SRE_EL1 +orr r3, #(ICC_SRE_EL1_SRE) +mcr p15, 0, r3, c12, c12, 5 + +@ Like ICC_SRE_EL3, enable EL1 access to ICC_SRE and system register access +@ for EL2. +mrc p15, 4, r3, c12, c9, 5 @ ICC_SRE_EL2 aka ICC_HSRE +orr r3, r3, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE) +mcr p15, 4, r3, c12, c9, 5 +isb + +@ Back to SVC mode +cps #SVC_MODE +skip_zx_hack: +``` diff --git a/MAINTAINERS b/MAINTAINERS index 2fb1c75afd16..22368f96be9f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3782,6 +3782,15 @@ F: drivers/video/fbdev/vt8500lcdfb.* F: drivers/video/fbdev/wm8505fb* F: drivers/video/fbdev/wmt_ge_rops.* +ARM/ZTE ZX29 SOC SUPPORT +M: Stefan Dösinger +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Odd fixes +F: Documentation/arch/arm/zte/ +F: Documentation/devicetree/bindings/arm/zte.yaml +F: arch/arm/boot/dts/zte/ +F: arch/arm/mach-zte/ + ARM/ZYNQ ARCHITECTURE M: Michal Simek L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 71fc5dd4123f..c1045154412a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -465,6 +465,8 @@ source "arch/arm/mach-versatile/Kconfig" source "arch/arm/mach-vt8500/Kconfig" +source "arch/arm/mach-zte/Kconfig" + source "arch/arm/mach-zynq/Kconfig" # ARMv7-M architecture diff --git a/arch/arm/Makefile b/arch/arm/Makefile index b7de4b6b284c..573813ef5e77 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -223,6 +223,7 @@ machine-$(CONFIG_ARCH_SUNXI) += sunxi machine-$(CONFIG_ARCH_TEGRA) += tegra machine-$(CONFIG_ARCH_U8500) += ux500 machine-$(CONFIG_ARCH_VT8500) += vt8500 +machine-$(CONFIG_ARCH_ZTE) += zte machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_PLAT_VERSATILE) += versatile machine-$(CONFIG_PLAT_SPEAR) += spear diff --git a/arch/arm/mach-zte/Kconfig b/arch/arm/mach-zte/Kconfig new file mode 100644 index 000000000000..d3b404ca488d --- /dev/null +++ b/arch/arm/mach-zte/Kconfig @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only +menuconfig ARCH_ZTE + bool "ZTE zx family" + depends on ARCH_MULTI_V7 + help + Support for ZTE zx-based family of processors. + +if ARCH_ZTE + +config SOC_ZX297520V3 + bool "zx297520v3 SoC" + default y + select ARM_GIC_V3 + # This board does not have PSCI firmware, but ARM_GIC_V3 depends on + # ARM_PSCI_FW being enabled. + select ARM_PSCI_FW + select ARM_AMBA + select HAVE_ARM_ARCH_TIMER + select PM_GENERIC_DOMAINS if PM + help + Support for ZTE zx297520v3 SoC. It is a single core SoC used in cheap + LTE to WiFi routers. These devices can be identified by the occurrence + of the string "zx297520v3" in the boot output and /proc/cpuinfo of + their stock firmware. + + Please read Documentation/arch/arm/zte/zx297520v3.rst on how to boot + the kernel. + +endif diff --git a/arch/arm/mach-zte/Makefile b/arch/arm/mach-zte/Makefile new file mode 100644 index 000000000000..1bfe4fddd6af --- /dev/null +++ b/arch/arm/mach-zte/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_SOC_ZX297520V3) += zx297520v3.o diff --git a/arch/arm/mach-zte/zx297520v3.c b/arch/arm/mach-zte/zx297520v3.c new file mode 100644 index 000000000000..06f71348459e --- /dev/null +++ b/arch/arm/mach-zte/zx297520v3.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2026 Stefan Dösinger + */ + +#include +#include + +static const char *const zx297520v3_dt_compat[] __initconst = { + "zte,zx297520v3", + NULL, +}; + +DT_MACHINE_START(ZX, "ZTE zx297520v3 (Device Tree)") + .dt_compat = zx297520v3_dt_compat, +MACHINE_END From 2430f2080f2a4e45b69befba26ef726d62180bba Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 28 Apr 2026 15:57:33 +0200 Subject: [PATCH 09/20] firmware: imx: sm-misc: Make scmi_imx_misc_ctrl_nb variable static File-scope 'scmi_imx_misc_ctrl_nb' is not used outside of this unit, so make it static to silence sparse warning: sm-misc.c:19:23: warning: symbol 'scmi_imx_misc_ctrl_nb' was not declared. Should it be static? Reviewed-by: Daniel Baluta Signed-off-by: Krzysztof Kozlowski Signed-off-by: Frank Li --- drivers/firmware/imx/sm-misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/imx/sm-misc.c b/drivers/firmware/imx/sm-misc.c index 0a8ada329c9d..8d95a901734a 100644 --- a/drivers/firmware/imx/sm-misc.c +++ b/drivers/firmware/imx/sm-misc.c @@ -16,7 +16,7 @@ static const struct scmi_imx_misc_proto_ops *imx_misc_ctrl_ops; static struct scmi_protocol_handle *ph; -struct notifier_block scmi_imx_misc_ctrl_nb; +static struct notifier_block scmi_imx_misc_ctrl_nb; int scmi_imx_misc_ctrl_set(u32 id, u32 val) { From 14c22bd4b3bcc73e14c5215ded2c6d44fac89b96 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 30 Apr 2026 16:32:21 +0200 Subject: [PATCH 10/20] arm64: Kconfig: drop unneeded dependency on OF_GPIO for ARCH_MVEBU OF_GPIO is selected automatically on all OF systems. Any symbols it controls also provide stubs so there's really no reason to select it explicitly. ARCH_MVEBU already selects GPIOLIB, drop the redundant OF_GPIO dependency. Signed-off-by: Bartosz Golaszewski Reviewed-by: Linus Walleij Signed-off-by: Arnd Bergmann --- arch/arm64/Kconfig.platforms | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 72c812e76b0b..dc995a732117 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -243,7 +243,6 @@ config ARCH_MVEBU select MVEBU_ODMI select MVEBU_PIC select MVEBU_SEI - select OF_GPIO select PINCTRL select PINCTRL_ARMADA_37XX select PINCTRL_ARMADA_AP806 From 05836235e5412310057ea14e41e24dbc45a429bd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 21 May 2026 12:14:57 -0700 Subject: [PATCH 11/20] ARM: zte: clean up zx297520v3 doc. warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix multiple documentation build warnings. Improve punctuation and formatting of the rendered output. Documentation/arch/arm/zte/zx297520v3.rst:66: WARNING: Title underline too short. 3. Building for built-in U-Boot --------------------------- [docutils] Documentation/arch/arm/zte/zx297520v3.rst:90: WARNING: Enumerated list ends without a blank line; unexpected unindent. [docutils] Documentation/arch/arm/zte/zx297520v3.rst:116: WARNING: Inline literal start-string without end-string. [docutils] Documentation/arch/arm/zte/zx297520v3.rst:137: ERROR: Unexpected indentation. [docutils] Documentation/arch/arm/zte/zx297520v3.rst:138: WARNING: Block quote ends without a blank line; unexpected unindent. [docutils] Documentation/arch/arm/zte/zx297520v3.rst:164: WARNING: Inline literal start-string without end-string. [docutils] Documentation/arch/arm/zte/zx297520v3.rst:164: WARNING: Inline interpreted text or phrase reference start-string without end-string. [docutils] Documentation/arch/arm/zte/zx297520v3.rst:7: WARNING: Document or section may not begin with a transition. [docutils] Fixes: 220ae5d36dba ("ARM: zte: Add zx297520v3 platform support") Signed-off-by: Randy Dunlap Reviewed-by: Stefan Dösinger Reviewed-by: Bagas Sanjaya Signed-off-by: Stefan Dösinger --- Documentation/arch/arm/zte/zx297520v3.rst | 105 +++++++++++----------- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/Documentation/arch/arm/zte/zx297520v3.rst b/Documentation/arch/arm/zte/zx297520v3.rst index 2122887e391a..d33f454bc895 100644 --- a/Documentation/arch/arm/zte/zx297520v3.rst +++ b/Documentation/arch/arm/zte/zx297520v3.rst @@ -4,15 +4,13 @@ Booting Linux on ZTE zx297520v3 SoCs ==================================== -............................................................................... - Author: Stefan Dösinger Date : 27 Jan 2026 1. Hardware description --------------------------- -Zx297520v3 SoCs use a 64 bit capable Cortex-A53 CPU and GICv3, although they +Zx297520v3 SoCs use a 64-bit capable Cortex-A53 CPU and GICv3, although they run in arm32 mode only. The CPU has support EL3, but no hypervisor (EL2) and it seems to lack VFP and NEON. @@ -27,7 +25,7 @@ Some devices, especially the stationary ones, have 100 mbit Ethernet and an Ethernet switch. Usually the devices have LEDs for status indication, although some have SPI or -I2C connected displays +I2C connected displays. Some have an SD card slot. If it exists, it is a better choice for the root file system because it easily outperforms the built-in NAND. @@ -39,7 +37,7 @@ IRQs on either ends. There is also a Cortex M0 CPU, which is responsible for early HW initialization and starting the Cortex A53 CPU. It does not have any essential purpose once -U-Boot is started. A SRAM-Based handover protocol exists to run custom code on +U-Boot is started. An SRAM-based handover protocol exists to run custom code on this CPU. 2. Booting via USB @@ -63,13 +61,13 @@ Contains an U-Boot version that can be used with the USB loader and sets up the CPU and interrupt controller to comply with Linux's booting requirements. 3. Building for built-in U-Boot ---------------------------- +------------------------------- The devices come with an ancient U-Boot that loads legacy uImages from NAND and boots them without a chance for the user to interrupt. The images are stored in files ap_cpuap.bin and ap_recovery.bin on a jffs2 partition named imagefs, usually mtd4. A file named "fotaflag" switches between the two modes. -In addition to the uImage header, those files have a 384 byte signature header, +In addition to the uImage header, those files have a 384-byte signature header, which is used for authenticating the images on some devices. Most devices have this authentication disabled and it is enough to pad the uImage files with 384 zero bytes. @@ -88,7 +86,7 @@ So to build an image that boots from NAND the following steps are necessary: 6) dd if=/dev/zero bs=1 count=384 of=ap_recovery.bin 7) cat uimg >> ap_recovery.bin 8) Place this file onto imagefs on the device. Delete ap_cpuap.bin if the -free space is not enough. + free space is not enough. 9) Create the file fotaflag: echo -n FOTA-RECOVERY > fotaflag For development, booting ap_recovery.bin is recommended because the normal boot @@ -113,55 +111,56 @@ the binary blobs. The assembly code below is given as an example of how to achieve this: -``` -#include -#include -#include +:: -@ Detect sane bootloaders and skip the hack -ldr r3, =0xf2000000 -ldr r3, [r3] -ldr r4, =(GICD_CTLR_ARE_NS | GICD_CTLR_DS) -cmp r3, r4 -beq skip_zx_hack -@ This allows EL1 to handle ints hat are normally handled by EL2/3. -ldr r3, =0xf2000000 -str r4, [r3] + #include + #include + #include -cps #MON_MODE + @ Detect sane bootloaders and skip the hack + ldr r3, =0xf2000000 + ldr r3, [r3] + ldr r4, =(GICD_CTLR_ARE_NS | GICD_CTLR_DS) + cmp r3, r4 + beq skip_zx_hack + @ This allows EL1 to handle ints hat are normally handled by EL2/3. + ldr r3, =0xf2000000 + str r4, [r3] -@ Work in non-secure physical address space: SCR_EL3.NS = 1. At least the UART -@ seems to respond only to non-secure addresses. I have taken insipiration from -@ Raspberry pi's armstub7.S here. -mov r3, #0x131 @ non-secure, Make F, A bits in CPSR writeable - @ Allow hypervisor call. -mcr p15, 0, r3, c1, c1, 0 + cps #MON_MODE -@ AP_PPI_MODE_REG: Configure timer PPIs (10, 11, 13, 14) to active-low. -ldr r3, =0xF22020a8 -ldr r4, =0x50 -str r4, [r3] -ldr r3, =0xF22020ac -ldr r4, =0x14 -str r4, [r3] + @ Work in non-secure physical address space: SCR_EL3.NS = 1. At least the UART + @ seems to respond only to non-secure addresses. I have taken insipiration from + @ Raspberry pi's armstub7.S here. + mov r3, #0x131 @ non-secure, Make F, A bits in CPSR writeable + @ Allow hypervisor call. + mcr p15, 0, r3, c1, c1, 0 -@ Enable EL2 access to ICC_SRE (bit 3, ICC_SRE_EL3.Enable). Enable system reg -@ access to GICv3 registers (bit 0, ICC_SRE_EL3.SRE) for EL1 and EL3. -mrc p15, 6, r3, c12, c12, 5 @ ICC_SRE_EL3 -orr r3, #0x9 @ FIXME: No defines for SRE_EL3 values? -mcr p15, 6, r3, c12, c12, 5 -mrc p15, 0, r3, c12, c12, 5 @ ICC_SRE_EL1 -orr r3, #(ICC_SRE_EL1_SRE) -mcr p15, 0, r3, c12, c12, 5 + @ AP_PPI_MODE_REG: Configure timer PPIs (10, 11, 13, 14) to active-low. + ldr r3, =0xF22020a8 + ldr r4, =0x50 + str r4, [r3] + ldr r3, =0xF22020ac + ldr r4, =0x14 + str r4, [r3] -@ Like ICC_SRE_EL3, enable EL1 access to ICC_SRE and system register access -@ for EL2. -mrc p15, 4, r3, c12, c9, 5 @ ICC_SRE_EL2 aka ICC_HSRE -orr r3, r3, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE) -mcr p15, 4, r3, c12, c9, 5 -isb + @ Enable EL2 access to ICC_SRE (bit 3, ICC_SRE_EL3.Enable). Enable system reg + @ access to GICv3 registers (bit 0, ICC_SRE_EL3.SRE) for EL1 and EL3. + mrc p15, 6, r3, c12, c12, 5 @ ICC_SRE_EL3 + orr r3, #0x9 @ FIXME: No defines for SRE_EL3 values? + mcr p15, 6, r3, c12, c12, 5 + mrc p15, 0, r3, c12, c12, 5 @ ICC_SRE_EL1 + orr r3, #(ICC_SRE_EL1_SRE) + mcr p15, 0, r3, c12, c12, 5 + + @ Like ICC_SRE_EL3, enable EL1 access to ICC_SRE and system register access + @ for EL2. + mrc p15, 4, r3, c12, c9, 5 @ ICC_SRE_EL2 aka ICC_HSRE + orr r3, r3, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE) + mcr p15, 4, r3, c12, c9, 5 + isb + + @ Back to SVC mode + cps #SVC_MODE + skip_zx_hack: -@ Back to SVC mode -cps #SVC_MODE -skip_zx_hack: -``` From 7afbe21e94a439874f2df071265a8105efae1244 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Sat, 9 May 2026 15:38:19 -0700 Subject: [PATCH 12/20] arm: boot: ep93xx: don't rely on machine_is_*() for removed board files Code in misc-ep93xx.h relies on machine_is_*() macros for several boards that no longer have legacy board files. They were removed in commit e5ef574dda70 ("ARM: ep93xx: delete all boardfiles"). This prevents the removal of machine IDs no longer used by the kernel from mach-types. To resolve this issue, create local copies of these macros. (The checks themselves are still valid because the IDs are still passed in by the bootloader on these machines.) Also take the opportunity to remove three repeated checks for the same ID. Signed-off-by: Ethan Nelson-Moore Acked-by: Alexander Sverdlin Signed-off-by: Alexander Sverdlin --- arch/arm/boot/compressed/misc-ep93xx.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/compressed/misc-ep93xx.h b/arch/arm/boot/compressed/misc-ep93xx.h index 65b4121d1490..b0a1b42aab31 100644 --- a/arch/arm/boot/compressed/misc-ep93xx.h +++ b/arch/arm/boot/compressed/misc-ep93xx.h @@ -3,7 +3,22 @@ * Copyright (C) 2006 Lennert Buytenhek */ -#include +/* + * These machine IDs are no longer used by the kernel since EP93xx was converted + * to DT booting, but they are still passed in by bootloaders, so we use our own + * local definitions of the relevant macros. + */ +#define machine_is_bk3() (__machine_arch_type == 1880) +#define machine_is_edb9301() (__machine_arch_type == 462) +#define machine_is_edb9302a() (__machine_arch_type == 1127) +#define machine_is_edb9302() (__machine_arch_type == 538) +#define machine_is_edb9307a() (__machine_arch_type == 1128) +#define machine_is_edb9307() (__machine_arch_type == 607) +#define machine_is_edb9312() (__machine_arch_type == 451) +#define machine_is_edb9315a() (__machine_arch_type == 772) +#define machine_is_edb9315() (__machine_arch_type == 463) +#define machine_is_ts72xx() (__machine_arch_type == 673) +#define machine_is_vision_ep9307() (__machine_arch_type == 1578) static inline unsigned int __raw_readl(unsigned int ptr) { @@ -60,14 +75,11 @@ static inline void ep93xx_decomp_setup(void) if (machine_is_edb9301() || machine_is_edb9302() || machine_is_edb9302a() || - machine_is_edb9302a() || machine_is_edb9307() || machine_is_edb9307a() || - machine_is_edb9307a() || machine_is_edb9312() || machine_is_edb9315() || machine_is_edb9315a() || - machine_is_edb9315a() || machine_is_ts72xx() || machine_is_bk3() || machine_is_vision_ep9307()) From e73bd62dd7de707ecbf0d326efcad6756c674da4 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 2 May 2026 14:14:26 +0200 Subject: [PATCH 13/20] ARM: mvebu: drop unnecessary NULL check Don't check the returned pointer from of_find_compatible_node. We pass this pointer to of_iomap, which handles np==NULL correctly. Signed-off-by: Martin Kaiser Signed-off-by: Gregory CLEMENT --- arch/arm/mach-mvebu/coherency.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index fa2c1e1aeb96..a8288a29c1f5 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -133,8 +133,6 @@ static void __init armada_370_coherency_init(struct device_node *np) cpu_config_np = of_find_compatible_node(NULL, NULL, "marvell,armada-xp-cpu-config"); - if (!cpu_config_np) - goto exit; cpu_config_base = of_iomap(cpu_config_np, 0); if (!cpu_config_base) { From 79c72baaae2322ee7ef2aef26d04250e580dccd9 Mon Sep 17 00:00:00 2001 From: Martin Kaiser Date: Sat, 2 May 2026 14:14:27 +0200 Subject: [PATCH 14/20] ARM: mvebu: simplify of_node_put calls In armada_370_coherency_init, cpu_config_np is no longer needed after of_iomap. We can call of_node_put earlier and summarize the two calls. Signed-off-by: Martin Kaiser Signed-off-by: Gregory CLEMENT --- arch/arm/mach-mvebu/coherency.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index a8288a29c1f5..f27b4ec13df2 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -135,12 +135,9 @@ static void __init armada_370_coherency_init(struct device_node *np) "marvell,armada-xp-cpu-config"); cpu_config_base = of_iomap(cpu_config_np, 0); - if (!cpu_config_base) { - of_node_put(cpu_config_np); - goto exit; - } - of_node_put(cpu_config_np); + if (!cpu_config_base) + goto exit; cpuhp_setup_state_nocalls(CPUHP_AP_ARM_MVEBU_COHERENCY, "arm/mvebu/coherency:starting", From b2a4bd1ee306a9d9f53ab76f5f9fea1890e457f1 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Fri, 8 May 2026 19:27:43 -0700 Subject: [PATCH 15/20] arm: mvebu_v5_defconfig: remove stale MACH_LINKSTATION_LSCHL reference The legacy board file for MACH_LINKSTATION_LSCHL was removed in commit ecfe69639157 ("ARM: orion5x: remove legacy support of ls-chl") after it was converted to DT booting, but a reference to it remained in mvebu_v5_defconfig. Drop this unused code. Signed-off-by: Ethan Nelson-Moore Signed-off-by: Gregory CLEMENT --- arch/arm/configs/mvebu_v5_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig index d1742a7cae6a..c42e2a4f8bc1 100644 --- a/arch/arm/configs/mvebu_v5_defconfig +++ b/arch/arm/configs/mvebu_v5_defconfig @@ -15,7 +15,6 @@ CONFIG_MACH_DNS323=y CONFIG_MACH_TS209=y CONFIG_MACH_TERASTATION_PRO2=y CONFIG_MACH_LINKSTATION_PRO=y -CONFIG_MACH_LINKSTATION_LSCHL=y CONFIG_MACH_LINKSTATION_MINI=y CONFIG_MACH_TS409=y CONFIG_MACH_TS78XX=y From bf4ad3be0679460585ab17dbcf298d085cf23429 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Sat, 16 May 2026 19:37:20 -0700 Subject: [PATCH 16/20] ARM: orion5x: update board check in mss2_pci_init() to use the DT The mss2_pci_init() function contains a check for the ARM machine ID via the machine_is_mss2() macro. The board concerned now supports only FDT booting, which does not use machine IDs, and therefore the code should be updated to check the DT compatible property instead. The machine was converted to FDT booting in commit fbf04d814d0a ("ARM: orion5x: convert Maxtor Shared Storage II to the Device Tree"). The presence of this machine ID check prevents the removal of machine IDs no longer used by the kernel from arch/arm/tools/mach-types, because the machine_is_*() macros are generated from mach-types. To resolve this issue, use of_machine_is_compatible() instead. Signed-off-by: Ethan Nelson-Moore Signed-off-by: Gregory CLEMENT --- arch/arm/mach-orion5x/board-mss2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-orion5x/board-mss2.c b/arch/arm/mach-orion5x/board-mss2.c index 9e3d69891d2f..322ae29d05aa 100644 --- a/arch/arm/mach-orion5x/board-mss2.c +++ b/arch/arm/mach-orion5x/board-mss2.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include "orion5x.h" @@ -47,7 +47,7 @@ static struct hw_pci mss2_pci __initdata = { static int __init mss2_pci_init(void) { - if (machine_is_mss2()) + if (of_machine_is_compatible("maxtor,shared-storage-2")) pci_common_init(&mss2_pci); return 0; From 36d46348eb5fc4bc505cd2290ddd70c25fbe6bb3 Mon Sep 17 00:00:00 2001 From: Yuho Choi Date: Wed, 13 May 2026 23:40:04 -0400 Subject: [PATCH 17/20] ARM: imx3: Fix CCM node reference leak of_find_compatible_node() returns a referenced device node. The i.MX31 and i.MX35 early init paths use the node to map the CCM registers with of_iomap(), but never drop the node reference. Release the node after the mapping is created. Fixes: 2cf98d12958c ("ARM: imx3: Retrieve the CCM base address from devicetree") Signed-off-by: Yuho Choi Signed-off-by: Frank Li --- arch/arm/mach-imx/mm-imx3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c index 0788c5cc7f9e..9b0b014d7fe2 100644 --- a/arch/arm/mach-imx/mm-imx3.c +++ b/arch/arm/mach-imx/mm-imx3.c @@ -106,6 +106,7 @@ void __init imx31_init_early(void) arm_pm_idle = imx31_idle; np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); mx3_ccm_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!mx3_ccm_base); } #endif /* ifdef CONFIG_SOC_IMX31 */ @@ -143,6 +144,7 @@ void __init imx35_init_early(void) arch_ioremap_caller = imx3_ioremap_caller; np = of_find_compatible_node(NULL, NULL, "fsl,imx35-ccm"); mx3_ccm_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!mx3_ccm_base); } #endif /* ifdef CONFIG_SOC_IMX35 */ From ccb4b54b8ecf1ebafef96d538cd6c5c8455bb390 Mon Sep 17 00:00:00 2001 From: Yuho Choi Date: Mon, 25 May 2026 00:01:58 -0400 Subject: [PATCH 18/20] ARM: imx31: Fix IIM mapping leak in revision check mx31_read_cpu_rev() maps the IIM registers with of_iomap() to read the silicon revision, but returns without unmapping the MMIO mapping. Keep the normalized revision value in a local variable and route the return path through iounmap() after the revision register has been read. Fixes: 3172225d45bd ("ARM: imx31: Retrieve the IIM base address from devicetree") Signed-off-by: Yuho Choi Signed-off-by: Frank Li --- arch/arm/mach-imx/cpu-imx31.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c index 35c544924e50..e81ef9e36a1f 100644 --- a/arch/arm/mach-imx/cpu-imx31.c +++ b/arch/arm/mach-imx/cpu-imx31.c @@ -36,6 +36,7 @@ static int mx31_read_cpu_rev(void) void __iomem *iim_base; struct device_node *np; u32 i, srev; + int rev = IMX_CHIP_REVISION_UNKNOWN; np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim"); iim_base = of_iomap(np, 0); @@ -48,13 +49,17 @@ static int mx31_read_cpu_rev(void) for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) if (srev == mx31_cpu_type[i].srev) { + rev = mx31_cpu_type[i].rev; imx_print_silicon_rev(mx31_cpu_type[i].name, mx31_cpu_type[i].rev); - return mx31_cpu_type[i].rev; + goto out; } imx_print_silicon_rev("i.MX31", IMX_CHIP_REVISION_UNKNOWN); - return IMX_CHIP_REVISION_UNKNOWN; + +out: + iounmap(iim_base); + return rev; } int mx31_revision(void) From d7a16385680344f999664db08a94913b29d45453 Mon Sep 17 00:00:00 2001 From: Ethan Nelson-Moore Date: Tue, 9 Jun 2026 21:56:26 -0700 Subject: [PATCH 19/20] ARM: remove the last few uses of do_bad_IRQ() The do_bad_IRQ() macro simply calls handle_bad_irq() with a lock around it. It also carries a comment stating that uses of it should be replaced. According to commit aec0095653cd ("irqchip: gic: Call handle_bad_irq() directly"), which replaced another use of do_bad_IRQ(), locking the IRQ descriptor is not necessary for error reporting. Therefore, replace all uses of do_bad_IRQ() with calls to handle_bad_irq() and remove do_bad_IRQ(). Signed-off-by: Ethan Nelson-Moore Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20260610045626.248643-1-enelsonmoore@gmail.com Signed-off-by: Arnd Bergmann --- arch/arm/common/sa1111.c | 2 +- arch/arm/include/asm/mach/irq.h | 10 ---------- arch/arm/mach-footbridge/isa-irq.c | 2 +- drivers/irqchip/irq-versatile-fpga.c | 2 +- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 449c8bb86453..a0f854cf4748 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -221,7 +221,7 @@ static void sa1111_irq_handler(struct irq_desc *desc) writel_relaxed(stat1, mapbase + SA1111_INTSTATCLR1); if (stat0 == 0 && stat1 == 0) { - do_bad_IRQ(desc); + handle_bad_irq(desc); return; } diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h index dfe832a3bfc7..fdcd8388977d 100644 --- a/arch/arm/include/asm/mach/irq.h +++ b/arch/arm/include/asm/mach/irq.h @@ -17,14 +17,4 @@ struct seq_file; extern void init_FIQ(int); extern int show_fiq_list(struct seq_file *, int); -/* - * This is for easy migration, but should be changed in the source - */ -#define do_bad_IRQ(desc) \ -do { \ - raw_spin_lock(&desc->lock); \ - handle_bad_irq(desc); \ - raw_spin_unlock(&desc->lock); \ -} while(0) - #endif diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c index 842ddb4121ef..48c7b3efd555 100644 --- a/arch/arm/mach-footbridge/isa-irq.c +++ b/arch/arm/mach-footbridge/isa-irq.c @@ -89,7 +89,7 @@ static void isa_irq_handler(struct irq_desc *desc) unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE; if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) { - do_bad_IRQ(desc); + handle_bad_irq(desc); return; } diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c index 034ce6afe170..6eaad836d9ff 100644 --- a/drivers/irqchip/irq-versatile-fpga.c +++ b/drivers/irqchip/irq-versatile-fpga.c @@ -89,7 +89,7 @@ static void fpga_irq_handle(struct irq_desc *desc) status = readl(f->base + IRQ_STATUS); if (status == 0) { - do_bad_IRQ(desc); + handle_bad_irq(desc); goto out; } From cb2c3b5e113f26f74ef05926c6ace0f83cc3d0b3 Mon Sep 17 00:00:00 2001 From: Prasad Bolisetty Date: Thu, 11 Jun 2026 13:19:14 -0700 Subject: [PATCH 20/20] MAINTAINERS: Add Axiado reviewer and Maintainers Adding 3 new maintainers Prasad,Tzu-Hao, and Karthikeyan Removed previous maintainer as the previous maintainer moved from project Signed-off-by: Prasad Bolisetty Acked-by: Harshit Shah Signed-off-by: Tzu-Hao Wei Signed-off-by: Karthikeyan Mitran Signed-off-by: Arnd Bergmann --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 093f711c7051..25040c25208a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2615,7 +2615,9 @@ F: arch/arm/mach-aspeed/ N: aspeed ARM/AXIADO ARCHITECTURE -M: Harshit Shah +M: Prasad Bolisetty +M: Tzu-Hao Wei +M: Karthikeyan Mitran L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/arm/axiado.yaml