Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-realview/hotplug.c
10817 views
1
/*
2
* 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
#include <linux/kernel.h>
12
#include <linux/errno.h>
13
#include <linux/smp.h>
14
15
#include <asm/cacheflush.h>
16
17
extern volatile int pen_release;
18
19
static inline void cpu_enter_lowpower(void)
20
{
21
unsigned int v;
22
23
flush_cache_all();
24
asm volatile(
25
" mcr p15, 0, %1, c7, c5, 0\n"
26
" mcr p15, 0, %1, c7, c10, 4\n"
27
/*
28
* Turn off coherency
29
*/
30
" mrc p15, 0, %0, c1, c0, 1\n"
31
" bic %0, %0, #0x20\n"
32
" mcr p15, 0, %0, c1, c0, 1\n"
33
" mrc p15, 0, %0, c1, c0, 0\n"
34
" bic %0, %0, %2\n"
35
" mcr p15, 0, %0, c1, c0, 0\n"
36
: "=&r" (v)
37
: "r" (0), "Ir" (CR_C)
38
: "cc");
39
}
40
41
static inline void cpu_leave_lowpower(void)
42
{
43
unsigned int v;
44
45
asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
46
" orr %0, %0, %1\n"
47
" mcr p15, 0, %0, c1, c0, 0\n"
48
" mrc p15, 0, %0, c1, c0, 1\n"
49
" orr %0, %0, #0x20\n"
50
" mcr p15, 0, %0, c1, c0, 1\n"
51
: "=&r" (v)
52
: "Ir" (CR_C)
53
: "cc");
54
}
55
56
static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
57
{
58
/*
59
* there is no power-control hardware on this platform, so all
60
* we can do is put the core into WFI; this is safe as the calling
61
* code will have already disabled interrupts
62
*/
63
for (;;) {
64
/*
65
* here's the WFI
66
*/
67
asm(".word 0xe320f003\n"
68
:
69
:
70
: "memory", "cc");
71
72
if (pen_release == cpu) {
73
/*
74
* OK, proper wakeup, we're done
75
*/
76
break;
77
}
78
79
/*
80
* Getting here, means that we have come out of WFI without
81
* having been woken up - this shouldn't happen
82
*
83
* Just note it happening - when we're woken, we can report
84
* its occurrence.
85
*/
86
(*spurious)++;
87
}
88
}
89
90
int platform_cpu_kill(unsigned int cpu)
91
{
92
return 1;
93
}
94
95
/*
96
* platform-specific code to shutdown a CPU
97
*
98
* Called with IRQs disabled
99
*/
100
void platform_cpu_die(unsigned int cpu)
101
{
102
int spurious = 0;
103
104
/*
105
* we're ready for shutdown now, so do it
106
*/
107
cpu_enter_lowpower();
108
platform_do_lowpower(cpu, &spurious);
109
110
/*
111
* bring this CPU back into the world of cache
112
* coherency, and then restore interrupts
113
*/
114
cpu_leave_lowpower();
115
116
if (spurious)
117
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
118
}
119
120
int platform_cpu_disable(unsigned int cpu)
121
{
122
/*
123
* we don't allow CPU 0 to be shutdown (it is still too special
124
* e.g. clock tick interrupts)
125
*/
126
return cpu == 0 ? -EPERM : 0;
127
}
128
129