]> git.ipfire.org Git - people/arne_f/kernel.git/commitdiff
bus: mvebu: pass the coherency availability information at init time
authorGreg Ungerer <gerg@uclinux.org>
Mon, 14 Apr 2014 13:47:01 +0000 (15:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 4 Jul 2015 02:49:05 +0000 (19:49 -0700)
commit 5686a1e5aa436c49187a60052d5885fb1f541ce6 upstream.

Until now, the mvebu-mbus was guessing by itself whether hardware I/O
coherency was available or not by poking into the Device Tree to see
if the coherency fabric Device Tree node was present or not.

However, on some upcoming SoCs, the presence or absence of the
coherency fabric DT node isn't sufficient: in CONFIG_SMP, the
coherency can be enabled, but not in !CONFIG_SMP.

In order to clean this up, the mvebu_mbus_dt_init() function is
extended to get a boolean argument telling whether coherency is
enabled or not. Therefore, the logic to decide whether coherency is
available or not now belongs to the core SoC code instead of the
mvebu-mbus driver itself, which is much better.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Link: https://lkml.kernel.org/r/1397483228-25625-4-git-send-email-thomas.petazzoni@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
[ Greg Ungerer: back ported to linux-3.14.y
  Back port necessary due to large code differences in affected files.
  This change in combination with commit e553554536 ("ARM: mvebu: disable
  I/O coherency on non-SMP situations on Armada 370/375/38x/XP") is
  critical to the hardware I/O coherency being set correctly by both the
  mbus driver and all peripheral hardware drivers. Without this change
  drivers will incorrectly enable I/O coherency window attributes and
  this causes rare unreliable system behavior including oops. ]

Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm/mach-dove/board-dt.c
arch/arm/mach-kirkwood/board-dt.c
arch/arm/mach-mvebu/armada-370-xp.c
arch/arm/mach-mvebu/coherency.c
arch/arm/mach-mvebu/coherency.h
drivers/bus/mvebu-mbus.c
include/linux/mbus.h

index 49fa9abd09daec9097c81d58d2633feccd8ec6f4..7a7a09a5d5fff975d37bb71d53a7bdfb5a01618d 100644 (file)
@@ -26,7 +26,7 @@ static void __init dove_dt_init(void)
 #ifdef CONFIG_CACHE_TAUROS2
        tauros2_init(0);
 #endif
-       BUG_ON(mvebu_mbus_dt_init());
+       BUG_ON(mvebu_mbus_dt_init(false));
        of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
index 78188159484d79e760d8ec22a6303a81d100aeae..79e629da1c92120cf949662537c771b4c51dff4c 100644 (file)
@@ -116,7 +116,7 @@ static void __init kirkwood_dt_init(void)
         */
        writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
 
-       BUG_ON(mvebu_mbus_dt_init());
+       BUG_ON(mvebu_mbus_dt_init(false));
 
        kirkwood_l2_init();
 
index f6c9d1d85c14271b2adbaddaab8431d8c675033c..79c3766a56fd5c4cc07102097b0a653ea9e68d77 100644 (file)
@@ -41,7 +41,7 @@ static void __init armada_370_xp_timer_and_clk_init(void)
        of_clk_init(NULL);
        clocksource_of_init();
        coherency_init();
-       BUG_ON(mvebu_mbus_dt_init());
+       BUG_ON(mvebu_mbus_dt_init(coherency_available()));
 #ifdef CONFIG_CACHE_L2X0
        l2x0_of_init(0, ~0UL);
 #endif
index c295c10f92178720a25e26432cfc670527fa94c9..49bad4d66fa2c273253c7cd60b84761a2980c092 100644 (file)
@@ -121,6 +121,20 @@ static struct notifier_block mvebu_hwcc_platform_nb = {
        .notifier_call = mvebu_hwcc_platform_notifier,
 };
 
+/*
+ * Keep track of whether we have IO hardware coherency enabled or not.
+ * On Armada 370's we will not be using it for example. We need to make
+ * that available [through coherency_available()] so the mbus controller
+ * doesn't enable the IO coherency bit in the attribute bits of the
+ * chip selects.
+ */
+static int coherency_enabled;
+
+int coherency_available(void)
+{
+       return coherency_enabled;
+}
+
 int __init coherency_init(void)
 {
        struct device_node *np;
@@ -164,6 +178,7 @@ int __init coherency_init(void)
                coherency_base = of_iomap(np, 0);
                coherency_cpu_base = of_iomap(np, 1);
                set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
+               coherency_enabled = 1;
                of_node_put(np);
        }
 
index 760226c4135309b4ec79ddda47ba9fb18c31a3f4..63e18c64a8e3af9ff24c3ea1c01ab94cf8ee4f2b 100644 (file)
@@ -17,6 +17,7 @@
 extern unsigned long coherency_phys_base;
 
 int set_cpu_coherent(unsigned int cpu_id, int smp_group_id);
+int coherency_available(void);
 int coherency_init(void);
 
 #endif /* __MACH_370_XP_COHERENCY_H */
index e990deed2d33fc26f21e9cba73296f0198e6149d..1aa0130a63d56f03ab59328b2a0e563359f0b34e 100644 (file)
@@ -701,7 +701,6 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
                                         phys_addr_t sdramwins_phys_base,
                                         size_t sdramwins_size)
 {
-       struct device_node *np;
        int win;
 
        mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size);
@@ -714,12 +713,6 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus,
                return -ENOMEM;
        }
 
-       np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric");
-       if (np) {
-               mbus->hw_io_coherency = 1;
-               of_node_put(np);
-       }
-
        for (win = 0; win < mbus->soc->num_wins; win++)
                mvebu_mbus_disable_window(mbus, win);
 
@@ -889,7 +882,7 @@ static void __init mvebu_mbus_get_pcie_resources(struct device_node *np,
        }
 }
 
-int __init mvebu_mbus_dt_init(void)
+int __init mvebu_mbus_dt_init(bool is_coherent)
 {
        struct resource mbuswins_res, sdramwins_res;
        struct device_node *np, *controller;
@@ -928,6 +921,8 @@ int __init mvebu_mbus_dt_init(void)
                return -EINVAL;
        }
 
+       mbus_state.hw_io_coherency = is_coherent;
+
        /* Get optional pcie-{mem,io}-aperture properties */
        mvebu_mbus_get_pcie_resources(np, &mbus_state.pcie_mem_aperture,
                                          &mbus_state.pcie_io_aperture);
index 345b8c53b8974d7a6cc271fda41c851ee5835f7c..550c88fb0267f158c26d05714e411805ba15ee90 100644 (file)
@@ -73,6 +73,6 @@ int mvebu_mbus_del_window(phys_addr_t base, size_t size);
 int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base,
                    size_t mbus_size, phys_addr_t sdram_phys_base,
                    size_t sdram_size);
-int mvebu_mbus_dt_init(void);
+int mvebu_mbus_dt_init(bool is_coherent);
 
 #endif /* __LINUX_MBUS_H */