aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2012-11-19 12:01:20 +0000
committerJon Medhurst <tixy@linaro.org>2013-04-29 09:43:08 +0100
commit0f088b80413a876cbb52cacb0025077a3c2f99cb (patch)
treee4a07faac45a9baf74df3121341cfffd20f9e7a4 /drivers
parent67dc20ed366ed6b4f016b189a1311e1be8cf5f9d (diff)
ARM: CCI: ensure powerdown-time data is flushed from cache
Non-local variables used by the CCI management function called after disabling the cache must be flushed out to main memory in advance, otherwise incoherency of those values may occur if they are sitting in the cache of some other CPU when cci_disable() executes. This patch adds the appropriate flushing to the CCI driver to ensure that the relevant data is available in RAM ahead of time. Because this creates a dependency on arch-specific cacheflushing functions, this patch also makes ARM_CCI depend on ARM. Signed-off-by: Dave Martin <dave.martin@linaro.org> Signed-off-by: Nicolas Pitre <nico@linaro.org> Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bus/Kconfig1
-rw-r--r--drivers/bus/arm-cci.c13
2 files changed, 14 insertions, 0 deletions
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index d032f74ff21..cd4ac9f001f 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -22,5 +22,6 @@ config OMAP_INTERCONNECT
config ARM_CCI
bool "ARM CCI driver support"
+ depends on ARM
endmenu
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 11c15134408..3bdab2c135b 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -21,6 +21,10 @@
#include <linux/slab.h>
#include <linux/arm-cci.h>
+#include <asm/cacheflush.h>
+#include <asm/memory.h>
+#include <asm/outercache.h>
+
#define CCI_STATUS_OFFSET 0xc
#define STATUS_CHANGE_PENDING (1 << 0)
@@ -78,6 +82,15 @@ static int cci_driver_probe(struct platform_device *pdev)
goto ioremap_err;
}
+ /*
+ * Multi-cluster systems may need this data when non-coherent, during
+ * cluster power-up/power-down. Make sure it reaches main memory:
+ */
+ __cpuc_flush_dcache_area(info, sizeof *info);
+ __cpuc_flush_dcache_area(&info, sizeof info);
+ outer_clean_range(virt_to_phys(info), virt_to_phys(info + 1));
+ outer_clean_range(virt_to_phys(&info), virt_to_phys(&info + 1));
+
platform_set_drvdata(pdev, info);
pr_info("CCI loaded at %p\n", info->baseaddr);