Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4610035 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'pm-cpuidle'

* pm-cpuidle:
  cpuidle: powernv/pseries: Auto-promotion of snooze to deeper idle state
parents 3bcda76d 78eaa10f
Loading
Loading
Loading
Loading
+12 −0
Original line number Original line Diff line number Diff line
@@ -29,18 +29,25 @@ struct cpuidle_driver powernv_idle_driver = {


static int max_idle_state;
static int max_idle_state;
static struct cpuidle_state *cpuidle_state_table;
static struct cpuidle_state *cpuidle_state_table;
static u64 snooze_timeout;
static bool snooze_timeout_en;


static int snooze_loop(struct cpuidle_device *dev,
static int snooze_loop(struct cpuidle_device *dev,
			struct cpuidle_driver *drv,
			struct cpuidle_driver *drv,
			int index)
			int index)
{
{
	u64 snooze_exit_time;

	local_irq_enable();
	local_irq_enable();
	set_thread_flag(TIF_POLLING_NRFLAG);
	set_thread_flag(TIF_POLLING_NRFLAG);


	snooze_exit_time = get_tb() + snooze_timeout;
	ppc64_runlatch_off();
	ppc64_runlatch_off();
	while (!need_resched()) {
	while (!need_resched()) {
		HMT_low();
		HMT_low();
		HMT_very_low();
		HMT_very_low();
		if (snooze_timeout_en && get_tb() > snooze_exit_time)
			break;
	}
	}


	HMT_medium();
	HMT_medium();
@@ -252,6 +259,11 @@ static int powernv_idle_probe(void)
		cpuidle_state_table = powernv_states;
		cpuidle_state_table = powernv_states;
		/* Device tree can indicate more idle states */
		/* Device tree can indicate more idle states */
		max_idle_state = powernv_add_idle_states();
		max_idle_state = powernv_add_idle_states();
		if (max_idle_state > 1) {
			snooze_timeout_en = true;
			snooze_timeout = powernv_states[1].target_residency *
					 tb_ticks_per_usec;
		}
 	} else
 	} else
 		return -ENODEV;
 		return -ENODEV;


+11 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,8 @@ struct cpuidle_driver pseries_idle_driver = {


static int max_idle_state;
static int max_idle_state;
static struct cpuidle_state *cpuidle_state_table;
static struct cpuidle_state *cpuidle_state_table;
static u64 snooze_timeout;
static bool snooze_timeout_en;


static inline void idle_loop_prolog(unsigned long *in_purr)
static inline void idle_loop_prolog(unsigned long *in_purr)
{
{
@@ -58,14 +60,18 @@ static int snooze_loop(struct cpuidle_device *dev,
			int index)
			int index)
{
{
	unsigned long in_purr;
	unsigned long in_purr;
	u64 snooze_exit_time;


	idle_loop_prolog(&in_purr);
	idle_loop_prolog(&in_purr);
	local_irq_enable();
	local_irq_enable();
	set_thread_flag(TIF_POLLING_NRFLAG);
	set_thread_flag(TIF_POLLING_NRFLAG);
	snooze_exit_time = get_tb() + snooze_timeout;


	while (!need_resched()) {
	while (!need_resched()) {
		HMT_low();
		HMT_low();
		HMT_very_low();
		HMT_very_low();
		if (snooze_timeout_en && get_tb() > snooze_exit_time)
			break;
	}
	}


	HMT_medium();
	HMT_medium();
@@ -244,6 +250,11 @@ static int pseries_idle_probe(void)
	} else
	} else
		return -ENODEV;
		return -ENODEV;


	if (max_idle_state > 1) {
		snooze_timeout_en = true;
		snooze_timeout = cpuidle_state_table[1].target_residency *
				 tb_ticks_per_usec;
	}
	return 0;
	return 0;
}
}