diff options
Diffstat (limited to 'arch/arm/mach-exynos/platsmp.c')
-rw-r--r-- | arch/arm/mach-exynos/platsmp.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 9c6dd1451136..7a1ebfeeeeb8 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c | |||
@@ -126,6 +126,18 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious) | |||
126 | */ | 126 | */ |
127 | void exynos_cpu_power_down(int cpu) | 127 | void exynos_cpu_power_down(int cpu) |
128 | { | 128 | { |
129 | if (cpu == 0 && (of_machine_is_compatible("samsung,exynos5420") || | ||
130 | of_machine_is_compatible("samsung,exynos5800"))) { | ||
131 | /* | ||
132 | * Bypass power down for CPU0 during suspend. Check for | ||
133 | * the SYS_PWR_REG value to decide if we are suspending | ||
134 | * the system. | ||
135 | */ | ||
136 | int val = pmu_raw_readl(EXYNOS5_ARM_CORE0_SYS_PWR_REG); | ||
137 | |||
138 | if (!(val & S5P_CORE_LOCAL_PWR_EN)) | ||
139 | return; | ||
140 | } | ||
129 | pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu)); | 141 | pmu_raw_writel(0, EXYNOS_ARM_CORE_CONFIGURATION(cpu)); |
130 | } | 142 | } |
131 | 143 | ||
@@ -204,6 +216,26 @@ static inline void __iomem *cpu_boot_reg(int cpu) | |||
204 | } | 216 | } |
205 | 217 | ||
206 | /* | 218 | /* |
219 | * Set wake up by local power mode and execute software reset for given core. | ||
220 | * | ||
221 | * Currently this is needed only when booting secondary CPU on Exynos3250. | ||
222 | */ | ||
223 | static void exynos_core_restart(u32 core_id) | ||
224 | { | ||
225 | u32 val; | ||
226 | |||
227 | if (!of_machine_is_compatible("samsung,exynos3250")) | ||
228 | return; | ||
229 | |||
230 | val = pmu_raw_readl(EXYNOS_ARM_CORE_STATUS(core_id)); | ||
231 | val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG; | ||
232 | pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id)); | ||
233 | |||
234 | pr_info("CPU%u: Software reset\n", core_id); | ||
235 | pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET); | ||
236 | } | ||
237 | |||
238 | /* | ||
207 | * Write pen_release in a way that is guaranteed to be visible to all | 239 | * Write pen_release in a way that is guaranteed to be visible to all |
208 | * observers, irrespective of whether they're taking part in coherency | 240 | * observers, irrespective of whether they're taking part in coherency |
209 | * or not. This is necessary for the hotplug code to work reliably. | 241 | * or not. This is necessary for the hotplug code to work reliably. |
@@ -279,6 +311,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
279 | return -ETIMEDOUT; | 311 | return -ETIMEDOUT; |
280 | } | 312 | } |
281 | } | 313 | } |
314 | |||
315 | exynos_core_restart(core_id); | ||
316 | |||
282 | /* | 317 | /* |
283 | * Send the secondary CPU a soft interrupt, thereby causing | 318 | * Send the secondary CPU a soft interrupt, thereby causing |
284 | * the boot monitor to read the system wide flags register, | 319 | * the boot monitor to read the system wide flags register, |