diff options
| -rw-r--r-- | drivers/acpi/processor_idle.c | 63 | 
1 files changed, 27 insertions, 36 deletions
| diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 397f2a7fee48..4e6e758bd397 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -64,7 +64,6 @@  #define _COMPONENT              ACPI_PROCESSOR_COMPONENT  ACPI_MODULE_NAME("processor_idle");  #define ACPI_PROCESSOR_FILE_POWER	"power" -#define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)  #define PM_TIMER_TICK_NS		(1000000000ULL/PM_TIMER_FREQUENCY)  #define C2_OVERHEAD			1	/* 1us */  #define C3_OVERHEAD			1	/* 1us */ @@ -78,6 +77,10 @@ module_param(nocst, uint, 0000);  static unsigned int latency_factor __read_mostly = 2;  module_param(latency_factor, uint, 0644); +static s64 us_to_pm_timer_ticks(s64 t) +{ +	return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); +}  /*   * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.   * For now disable this. Probably a bug somewhere else. @@ -108,25 +111,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {  	{},  }; -static inline u32 ticks_elapsed(u32 t1, u32 t2) -{ -	if (t2 >= t1) -		return (t2 - t1); -	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) -		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); -	else -		return ((0xFFFFFFFF - t1) + t2); -} - -static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) -{ -	if (t2 >= t1) -		return PM_TIMER_TICKS_TO_US(t2 - t1); -	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) -		return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); -	else -		return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); -}  /*   * Callers should disable interrupts before the call and enable @@ -802,7 +786,8 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)  static int acpi_idle_enter_c1(struct cpuidle_device *dev,  			      struct cpuidle_state *state)  { -	u32 t1, t2; +	ktime_t  kt1, kt2; +	s64 idle_time;  	struct acpi_processor *pr;  	struct acpi_processor_cx *cx = cpuidle_get_statedata(state); @@ -820,14 +805,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,  		return 0;  	} -	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); +	kt1 = ktime_get_real();  	acpi_idle_do_entry(cx); -	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); +	kt2 = ktime_get_real(); +	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));  	local_irq_enable();  	cx->usage++; -	return ticks_elapsed_in_us(t1, t2); +	return idle_time;  }  /** @@ -840,8 +826,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,  {  	struct acpi_processor *pr;  	struct acpi_processor_cx *cx = cpuidle_get_statedata(state); -	u32 t1, t2; -	int sleep_ticks = 0; +	ktime_t  kt1, kt2; +	s64 idle_time; +	s64 sleep_ticks = 0;  	pr = __get_cpu_var(processors); @@ -874,18 +861,19 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,  	if (cx->type == ACPI_STATE_C3)  		ACPI_FLUSH_CPU_CACHE(); -	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); +	kt1 = ktime_get_real();  	/* Tell the scheduler that we are going deep-idle: */  	sched_clock_idle_sleep_event();  	acpi_idle_do_entry(cx); -	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); +	kt2 = ktime_get_real(); +	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));  #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)  	/* TSC could halt in idle, so notify users */  	if (tsc_halts_in_c(cx->type))  		mark_tsc_unstable("TSC halts in idle");;  #endif -	sleep_ticks = ticks_elapsed(t1, t2); +	sleep_ticks = us_to_pm_timer_ticks(idle_time);  	/* Tell the scheduler how much we idled: */  	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); @@ -897,7 +885,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,  	acpi_state_timer_broadcast(pr, cx, 0);  	cx->time += sleep_ticks; -	return ticks_elapsed_in_us(t1, t2); +	return idle_time;  }  static int c3_cpu_count; @@ -915,8 +903,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  {  	struct acpi_processor *pr;  	struct acpi_processor_cx *cx = cpuidle_get_statedata(state); -	u32 t1, t2; -	int sleep_ticks = 0; +	ktime_t  kt1, kt2; +	s64 idle_time; +	s64 sleep_ticks = 0; +  	pr = __get_cpu_var(processors); @@ -983,9 +973,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  		ACPI_FLUSH_CPU_CACHE();  	} -	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); +	kt1 = ktime_get_real();  	acpi_idle_do_entry(cx); -	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); +	kt2 = ktime_get_real(); +	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));  	/* Re-enable bus master arbitration */  	if (pr->flags.bm_check && pr->flags.bm_control) { @@ -1000,7 +991,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  	if (tsc_halts_in_c(ACPI_STATE_C3))  		mark_tsc_unstable("TSC halts in idle");  #endif -	sleep_ticks = ticks_elapsed(t1, t2); +	sleep_ticks = us_to_pm_timer_ticks(idle_time);  	/* Tell the scheduler how much we idled: */  	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); @@ -1011,7 +1002,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,  	acpi_state_timer_broadcast(pr, cx, 0);  	cx->time += sleep_ticks; -	return ticks_elapsed_in_us(t1, t2); +	return idle_time;  }  struct cpuidle_driver acpi_idle_driver = { | 
