aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2013-02-18 08:47:25 -0500
committerSimon Horman <horms+renesas@verge.net.au>2013-03-12 13:13:21 -0400
commitbbf2627c77355ee07cb589904efaf814cfc223d1 (patch)
treee9123757a1958c1068c6c3b50dddf8c8cd4f647f /arch/arm/mach-shmobile
parentabf88136f73da52162d7e70bd1d8d4294c08bf1e (diff)
ARM: shmobile: Update r8a7779 to check SCU for hotplug
Update the r8a7779 CPU Hotplug code to use SCU PSR to wait for the target CPU core. Previously the shared code in hotplug.c was used to let cpu_kill() wait for cpu_die(). With this change in place the r8a7779 SMP code does not depend on hotplug.c anymore. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index e69ce259a2d7..63c8db966fb2 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -26,6 +26,7 @@
26#include <linux/irqchip/arm-gic.h> 26#include <linux/irqchip/arm-gic.h>
27#include <mach/common.h> 27#include <mach/common.h>
28#include <mach/r8a7779.h> 28#include <mach/r8a7779.h>
29#include <asm/cacheflush.h>
29#include <asm/smp_plat.h> 30#include <asm/smp_plat.h>
30#include <asm/smp_scu.h> 31#include <asm/smp_scu.h>
31#include <asm/smp_twd.h> 32#include <asm/smp_twd.h>
@@ -68,6 +69,16 @@ void __init r8a7779_register_twd(void)
68} 69}
69#endif 70#endif
70 71
72static int r8a7779_scu_psr_core_disabled(int cpu)
73{
74 unsigned long mask = 3 << (cpu * 8);
75
76 if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask)
77 return 1;
78
79 return 0;
80}
81
71static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) 82static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
72{ 83{
73 void __iomem *scu_base = shmobile_scu_base; 84 void __iomem *scu_base = shmobile_scu_base;
@@ -89,9 +100,6 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu)
89 100
90 cpu = cpu_logical_map(cpu); 101 cpu = cpu_logical_map(cpu);
91 102
92 /* disable cache coherency */
93 modify_scu_cpu_psr(3 << (cpu * 8), 0);
94
95 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) 103 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
96 ch = r8a7779_ch_cpu[cpu]; 104 ch = r8a7779_ch_cpu[cpu];
97 105
@@ -110,7 +118,7 @@ static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu)
110 * finish before asking SoC-specific code to power off the CPU core. 118 * finish before asking SoC-specific code to power off the CPU core.
111 */ 119 */
112 for (k = 0; k < 1000; k++) { 120 for (k = 0; k < 1000; k++) {
113 if (shmobile_cpu_is_dead(cpu)) 121 if (r8a7779_scu_psr_core_disabled(cpu))
114 return r8a7779_platform_cpu_kill(cpu); 122 return r8a7779_platform_cpu_kill(cpu);
115 123
116 mdelay(1); 124 mdelay(1);
@@ -119,6 +127,24 @@ static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu)
119 return 0; 127 return 0;
120} 128}
121 129
130static void __maybe_unused r8a7779_cpu_die(unsigned int cpu)
131{
132 dsb();
133 flush_cache_all();
134
135 /* disable cache coherency */
136 modify_scu_cpu_psr(3 << (cpu * 8), 0);
137
138 /* Endless loop until power off from r8a7779_cpu_kill() */
139 while (1)
140 cpu_do_idle();
141}
142
143static int __maybe_unused r8a7779_cpu_disable(unsigned int cpu)
144{
145 /* only CPU1->3 have power domains, do not allow hotplug of CPU0 */
146 return cpu == 0 ? -EPERM : 0;
147}
122 148
123static void __cpuinit r8a7779_secondary_init(unsigned int cpu) 149static void __cpuinit r8a7779_secondary_init(unsigned int cpu)
124{ 150{
@@ -179,7 +205,7 @@ struct smp_operations r8a7779_smp_ops __initdata = {
179 .smp_boot_secondary = r8a7779_boot_secondary, 205 .smp_boot_secondary = r8a7779_boot_secondary,
180#ifdef CONFIG_HOTPLUG_CPU 206#ifdef CONFIG_HOTPLUG_CPU
181 .cpu_kill = r8a7779_cpu_kill, 207 .cpu_kill = r8a7779_cpu_kill,
182 .cpu_die = shmobile_cpu_die, 208 .cpu_die = r8a7779_cpu_die,
183 .cpu_disable = shmobile_cpu_disable, 209 .cpu_disable = r8a7779_cpu_disable,
184#endif 210#endif
185}; 211};