Subject: [PATCH 14/16] ARM: TC2: ensure powerdown-time data is flushed from cache

From: [email-masked] (Dave Martin)
Date: Thu, 10 Jan 2013 18:50:52 +0000

On Wed, Jan 09, 2013 at 07:20:49PM -0500, Nicolas Pitre wrote:
> From: Dave Martin <[email-masked]>

To avoid confusion, the prefix in the subject line should be "CCI", not
"TC2".  Any platform which calls disable_cci() after turning caches off
and/or disabling the SMP bit may fall foul of this otherwise ... i.e.,
any platform which has CCI.

Let me know if you want me to send you a modified patch.

Cheers
---Daave

> 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 <[email-masked]>
> Signed-off-by: Nicolas Pitre <[email-masked]>
> ---
>  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
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel