]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'mvebu/dt' into mvebu/for-next
authorGregory CLEMENT <gregory.clement@free-electrons.com>
Mon, 2 Nov 2015 20:53:30 +0000 (21:53 +0100)
committerGregory CLEMENT <gregory.clement@free-electrons.com>
Mon, 2 Nov 2015 20:53:30 +0000 (21:53 +0100)
Documentation/devicetree/bindings/arm/coherency-fabric.txt
Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt [new file with mode: 0644]
arch/arm/boot/dts/armada-385-db-ap.dts
arch/arm/mach-mvebu/board-v7.c
arch/arm/mach-mvebu/coherency.c
arch/arm/mach-mvebu/pmsu.c
arch/arm/mach-orion5x/Kconfig
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/tsx09-common.c
arch/arm/plat-orion/common.c

index 8dd46617c889afa3f05f1e578ddc34bc76d94cc8..9b5c3f620e65ea348ac57eed59a63c1c61d2e3a0 100644 (file)
@@ -27,6 +27,11 @@ Required properties:
  * For "marvell,armada-380-coherency-fabric", only one pair is needed
    for the per-CPU fabric registers.
 
+Optional properties:
+
+- broken-idle: boolean to set when the Idle mode is not supported by the
+  hardware.
+
 Examples:
 
 coherency-fabric@d0020200 {
diff --git a/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt b/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt
new file mode 100644 (file)
index 0000000..2cdcd71
--- /dev/null
@@ -0,0 +1,20 @@
+MVEBU CPU Config registers
+--------------------------
+
+MVEBU (Marvell SOCs: Armada 370/XP)
+
+Required properties:
+
+- compatible: one of:
+       - "marvell,armada-370-cpu-config"
+       - "marvell,armada-xp-cpu-config"
+
+- reg: Should contain CPU config registers location and length, in
+  their per-CPU variant
+
+Example:
+
+       cpu-config@21000 {
+               compatible = "marvell,armada-xp-cpu-config";
+               reg = <0x21000 0x8>;
+       };
index 4de813c236bf9d17eb50c8959a3003b3224a2c9a..acd5b1519edb2be2f4cd58246fba337a7059ffa1 100644 (file)
@@ -46,7 +46,7 @@
 
 / {
        model = "Marvell Armada 385 Access Point Development Board";
-       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada38x";
+       compatible = "marvell,a385-db-ap", "marvell,armada385", "marvell,armada380";
 
        chosen {
                stdout-path = "serial1:115200n8";
index 9f739f3cad4c7e584391c0e8f79ec27376d5fa4c..1648edd515a2c2c5f313b0c9d3d68d6bebad545c 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/memblock.h>
 #include <linux/mbus.h>
-#include <linux/signal.h>
 #include <linux/slab.h>
 #include <linux/irqchip.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -105,27 +104,6 @@ static void __init mvebu_memblock_reserve(void)
 static void __init mvebu_memblock_reserve(void) {}
 #endif
 
-/*
- * Early versions of Armada 375 SoC have a bug where the BootROM
- * leaves an external data abort pending. The kernel is hit by this
- * data abort as soon as it enters userspace, because it unmasks the
- * data aborts at this moment. We register a custom abort handler
- * below to ignore the first data abort to work around this
- * problem.
- */
-static int armada_375_external_abort_wa(unsigned long addr, unsigned int fsr,
-                                       struct pt_regs *regs)
-{
-       static int ignore_first;
-
-       if (!ignore_first && fsr == 0x1406) {
-               ignore_first = 1;
-               return 0;
-       }
-
-       return 1;
-}
-
 static void __init mvebu_init_irq(void)
 {
        irqchip_init();
@@ -134,17 +112,6 @@ static void __init mvebu_init_irq(void)
        BUG_ON(mvebu_mbus_dt_init(coherency_available()));
 }
 
-static void __init external_abort_quirk(void)
-{
-       u32 dev, rev;
-
-       if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
-               return;
-
-       hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
-                       "imprecise external abort");
-}
-
 static void __init i2c_quirk(void)
 {
        struct device_node *np;
@@ -177,8 +144,6 @@ static void __init mvebu_dt_init(void)
 {
        if (of_machine_is_compatible("marvell,armadaxp"))
                i2c_quirk();
-       if (of_machine_is_compatible("marvell,a375-db"))
-               external_abort_quirk();
 
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
index 44eedf331ae7df40bb76fcfec0358e89ce128d76..55348ee5a35228cf5e8cbb8f55b0b16b4d56c805 100644 (file)
@@ -40,6 +40,7 @@
 unsigned long coherency_phys_base;
 void __iomem *coherency_base;
 static void __iomem *coherency_cpu_base;
+static void __iomem *cpu_config_base;
 
 /* Coherency fabric registers */
 #define IO_SYNC_BARRIER_CTL_OFFSET                0x0
@@ -65,6 +66,31 @@ static const struct of_device_id of_coherency_table[] = {
 int ll_enable_coherency(void);
 void ll_add_cpu_to_smp_group(void);
 
+#define CPU_CONFIG_SHARED_L2 BIT(16)
+
+/*
+ * Disable the "Shared L2 Present" bit in CPU Configuration register
+ * on Armada XP.
+ *
+ * The "Shared L2 Present" bit affects the "level of coherence" value
+ * in the clidr CP15 register.  Cache operation functions such as
+ * "flush all" and "invalidate all" operate on all the cache levels
+ * that included in the defined level of coherence. When HW I/O
+ * coherency is used, this bit causes unnecessary flushes of the L2
+ * cache.
+ */
+static void armada_xp_clear_shared_l2(void)
+{
+       u32 reg;
+
+       if (!cpu_config_base)
+               return;
+
+       reg = readl(cpu_config_base);
+       reg &= ~CPU_CONFIG_SHARED_L2;
+       writel(reg, cpu_config_base);
+}
+
 static int mvebu_hwcc_notifier(struct notifier_block *nb,
                               unsigned long event, void *__dev)
 {
@@ -85,9 +111,24 @@ static struct notifier_block mvebu_hwcc_pci_nb = {
        .notifier_call = mvebu_hwcc_notifier,
 };
 
+static int armada_xp_clear_shared_l2_notifier_func(struct notifier_block *nfb,
+                                       unsigned long action, void *hcpu)
+{
+       if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+               armada_xp_clear_shared_l2();
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block armada_xp_clear_shared_l2_notifier = {
+       .notifier_call = armada_xp_clear_shared_l2_notifier_func,
+       .priority = 100,
+};
+
 static void __init armada_370_coherency_init(struct device_node *np)
 {
        struct resource res;
+       struct device_node *cpu_config_np;
 
        of_address_to_resource(np, 0, &res);
        coherency_phys_base = res.start;
@@ -100,6 +141,23 @@ static void __init armada_370_coherency_init(struct device_node *np)
        sync_cache_w(&coherency_phys_base);
        coherency_base = of_iomap(np, 0);
        coherency_cpu_base = of_iomap(np, 1);
+
+       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) {
+               of_node_put(cpu_config_np);
+               goto exit;
+       }
+
+       of_node_put(cpu_config_np);
+
+       register_cpu_notifier(&armada_xp_clear_shared_l2_notifier);
+
+exit:
        set_cpu_coherent();
 }
 
@@ -204,6 +262,8 @@ int set_cpu_coherent(void)
                        pr_warn("Coherency fabric is not initialized\n");
                        return 1;
                }
+
+               armada_xp_clear_shared_l2();
                ll_add_cpu_to_smp_group();
                return ll_enable_coherency();
        }
index e8fdb9ceedf0c7c9402bff4123ea9c375a1ccbfe..ed8fda4cd055848e871bb0f592b23735d4c843aa 100644 (file)
@@ -296,11 +296,11 @@ int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
        /* Test the CR_C bit and set it if it was cleared */
        asm volatile(
        "mrc    p15, 0, r0, c1, c0, 0 \n\t"
-       "tst    r0, #(1 << 2) \n\t"
+       "tst    r0, %0 \n\t"
        "orreq  r0, r0, #(1 << 2) \n\t"
        "mcreq  p15, 0, r0, c1, c0, 0 \n\t"
        "isb    "
-       : : : "r0");
+       : : "Ir" (CR_C) : "r0");
 
        pr_debug("Failed to suspend the system\n");
 
@@ -379,6 +379,16 @@ static struct notifier_block mvebu_v7_cpu_pm_notifier = {
 
 static struct platform_device mvebu_v7_cpuidle_device;
 
+static int broken_idle(struct device_node *np)
+{
+       if (of_property_read_bool(np, "broken-idle")) {
+               pr_warn("CPU idle is currently broken: disabling\n");
+               return 1;
+       }
+
+       return 0;
+}
+
 static __init int armada_370_cpuidle_init(void)
 {
        struct device_node *np;
@@ -387,7 +397,9 @@ static __init int armada_370_cpuidle_init(void)
        np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
        if (!np)
                return -ENODEV;
-       of_node_put(np);
+
+       if (broken_idle(np))
+               goto end;
 
        /*
         * On Armada 370, there is "a slow exit process from the deep
@@ -406,6 +418,8 @@ static __init int armada_370_cpuidle_init(void)
        mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
        mvebu_v7_cpuidle_device.name = "cpuidle-armada-370";
 
+end:
+       of_node_put(np);
        return 0;
 }
 
@@ -422,6 +436,10 @@ static __init int armada_38x_cpuidle_init(void)
                                     "marvell,armada-380-coherency-fabric");
        if (!np)
                return -ENODEV;
+
+       if (broken_idle(np))
+               goto end;
+
        of_node_put(np);
 
        np = of_find_compatible_node(NULL, NULL,
@@ -430,7 +448,6 @@ static __init int armada_38x_cpuidle_init(void)
                return -ENODEV;
        mpsoc_base = of_iomap(np, 0);
        BUG_ON(!mpsoc_base);
-       of_node_put(np);
 
        /* Set up reset mask when powering down the cpus */
        reg = readl(mpsoc_base + MPCORE_RESET_CTL);
@@ -450,6 +467,8 @@ static __init int armada_38x_cpuidle_init(void)
        mvebu_v7_cpuidle_device.dev.platform_data = armada_38x_cpu_suspend;
        mvebu_v7_cpuidle_device.name = "cpuidle-armada-38x";
 
+end:
+       of_node_put(np);
        return 0;
 }
 
@@ -460,12 +479,16 @@ static __init int armada_xp_cpuidle_init(void)
        np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
        if (!np)
                return -ENODEV;
-       of_node_put(np);
+
+       if (broken_idle(np))
+               goto end;
 
        mvebu_cpu_resume = armada_370_xp_cpu_resume;
        mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend;
        mvebu_v7_cpuidle_device.name = "cpuidle-armada-xp";
 
+end:
+       of_node_put(np);
        return 0;
 }
 
index 08d2be2ea41f43c8273de58924741da7c72f6e43..66f1c952c0483d4dc5830fe66fd66bcf4f058f40 100644 (file)
@@ -45,6 +45,7 @@ config MACH_KUROBOX_PRO
 
 config MACH_DNS323
        bool "D-Link DNS-323"
+       select GENERIC_NET_UTILS
        select I2C_BOARDINFO
        help
          Say 'Y' here if you want your kernel to support the
@@ -52,6 +53,7 @@ config MACH_DNS323
 
 config MACH_TS209
        bool "QNAP TS-109/TS-209"
+       select GENERIC_NET_UTILS
        help
          Say 'Y' here if you want your kernel to support the
          QNAP TS-109/TS-209 platform.
@@ -93,6 +95,7 @@ config MACH_LINKSTATION_LS_HGL
 
 config MACH_TS409
        bool "QNAP TS-409"
+       select GENERIC_NET_UTILS
        help
          Say 'Y' here if you want your kernel to support the
          QNAP TS-409 platform.
index f267e58a82833b45647608aea78990bc5e673a0a..bc279a8530753ea6531dbb0b5098498d86fa78de 100644 (file)
@@ -173,42 +173,10 @@ static struct mv643xx_eth_platform_data dns323_eth_data = {
        .phy_addr = MV643XX_ETH_PHY_ADDR(8),
 };
 
-/* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these
- * functions be kept somewhere?
- */
-static int __init dns323_parse_hex_nibble(char n)
-{
-       if (n >= '0' && n <= '9')
-               return n - '0';
-
-       if (n >= 'A' && n <= 'F')
-               return n - 'A' + 10;
-
-       if (n >= 'a' && n <= 'f')
-               return n - 'a' + 10;
-
-       return -1;
-}
-
-static int __init dns323_parse_hex_byte(const char *b)
-{
-       int hi;
-       int lo;
-
-       hi = dns323_parse_hex_nibble(b[0]);
-       lo = dns323_parse_hex_nibble(b[1]);
-
-       if (hi < 0 || lo < 0)
-               return -1;
-
-       return (hi << 4) | lo;
-}
-
 static int __init dns323_read_mac_addr(void)
 {
        u_int8_t addr[6];
-       int i;
-       char *mac_page;
+       void __iomem *mac_page;
 
        /* MAC address is stored as a regular ol' string in /dev/mtdblock4
         * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
@@ -217,23 +185,8 @@ static int __init dns323_read_mac_addr(void)
        if (!mac_page)
                return -ENOMEM;
 
-       /* Sanity check the string we're looking at */
-       for (i = 0; i < 5; i++) {
-               if (*(mac_page + (i * 3) + 2) != ':') {
-                       goto error_fail;
-               }
-       }
-
-       for (i = 0; i < 6; i++) {
-               int byte;
-
-               byte = dns323_parse_hex_byte(mac_page + (i * 3));
-               if (byte < 0) {
-                       goto error_fail;
-               }
-
-               addr[i] = byte;
-       }
+       if (!mac_pton((__force const char *) mac_page, addr))
+               goto error_fail;
 
        iounmap(mac_page);
        printk("DNS-323: Found ethernet MAC address: %pM\n", addr);
index 24b2959719faf1d93e240436cc486463cf52a6f7..d42e006597c7b1e1cf4078972669b0cec3bfd6d0 100644 (file)
@@ -53,53 +53,12 @@ struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
        .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
-static int __init qnap_tsx09_parse_hex_nibble(char n)
-{
-       if (n >= '0' && n <= '9')
-               return n - '0';
-
-       if (n >= 'A' && n <= 'F')
-               return n - 'A' + 10;
-
-       if (n >= 'a' && n <= 'f')
-               return n - 'a' + 10;
-
-       return -1;
-}
-
-static int __init qnap_tsx09_parse_hex_byte(const char *b)
-{
-       int hi;
-       int lo;
-
-       hi = qnap_tsx09_parse_hex_nibble(b[0]);
-       lo = qnap_tsx09_parse_hex_nibble(b[1]);
-
-       if (hi < 0 || lo < 0)
-               return -1;
-
-       return (hi << 4) | lo;
-}
-
 static int __init qnap_tsx09_check_mac_addr(const char *addr_str)
 {
        u_int8_t addr[6];
-       int i;
 
-       for (i = 0; i < 6; i++) {
-               int byte;
-
-               /*
-                * Enforce "xx:xx:xx:xx:xx:xx\n" format.
-                */
-               if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
-                       return -1;
-
-               byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3));
-               if (byte < 0)
-                       return -1;
-               addr[i] = byte;
-       }
+       if (!mac_pton(addr_str, addr))
+               return -1;
 
        printk(KERN_INFO "tsx09: found ethernet mac address %pM\n", addr);
 
@@ -118,12 +77,12 @@ void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size)
        unsigned long addr;
 
        for (addr = mem_base; addr < (mem_base + size); addr += 1024) {
-               char *nor_page;
+               void __iomem *nor_page;
                int ret = 0;
 
                nor_page = ioremap(addr, 1024);
                if (nor_page != NULL) {
-                       ret = qnap_tsx09_check_mac_addr(nor_page);
+                       ret = qnap_tsx09_check_mac_addr((__force const char *)nor_page);
                        iounmap(nor_page);
                }
 
index 2235081a04eeac818f58b44923aa565026c0b746..8861c367d06114651920b05420e53ebde3099712 100644 (file)
@@ -495,7 +495,7 @@ void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
 
        d->netdev = &orion_ge00.dev;
        for (i = 0; i < d->nr_chips; i++)
-               d->chip[i].host_dev = &orion_ge00_shared.dev;
+               d->chip[i].host_dev = &orion_ge_mvmdio.dev;
        orion_switch_device.dev.platform_data = d;
 
        platform_device_register(&orion_switch_device);