diff options
author | Kukjin Kim <kgene.kim@samsung.com> | 2014-07-22 23:18:15 (GMT) |
---|---|---|
committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-07-22 23:18:15 (GMT) |
commit | 5f534d10d223636b3cd214376471fcfef71baea2 (patch) | |
tree | 38c14b78e01e7270ccce6d6144d124a7129ca707 /arch/arm/mach-exynos | |
parent | 036c37c5809585495661d0eb6e78e0a3612ccde3 (diff) | |
parent | fc2cac41ebbfb16da8b036cba6ec6714ab780a6d (diff) | |
download | linux-5f534d10d223636b3cd214376471fcfef71baea2.tar.xz |
Merge branch 'v3.17-next/cpuidle-exynos' into v3.17-next/power-exynos
Diffstat (limited to 'arch/arm/mach-exynos')
-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 80cbbc7..2a43a17 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) if (!IS_ENABLED(CONFIG_SMP)) exynos_sysram_init(); - exynos_cpuidle_init(); + if (!of_machine_is_compatible("samsung,exynos5420")) + exynos_cpuidle_init(); + exynos_cpufreq_init(); 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 ace0ed6..13a2108 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) return -ETIMEDOUT; /* timeout */ } +static void exynos_powered_up(void) +{ + unsigned int mpidr, cpu, cluster; + + mpidr = read_cpuid_mpidr(); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + arch_spin_lock(&exynos_mcpm_lock); + if (cpu_use_count[cpu][cluster] == 0) + cpu_use_count[cpu][cluster] = 1; + arch_spin_unlock(&exynos_mcpm_lock); +} + +static void exynos_suspend(u64 residency) +{ + unsigned int mpidr, cpunr; + + exynos_power_down(); + + /* + * Execution reaches here only if cpu did not power down. + * Hence roll back the changes done in exynos_power_down function. + * + * CAUTION: "This function requires the stack data to be visible through + * power down and can only be executed on processors like A15 and A7 + * that hit the cache with the C bit clear in the SCTLR register." + */ + mpidr = read_cpuid_mpidr(); + cpunr = exynos_pmu_cpunr(mpidr); + + exynos_cpu_power_up(cpunr); +} + static const struct mcpm_platform_ops exynos_power_ops = { .power_up = exynos_power_up, .power_down = exynos_power_down, .wait_for_powerdown = exynos_wait_for_powerdown, + .suspend = exynos_suspend, + .powered_up = exynos_powered_up, }; 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 1993e6b..c45a2dc 100644 --- a/arch/arm/mach-exynos/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h @@ -319,4 +319,13 @@ #define EXYNOS5420_SWRESET_KFC_SEL 0x3 +#include <asm/cputype.h> +#define MAX_CPUS_IN_CLUSTER 4 + +static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr) +{ + return ((MPIDR_AFFINITY_LEVEL(mpidr, 1) * MAX_CPUS_IN_CLUSTER) + + MPIDR_AFFINITY_LEVEL(mpidr, 0)); +} + #endif /* __ASM_ARCH_REGS_PMU_H */ |