aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r--drivers/acpi/processor_idle.c124
1 files changed, 32 insertions, 92 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7bc22a471fe3..4e6e758bd397 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.
@@ -101,57 +104,6 @@ static int set_max_cstate(const struct dmi_system_id *id)
101/* Actually this shouldn't be __cpuinitdata, would be better to fix the 104/* Actually this shouldn't be __cpuinitdata, would be better to fix the
102 callers to only run once -AK */ 105 callers to only run once -AK */
103static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { 106static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
104 { set_max_cstate, "IBM ThinkPad R40e", {
105 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
106 DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
107 { set_max_cstate, "IBM ThinkPad R40e", {
108 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
109 DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
110 { set_max_cstate, "IBM ThinkPad R40e", {
111 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
112 DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
113 { set_max_cstate, "IBM ThinkPad R40e", {
114 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
115 DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
116 { set_max_cstate, "IBM ThinkPad R40e", {
117 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
118 DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
119 { set_max_cstate, "IBM ThinkPad R40e", {
120 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
121 DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
122 { set_max_cstate, "IBM ThinkPad R40e", {
123 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
124 DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
125 { set_max_cstate, "IBM ThinkPad R40e", {
126 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
127 DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
128 { set_max_cstate, "IBM ThinkPad R40e", {
129 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
130 DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
131 { set_max_cstate, "IBM ThinkPad R40e", {
132 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
133 DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
134 { set_max_cstate, "IBM ThinkPad R40e", {
135 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
136 DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
137 { set_max_cstate, "IBM ThinkPad R40e", {
138 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
139 DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
140 { set_max_cstate, "IBM ThinkPad R40e", {
141 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
142 DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
143 { set_max_cstate, "IBM ThinkPad R40e", {
144 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
145 DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
146 { set_max_cstate, "IBM ThinkPad R40e", {
147 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
148 DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
149 { set_max_cstate, "IBM ThinkPad R40e", {
150 DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
151 DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
152 { set_max_cstate, "Medion 41700", {
153 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
154 DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
155 { set_max_cstate, "Clevo 5600D", { 107 { set_max_cstate, "Clevo 5600D", {
156 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), 108 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
157 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, 109 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -159,25 +111,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
159 {}, 111 {},
160}; 112};
161 113
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 114
182/* 115/*
183 * Callers should disable interrupts before the call and enable 116 * Callers should disable interrupts before the call and enable
@@ -630,7 +563,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
630 * In either case, the proper way to 563 * In either case, the proper way to
631 * handle BM_RLD is to set it and leave it set. 564 * handle BM_RLD is to set it and leave it set.
632 */ 565 */
633 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); 566 acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
634 567
635 return; 568 return;
636} 569}
@@ -800,9 +733,9 @@ static int acpi_idle_bm_check(void)
800{ 733{
801 u32 bm_status = 0; 734 u32 bm_status = 0;
802 735
803 acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); 736 acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
804 if (bm_status) 737 if (bm_status)
805 acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); 738 acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
806 /* 739 /*
807 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect 740 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
808 * the true state of bus mastering activity; forcing us to 741 * the true state of bus mastering activity; forcing us to
@@ -853,7 +786,8 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
853static int acpi_idle_enter_c1(struct cpuidle_device *dev, 786static int acpi_idle_enter_c1(struct cpuidle_device *dev,
854 struct cpuidle_state *state) 787 struct cpuidle_state *state)
855{ 788{
856 u32 t1, t2; 789 ktime_t kt1, kt2;
790 s64 idle_time;
857 struct acpi_processor *pr; 791 struct acpi_processor *pr;
858 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 792 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
859 793
@@ -871,14 +805,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
871 return 0; 805 return 0;
872 } 806 }
873 807
874 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 808 kt1 = ktime_get_real();
875 acpi_idle_do_entry(cx); 809 acpi_idle_do_entry(cx);
876 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 810 kt2 = ktime_get_real();
811 idle_time = ktime_to_us(ktime_sub(kt2, kt1));
877 812
878 local_irq_enable(); 813 local_irq_enable();
879 cx->usage++; 814 cx->usage++;
880 815
881 return ticks_elapsed_in_us(t1, t2); 816 return idle_time;
882} 817}
883 818
884/** 819/**
@@ -891,8 +826,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
891{ 826{
892 struct acpi_processor *pr; 827 struct acpi_processor *pr;
893 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 828 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
894 u32 t1, t2; 829 ktime_t kt1, kt2;
895 int sleep_ticks = 0; 830 s64 idle_time;
831 s64 sleep_ticks = 0;
896 832
897 pr = __get_cpu_var(processors); 833 pr = __get_cpu_var(processors);
898 834
@@ -925,18 +861,19 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
925 if (cx->type == ACPI_STATE_C3) 861 if (cx->type == ACPI_STATE_C3)
926 ACPI_FLUSH_CPU_CACHE(); 862 ACPI_FLUSH_CPU_CACHE();
927 863
928 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 864 kt1 = ktime_get_real();
929 /* Tell the scheduler that we are going deep-idle: */ 865 /* Tell the scheduler that we are going deep-idle: */
930 sched_clock_idle_sleep_event(); 866 sched_clock_idle_sleep_event();
931 acpi_idle_do_entry(cx); 867 acpi_idle_do_entry(cx);
932 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 868 kt2 = ktime_get_real();
869 idle_time = ktime_to_us(ktime_sub(kt2, kt1));
933 870
934#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) 871#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
935 /* TSC could halt in idle, so notify users */ 872 /* TSC could halt in idle, so notify users */
936 if (tsc_halts_in_c(cx->type)) 873 if (tsc_halts_in_c(cx->type))
937 mark_tsc_unstable("TSC halts in idle");; 874 mark_tsc_unstable("TSC halts in idle");;
938#endif 875#endif
939 sleep_ticks = ticks_elapsed(t1, t2); 876 sleep_ticks = us_to_pm_timer_ticks(idle_time);
940 877
941 /* Tell the scheduler how much we idled: */ 878 /* Tell the scheduler how much we idled: */
942 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); 879 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +885,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
948 885
949 acpi_state_timer_broadcast(pr, cx, 0); 886 acpi_state_timer_broadcast(pr, cx, 0);
950 cx->time += sleep_ticks; 887 cx->time += sleep_ticks;
951 return ticks_elapsed_in_us(t1, t2); 888 return idle_time;
952} 889}
953 890
954static int c3_cpu_count; 891static int c3_cpu_count;
@@ -966,8 +903,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
966{ 903{
967 struct acpi_processor *pr; 904 struct acpi_processor *pr;
968 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 905 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
969 u32 t1, t2; 906 ktime_t kt1, kt2;
970 int sleep_ticks = 0; 907 s64 idle_time;
908 s64 sleep_ticks = 0;
909
971 910
972 pr = __get_cpu_var(processors); 911 pr = __get_cpu_var(processors);
973 912
@@ -1028,20 +967,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1028 c3_cpu_count++; 967 c3_cpu_count++;
1029 /* Disable bus master arbitration when all CPUs are in C3 */ 968 /* Disable bus master arbitration when all CPUs are in C3 */
1030 if (c3_cpu_count == num_online_cpus()) 969 if (c3_cpu_count == num_online_cpus())
1031 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); 970 acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
1032 spin_unlock(&c3_lock); 971 spin_unlock(&c3_lock);
1033 } else if (!pr->flags.bm_check) { 972 } else if (!pr->flags.bm_check) {
1034 ACPI_FLUSH_CPU_CACHE(); 973 ACPI_FLUSH_CPU_CACHE();
1035 } 974 }
1036 975
1037 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 976 kt1 = ktime_get_real();
1038 acpi_idle_do_entry(cx); 977 acpi_idle_do_entry(cx);
1039 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 978 kt2 = ktime_get_real();
979 idle_time = ktime_to_us(ktime_sub(kt2, kt1));
1040 980
1041 /* Re-enable bus master arbitration */ 981 /* Re-enable bus master arbitration */
1042 if (pr->flags.bm_check && pr->flags.bm_control) { 982 if (pr->flags.bm_check && pr->flags.bm_control) {
1043 spin_lock(&c3_lock); 983 spin_lock(&c3_lock);
1044 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); 984 acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
1045 c3_cpu_count--; 985 c3_cpu_count--;
1046 spin_unlock(&c3_lock); 986 spin_unlock(&c3_lock);
1047 } 987 }
@@ -1051,7 +991,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1051 if (tsc_halts_in_c(ACPI_STATE_C3)) 991 if (tsc_halts_in_c(ACPI_STATE_C3))
1052 mark_tsc_unstable("TSC halts in idle"); 992 mark_tsc_unstable("TSC halts in idle");
1053#endif 993#endif
1054 sleep_ticks = ticks_elapsed(t1, t2); 994 sleep_ticks = us_to_pm_timer_ticks(idle_time);
1055 /* Tell the scheduler how much we idled: */ 995 /* Tell the scheduler how much we idled: */
1056 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); 996 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
1057 997
@@ -1062,7 +1002,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1062 1002
1063 acpi_state_timer_broadcast(pr, cx, 0); 1003 acpi_state_timer_broadcast(pr, cx, 0);
1064 cx->time += sleep_ticks; 1004 cx->time += sleep_ticks;
1065 return ticks_elapsed_in_us(t1, t2); 1005 return idle_time;
1066} 1006}
1067 1007
1068struct cpuidle_driver acpi_idle_driver = { 1008struct cpuidle_driver acpi_idle_driver = {