From: Florian Fainelli Date: Fri, 1 Dec 2017 00:10:12 +0000 (+0100) Subject: ARM: 8730/1: B15: Add suspend/resume hooks X-Git-Tag: v4.16-rc1~94^2^2~16 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=534f5f36a2c10fda181de2d7023d2100e2a59048;p=linux.git ARM: 8730/1: B15: Add suspend/resume hooks The Broadcom Brahma-B15 CPU readahead cache registers will be restored to their Power-on-Reset values after a S3 suspend/resume cycles, so we want to restore what we had enabled before. Another thing we want to take care of is disabling the read-ahead cache prior to suspending to avoid any sort of side effect with the spinlock we need to grab to serialize register accesses. Signed-off-by: Florian Fainelli Signed-off-by: Russell King --- diff --git a/arch/arm/mm/cache-b15-rac.c b/arch/arm/mm/cache-b15-rac.c index d85b63211759..9ee1d89cced0 100644 --- a/arch/arm/mm/cache-b15-rac.c +++ b/arch/arm/mm/cache-b15-rac.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,10 @@ extern void v7_flush_kern_cache_all(void); RACENPREF_MASK << RACENDATA_SHIFT) #define RAC_ENABLED 0 +/* Special state where we want to bypass the spinlock and call directly + * into the v7 cache maintenance operations during suspend/resume + */ +#define RAC_SUSPENDED 1 static void __iomem *b15_rac_base; static DEFINE_SPINLOCK(rac_lock); @@ -96,6 +101,12 @@ void b15_flush_##name(void) \ unsigned int do_flush; \ u32 val = 0; \ \ + if (test_bit(RAC_SUSPENDED, &b15_rac_flags)) { \ + v7_flush_##name(); \ + bar; \ + return; \ + } \ + \ spin_lock(&rac_lock); \ do_flush = test_bit(RAC_ENABLED, &b15_rac_flags); \ if (do_flush) \ @@ -208,6 +219,39 @@ static int b15_rac_dead_cpu(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ +#ifdef CONFIG_PM_SLEEP +static int b15_rac_suspend(void) +{ + /* Suspend the read-ahead cache oeprations, forcing our cache + * implementation to fallback to the regular ARMv7 calls. + * + * We are guaranteed to be running on the boot CPU at this point and + * with every other CPU quiesced, so setting RAC_SUSPENDED is not racy + * here. + */ + rac_config0_reg = b15_rac_disable_and_flush(); + set_bit(RAC_SUSPENDED, &b15_rac_flags); + + return 0; +} + +static void b15_rac_resume(void) +{ + /* Coming out of a S3 suspend/resume cycle, the read-ahead cache + * register RAC_CONFIG0_REG will be restored to its default value, make + * sure we re-enable it and set the enable flag, we are also guaranteed + * to run on the boot CPU, so not racy again. + */ + __b15_rac_enable(rac_config0_reg); + clear_bit(RAC_SUSPENDED, &b15_rac_flags); +} + +static struct syscore_ops b15_rac_syscore_ops = { + .suspend = b15_rac_suspend, + .resume = b15_rac_resume, +}; +#endif + static int __init b15_rac_init(void) { struct device_node *dn; @@ -242,6 +286,10 @@ static int __init b15_rac_init(void) goto out_cpu_dead; #endif +#ifdef CONFIG_PM_SLEEP + register_syscore_ops(&b15_rac_syscore_ops); +#endif + spin_lock(&rac_lock); reg = __raw_readl(b15_rac_base + RAC_CONFIG0_REG); for_each_possible_cpu(cpu)