aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
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,