diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-exynos/exynos.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-exynos/mcpm-exynos.c | 36 | ||||
-rw-r--r-- | arch/arm/mach-exynos/regs-pmu.h | 9 |
3 files changed, 48 insertions, 1 deletions
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 80cbbc74d2c8..2a43a1734eca 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c | |||
@@ -335,7 +335,9 @@ static void __init exynos_dt_machine_init(void) | |||
335 | if (!IS_ENABLED(CONFIG_SMP)) | 335 | if (!IS_ENABLED(CONFIG_SMP)) |
336 | exynos_sysram_init(); | 336 | exynos_sysram_init(); |
337 | 337 | ||
338 | exynos_cpuidle_init(); | 338 | if (!of_machine_is_compatible("samsung,exynos5420")) |
339 | exynos_cpuidle_init(); | ||
340 | |||
339 | exynos_cpufreq_init(); | 341 | exynos_cpufreq_init(); |
340 | 342 | ||
341 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 343 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index ace0ed617476..13a210865c6f 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c | |||
@@ -257,10 +257,46 @@ static int exynos_wait_for_powerdown(unsigned int cpu, unsigned int cluster) | |||
257 | return -ETIMEDOUT; /* timeout */ | 257 | return -ETIMEDOUT; /* timeout */ |
258 | } | 258 | } |
259 | 259 | ||
260 | static void exynos_powered_up(void) | ||
261 | { | ||
262 | unsigned int mpidr, cpu, cluster; | ||
263 | |||
264 | mpidr = read_cpuid_mpidr(); | ||
265 | cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); | ||
266 | cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); | ||
267 | |||
268 | arch_spin_lock(&exynos_mcpm_lock); | ||
269 | if (cpu_use_count[cpu][cluster] == 0) | ||
270 | cpu_use_count[cpu][cluster] = 1; | ||
271 | arch_spin_unlock(&exynos_mcpm_lock); | ||
272 | } | ||
273 | |||
274 | static void exynos_suspend(u64 residency) | ||
275 | { | ||
276 | unsigned int mpidr, cpunr; | ||
277 | |||
278 | exynos_power_down(); | ||
279 | |||
280 | /* | ||
281 | * Execution reaches here only if cpu did not power down. | ||
282 | * Hence roll back the changes done in exynos_power_down function. | ||
283 | * | ||
284 | * CAUTION: "This function requires the stack data to be visible through | ||
285 | * power down and can only be executed on processors like A15 and A7 | ||
286 | * that hit the cache with the C bit clear in the SCTLR register." | ||
287 | */ | ||
288 | mpidr = read_cpuid_mpidr(); | ||
289 | cpunr = exynos_pmu_cpunr(mpidr); | ||
290 | |||
291 | exynos_cpu_power_up(cpunr); | ||
292 | } | ||
293 | |||
260 | static const struct mcpm_platform_ops exynos_power_ops = { | 294 | static const struct mcpm_platform_ops exynos_power_ops = { |
261 | .power_up = exynos_power_up, | 295 | .power_up = exynos_power_up, |
262 | .power_down = exynos_power_down, | 296 | .power_down = exynos_power_down, |
263 | .wait_for_powerdown = exynos_wait_for_powerdown, | 297 | .wait_for_powerdown = exynos_wait_for_powerdown, |
298 | .suspend = exynos_suspend, | ||
299 | .powered_up = exynos_powered_up, | ||
264 | }; | 300 | }; |
265 | 301 | ||
266 | static void __init exynos_mcpm_usage_count_init(void) | 302 | static void __init exynos_mcpm_usage_count_init(void) |
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h index 1993e6bd5388..c45a2dc53e84 100644 --- a/arch/arm/mach-exynos/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h | |||
@@ -319,4 +319,13 @@ | |||
319 | 319 | ||
320 | #define EXYNOS5420_SWRESET_KFC_SEL 0x3 | 320 | #define EXYNOS5420_SWRESET_KFC_SEL 0x3 |
321 | 321 | ||
322 | #include <asm/cputype.h> | ||
323 | #define MAX_CPUS_IN_CLUSTER 4 | ||
324 | |||
325 | static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr) | ||
326 | { | ||
327 | return ((MPIDR_AFFINITY_LEVEL(mpidr, 1) * MAX_CPUS_IN_CLUSTER) | ||
328 | + MPIDR_AFFINITY_LEVEL(mpidr, 0)); | ||
329 | } | ||
330 | |||
322 | #endif /* __ASM_ARCH_REGS_PMU_H */ | 331 | #endif /* __ASM_ARCH_REGS_PMU_H */ |