aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/processor_idle.c63
1 files changed, 27 insertions, 36 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7bc22a471fe3..879af875c213 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -64,7 +64,6 @@
64#define _COMPONENT ACPI_PROCESSOR_COMPONENT 64#define _COMPONENT ACPI_PROCESSOR_COMPONENT
65ACPI_MODULE_NAME("processor_idle"); 65ACPI_MODULE_NAME("processor_idle");
66#define ACPI_PROCESSOR_FILE_POWER "power" 66#define ACPI_PROCESSOR_FILE_POWER "power"
67#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
68#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) 67#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
69#define C2_OVERHEAD 1 /* 1us */ 68#define C2_OVERHEAD 1 /* 1us */
70#define C3_OVERHEAD 1 /* 1us */ 69#define C3_OVERHEAD 1 /* 1us */
@@ -78,6 +77,10 @@ module_param(nocst, uint, 0000);
78static unsigned int latency_factor __read_mostly = 2; 77static unsigned int latency_factor __read_mostly = 2;
79module_param(latency_factor, uint, 0644); 78module_param(latency_factor, uint, 0644);
80 79
80static s64 us_to_pm_timer_ticks(s64 t)
81{
82 return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
83}
81/* 84/*
82 * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. 85 * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
83 * For now disable this. Probably a bug somewhere else. 86 * For now disable this. Probably a bug somewhere else.
@@ -159,25 +162,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
159 {}, 162 {},
160}; 163};
161 164
162static inline u32 ticks_elapsed(u32 t1, u32 t2)
163{
164 if (t2 >= t1)
165 return (t2 - t1);
166 else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
167 return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
168 else
169 return ((0xFFFFFFFF - t1) + t2);
170}
171
172static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
173{
174 if (t2 >= t1)
175 return PM_TIMER_TICKS_TO_US(t2 - t1);
176 else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
177 return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
178 else
179 return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
180}
181 165
182/* 166/*
183 * Callers should disable interrupts before the call and enable 167 * Callers should disable interrupts before the call and enable
@@ -853,7 +837,8 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
853static int acpi_idle_enter_c1(struct cpuidle_device *dev, 837static int acpi_idle_enter_c1(struct cpuidle_device *dev,
854 struct cpuidle_state *state) 838 struct cpuidle_state *state)
855{ 839{
856 u32 t1, t2; 840 ktime_t kt1, kt2;
841 s64 idle_time;
857 struct acpi_processor *pr; 842 struct acpi_processor *pr;
858 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 843 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
859 844
@@ -871,14 +856,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
871 return 0; 856 return 0;
872 } 857 }
873 858
874 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 859 kt1 = ktime_get_real();
875 acpi_idle_do_entry(cx); 860 acpi_idle_do_entry(cx);
876 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 861 kt2 = ktime_get_real();
862 idle_time = ktime_to_us(ktime_sub(kt2, kt1));
877 863
878 local_irq_enable(); 864 local_irq_enable();
879 cx->usage++; 865 cx->usage++;
880 866
881 return ticks_elapsed_in_us(t1, t2); 867 return idle_time;
882} 868}
883 869
884/** 870/**
@@ -891,8 +877,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
891{ 877{
892 struct acpi_processor *pr; 878 struct acpi_processor *pr;
893 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 879 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
894 u32 t1, t2; 880 ktime_t kt1, kt2;
895 int sleep_ticks = 0; 881 s64 idle_time;
882 s64 sleep_ticks = 0;
896 883
897 pr = __get_cpu_var(processors); 884 pr = __get_cpu_var(processors);
898 885
@@ -925,18 +912,19 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
925 if (cx->type == ACPI_STATE_C3) 912 if (cx->type == ACPI_STATE_C3)
926 ACPI_FLUSH_CPU_CACHE(); 913 ACPI_FLUSH_CPU_CACHE();
927 914
928 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 915 kt1 = ktime_get_real();
929 /* Tell the scheduler that we are going deep-idle: */ 916 /* Tell the scheduler that we are going deep-idle: */
930 sched_clock_idle_sleep_event(); 917 sched_clock_idle_sleep_event();
931 acpi_idle_do_entry(cx); 918 acpi_idle_do_entry(cx);
932 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 919 kt2 = ktime_get_real();
920 idle_time = ktime_to_us(ktime_sub(kt2, kt1));
933 921
934#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) 922#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
935 /* TSC could halt in idle, so notify users */ 923 /* TSC could halt in idle, so notify users */
936 if (tsc_halts_in_c(cx->type)) 924 if (tsc_halts_in_c(cx->type))
937 mark_tsc_unstable("TSC halts in idle");; 925 mark_tsc_unstable("TSC halts in idle");;
938#endif 926#endif
939 sleep_ticks = ticks_elapsed(t1, t2); 927 sleep_ticks = us_to_pm_timer_ticks(idle_time);
940 928
941 /* Tell the scheduler how much we idled: */ 929 /* Tell the scheduler how much we idled: */
942 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); 930 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +936,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
948 936
949 acpi_state_timer_broadcast(pr, cx, 0); 937 acpi_state_timer_broadcast(pr, cx, 0);
950 cx->time += sleep_ticks; 938 cx->time += sleep_ticks;
951 return ticks_elapsed_in_us(t1, t2); 939 return idle_time;
952} 940}
953 941
954static int c3_cpu_count; 942static int c3_cpu_count;
@@ -966,8 +954,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
966{ 954{
967 struct acpi_processor *pr; 955 struct acpi_processor *pr;
968 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 956 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
969 u32 t1, t2; 957 ktime_t kt1, kt2;
970 int sleep_ticks = 0; 958 s64 idle_time;
959 s64 sleep_ticks = 0;
960
971 961
972 pr = __get_cpu_var(processors); 962 pr = __get_cpu_var(processors);
973 963
@@ -1034,9 +1024,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1034 ACPI_FLUSH_CPU_CACHE(); 1024 ACPI_FLUSH_CPU_CACHE();
1035 } 1025 }
1036 1026
1037 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 1027 kt1 = ktime_get_real();
1038 acpi_idle_do_entry(cx); 1028 acpi_idle_do_entry(cx);
1039 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 1029 kt2 = ktime_get_real();
1030 idle_time = ktime_to_us(ktime_sub(kt2, kt1));
1040 1031
1041 /* Re-enable bus master arbitration */ 1032 /* Re-enable bus master arbitration */
1042 if (pr->flags.bm_check && pr->flags.bm_control) { 1033 if (pr->flags.bm_check && pr->flags.bm_control) {
@@ -1051,7 +1042,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1051 if (tsc_halts_in_c(ACPI_STATE_C3)) 1042 if (tsc_halts_in_c(ACPI_STATE_C3))
1052 mark_tsc_unstable("TSC halts in idle"); 1043 mark_tsc_unstable("TSC halts in idle");
1053#endif 1044#endif
1054 sleep_ticks = ticks_elapsed(t1, t2); 1045 sleep_ticks = us_to_pm_timer_ticks(idle_time);
1055 /* Tell the scheduler how much we idled: */ 1046 /* Tell the scheduler how much we idled: */
1056 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); 1047 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
1057 1048
@@ -1062,7 +1053,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1062 1053
1063 acpi_state_timer_broadcast(pr, cx, 0); 1054 acpi_state_timer_broadcast(pr, cx, 0);
1064 cx->time += sleep_ticks; 1055 cx->time += sleep_ticks;
1065 return ticks_elapsed_in_us(t1, t2); 1056 return idle_time;
1066} 1057}
1067 1058
1068struct cpuidle_driver acpi_idle_driver = { 1059struct cpuidle_driver acpi_idle_driver = {