diff options
| author | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2014-09-13 13:49:31 -0400 |
|---|---|---|
| committer | Kukjin Kim <kgene.kim@samsung.com> | 2014-10-20 11:06:22 -0400 |
| commit | 6f0b7c0c6faa76c32891ef1f7ee37c7e10aeb039 (patch) | |
| tree | 00712ee5ab9c84ed2c4f954d8004f7c2e1c8d833 | |
| parent | f114040e3ea6e07372334ade75d1ee0775c355e1 (diff) | |
ARM: EXYNOS: Move code from hotplug.c to platsmp.c
Cleanup a little the SMP/hotplug code for Exynos by:
1. Moving completely all functions from hotplug.c into the platsmp.c;
2. Deleting the hotplug.c file.
After recent cleanups (e.g. 75ad2ab28f0f "ARM: EXYNOS: use
v7_exit_coherency_flush macro for cache disabling") there was only CPU
power down related code in hotplug.c file.
Rationale behind the code movement and benefits:
1. The file platsmp.c is the only user of code located in hotplug.c.
Keeping code in hotplug.c required declaring exynos_cpu_die() in common.h.
Such dependencies and mentioned exynos_cpu_die() declaration can be
removed.
2. In next patches exynos_set_delayed_reset_assertion() will be
introduced. This function will be called by:
- cpu_leave_power (hotplug.c),
- platform_do_lowpower (hotplug.c),
- exynos_boot_secondary (platsmp.c).
Merging hotplug.c into platsmp.c leads to simpler and cleaner code with
less dependencies between files.
The commit only moves code around with one additional observable change:
the hotplug.c was compiled with custom CFLAGS (-march=armv7-a). These
CFLAGS are not necessary any more.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
| -rw-r--r-- | arch/arm/mach-exynos/Makefile | 3 | ||||
| -rw-r--r-- | arch/arm/mach-exynos/common.h | 2 | ||||
| -rw-r--r-- | arch/arm/mach-exynos/hotplug.c | 91 | ||||
| -rw-r--r-- | arch/arm/mach-exynos/platsmp.c | 74 |
4 files changed, 74 insertions, 96 deletions
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 27ae6144679c..d634de588d96 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile | |||
| @@ -16,9 +16,6 @@ obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o | |||
| 16 | 16 | ||
| 17 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 17 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
| 18 | 18 | ||
| 19 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
| 20 | CFLAGS_hotplug.o += -march=armv7-a | ||
| 21 | |||
| 22 | plus_sec := $(call as-instr,.arch_extension sec,+sec) | 19 | plus_sec := $(call as-instr,.arch_extension sec,+sec) |
| 23 | AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) | 20 | AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) |
| 24 | 21 | ||
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index 47b904b3b973..3d3e6af9d015 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h | |||
| @@ -130,8 +130,6 @@ extern void exynos_cpu_resume(void); | |||
| 130 | 130 | ||
| 131 | extern struct smp_operations exynos_smp_ops; | 131 | extern struct smp_operations exynos_smp_ops; |
| 132 | 132 | ||
| 133 | extern void exynos_cpu_die(unsigned int cpu); | ||
| 134 | |||
| 135 | /* PMU(Power Management Unit) support */ | 133 | /* PMU(Power Management Unit) support */ |
| 136 | 134 | ||
| 137 | #define PMU_TABLE_END (-1U) | 135 | #define PMU_TABLE_END (-1U) |
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c deleted file mode 100644 index 4d86961a7957..000000000000 --- a/arch/arm/mach-exynos/hotplug.c +++ /dev/null | |||
| @@ -1,91 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Cloned from linux/arch/arm/mach-realview/hotplug.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 ARM Ltd. | ||
| 5 | * All Rights Reserved | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/errno.h> | ||
| 14 | #include <linux/smp.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | |||
| 17 | #include <asm/cacheflush.h> | ||
| 18 | #include <asm/cp15.h> | ||
| 19 | #include <asm/smp_plat.h> | ||
| 20 | |||
| 21 | #include "common.h" | ||
| 22 | #include "regs-pmu.h" | ||
| 23 | |||
| 24 | static inline void cpu_leave_lowpower(void) | ||
| 25 | { | ||
| 26 | unsigned int v; | ||
| 27 | |||
| 28 | asm volatile( | ||
| 29 | "mrc p15, 0, %0, c1, c0, 0\n" | ||
| 30 | " orr %0, %0, %1\n" | ||
| 31 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
| 32 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
| 33 | " orr %0, %0, %2\n" | ||
| 34 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
| 35 | : "=&r" (v) | ||
| 36 | : "Ir" (CR_C), "Ir" (0x40) | ||
| 37 | : "cc"); | ||
| 38 | } | ||
| 39 | |||
| 40 | static inline void platform_do_lowpower(unsigned int cpu, int *spurious) | ||
| 41 | { | ||
| 42 | u32 mpidr = cpu_logical_map(cpu); | ||
| 43 | u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); | ||
| 44 | |||
| 45 | for (;;) { | ||
| 46 | |||
| 47 | /* Turn the CPU off on next WFI instruction. */ | ||
| 48 | exynos_cpu_power_down(core_id); | ||
| 49 | |||
| 50 | wfi(); | ||
| 51 | |||
| 52 | if (pen_release == core_id) { | ||
| 53 | /* | ||
| 54 | * OK, proper wakeup, we're done | ||
| 55 | */ | ||
| 56 | break; | ||
| 57 | } | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Getting here, means that we have come out of WFI without | ||
| 61 | * having been woken up - this shouldn't happen | ||
| 62 | * | ||
| 63 | * Just note it happening - when we're woken, we can report | ||
| 64 | * its occurrence. | ||
| 65 | */ | ||
| 66 | (*spurious)++; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | /* | ||
| 71 | * platform-specific code to shutdown a CPU | ||
| 72 | * | ||
| 73 | * Called with IRQs disabled | ||
| 74 | */ | ||
| 75 | void __ref exynos_cpu_die(unsigned int cpu) | ||
| 76 | { | ||
| 77 | int spurious = 0; | ||
| 78 | |||
| 79 | v7_exit_coherency_flush(louis); | ||
| 80 | |||
| 81 | platform_do_lowpower(cpu, &spurious); | ||
| 82 | |||
| 83 | /* | ||
| 84 | * bring this CPU back into the world of cache | ||
| 85 | * coherency, and then restore interrupts | ||
| 86 | */ | ||
| 87 | cpu_leave_lowpower(); | ||
| 88 | |||
| 89 | if (spurious) | ||
| 90 | pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); | ||
| 91 | } | ||
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 41ae28d69e6f..87a73eec9b36 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
| 23 | 23 | ||
| 24 | #include <asm/cacheflush.h> | 24 | #include <asm/cacheflush.h> |
| 25 | #include <asm/cp15.h> | ||
| 25 | #include <asm/smp_plat.h> | 26 | #include <asm/smp_plat.h> |
| 26 | #include <asm/smp_scu.h> | 27 | #include <asm/smp_scu.h> |
| 27 | #include <asm/firmware.h> | 28 | #include <asm/firmware.h> |
| @@ -33,6 +34,54 @@ | |||
| 33 | 34 | ||
| 34 | extern void exynos4_secondary_startup(void); | 35 | extern void exynos4_secondary_startup(void); |
| 35 | 36 | ||
| 37 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 38 | static inline void cpu_leave_lowpower(void) | ||
| 39 | { | ||
| 40 | unsigned int v; | ||
| 41 | |||
| 42 | asm volatile( | ||
| 43 | "mrc p15, 0, %0, c1, c0, 0\n" | ||
| 44 | " orr %0, %0, %1\n" | ||
| 45 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
| 46 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
| 47 | " orr %0, %0, %2\n" | ||
| 48 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
| 49 | : "=&r" (v) | ||
| 50 | : "Ir" (CR_C), "Ir" (0x40) | ||
| 51 | : "cc"); | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline void platform_do_lowpower(unsigned int cpu, int *spurious) | ||
| 55 | { | ||
| 56 | u32 mpidr = cpu_logical_map(cpu); | ||
| 57 | u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); | ||
| 58 | |||
| 59 | for (;;) { | ||
| 60 | |||
| 61 | /* Turn the CPU off on next WFI instruction. */ | ||
| 62 | exynos_cpu_power_down(core_id); | ||
| 63 | |||
| 64 | wfi(); | ||
| 65 | |||
| 66 | if (pen_release == core_id) { | ||
| 67 | /* | ||
| 68 | * OK, proper wakeup, we're done | ||
| 69 | */ | ||
| 70 | break; | ||
| 71 | } | ||
| 72 | |||
| 73 | /* | ||
| 74 | * Getting here, means that we have come out of WFI without | ||
| 75 | * having been woken up - this shouldn't happen | ||
| 76 | * | ||
| 77 | * Just note it happening - when we're woken, we can report | ||
| 78 | * its occurrence. | ||
| 79 | */ | ||
| 80 | (*spurious)++; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
| 84 | |||
| 36 | /** | 85 | /** |
| 37 | * exynos_core_power_down : power down the specified cpu | 86 | * exynos_core_power_down : power down the specified cpu |
| 38 | * @cpu : the cpu to power down | 87 | * @cpu : the cpu to power down |
| @@ -318,6 +367,31 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus) | |||
| 318 | } | 367 | } |
| 319 | } | 368 | } |
| 320 | 369 | ||
| 370 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 371 | /* | ||
| 372 | * platform-specific code to shutdown a CPU | ||
| 373 | * | ||
| 374 | * Called with IRQs disabled | ||
| 375 | */ | ||
| 376 | static void __ref exynos_cpu_die(unsigned int cpu) | ||
| 377 | { | ||
| 378 | int spurious = 0; | ||
| 379 | |||
| 380 | v7_exit_coherency_flush(louis); | ||
| 381 | |||
| 382 | platform_do_lowpower(cpu, &spurious); | ||
| 383 | |||
| 384 | /* | ||
| 385 | * bring this CPU back into the world of cache | ||
| 386 | * coherency, and then restore interrupts | ||
| 387 | */ | ||
| 388 | cpu_leave_lowpower(); | ||
| 389 | |||
| 390 | if (spurious) | ||
| 391 | pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); | ||
| 392 | } | ||
| 393 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
| 394 | |||
| 321 | struct smp_operations exynos_smp_ops __initdata = { | 395 | struct smp_operations exynos_smp_ops __initdata = { |
| 322 | .smp_init_cpus = exynos_smp_init_cpus, | 396 | .smp_init_cpus = exynos_smp_init_cpus, |
| 323 | .smp_prepare_cpus = exynos_smp_prepare_cpus, | 397 | .smp_prepare_cpus = exynos_smp_prepare_cpus, |
