[PATCH 14/16] ARM: TC2: ensure powerdown-time data is flushed from cache
Nicolas Pitre
nicolas.pitre at linaro.org
Wed Jan 9 19:20:49 EST 2013
From: Dave Martin <dave.martin at linaro.org>
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 at linaro.org>
Signed-off-by: Nicolas Pitre <nico at linaro.org>
---
drivers/misc/Kconfig | 1 +
drivers/misc/arm-cci.c | 21 +++++++++++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 30d5be1ad2..b24630696c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -501,6 +501,7 @@ config USB_SWITCH_FSA9480
config ARM_CCI
bool "ARM CCI driver support"
+ depends on ARM
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
diff --git a/drivers/misc/arm-cci.c b/drivers/misc/arm-cci.c
index f329c43099..739e1c96d3 100644
--- a/drivers/misc/arm-cci.c
+++ b/drivers/misc/arm-cci.c
@@ -21,8 +21,16 @@
#include <linux/slab.h>
#include <linux/arm-cci.h>
-#define CCI400_EAG_OFFSET 0x4000
-#define CCI400_KF_OFFSET 0x5000
+#include <asm/cacheflush.h>
+#include <asm/memory.h>
+#include <asm/outercache.h>
+
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+
+#define CCI400_PMCR 0x0100
+#define CCI400_EAG_OFFSET 0x4000
+#define CCI400_KF_OFFSET 0x5000
#define DRIVER_NAME "CCI"
struct cci_drvdata {
@@ -73,6 +81,15 @@ static int __devinit 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);
--
1.8.0
More information about the linux-arm-kernel
mailing list