aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>2014-09-13 13:49:31 -0400
committerKukjin Kim <kgene.kim@samsung.com>2014-10-20 11:06:22 -0400
commit6f0b7c0c6faa76c32891ef1f7ee37c7e10aeb039 (patch)
tree00712ee5ab9c84ed2c4f954d8004f7c2e1c8d833 /arch/arm
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-exynos/Makefile3
-rw-r--r--arch/arm/mach-exynos/common.h2
-rw-r--r--arch/arm/mach-exynos/hotplug.c91
-rw-r--r--arch/arm/mach-exynos/platsmp.c74
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
17obj-$(CONFIG_SMP) += platsmp.o headsmp.o 17obj-$(CONFIG_SMP) += platsmp.o headsmp.o
18 18
19obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
20CFLAGS_hotplug.o += -march=armv7-a
21
22plus_sec := $(call as-instr,.arch_extension sec,+sec) 19plus_sec := $(call as-instr,.arch_extension sec,+sec)
23AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec) 20AFLAGS_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
131extern struct smp_operations exynos_smp_ops; 131extern struct smp_operations exynos_smp_ops;
132 132
133extern 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
24static 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
40static 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 */
75void __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
34extern void exynos4_secondary_startup(void); 35extern void exynos4_secondary_startup(void);
35 36
37#ifdef CONFIG_HOTPLUG_CPU
38static 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
54static 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 */
376static 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
321struct smp_operations exynos_smp_ops __initdata = { 395struct 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,