Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: ixp4xx: Add device tree boot support

This adds a minimal support for booting IXP4xx systems
from device tree.

We have to add hacks to the QMGR, NPE and notably also
ethernet and watchdog drivers so that they don't crash
the platform: these drivers are unconditionally starting
to grab regions of statically remapped IO space with no
concern of the device model or other platforms.

We will go in and properly fix these drivers as we go
along but for now this hack gets us to a place where we
can start working on proper device tree support for these
platforms.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

+106
+14
arch/arm/mach-ixp4xx/Kconfig
··· 4 4 5 5 comment "IXP4xx Platforms" 6 6 7 + config MACH_IXP4XX_OF 8 + bool 9 + prompt "Devce Tree IXP4xx boards" 10 + default y 11 + select ARM_APPENDED_DTB # Old Redboot bootloaders deployed 12 + select I2C 13 + select I2C_IOP3XX 14 + select PCI 15 + select SERIAL_OF_PLATFORM 16 + select TIMER_OF 17 + select USE_OF 18 + help 19 + Say 'Y' here to support Device Tree-based IXP4xx platforms. 20 + 7 21 config MACH_NSLU2 8 22 bool 9 23 prompt "Linksys NSLU2"
+3
arch/arm/mach-ixp4xx/Makefile
··· 6 6 obj-pci-y := 7 7 obj-pci-n := 8 8 9 + # Device tree platform 10 + obj-pci-$(CONFIG_MACH_IXP4XX_OF) += ixp4xx-of.o 11 + 9 12 obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o 10 13 obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o 11 14 obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o
+60
arch/arm/mach-ixp4xx/ixp4xx-of.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * IXP4xx Device Tree boot support 4 + */ 5 + #include <linux/kernel.h> 6 + #include <linux/init.h> 7 + #include <linux/io.h> 8 + 9 + #include <asm/mach/arch.h> 10 + #include <asm/mach/map.h> 11 + 12 + #include <mach/hardware.h> 13 + #include <mach/ixp4xx-regs.h> 14 + 15 + static struct map_desc ixp4xx_of_io_desc[] __initdata = { 16 + /* 17 + * This is needed for runtime system configuration checks, 18 + * such as reading if hardware so-and-so is present. This 19 + * could eventually be converted into a syscon once all boards 20 + * are converted to device tree. 21 + */ 22 + { 23 + .virtual = IXP4XX_EXP_CFG_BASE_VIRT, 24 + .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS), 25 + .length = SZ_4K, 26 + .type = MT_DEVICE, 27 + }, 28 + #ifdef CONFIG_DEBUG_UART_8250 29 + /* This is needed for LL-debug/earlyprintk/debug-macro.S */ 30 + { 31 + .virtual = CONFIG_DEBUG_UART_VIRT, 32 + .pfn = __phys_to_pfn(CONFIG_DEBUG_UART_PHYS), 33 + .length = SZ_4K, 34 + .type = MT_DEVICE, 35 + }, 36 + #endif 37 + }; 38 + 39 + static void __init ixp4xx_of_map_io(void) 40 + { 41 + iotable_init(ixp4xx_of_io_desc, ARRAY_SIZE(ixp4xx_of_io_desc)); 42 + } 43 + 44 + /* 45 + * We handle 4 differen SoC families. These compatible strings are enough 46 + * to provide the core so that different boards can add their more detailed 47 + * specifics. 48 + */ 49 + static const char *ixp4xx_of_board_compat[] = { 50 + "intel,ixp42x", 51 + "intel,ixp43x", 52 + "intel,ixp45x", 53 + "intel,ixp46x", 54 + NULL, 55 + }; 56 + 57 + DT_MACHINE_START(IXP4XX_DT, "IXP4xx (Device Tree)") 58 + .map_io = ixp4xx_of_map_io, 59 + .dt_compat = ixp4xx_of_board_compat, 60 + MACHINE_END
+5
arch/arm/mach-ixp4xx/ixp4xx_npe.c
··· 20 20 #include <linux/io.h> 21 21 #include <linux/kernel.h> 22 22 #include <linux/module.h> 23 + #include <linux/of.h> 23 24 #include <mach/npe.h> 24 25 25 26 #define DEBUG_MSG 0 ··· 688 687 { 689 688 690 689 int i, found = 0; 690 + 691 + /* This driver does not work with device tree */ 692 + if (of_have_populated_dt()) 693 + return -ENODEV; 691 694 692 695 for (i = 0; i < NPE_COUNT; i++) { 693 696 struct npe *npe = &npe_tab[i];
+5
arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
··· 12 12 #include <linux/interrupt.h> 13 13 #include <linux/kernel.h> 14 14 #include <linux/module.h> 15 + #include <linux/of.h> 15 16 #include <mach/qmgr.h> 16 17 17 18 #include "irqs.h" ··· 289 288 { 290 289 int i, err; 291 290 irq_handler_t handler1, handler2; 291 + 292 + /* This driver does not work with device tree */ 293 + if (of_have_populated_dt()) 294 + return -ENODEV; 292 295 293 296 mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS, 294 297 IXP4XX_QMGR_REGION_SIZE,
+10
drivers/net/ethernet/xscale/ixp4xx_eth.c
··· 31 31 #include <linux/io.h> 32 32 #include <linux/kernel.h> 33 33 #include <linux/net_tstamp.h> 34 + #include <linux/of.h> 34 35 #include <linux/phy.h> 35 36 #include <linux/platform_device.h> 36 37 #include <linux/ptp_classify.h> ··· 1498 1497 static int __init eth_init_module(void) 1499 1498 { 1500 1499 int err; 1500 + 1501 + /* 1502 + * FIXME: we bail out on device tree boot but this really needs 1503 + * to be fixed in a nicer way: this registers the MDIO bus before 1504 + * even matching the driver infrastructure, we should only probe 1505 + * detected hardware. 1506 + */ 1507 + if (of_have_populated_dt()) 1508 + return -ENODEV; 1501 1509 if ((err = ixp4xx_mdio_register())) 1502 1510 return err; 1503 1511 return platform_driver_register(&ixp4xx_eth_driver);
+9
drivers/watchdog/ixp4xx_wdt.c
··· 21 21 #include <linux/kernel.h> 22 22 #include <linux/fs.h> 23 23 #include <linux/miscdevice.h> 24 + #include <linux/of.h> 24 25 #include <linux/watchdog.h> 25 26 #include <linux/init.h> 26 27 #include <linux/bitops.h> ··· 177 176 { 178 177 int ret; 179 178 179 + /* 180 + * FIXME: we bail out on device tree boot but this really needs 181 + * to be fixed in a nicer way: this registers the MDIO bus before 182 + * even matching the driver infrastructure, we should only probe 183 + * detected hardware. 184 + */ 185 + if (of_have_populated_dt()) 186 + return -ENODEV; 180 187 if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) { 181 188 pr_err("Rev. A0 IXP42x CPU detected - watchdog disabled\n"); 182 189