diff options
| author | Kukjin Kim <kgene.kim@samsung.com> | 2014-07-22 19:18:15 -0400 |
|---|---|---|
| committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-07-22 19:18:15 -0400 |
| commit | 5f534d10d223636b3cd214376471fcfef71baea2 (patch) | |
| tree | 38c14b78e01e7270ccce6d6144d124a7129ca707 | |
| parent | 036c37c5809585495661d0eb6e78e0a3612ccde3 (diff) | |
| parent | fc2cac41ebbfb16da8b036cba6ec6714ab780a6d (diff) | |
Merge branch 'v3.17-next/cpuidle-exynos' into v3.17-next/power-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 | ||||
| -rw-r--r-- | drivers/cpuidle/Kconfig.arm | 2 | ||||
| -rw-r--r-- | drivers/cpuidle/cpuidle-big_little.c | 12 |
5 files changed, 60 insertions, 3 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 */ |
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index b6d69e899f5d..2f6b33ea6e08 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm | |||
| @@ -9,7 +9,7 @@ config ARM_ARMADA_370_XP_CPUIDLE | |||
| 9 | 9 | ||
| 10 | config ARM_BIG_LITTLE_CPUIDLE | 10 | config ARM_BIG_LITTLE_CPUIDLE |
| 11 | bool "Support for ARM big.LITTLE processors" | 11 | bool "Support for ARM big.LITTLE processors" |
| 12 | depends on ARCH_VEXPRESS_TC2_PM | 12 | depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS |
| 13 | select ARM_CPU_SUSPEND | 13 | select ARM_CPU_SUSPEND |
| 14 | select CPU_IDLE_MULTIPLE_DRIVERS | 14 | select CPU_IDLE_MULTIPLE_DRIVERS |
| 15 | help | 15 | help |
diff --git a/drivers/cpuidle/cpuidle-big_little.c b/drivers/cpuidle/cpuidle-big_little.c index b45fc6249041..344d79fa3407 100644 --- a/drivers/cpuidle/cpuidle-big_little.c +++ b/drivers/cpuidle/cpuidle-big_little.c | |||
| @@ -163,14 +163,24 @@ static int __init bl_idle_driver_init(struct cpuidle_driver *drv, int cpu_id) | |||
| 163 | return 0; | 163 | return 0; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static const struct of_device_id compatible_machine_match[] = { | ||
| 167 | { .compatible = "arm,vexpress,v2p-ca15_a7" }, | ||
| 168 | { .compatible = "samsung,exynos5420" }, | ||
| 169 | {}, | ||
| 170 | }; | ||
| 171 | |||
| 166 | static int __init bl_idle_init(void) | 172 | static int __init bl_idle_init(void) |
| 167 | { | 173 | { |
| 168 | int ret; | 174 | int ret; |
| 175 | struct device_node *root = of_find_node_by_path("/"); | ||
| 176 | |||
| 177 | if (!root) | ||
| 178 | return -ENODEV; | ||
| 169 | 179 | ||
| 170 | /* | 180 | /* |
| 171 | * Initialize the driver just for a compliant set of machines | 181 | * Initialize the driver just for a compliant set of machines |
| 172 | */ | 182 | */ |
| 173 | if (!of_machine_is_compatible("arm,vexpress,v2p-ca15_a7")) | 183 | if (!of_match_node(compatible_machine_match, root)) |
| 174 | return -ENODEV; | 184 | return -ENODEV; |
| 175 | /* | 185 | /* |
| 176 | * For now the differentiation between little and big cores | 186 | * For now the differentiation between little and big cores |
