ARM: ixp4xx: Add device tree boot support
authorLinus Walleij <linus.walleij@linaro.org>
Sun, 27 Jan 2019 13:08:36 +0000 (14:08 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Tue, 23 Apr 2019 14:02:15 +0000 (16:02 +0200)
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>
arch/arm/mach-ixp4xx/Kconfig
arch/arm/mach-ixp4xx/Makefile
arch/arm/mach-ixp4xx/ixp4xx-of.c [new file with mode: 0644]
arch/arm/mach-ixp4xx/ixp4xx_npe.c
arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
drivers/net/ethernet/xscale/ixp4xx_eth.c
drivers/watchdog/ixp4xx_wdt.c

index fea008123eb1555c39b310ada81d18d028be1132..0973270f48632deffd3fea895b167e91fc2b84e7 100644 (file)
@@ -4,6 +4,20 @@ menu "Intel IXP4xx Implementation Options"
 
 comment "IXP4xx Platforms"
 
+config MACH_IXP4XX_OF
+       bool
+       prompt "Devce Tree IXP4xx boards"
+       default y
+       select ARM_APPENDED_DTB # Old Redboot bootloaders deployed
+       select I2C
+       select I2C_IOP3XX
+       select PCI
+       select SERIAL_OF_PLATFORM
+       select TIMER_OF
+       select USE_OF
+       help
+         Say 'Y' here to support Device Tree-based IXP4xx platforms.
+
 config MACH_NSLU2
        bool
        prompt "Linksys NSLU2"
index f09994500a34c51d2d3c2d82cb7e51f65e525815..5f63b3012826c2d95a2471eca4051d4f4b55bb92 100644 (file)
@@ -6,6 +6,9 @@
 obj-pci-y      :=
 obj-pci-n      :=
 
+# Device tree platform
+obj-pci-$(CONFIG_MACH_IXP4XX_OF)       += ixp4xx-of.o
+
 obj-pci-$(CONFIG_ARCH_IXDP4XX)         += ixdp425-pci.o
 obj-pci-$(CONFIG_MACH_AVILA)           += avila-pci.o
 obj-pci-$(CONFIG_MACH_IXDPG425)                += ixdpg425-pci.o
diff --git a/arch/arm/mach-ixp4xx/ixp4xx-of.c b/arch/arm/mach-ixp4xx/ixp4xx-of.c
new file mode 100644 (file)
index 0000000..7449b83
--- /dev/null
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IXP4xx Device Tree boot support
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/ixp4xx-regs.h>
+
+static struct map_desc ixp4xx_of_io_desc[] __initdata = {
+       /*
+        * This is needed for runtime system configuration checks,
+        * such as reading if hardware so-and-so is present. This
+        * could eventually be converted into a syscon once all boards
+        * are converted to device tree.
+        */
+       {
+               .virtual = IXP4XX_EXP_CFG_BASE_VIRT,
+               .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
+               .length = SZ_4K,
+               .type = MT_DEVICE,
+       },
+#ifdef CONFIG_DEBUG_UART_8250
+       /* This is needed for LL-debug/earlyprintk/debug-macro.S */
+       {
+               .virtual = CONFIG_DEBUG_UART_VIRT,
+               .pfn = __phys_to_pfn(CONFIG_DEBUG_UART_PHYS),
+               .length = SZ_4K,
+               .type = MT_DEVICE,
+       },
+#endif
+};
+
+static void __init ixp4xx_of_map_io(void)
+{
+       iotable_init(ixp4xx_of_io_desc, ARRAY_SIZE(ixp4xx_of_io_desc));
+}
+
+/*
+ * We handle 4 differen SoC families. These compatible strings are enough
+ * to provide the core so that different boards can add their more detailed
+ * specifics.
+ */
+static const char *ixp4xx_of_board_compat[] = {
+       "intel,ixp42x",
+       "intel,ixp43x",
+       "intel,ixp45x",
+       "intel,ixp46x",
+       NULL,
+};
+
+DT_MACHINE_START(IXP4XX_DT, "IXP4xx (Device Tree)")
+       .map_io         = ixp4xx_of_map_io,
+       .dt_compat      = ixp4xx_of_board_compat,
+MACHINE_END
index d4eb09a62863639ebb8205e2d203d4c9d089462f..e0ce22cd9bfcfd87b95d99653c7d15d70a8a4a63 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <mach/npe.h>
 
 #define DEBUG_MSG                      0
@@ -688,6 +689,10 @@ static int __init npe_init_module(void)
 
        int i, found = 0;
 
+       /* This driver does not work with device tree */
+       if (of_have_populated_dt())
+               return -ENODEV;
+
        for (i = 0; i < NPE_COUNT; i++) {
                struct npe *npe = &npe_tab[i];
                if (!(ixp4xx_read_feature_bits() &
index 4c7c960e1b4caa5d9f8d06accc5c71ea8e4640db..2665347a2c6fa48c724f9d1d712fe0fed0da1bf6 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <mach/qmgr.h>
 
 #include "irqs.h"
@@ -289,6 +290,10 @@ static int qmgr_init(void)
        int i, err;
        irq_handler_t handler1, handler2;
 
+       /* This driver does not work with device tree */
+       if (of_have_populated_dt())
+               return -ENODEV;
+
        mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
                                     IXP4XX_QMGR_REGION_SIZE,
                                     "IXP4xx Queue Manager");
index ed6623a9801e4c42916d1d32f399cc96bdec0547..05d27fa9835f28326a11d730f058ee05a63bb88f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/net_tstamp.h>
+#include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/ptp_classify.h>
@@ -1497,6 +1498,15 @@ static struct platform_driver ixp4xx_eth_driver = {
 static int __init eth_init_module(void)
 {
        int err;
+
+       /*
+        * FIXME: we bail out on device tree boot but this really needs
+        * to be fixed in a nicer way: this registers the MDIO bus before
+        * even matching the driver infrastructure, we should only probe
+        * detected hardware.
+        */
+       if (of_have_populated_dt())
+               return -ENODEV;
        if ((err = ixp4xx_mdio_register()))
                return err;
        return platform_driver_register(&ixp4xx_eth_driver);
index f20cc53ff71976cdfb48bb956fb83e8fd88b1e91..a80449bb36f0e0dd7062491ebdeefbc7faf53601 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
+#include <linux/of.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
@@ -176,6 +177,14 @@ static int __init ixp4xx_wdt_init(void)
 {
        int ret;
 
+       /*
+        * FIXME: we bail out on device tree boot but this really needs
+        * to be fixed in a nicer way: this registers the MDIO bus before
+        * even matching the driver infrastructure, we should only probe
+        * detected hardware.
+        */
+       if (of_have_populated_dt())
+               return -ENODEV;
        if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) {
                pr_err("Rev. A0 IXP42x CPU detected - watchdog disabled\n");