@@ -43,9 +43,31 @@ struct stop_psscr_table {
43
43
44
44
static struct stop_psscr_table stop_psscr_table [CPUIDLE_STATE_MAX ] __read_mostly ;
45
45
46
- static u64 snooze_timeout __read_mostly ;
46
+ static u64 default_snooze_timeout __read_mostly ;
47
47
static bool snooze_timeout_en __read_mostly ;
48
48
49
+ static u64 get_snooze_timeout (struct cpuidle_device * dev ,
50
+ struct cpuidle_driver * drv ,
51
+ int index )
52
+ {
53
+ int i ;
54
+
55
+ if (unlikely (!snooze_timeout_en ))
56
+ return default_snooze_timeout ;
57
+
58
+ for (i = index + 1 ; i < drv -> state_count ; i ++ ) {
59
+ struct cpuidle_state * s = & drv -> states [i ];
60
+ struct cpuidle_state_usage * su = & dev -> states_usage [i ];
61
+
62
+ if (s -> disabled || su -> disable )
63
+ continue ;
64
+
65
+ return s -> target_residency * tb_ticks_per_usec ;
66
+ }
67
+
68
+ return default_snooze_timeout ;
69
+ }
70
+
49
71
static int snooze_loop (struct cpuidle_device * dev ,
50
72
struct cpuidle_driver * drv ,
51
73
int index )
@@ -56,7 +78,7 @@ static int snooze_loop(struct cpuidle_device *dev,
56
78
57
79
local_irq_enable ();
58
80
59
- snooze_exit_time = get_tb () + snooze_timeout ;
81
+ snooze_exit_time = get_tb () + get_snooze_timeout ( dev , drv , index ) ;
60
82
ppc64_runlatch_off ();
61
83
HMT_very_low ();
62
84
while (!need_resched ()) {
@@ -465,11 +487,9 @@ static int powernv_idle_probe(void)
465
487
cpuidle_state_table = powernv_states ;
466
488
/* Device tree can indicate more idle states */
467
489
max_idle_state = powernv_add_idle_states ();
468
- if (max_idle_state > 1 ) {
490
+ default_snooze_timeout = TICK_USEC * tb_ticks_per_usec ;
491
+ if (max_idle_state > 1 )
469
492
snooze_timeout_en = true;
470
- snooze_timeout = powernv_states [1 ].target_residency *
471
- tb_ticks_per_usec ;
472
- }
473
493
} else
474
494
return - ENODEV ;
475
495
0 commit comments