This source file includes following definitions.
- arm_cpuidle_simple_enter
- arm_cpuidle_suspend
- arm_cpuidle_get_ops
- arm_cpuidle_read_ops
- arm_cpuidle_init
1
2
3
4
5
6 #include <linux/cpuidle.h>
7 #include <linux/of.h>
8 #include <linux/of_device.h>
9 #include <asm/cpuidle.h>
10
11 extern struct of_cpuidle_method __cpuidle_method_of_table[];
12
13 static const struct of_cpuidle_method __cpuidle_method_of_table_sentinel
14 __used __section(__cpuidle_method_of_table_end);
15
16 static struct cpuidle_ops cpuidle_ops[NR_CPUS] __ro_after_init;
17
18
19
20
21
22
23
24
25
26
27
28
29 int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
30 struct cpuidle_driver *drv, int index)
31 {
32 cpu_do_idle();
33
34 return index;
35 }
36
37
38
39
40
41
42
43
44
45
46 int arm_cpuidle_suspend(int index)
47 {
48 int cpu = smp_processor_id();
49
50 return cpuidle_ops[cpu].suspend(index);
51 }
52
53
54
55
56
57
58
59
60
61
62 static const struct cpuidle_ops *__init arm_cpuidle_get_ops(const char *method)
63 {
64 struct of_cpuidle_method *m = __cpuidle_method_of_table;
65
66 for (; m->method; m++)
67 if (!strcmp(m->method, method))
68 return m->ops;
69
70 return NULL;
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu)
88 {
89 const char *enable_method;
90 const struct cpuidle_ops *ops;
91
92 enable_method = of_get_property(dn, "enable-method", NULL);
93 if (!enable_method)
94 return -ENOENT;
95
96 ops = arm_cpuidle_get_ops(enable_method);
97 if (!ops) {
98 pr_warn("%pOF: unsupported enable-method property: %s\n",
99 dn, enable_method);
100 return -EOPNOTSUPP;
101 }
102
103 if (!ops->init || !ops->suspend) {
104 pr_warn("cpuidle_ops '%s': no init or suspend callback\n",
105 enable_method);
106 return -EOPNOTSUPP;
107 }
108
109 cpuidle_ops[cpu] = *ops;
110
111 pr_notice("cpuidle: enable-method property '%s'"
112 " found operations\n", enable_method);
113
114 return 0;
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 int __init arm_cpuidle_init(int cpu)
135 {
136 struct device_node *cpu_node = of_cpu_device_node_get(cpu);
137 int ret;
138
139 if (!cpu_node)
140 return -ENODEV;
141
142 ret = arm_cpuidle_read_ops(cpu_node, cpu);
143 if (!ret)
144 ret = cpuidle_ops[cpu].init(cpu_node, cpu);
145
146 of_node_put(cpu_node);
147
148 return ret;
149 }