Blame view
arch/arm/mach-exynos/hotplug.c
2.58 KB
7d30e8b38
|
1 |
/* linux arch/arm/mach-exynos4/hotplug.c |
11adcc29f
|
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
* * Cloned from linux/arch/arm/mach-realview/hotplug.c * * Copyright (C) 2002 ARM Ltd. * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/kernel.h> #include <linux/errno.h> #include <linux/smp.h> |
911c29b0e
|
16 |
#include <linux/io.h> |
11adcc29f
|
17 18 |
#include <asm/cacheflush.h> |
911c29b0e
|
19 |
#include <mach/regs-pmu.h> |
11adcc29f
|
20 |
extern volatile int pen_release; |
11adcc29f
|
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
static inline void cpu_enter_lowpower(void) { unsigned int v; flush_cache_all(); asm volatile( " mcr p15, 0, %1, c7, c5, 0 " " mcr p15, 0, %1, c7, c10, 4 " /* * Turn off coherency */ " mrc p15, 0, %0, c1, c0, 1 " |
ad849a223
|
36 37 |
" bic %0, %0, %3 " |
11adcc29f
|
38 39 40 41 |
" mcr p15, 0, %0, c1, c0, 1 " " mrc p15, 0, %0, c1, c0, 0 " |
30b99d07b
|
42 43 |
" bic %0, %0, %2 " |
11adcc29f
|
44 45 46 |
" mcr p15, 0, %0, c1, c0, 0 " : "=&r" (v) |
ad849a223
|
47 |
: "r" (0), "Ir" (CR_C), "Ir" (0x40) |
11adcc29f
|
48 49 50 51 52 53 54 55 56 57 |
: "cc"); } static inline void cpu_leave_lowpower(void) { unsigned int v; asm volatile( "mrc p15, 0, %0, c1, c0, 0 " |
e3d9c625f
|
58 59 |
" orr %0, %0, %1 " |
11adcc29f
|
60 61 62 63 |
" mcr p15, 0, %0, c1, c0, 0 " " mrc p15, 0, %0, c1, c0, 1 " |
ad849a223
|
64 65 |
" orr %0, %0, %2 " |
11adcc29f
|
66 67 68 |
" mcr p15, 0, %0, c1, c0, 1 " : "=&r" (v) |
ad849a223
|
69 |
: "Ir" (CR_C), "Ir" (0x40) |
11adcc29f
|
70 71 |
: "cc"); } |
d4450261e
|
72 |
static inline void platform_do_lowpower(unsigned int cpu, int *spurious) |
11adcc29f
|
73 |
{ |
11adcc29f
|
74 |
for (;;) { |
911c29b0e
|
75 76 77 78 |
/* make cpu1 to be turned off at next WFI command */ if (cpu == 1) __raw_writel(0, S5P_ARM_CORE1_CONFIGURATION); |
11adcc29f
|
79 80 81 82 83 84 85 86 |
/* * here's the WFI */ asm(".word 0xe320f003 " : : : "memory", "cc"); |
2f41c36b0
|
87 |
if (pen_release == cpu_logical_map(cpu)) { |
11adcc29f
|
88 89 90 91 92 93 94 |
/* * OK, proper wakeup, we're done */ break; } /* |
d4450261e
|
95 |
* Getting here, means that we have come out of WFI without |
11adcc29f
|
96 97 |
* having been woken up - this shouldn't happen * |
d4450261e
|
98 99 |
* Just note it happening - when we're woken, we can report * its occurrence. |
11adcc29f
|
100 |
*/ |
d4450261e
|
101 |
(*spurious)++; |
11adcc29f
|
102 103 104 105 106 |
} } int platform_cpu_kill(unsigned int cpu) { |
3c030beab
|
107 |
return 1; |
11adcc29f
|
108 109 110 111 112 113 114 115 116 |
} /* * platform-specific code to shutdown a CPU * * Called with IRQs disabled */ void platform_cpu_die(unsigned int cpu) { |
d4450261e
|
117 |
int spurious = 0; |
11adcc29f
|
118 119 120 121 |
/* * we're ready for shutdown now, so do it */ cpu_enter_lowpower(); |
d4450261e
|
122 |
platform_do_lowpower(cpu, &spurious); |
11adcc29f
|
123 124 125 126 127 128 |
/* * bring this CPU back into the world of cache * coherency, and then restore interrupts */ cpu_leave_lowpower(); |
d4450261e
|
129 130 131 132 |
if (spurious) pr_warn("CPU%u: %u spurious wakeup calls ", cpu, spurious); |
11adcc29f
|
133 134 135 136 137 138 139 140 141 142 |
} int platform_cpu_disable(unsigned int cpu) { /* * we don't allow CPU 0 to be shutdown (it is still too special * e.g. clock tick interrupts) */ return cpu == 0 ? -EPERM : 0; } |