aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/vexpress/arm-spc.c
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/misc/vexpress/arm-spc.c
parent0cb6b75d8bd32750432a9c2ac544321b3fa2d894 (diff)
downloadvexpress-lsk-9ed7d1a299474c62124c5478f70f86c525914cf1.tar.gz
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/misc/vexpress/arm-spc.c')
-rw-r--r--drivers/misc/vexpress/arm-spc.c11
1 files changed, 11 insertions, 0 deletions
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;