17
17
#include <linux/module.h>
18
18
#include <linux/of.h>
19
19
#include <linux/of_device.h>
20
+ #include <linux/platform_device.h>
20
21
#include <linux/psci.h>
21
22
#include <linux/pm_runtime.h>
22
23
#include <linux/slab.h>
24
+ #include <linux/string.h>
23
25
24
26
#include <asm/cpuidle.h>
25
27
@@ -33,7 +35,7 @@ struct psci_cpuidle_data {
33
35
34
36
static DEFINE_PER_CPU_READ_MOSTLY (struct psci_cpuidle_data , psci_cpuidle_data ) ;
35
37
static DEFINE_PER_CPU (u32 , domain_state ) ;
36
- static bool psci_cpuidle_use_cpuhp __initdata ;
38
+ static bool psci_cpuidle_use_cpuhp ;
37
39
38
40
void psci_set_domain_state (u32 state )
39
41
{
@@ -104,7 +106,7 @@ static int psci_idle_cpuhp_down(unsigned int cpu)
104
106
return 0 ;
105
107
}
106
108
107
- static void __init psci_idle_init_cpuhp (void )
109
+ static void psci_idle_init_cpuhp (void )
108
110
{
109
111
int err ;
110
112
@@ -127,30 +129,13 @@ static int psci_enter_idle_state(struct cpuidle_device *dev,
127
129
return psci_enter_state (idx , state [idx ]);
128
130
}
129
131
130
- static struct cpuidle_driver psci_idle_driver __initdata = {
131
- .name = "psci_idle" ,
132
- .owner = THIS_MODULE ,
133
- /*
134
- * PSCI idle states relies on architectural WFI to
135
- * be represented as state index 0.
136
- */
137
- .states [0 ] = {
138
- .enter = psci_enter_idle_state ,
139
- .exit_latency = 1 ,
140
- .target_residency = 1 ,
141
- .power_usage = UINT_MAX ,
142
- .name = "WFI" ,
143
- .desc = "ARM WFI" ,
144
- }
145
- };
146
-
147
- static const struct of_device_id psci_idle_state_match [] __initconst = {
132
+ static const struct of_device_id psci_idle_state_match [] = {
148
133
{ .compatible = "arm,idle-state" ,
149
134
.data = psci_enter_idle_state },
150
135
{ },
151
136
};
152
137
153
- int __init psci_dt_parse_state_node (struct device_node * np , u32 * state )
138
+ int psci_dt_parse_state_node (struct device_node * np , u32 * state )
154
139
{
155
140
int err = of_property_read_u32 (np , "arm,psci-suspend-param" , state );
156
141
@@ -167,9 +152,9 @@ int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
167
152
return 0 ;
168
153
}
169
154
170
- static int __init psci_dt_cpu_init_topology (struct cpuidle_driver * drv ,
171
- struct psci_cpuidle_data * data ,
172
- unsigned int state_count , int cpu )
155
+ static int psci_dt_cpu_init_topology (struct cpuidle_driver * drv ,
156
+ struct psci_cpuidle_data * data ,
157
+ unsigned int state_count , int cpu )
173
158
{
174
159
/* Currently limit the hierarchical topology to be used in OSI mode. */
175
160
if (!psci_has_osi_support ())
@@ -190,17 +175,18 @@ static int __init psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
190
175
return 0 ;
191
176
}
192
177
193
- static int __init psci_dt_cpu_init_idle (struct cpuidle_driver * drv ,
194
- struct device_node * cpu_node ,
195
- unsigned int state_count , int cpu )
178
+ static int psci_dt_cpu_init_idle (struct device * dev , struct cpuidle_driver * drv ,
179
+ struct device_node * cpu_node ,
180
+ unsigned int state_count , int cpu )
196
181
{
197
182
int i , ret = 0 ;
198
183
u32 * psci_states ;
199
184
struct device_node * state_node ;
200
185
struct psci_cpuidle_data * data = per_cpu_ptr (& psci_cpuidle_data , cpu );
201
186
202
187
state_count ++ ; /* Add WFI state too */
203
- psci_states = kcalloc (state_count , sizeof (* psci_states ), GFP_KERNEL );
188
+ psci_states = devm_kcalloc (dev , state_count , sizeof (* psci_states ),
189
+ GFP_KERNEL );
204
190
if (!psci_states )
205
191
return - ENOMEM ;
206
192
@@ -213,32 +199,26 @@ static int __init psci_dt_cpu_init_idle(struct cpuidle_driver *drv,
213
199
of_node_put (state_node );
214
200
215
201
if (ret )
216
- goto free_mem ;
202
+ return ret ;
217
203
218
204
pr_debug ("psci-power-state %#x index %d\n" , psci_states [i ], i );
219
205
}
220
206
221
- if (i != state_count ) {
222
- ret = - ENODEV ;
223
- goto free_mem ;
224
- }
207
+ if (i != state_count )
208
+ return - ENODEV ;
225
209
226
210
/* Initialize optional data, used for the hierarchical topology. */
227
211
ret = psci_dt_cpu_init_topology (drv , data , state_count , cpu );
228
212
if (ret < 0 )
229
- goto free_mem ;
213
+ return ret ;
230
214
231
215
/* Idle states parsed correctly, store them in the per-cpu struct. */
232
216
data -> psci_states = psci_states ;
233
217
return 0 ;
234
-
235
- free_mem :
236
- kfree (psci_states );
237
- return ret ;
238
218
}
239
219
240
- static __init int psci_cpu_init_idle (struct cpuidle_driver * drv ,
241
- unsigned int cpu , unsigned int state_count )
220
+ static int psci_cpu_init_idle (struct device * dev , struct cpuidle_driver * drv ,
221
+ unsigned int cpu , unsigned int state_count )
242
222
{
243
223
struct device_node * cpu_node ;
244
224
int ret ;
@@ -254,14 +234,22 @@ static __init int psci_cpu_init_idle(struct cpuidle_driver *drv,
254
234
if (!cpu_node )
255
235
return - ENODEV ;
256
236
257
- ret = psci_dt_cpu_init_idle (drv , cpu_node , state_count , cpu );
237
+ ret = psci_dt_cpu_init_idle (dev , drv , cpu_node , state_count , cpu );
258
238
259
239
of_node_put (cpu_node );
260
240
261
241
return ret ;
262
242
}
263
243
264
- static int __init psci_idle_init_cpu (int cpu )
244
+ static void psci_cpu_deinit_idle (int cpu )
245
+ {
246
+ struct psci_cpuidle_data * data = per_cpu_ptr (& psci_cpuidle_data , cpu );
247
+
248
+ psci_dt_detach_cpu (data -> dev );
249
+ psci_cpuidle_use_cpuhp = false;
250
+ }
251
+
252
+ static int psci_idle_init_cpu (struct device * dev , int cpu )
265
253
{
266
254
struct cpuidle_driver * drv ;
267
255
struct device_node * cpu_node ;
@@ -284,66 +272,72 @@ static int __init psci_idle_init_cpu(int cpu)
284
272
if (ret )
285
273
return ret ;
286
274
287
- drv = kmemdup ( & psci_idle_driver , sizeof (* drv ), GFP_KERNEL );
275
+ drv = devm_kzalloc ( dev , sizeof (* drv ), GFP_KERNEL );
288
276
if (!drv )
289
277
return - ENOMEM ;
290
278
279
+ drv -> name = "psci_idle" ;
280
+ drv -> owner = THIS_MODULE ;
291
281
drv -> cpumask = (struct cpumask * )cpumask_of (cpu );
292
282
293
283
/*
294
- * Initialize idle states data, starting at index 1, since
295
- * by default idle state 0 is the quiescent state reached
296
- * by the cpu by executing the wfi instruction.
297
- *
284
+ * PSCI idle states relies on architectural WFI to be represented as
285
+ * state index 0.
286
+ */
287
+ drv -> states [0 ].enter = psci_enter_idle_state ;
288
+ drv -> states [0 ].exit_latency = 1 ;
289
+ drv -> states [0 ].target_residency = 1 ;
290
+ drv -> states [0 ].power_usage = UINT_MAX ;
291
+ strcpy (drv -> states [0 ].name , "WFI" );
292
+ strcpy (drv -> states [0 ].desc , "ARM WFI" );
293
+
294
+ /*
298
295
* If no DT idle states are detected (ret == 0) let the driver
299
296
* initialization fail accordingly since there is no reason to
300
297
* initialize the idle driver if only wfi is supported, the
301
298
* default archictectural back-end already executes wfi
302
299
* on idle entry.
303
300
*/
304
301
ret = dt_init_idle_driver (drv , psci_idle_state_match , 1 );
305
- if (ret <= 0 ) {
306
- ret = ret ? : - ENODEV ;
307
- goto out_kfree_drv ;
308
- }
302
+ if (ret <= 0 )
303
+ return ret ? : - ENODEV ;
309
304
310
305
/*
311
306
* Initialize PSCI idle states.
312
307
*/
313
- ret = psci_cpu_init_idle (drv , cpu , ret );
308
+ ret = psci_cpu_init_idle (dev , drv , cpu , ret );
314
309
if (ret ) {
315
310
pr_err ("CPU %d failed to PSCI idle\n" , cpu );
316
- goto out_kfree_drv ;
311
+ return ret ;
317
312
}
318
313
319
314
ret = cpuidle_register (drv , NULL );
320
315
if (ret )
321
- goto out_kfree_drv ;
316
+ goto deinit ;
322
317
323
318
cpuidle_cooling_register (drv );
324
319
325
320
return 0 ;
326
-
327
- out_kfree_drv :
328
- kfree (drv );
321
+ deinit :
322
+ psci_cpu_deinit_idle (cpu );
329
323
return ret ;
330
324
}
331
325
332
326
/*
333
- * psci_idle_init - Initializes PSCI cpuidle driver
327
+ * psci_idle_probe - Initializes PSCI cpuidle driver
334
328
*
335
329
* Initializes PSCI cpuidle driver for all CPUs, if any CPU fails
336
330
* to register cpuidle driver then rollback to cancel all CPUs
337
331
* registration.
338
332
*/
339
- static int __init psci_idle_init ( void )
333
+ static int psci_cpuidle_probe ( struct platform_device * pdev )
340
334
{
341
335
int cpu , ret ;
342
336
struct cpuidle_driver * drv ;
343
337
struct cpuidle_device * dev ;
344
338
345
339
for_each_possible_cpu (cpu ) {
346
- ret = psci_idle_init_cpu (cpu );
340
+ ret = psci_idle_init_cpu (& pdev -> dev , cpu );
347
341
if (ret )
348
342
goto out_fail ;
349
343
}
@@ -356,9 +350,34 @@ static int __init psci_idle_init(void)
356
350
dev = per_cpu (cpuidle_devices , cpu );
357
351
drv = cpuidle_get_cpu_driver (dev );
358
352
cpuidle_unregister (drv );
359
- kfree ( drv );
353
+ psci_cpu_deinit_idle ( cpu );
360
354
}
361
355
362
356
return ret ;
363
357
}
358
+
359
+ static struct platform_driver psci_cpuidle_driver = {
360
+ .probe = psci_cpuidle_probe ,
361
+ .driver = {
362
+ .name = "psci-cpuidle" ,
363
+ },
364
+ };
365
+
366
+ static int __init psci_idle_init (void )
367
+ {
368
+ struct platform_device * pdev ;
369
+ int ret ;
370
+
371
+ ret = platform_driver_register (& psci_cpuidle_driver );
372
+ if (ret )
373
+ return ret ;
374
+
375
+ pdev = platform_device_register_simple ("psci-cpuidle" , -1 , NULL , 0 );
376
+ if (IS_ERR (pdev )) {
377
+ platform_driver_unregister (& psci_cpuidle_driver );
378
+ return PTR_ERR (pdev );
379
+ }
380
+
381
+ return 0 ;
382
+ }
364
383
device_initcall (psci_idle_init );
0 commit comments