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:11 +0100
commit9ed7d1a299474c62124c5478f70f86c525914cf1 (patch)
treedce3427fcfa43c30a1d4a9fd3f0a23e52ebb05ad /drivers
parent0cb6b75d8bd32750432a9c2ac544321b3fa2d894 (diff)
ARM: TC2: ensure powerdown-time data is flushed from cache
Non-local variables used by the CCI and SPC management functions called by tc2_pm_power_down() 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 tc2_pm_power_down() executes. This patch adds the appropriate flushing to the CCI and SPC drivers 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 and ARM_SPC depend on ARM (pending a proper tidyup of those drivers). Signed-off-by: Dave Martin <dave.martin@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/vexpress/Kconfig1
-rw-r--r--drivers/misc/vexpress/arm-spc.c11
2 files changed, 12 insertions, 0 deletions
diff --git a/drivers/misc/vexpress/Kconfig b/drivers/misc/vexpress/Kconfig
index 8fb52f640bf..3e2676ae6ee 100644
--- a/drivers/misc/vexpress/Kconfig
+++ b/drivers/misc/vexpress/Kconfig
@@ -1,2 +1,3 @@
config ARM_SPC
bool "ARM SPC driver support"
+ depends on ARM
diff --git a/drivers/misc/vexpress/arm-spc.c b/drivers/misc/vexpress/arm-spc.c
index 6453d5b0ac5..6e2e4820c3a 100644
--- a/drivers/misc/vexpress/arm-spc.c
+++ b/drivers/misc/vexpress/arm-spc.c
@@ -25,6 +25,10 @@
#include <linux/spinlock.h>
#include <linux/vexpress.h>
+#include <asm/cacheflush.h>
+#include <asm/memory.h>
+#include <asm/outercache.h>
+
#define SNOOP_CTL_A15 0x404
#define SNOOP_CTL_A7 0x504
#define PERF_LVL_A15 0xB00
@@ -323,6 +327,13 @@ static int __devinit vexpress_spc_driver_probe(struct platform_device *pdev)
spin_lock_init(&info->lock);
platform_set_drvdata(pdev, info);
+ /*
+ * 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);
+ outer_clean_range(virt_to_phys(info), virt_to_phys(info + 1));
+
pr_info("vexpress_spc loaded at %p\n", info->baseaddr);
vexpress_spc_loaded = true;
return ret;