ARM: tegra: update the cache maintenance order for CPU shutdown
Subsystems (3)
PATCH v2 1/2 ARM: tegra: update the cache maintenance order for CPU shutdown
Updating the cache maintenance order before CPU shutdown when doing CPU hotplug.
The old order:
* clean L1 by flush_cache_all
* exit SMP
* CPU shutdown
Adapt to:
* disable L1 data cache by clear C bit
* clean L1 by v7_flush_dcache_louis
* exit SMP
* CPU shutdown
For CPU hotplug case, it's no need to do "flush_cache_all". And we should disable L1 data cache before clean L1 data cache. Then leaving the SMP coherency.
---
V2:
* no change
--- arch/arm/mach-tegra/hotplug.c | 4 ++-- arch/arm/mach-tegra/sleep-tegra20.S | 3 --- arch/arm/mach-tegra/sleep-tegra30.S | 3 --- arch/arm/mach-tegra/sleep.S | 4 +++- arch/arm/mach-tegra/sleep.h | 1 + 5 files changed, 6 insertions(+), 9 deletions(-)
arch/arm/mach-tegra/hotplug.c +2 -2
@@ -28,8 +28,8 @@ void __ref tegra_cpu_die(unsigned int cpu) { cpu =cpu_logical_map (cpu); -/* Flush the L1 data cache. */ -flush_cache_all (); +/* Clean L1 data cache */ +tegra_disable_clean_inv_dcache ();/* Shut down the current CPU. */ tegra_hotplug_shutdown ();
arch/arm/mach-tegra/sleep-tegra20.S +0 -3
@@ -33,9 +33,6 @@ * should never return */ ENTRY(tegra20_hotplug_shutdown) - /* Turn off SMP coherency */ - exit_smp r4, r5 - /* Put this CPU down */ cpu_id r0 bl tegra20_cpu_shutdown
arch/arm/mach-tegra/sleep-tegra30.S +0 -3
@@ -32,9 +32,6 @@ * Should never return. */ ENTRY(tegra30_hotplug_shutdown) - /* Turn off SMP coherency */ - exit_smp r4, r5 - /* Powergate this CPU */ mov r0, #TEGRA30_POWER_HOTPLUG_SHUTDOWN bl tegra30_cpu_shutdown
arch/arm/mach-tegra/sleep.S +3 -1
@@ -34,7 +34,7 @@ #include "flowctrl.h" #include "sleep.h" -#ifdef CONFIG_PM_SLEEP +#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP) /* * tegra_disable_clean_inv_dcache *
@@ -60,7 +60,9 @@ ENTRY(tegra_disable_clean_inv_dcache) ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc} ENDPROC(tegra_disable_clean_inv_dcache) +#endif +#ifdef CONFIG_PM_SLEEP /* * tegra_sleep_cpu_finish(unsigned long v2p) *
arch/arm/mach-tegra/sleep.h +1 -0
@@ -106,6 +106,7 @@ exit_l2_resume:#else void tegra_resume (void );int tegra_sleep_cpu_finish (unsigned long ); +void tegra_disable_clean_inv_dcache (void );#ifdef CONFIG_HOTPLUG_CPU void tegra20_hotplug_init (void );
Signature · 1 line
1.8.0.3
PATCH v2 2/2 ARM: tegra: moving the clock gating procedure to tegra_cpu_kill
The tegra_cpu_die was be executed by the CPU itslf. So the clock gating procedure won't be executed after the CPU hardware shutdown code. Moving the clock gating procedure to tegra_cpu_kill that will be run by another CPU after the CPU died.
---
V2:
* remove the redundant cpu_logical_map call in tegra_cpu_die when moving the clock gating code to tegra_cpu_kill
--- arch/arm/mach-tegra/common.h | 1 + arch/arm/mach-tegra/hotplug.c | 17 +++++++++++------ arch/arm/mach-tegra/platsmp.c | 1 + 3 files changed, 13 insertions(+), 6 deletions(-)
arch/arm/mach-tegra/common.h +1 -0
@@ -1,4 +1,5 @@extern struct smp_operations tegra_smp_ops; +extern int tegra_cpu_kill (unsigned int cpu);extern void tegra_cpu_die (unsigned int cpu);extern int tegra_cpu_disable (unsigned int cpu);
arch/arm/mach-tegra/hotplug.c +11 -6
@@ -19,6 +19,17 @@static void (*tegra_hotplug_shutdown)(void ); +int tegra_cpu_kill (unsigned cpu) +{ + cpu =cpu_logical_map (cpu); + +/* Clock gate the CPU */ +tegra_wait_cpu_in_reset (cpu); +tegra_disable_cpu_clock (cpu); + +return 1 ; +} +/* * platform-specific code to shutdown a CPU *
@@ -26,18 +37,12 @@ static void (*tegra_hotplug_shutdown)(void);*/ void __ref tegra_cpu_die (unsigned int cpu) { - cpu =cpu_logical_map (cpu); -/* Clean L1 data cache */ tegra_disable_clean_inv_dcache ();/* Shut down the current CPU. */ tegra_hotplug_shutdown (); -/* Clock gate the CPU */ -tegra_wait_cpu_in_reset (cpu); -tegra_disable_cpu_clock (cpu); -/* Should never return here. */ BUG (); }
arch/arm/mach-tegra/platsmp.c +1 -0
@@ -175,6 +175,7 @@ struct smp_operations tegra_smp_ops __initdata = { .smp_secondary_init = tegra_secondary_init, .smp_boot_secondary = tegra_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU + .cpu_kill = tegra_cpu_kill, .cpu_die = tegra_cpu_die, .cpu_disable = tegra_cpu_disable, #endif
Signature · 1 line
1.8.0.3
PATCH v2 1/2 ARM: tegra: update the cache maintenance order for CPU shutdown
In reply to Joseph LoQuoted 12 lines · Joseph Lo
Updating the cache maintenance order before CPU shutdown when doing CPU hotplug.
The old order:
* clean L1 byflush_cache_all
* exit SMP
* CPU shutdown
Adapt to:
* disable L1 data cache by clear C bit
* clean L1 byv7_flush_dcache_louis
* exit SMP
* CPU shutdown
Quoted 4 lines
For CPU hotplug case, it's no need to do "
flush_cache_all". And we should disable L1 data cache before clean L1 data cache. Then leaving the SMP coherency.
Both patches
PATCH v2 1/2 ARM: tegra: update the cache maintenance order for CPU shutdown
In reply to Joseph LoQuoted 12 lines · Joseph Lo
Updating the cache maintenance order before CPU shutdown when doing CPU hotplug.
The old order:
* clean L1 byflush_cache_all
* exit SMP
* CPU shutdown
Adapt to:
* disable L1 data cache by clear C bit
* clean L1 byv7_flush_dcache_louis
* exit SMP
* CPU shutdown
Quoted 3 lines
For CPU hotplug case, it's no need to do "
flush_cache_all". And we should disable L1 data cache before clean L1 data cache. Then leaving the SMP coherency.
The series, applied to Tegra's for-3.9/soc branch.