2828
2929#include "cpuidle-psci.h"
3030#include "dt_idle_states.h"
31+ #include "dt_idle_genpd.h"
3132
3233struct psci_cpuidle_data {
3334 u32 * psci_states ;
@@ -36,6 +37,7 @@ struct psci_cpuidle_data {
3637
3738static DEFINE_PER_CPU_READ_MOSTLY (struct psci_cpuidle_data , psci_cpuidle_data ) ;
3839static DEFINE_PER_CPU (u32 , domain_state ) ;
40+ static bool psci_cpuidle_use_syscore ;
3941static bool psci_cpuidle_use_cpuhp ;
4042
4143void psci_set_domain_state (u32 state )
@@ -165,15 +167,19 @@ static struct syscore_ops psci_idle_syscore_ops = {
165167 .resume = psci_idle_syscore_resume ,
166168};
167169
170+ static void psci_idle_init_syscore (void )
171+ {
172+ if (psci_cpuidle_use_syscore )
173+ register_syscore_ops (& psci_idle_syscore_ops );
174+ }
175+
168176static void psci_idle_init_cpuhp (void )
169177{
170178 int err ;
171179
172180 if (!psci_cpuidle_use_cpuhp )
173181 return ;
174182
175- register_syscore_ops (& psci_idle_syscore_ops );
176-
177183 err = cpuhp_setup_state_nocalls (CPUHP_AP_CPU_PM_STARTING ,
178184 "cpuidle/psci:online" ,
179185 psci_idle_cpuhp_up ,
@@ -221,22 +227,23 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
221227 if (!psci_has_osi_support ())
222228 return 0 ;
223229
224- if (IS_ENABLED (CONFIG_PREEMPT_RT ))
225- return 0 ;
226-
227- data -> dev = psci_dt_attach_cpu (cpu );
230+ data -> dev = dt_idle_attach_cpu (cpu , "psci" );
228231 if (IS_ERR_OR_NULL (data -> dev ))
229232 return PTR_ERR_OR_ZERO (data -> dev );
230233
234+ psci_cpuidle_use_syscore = true;
235+
231236 /*
232237 * Using the deepest state for the CPU to trigger a potential selection
233238 * of a shared state for the domain, assumes the domain states are all
234- * deeper states.
239+ * deeper states. On PREEMPT_RT the hierarchical topology is limited to
240+ * s2ram and s2idle.
235241 */
236- drv -> states [state_count - 1 ].flags |= CPUIDLE_FLAG_RCU_IDLE ;
237- drv -> states [state_count - 1 ].enter = psci_enter_domain_idle_state ;
238242 drv -> states [state_count - 1 ].enter_s2idle = psci_enter_s2idle_domain_idle_state ;
239- psci_cpuidle_use_cpuhp = true;
243+ if (!IS_ENABLED (CONFIG_PREEMPT_RT )) {
244+ drv -> states [state_count - 1 ].enter = psci_enter_domain_idle_state ;
245+ psci_cpuidle_use_cpuhp = true;
246+ }
240247
241248 return 0 ;
242249}
@@ -311,7 +318,8 @@ static void psci_cpu_deinit_idle(int cpu)
311318{
312319 struct psci_cpuidle_data * data = per_cpu_ptr (& psci_cpuidle_data , cpu );
313320
314- psci_dt_detach_cpu (data -> dev );
321+ dt_idle_detach_cpu (data -> dev );
322+ psci_cpuidle_use_syscore = false;
315323 psci_cpuidle_use_cpuhp = false;
316324}
317325
@@ -408,6 +416,7 @@ static int psci_cpuidle_probe(struct platform_device *pdev)
408416 goto out_fail ;
409417 }
410418
419+ psci_idle_init_syscore ();
411420 psci_idle_init_cpuhp ();
412421 return 0 ;
413422
0 commit comments