diff options
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 90 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.h | 20 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 153 |
3 files changed, 119 insertions, 144 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 9c36a53676b7..99e1ef9939be 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | #define PFX "powernow-k8: " | 47 | #define PFX "powernow-k8: " |
48 | #define BFX PFX "BIOS error: " | 48 | #define BFX PFX "BIOS error: " |
49 | #define VERSION "version 2.00.00" | 49 | #define VERSION "version 2.20.00" |
50 | #include "powernow-k8.h" | 50 | #include "powernow-k8.h" |
51 | 51 | ||
52 | /* serialize freq changes */ | 52 | /* serialize freq changes */ |
@@ -73,33 +73,11 @@ static u32 find_khz_freq_from_fid(u32 fid) | |||
73 | return 1000 * find_freq_from_fid(fid); | 73 | return 1000 * find_freq_from_fid(fid); |
74 | } | 74 | } |
75 | 75 | ||
76 | /* Return a frequency in MHz, given an input fid and did */ | 76 | static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate) |
77 | static u32 find_freq_from_fiddid(u32 fid, u32 did) | ||
78 | { | 77 | { |
79 | if (current_cpu_data.x86 == 0x10) | 78 | return data[pstate].frequency; |
80 | return 100 * (fid + 0x10) >> did; | ||
81 | else | ||
82 | return 100 * (fid + 0x8) >> did; | ||
83 | } | ||
84 | |||
85 | static u32 find_khz_freq_from_fiddid(u32 fid, u32 did) | ||
86 | { | ||
87 | return 1000 * find_freq_from_fiddid(fid, did); | ||
88 | } | ||
89 | |||
90 | static u32 find_fid_from_pstate(u32 pstate) | ||
91 | { | ||
92 | u32 hi, lo; | ||
93 | rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi); | ||
94 | return lo & HW_PSTATE_FID_MASK; | ||
95 | } | 79 | } |
96 | 80 | ||
97 | static u32 find_did_from_pstate(u32 pstate) | ||
98 | { | ||
99 | u32 hi, lo; | ||
100 | rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi); | ||
101 | return (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT; | ||
102 | } | ||
103 | 81 | ||
104 | /* Return the vco fid for an input fid | 82 | /* Return the vco fid for an input fid |
105 | * | 83 | * |
@@ -142,9 +120,7 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) | |||
142 | if (cpu_family == CPU_HW_PSTATE) { | 120 | if (cpu_family == CPU_HW_PSTATE) { |
143 | rdmsr(MSR_PSTATE_STATUS, lo, hi); | 121 | rdmsr(MSR_PSTATE_STATUS, lo, hi); |
144 | i = lo & HW_PSTATE_MASK; | 122 | i = lo & HW_PSTATE_MASK; |
145 | rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi); | 123 | data->currpstate = i; |
146 | data->currfid = lo & HW_PSTATE_FID_MASK; | ||
147 | data->currdid = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT; | ||
148 | return 0; | 124 | return 0; |
149 | } | 125 | } |
150 | do { | 126 | do { |
@@ -295,7 +271,7 @@ static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, | |||
295 | static int transition_pstate(struct powernow_k8_data *data, u32 pstate) | 271 | static int transition_pstate(struct powernow_k8_data *data, u32 pstate) |
296 | { | 272 | { |
297 | wrmsr(MSR_PSTATE_CTRL, pstate, 0); | 273 | wrmsr(MSR_PSTATE_CTRL, pstate, 0); |
298 | data->currfid = find_fid_from_pstate(pstate); | 274 | data->currpstate = pstate; |
299 | return 0; | 275 | return 0; |
300 | } | 276 | } |
301 | 277 | ||
@@ -845,17 +821,20 @@ err_out: | |||
845 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) | 821 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) |
846 | { | 822 | { |
847 | int i; | 823 | int i; |
824 | u32 hi = 0, lo = 0; | ||
825 | rdmsr(MSR_PSTATE_CUR_LIMIT, hi, lo); | ||
826 | data->max_hw_pstate = (hi & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT; | ||
848 | 827 | ||
849 | for (i = 0; i < data->acpi_data.state_count; i++) { | 828 | for (i = 0; i < data->acpi_data.state_count; i++) { |
850 | u32 index; | 829 | u32 index; |
851 | u32 hi = 0, lo = 0; | 830 | u32 hi = 0, lo = 0; |
852 | u32 fid; | ||
853 | u32 did; | ||
854 | 831 | ||
855 | index = data->acpi_data.states[i].control & HW_PSTATE_MASK; | 832 | index = data->acpi_data.states[i].control & HW_PSTATE_MASK; |
856 | if (index > MAX_HW_PSTATE) { | 833 | if (index > data->max_hw_pstate) { |
857 | printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index); | 834 | printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index); |
858 | printk(KERN_ERR PFX "Please report to BIOS manufacturer\n"); | 835 | printk(KERN_ERR PFX "Please report to BIOS manufacturer\n"); |
836 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | ||
837 | continue; | ||
859 | } | 838 | } |
860 | rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); | 839 | rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); |
861 | if (!(hi & HW_PSTATE_VALID_MASK)) { | 840 | if (!(hi & HW_PSTATE_VALID_MASK)) { |
@@ -864,22 +843,9 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf | |||
864 | continue; | 843 | continue; |
865 | } | 844 | } |
866 | 845 | ||
867 | fid = lo & HW_PSTATE_FID_MASK; | 846 | powernow_table[i].index = index; |
868 | did = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT; | ||
869 | 847 | ||
870 | dprintk(" %d : fid 0x%x, did 0x%x\n", index, fid, did); | 848 | powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; |
871 | |||
872 | powernow_table[i].index = index | (fid << HW_FID_INDEX_SHIFT) | (did << HW_DID_INDEX_SHIFT); | ||
873 | |||
874 | powernow_table[i].frequency = find_khz_freq_from_fiddid(fid, did); | ||
875 | |||
876 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { | ||
877 | printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", | ||
878 | powernow_table[i].frequency, | ||
879 | (unsigned int) (data->acpi_data.states[i].core_frequency * 1000)); | ||
880 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | ||
881 | continue; | ||
882 | } | ||
883 | } | 849 | } |
884 | return 0; | 850 | return 0; |
885 | } | 851 | } |
@@ -1020,22 +986,18 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i | |||
1020 | /* Take a frequency, and issue the hardware pstate transition command */ | 986 | /* Take a frequency, and issue the hardware pstate transition command */ |
1021 | static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index) | 987 | static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index) |
1022 | { | 988 | { |
1023 | u32 fid = 0; | ||
1024 | u32 did = 0; | ||
1025 | u32 pstate = 0; | 989 | u32 pstate = 0; |
1026 | int res, i; | 990 | int res, i; |
1027 | struct cpufreq_freqs freqs; | 991 | struct cpufreq_freqs freqs; |
1028 | 992 | ||
1029 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); | 993 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); |
1030 | 994 | ||
1031 | /* get fid did for hardware pstate transition */ | 995 | /* get MSR index for hardware pstate transition */ |
1032 | pstate = index & HW_PSTATE_MASK; | 996 | pstate = index & HW_PSTATE_MASK; |
1033 | if (pstate > MAX_HW_PSTATE) | 997 | if (pstate > data->max_hw_pstate) |
1034 | return 0; | 998 | return 0; |
1035 | fid = (index & HW_FID_INDEX_MASK) >> HW_FID_INDEX_SHIFT; | 999 | freqs.old = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); |
1036 | did = (index & HW_DID_INDEX_MASK) >> HW_DID_INDEX_SHIFT; | 1000 | freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); |
1037 | freqs.old = find_khz_freq_from_fiddid(data->currfid, data->currdid); | ||
1038 | freqs.new = find_khz_freq_from_fiddid(fid, did); | ||
1039 | 1001 | ||
1040 | for_each_cpu_mask(i, *(data->available_cores)) { | 1002 | for_each_cpu_mask(i, *(data->available_cores)) { |
1041 | freqs.cpu = i; | 1003 | freqs.cpu = i; |
@@ -1043,9 +1005,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i | |||
1043 | } | 1005 | } |
1044 | 1006 | ||
1045 | res = transition_pstate(data, pstate); | 1007 | res = transition_pstate(data, pstate); |
1046 | data->currfid = find_fid_from_pstate(pstate); | 1008 | freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); |
1047 | data->currdid = find_did_from_pstate(pstate); | ||
1048 | freqs.new = find_khz_freq_from_fiddid(data->currfid, data->currdid); | ||
1049 | 1009 | ||
1050 | for_each_cpu_mask(i, *(data->available_cores)) { | 1010 | for_each_cpu_mask(i, *(data->available_cores)) { |
1051 | freqs.cpu = i; | 1011 | freqs.cpu = i; |
@@ -1090,10 +1050,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1090 | if (query_current_values_with_pending_wait(data)) | 1050 | if (query_current_values_with_pending_wait(data)) |
1091 | goto err_out; | 1051 | goto err_out; |
1092 | 1052 | ||
1093 | if (cpu_family == CPU_HW_PSTATE) | 1053 | if (cpu_family != CPU_HW_PSTATE) { |
1094 | dprintk("targ: curr fid 0x%x, did 0x%x\n", | ||
1095 | data->currfid, data->currdid); | ||
1096 | else { | ||
1097 | dprintk("targ: curr fid 0x%x, vid 0x%x\n", | 1054 | dprintk("targ: curr fid 0x%x, vid 0x%x\n", |
1098 | data->currfid, data->currvid); | 1055 | data->currfid, data->currvid); |
1099 | 1056 | ||
@@ -1124,7 +1081,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1124 | mutex_unlock(&fidvid_mutex); | 1081 | mutex_unlock(&fidvid_mutex); |
1125 | 1082 | ||
1126 | if (cpu_family == CPU_HW_PSTATE) | 1083 | if (cpu_family == CPU_HW_PSTATE) |
1127 | pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); | 1084 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, newstate); |
1128 | else | 1085 | else |
1129 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1086 | pol->cur = find_khz_freq_from_fid(data->currfid); |
1130 | ret = 0; | 1087 | ret = 0; |
@@ -1223,7 +1180,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1223 | + (3 * (1 << data->irt) * 10)) * 1000; | 1180 | + (3 * (1 << data->irt) * 10)) * 1000; |
1224 | 1181 | ||
1225 | if (cpu_family == CPU_HW_PSTATE) | 1182 | if (cpu_family == CPU_HW_PSTATE) |
1226 | pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid); | 1183 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); |
1227 | else | 1184 | else |
1228 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1185 | pol->cur = find_khz_freq_from_fid(data->currfid); |
1229 | dprintk("policy current frequency %d kHz\n", pol->cur); | 1186 | dprintk("policy current frequency %d kHz\n", pol->cur); |
@@ -1240,8 +1197,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1240 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); | 1197 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); |
1241 | 1198 | ||
1242 | if (cpu_family == CPU_HW_PSTATE) | 1199 | if (cpu_family == CPU_HW_PSTATE) |
1243 | dprintk("cpu_init done, current fid 0x%x, did 0x%x\n", | 1200 | dprintk("cpu_init done, current pstate 0x%x\n", data->currpstate); |
1244 | data->currfid, data->currdid); | ||
1245 | else | 1201 | else |
1246 | dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1202 | dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1247 | data->currfid, data->currvid); | 1203 | data->currfid, data->currvid); |
@@ -1297,7 +1253,7 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
1297 | goto out; | 1253 | goto out; |
1298 | 1254 | ||
1299 | if (cpu_family == CPU_HW_PSTATE) | 1255 | if (cpu_family == CPU_HW_PSTATE) |
1300 | khz = find_khz_freq_from_fiddid(data->currfid, data->currdid); | 1256 | khz = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); |
1301 | else | 1257 | else |
1302 | khz = find_khz_freq_from_fid(data->currfid); | 1258 | khz = find_khz_freq_from_fid(data->currfid); |
1303 | 1259 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h index 7c4f6e0faed4..afd2b520d35c 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -10,6 +10,7 @@ struct powernow_k8_data { | |||
10 | 10 | ||
11 | u32 numps; /* number of p-states */ | 11 | u32 numps; /* number of p-states */ |
12 | u32 batps; /* number of p-states supported on battery */ | 12 | u32 batps; /* number of p-states supported on battery */ |
13 | u32 max_hw_pstate; /* maximum legal hardware pstate */ | ||
13 | 14 | ||
14 | /* these values are constant when the PSB is used to determine | 15 | /* these values are constant when the PSB is used to determine |
15 | * vid/fid pairings, but are modified during the ->target() call | 16 | * vid/fid pairings, but are modified during the ->target() call |
@@ -21,8 +22,8 @@ struct powernow_k8_data { | |||
21 | u32 plllock; /* pll lock time, units 1 us */ | 22 | u32 plllock; /* pll lock time, units 1 us */ |
22 | u32 exttype; /* extended interface = 1 */ | 23 | u32 exttype; /* extended interface = 1 */ |
23 | 24 | ||
24 | /* keep track of the current fid / vid or did */ | 25 | /* keep track of the current fid / vid or pstate */ |
25 | u32 currvid, currfid, currdid; | 26 | u32 currvid, currfid, currpstate; |
26 | 27 | ||
27 | /* the powernow_table includes all frequency and vid/fid pairings: | 28 | /* the powernow_table includes all frequency and vid/fid pairings: |
28 | * fid are the lower 8 bits of the index, vid are the upper 8 bits. | 29 | * fid are the lower 8 bits of the index, vid are the upper 8 bits. |
@@ -87,23 +88,14 @@ struct powernow_k8_data { | |||
87 | 88 | ||
88 | /* Hardware Pstate _PSS and MSR definitions */ | 89 | /* Hardware Pstate _PSS and MSR definitions */ |
89 | #define USE_HW_PSTATE 0x00000080 | 90 | #define USE_HW_PSTATE 0x00000080 |
90 | #define HW_PSTATE_FID_MASK 0x0000003f | ||
91 | #define HW_PSTATE_DID_MASK 0x000001c0 | ||
92 | #define HW_PSTATE_DID_SHIFT 6 | ||
93 | #define HW_PSTATE_MASK 0x00000007 | 91 | #define HW_PSTATE_MASK 0x00000007 |
94 | #define HW_PSTATE_VALID_MASK 0x80000000 | 92 | #define HW_PSTATE_VALID_MASK 0x80000000 |
95 | #define HW_FID_INDEX_SHIFT 8 | 93 | #define HW_PSTATE_MAX_MASK 0x000000f0 |
96 | #define HW_FID_INDEX_MASK 0x0000ff00 | 94 | #define HW_PSTATE_MAX_SHIFT 4 |
97 | #define HW_DID_INDEX_SHIFT 16 | ||
98 | #define HW_DID_INDEX_MASK 0x00ff0000 | ||
99 | #define HW_WATTS_MASK 0xff | ||
100 | #define HW_PWR_DVR_MASK 0x300 | ||
101 | #define HW_PWR_DVR_SHIFT 8 | ||
102 | #define HW_PWR_MAX_MULT 3 | ||
103 | #define MAX_HW_PSTATE 8 /* hw pstate supports up to 8 */ | ||
104 | #define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */ | 95 | #define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */ |
105 | #define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */ | 96 | #define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */ |
106 | #define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */ | 97 | #define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */ |
98 | #define MSR_PSTATE_CUR_LIMIT 0xc0010061 /* pstate current limit MSR */ | ||
107 | 99 | ||
108 | /* define the two driver architectures */ | 100 | /* define the two driver architectures */ |
109 | #define CPU_OPTERON 0 | 101 | #define CPU_OPTERON 0 |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 4bd33ce8a6f3..1bba99747f5b 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -37,17 +37,17 @@ | |||
37 | #define DEF_FREQUENCY_UP_THRESHOLD (80) | 37 | #define DEF_FREQUENCY_UP_THRESHOLD (80) |
38 | #define DEF_FREQUENCY_DOWN_THRESHOLD (20) | 38 | #define DEF_FREQUENCY_DOWN_THRESHOLD (20) |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * The polling frequency of this governor depends on the capability of | 41 | * The polling frequency of this governor depends on the capability of |
42 | * the processor. Default polling frequency is 1000 times the transition | 42 | * the processor. Default polling frequency is 1000 times the transition |
43 | * latency of the processor. The governor will work on any processor with | 43 | * latency of the processor. The governor will work on any processor with |
44 | * transition latency <= 10mS, using appropriate sampling | 44 | * transition latency <= 10mS, using appropriate sampling |
45 | * rate. | 45 | * rate. |
46 | * For CPUs with transition latency > 10mS (mostly drivers | 46 | * For CPUs with transition latency > 10mS (mostly drivers |
47 | * with CPUFREQ_ETERNAL), this governor will not work. | 47 | * with CPUFREQ_ETERNAL), this governor will not work. |
48 | * All times here are in uS. | 48 | * All times here are in uS. |
49 | */ | 49 | */ |
50 | static unsigned int def_sampling_rate; | 50 | static unsigned int def_sampling_rate; |
51 | #define MIN_SAMPLING_RATE_RATIO (2) | 51 | #define MIN_SAMPLING_RATE_RATIO (2) |
52 | /* for correct statistics, we need at least 10 ticks between each measure */ | 52 | /* for correct statistics, we need at least 10 ticks between each measure */ |
53 | #define MIN_STAT_SAMPLING_RATE \ | 53 | #define MIN_STAT_SAMPLING_RATE \ |
@@ -63,12 +63,12 @@ static unsigned int def_sampling_rate; | |||
63 | static void do_dbs_timer(struct work_struct *work); | 63 | static void do_dbs_timer(struct work_struct *work); |
64 | 64 | ||
65 | struct cpu_dbs_info_s { | 65 | struct cpu_dbs_info_s { |
66 | struct cpufreq_policy *cur_policy; | 66 | struct cpufreq_policy *cur_policy; |
67 | unsigned int prev_cpu_idle_up; | 67 | unsigned int prev_cpu_idle_up; |
68 | unsigned int prev_cpu_idle_down; | 68 | unsigned int prev_cpu_idle_down; |
69 | unsigned int enable; | 69 | unsigned int enable; |
70 | unsigned int down_skip; | 70 | unsigned int down_skip; |
71 | unsigned int requested_freq; | 71 | unsigned int requested_freq; |
72 | }; | 72 | }; |
73 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | 73 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); |
74 | 74 | ||
@@ -82,24 +82,24 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ | |||
82 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock | 82 | * cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock |
83 | * is recursive for the same process. -Venki | 83 | * is recursive for the same process. -Venki |
84 | */ | 84 | */ |
85 | static DEFINE_MUTEX (dbs_mutex); | 85 | static DEFINE_MUTEX (dbs_mutex); |
86 | static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer); | 86 | static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer); |
87 | 87 | ||
88 | struct dbs_tuners { | 88 | struct dbs_tuners { |
89 | unsigned int sampling_rate; | 89 | unsigned int sampling_rate; |
90 | unsigned int sampling_down_factor; | 90 | unsigned int sampling_down_factor; |
91 | unsigned int up_threshold; | 91 | unsigned int up_threshold; |
92 | unsigned int down_threshold; | 92 | unsigned int down_threshold; |
93 | unsigned int ignore_nice; | 93 | unsigned int ignore_nice; |
94 | unsigned int freq_step; | 94 | unsigned int freq_step; |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static struct dbs_tuners dbs_tuners_ins = { | 97 | static struct dbs_tuners dbs_tuners_ins = { |
98 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 98 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
99 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, | 99 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, |
100 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | 100 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, |
101 | .ignore_nice = 0, | 101 | .ignore_nice = 0, |
102 | .freq_step = 5, | 102 | .freq_step = 5, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | 105 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) |
@@ -109,13 +109,34 @@ static inline unsigned int get_cpu_idle_time(unsigned int cpu) | |||
109 | if (dbs_tuners_ins.ignore_nice) | 109 | if (dbs_tuners_ins.ignore_nice) |
110 | add_nice = kstat_cpu(cpu).cpustat.nice; | 110 | add_nice = kstat_cpu(cpu).cpustat.nice; |
111 | 111 | ||
112 | ret = kstat_cpu(cpu).cpustat.idle + | 112 | ret = kstat_cpu(cpu).cpustat.idle + |
113 | kstat_cpu(cpu).cpustat.iowait + | 113 | kstat_cpu(cpu).cpustat.iowait + |
114 | add_nice; | 114 | add_nice; |
115 | 115 | ||
116 | return ret; | 116 | return ret; |
117 | } | 117 | } |
118 | 118 | ||
119 | /* keep track of frequency transitions */ | ||
120 | static int | ||
121 | dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | ||
122 | void *data) | ||
123 | { | ||
124 | struct cpufreq_freqs *freq = data; | ||
125 | struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, | ||
126 | freq->cpu); | ||
127 | |||
128 | if (!this_dbs_info->enable) | ||
129 | return 0; | ||
130 | |||
131 | this_dbs_info->requested_freq = freq->new; | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static struct notifier_block dbs_cpufreq_notifier_block = { | ||
137 | .notifier_call = dbs_cpufreq_notifier | ||
138 | }; | ||
139 | |||
119 | /************************** sysfs interface ************************/ | 140 | /************************** sysfs interface ************************/ |
120 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | 141 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) |
121 | { | 142 | { |
@@ -127,8 +148,8 @@ static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) | |||
127 | return sprintf (buf, "%u\n", MIN_SAMPLING_RATE); | 148 | return sprintf (buf, "%u\n", MIN_SAMPLING_RATE); |
128 | } | 149 | } |
129 | 150 | ||
130 | #define define_one_ro(_name) \ | 151 | #define define_one_ro(_name) \ |
131 | static struct freq_attr _name = \ | 152 | static struct freq_attr _name = \ |
132 | __ATTR(_name, 0444, show_##_name, NULL) | 153 | __ATTR(_name, 0444, show_##_name, NULL) |
133 | 154 | ||
134 | define_one_ro(sampling_rate_max); | 155 | define_one_ro(sampling_rate_max); |
@@ -148,7 +169,7 @@ show_one(down_threshold, down_threshold); | |||
148 | show_one(ignore_nice_load, ignore_nice); | 169 | show_one(ignore_nice_load, ignore_nice); |
149 | show_one(freq_step, freq_step); | 170 | show_one(freq_step, freq_step); |
150 | 171 | ||
151 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | 172 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, |
152 | const char *buf, size_t count) | 173 | const char *buf, size_t count) |
153 | { | 174 | { |
154 | unsigned int input; | 175 | unsigned int input; |
@@ -164,7 +185,7 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | |||
164 | return count; | 185 | return count; |
165 | } | 186 | } |
166 | 187 | ||
167 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | 188 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, |
168 | const char *buf, size_t count) | 189 | const char *buf, size_t count) |
169 | { | 190 | { |
170 | unsigned int input; | 191 | unsigned int input; |
@@ -183,7 +204,7 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | |||
183 | return count; | 204 | return count; |
184 | } | 205 | } |
185 | 206 | ||
186 | static ssize_t store_up_threshold(struct cpufreq_policy *unused, | 207 | static ssize_t store_up_threshold(struct cpufreq_policy *unused, |
187 | const char *buf, size_t count) | 208 | const char *buf, size_t count) |
188 | { | 209 | { |
189 | unsigned int input; | 210 | unsigned int input; |
@@ -202,7 +223,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
202 | return count; | 223 | return count; |
203 | } | 224 | } |
204 | 225 | ||
205 | static ssize_t store_down_threshold(struct cpufreq_policy *unused, | 226 | static ssize_t store_down_threshold(struct cpufreq_policy *unused, |
206 | const char *buf, size_t count) | 227 | const char *buf, size_t count) |
207 | { | 228 | { |
208 | unsigned int input; | 229 | unsigned int input; |
@@ -228,16 +249,16 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
228 | int ret; | 249 | int ret; |
229 | 250 | ||
230 | unsigned int j; | 251 | unsigned int j; |
231 | 252 | ||
232 | ret = sscanf (buf, "%u", &input); | 253 | ret = sscanf(buf, "%u", &input); |
233 | if ( ret != 1 ) | 254 | if (ret != 1) |
234 | return -EINVAL; | 255 | return -EINVAL; |
235 | 256 | ||
236 | if ( input > 1 ) | 257 | if (input > 1) |
237 | input = 1; | 258 | input = 1; |
238 | 259 | ||
239 | mutex_lock(&dbs_mutex); | 260 | mutex_lock(&dbs_mutex); |
240 | if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ | 261 | if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */ |
241 | mutex_unlock(&dbs_mutex); | 262 | mutex_unlock(&dbs_mutex); |
242 | return count; | 263 | return count; |
243 | } | 264 | } |
@@ -261,14 +282,14 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy, | |||
261 | unsigned int input; | 282 | unsigned int input; |
262 | int ret; | 283 | int ret; |
263 | 284 | ||
264 | ret = sscanf (buf, "%u", &input); | 285 | ret = sscanf(buf, "%u", &input); |
265 | 286 | ||
266 | if ( ret != 1 ) | 287 | if (ret != 1) |
267 | return -EINVAL; | 288 | return -EINVAL; |
268 | 289 | ||
269 | if ( input > 100 ) | 290 | if (input > 100) |
270 | input = 100; | 291 | input = 100; |
271 | 292 | ||
272 | /* no need to test here if freq_step is zero as the user might actually | 293 | /* no need to test here if freq_step is zero as the user might actually |
273 | * want this, they would be crazy though :) */ | 294 | * want this, they would be crazy though :) */ |
274 | mutex_lock(&dbs_mutex); | 295 | mutex_lock(&dbs_mutex); |
@@ -322,18 +343,18 @@ static void dbs_check_cpu(int cpu) | |||
322 | 343 | ||
323 | policy = this_dbs_info->cur_policy; | 344 | policy = this_dbs_info->cur_policy; |
324 | 345 | ||
325 | /* | 346 | /* |
326 | * The default safe range is 20% to 80% | 347 | * The default safe range is 20% to 80% |
327 | * Every sampling_rate, we check | 348 | * Every sampling_rate, we check |
328 | * - If current idle time is less than 20%, then we try to | 349 | * - If current idle time is less than 20%, then we try to |
329 | * increase frequency | 350 | * increase frequency |
330 | * Every sampling_rate*sampling_down_factor, we check | 351 | * Every sampling_rate*sampling_down_factor, we check |
331 | * - If current idle time is more than 80%, then we try to | 352 | * - If current idle time is more than 80%, then we try to |
332 | * decrease frequency | 353 | * decrease frequency |
333 | * | 354 | * |
334 | * Any frequency increase takes it to the maximum frequency. | 355 | * Any frequency increase takes it to the maximum frequency. |
335 | * Frequency reduction happens at minimum steps of | 356 | * Frequency reduction happens at minimum steps of |
336 | * 5% (default) of max_frequency | 357 | * 5% (default) of max_frequency |
337 | */ | 358 | */ |
338 | 359 | ||
339 | /* Check for frequency increase */ | 360 | /* Check for frequency increase */ |
@@ -361,13 +382,13 @@ static void dbs_check_cpu(int cpu) | |||
361 | /* if we are already at full speed then break out early */ | 382 | /* if we are already at full speed then break out early */ |
362 | if (this_dbs_info->requested_freq == policy->max) | 383 | if (this_dbs_info->requested_freq == policy->max) |
363 | return; | 384 | return; |
364 | 385 | ||
365 | freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; | 386 | freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; |
366 | 387 | ||
367 | /* max freq cannot be less than 100. But who knows.... */ | 388 | /* max freq cannot be less than 100. But who knows.... */ |
368 | if (unlikely(freq_step == 0)) | 389 | if (unlikely(freq_step == 0)) |
369 | freq_step = 5; | 390 | freq_step = 5; |
370 | 391 | ||
371 | this_dbs_info->requested_freq += freq_step; | 392 | this_dbs_info->requested_freq += freq_step; |
372 | if (this_dbs_info->requested_freq > policy->max) | 393 | if (this_dbs_info->requested_freq > policy->max) |
373 | this_dbs_info->requested_freq = policy->max; | 394 | this_dbs_info->requested_freq = policy->max; |
@@ -427,15 +448,15 @@ static void dbs_check_cpu(int cpu) | |||
427 | } | 448 | } |
428 | 449 | ||
429 | static void do_dbs_timer(struct work_struct *work) | 450 | static void do_dbs_timer(struct work_struct *work) |
430 | { | 451 | { |
431 | int i; | 452 | int i; |
432 | mutex_lock(&dbs_mutex); | 453 | mutex_lock(&dbs_mutex); |
433 | for_each_online_cpu(i) | 454 | for_each_online_cpu(i) |
434 | dbs_check_cpu(i); | 455 | dbs_check_cpu(i); |
435 | schedule_delayed_work(&dbs_work, | 456 | schedule_delayed_work(&dbs_work, |
436 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 457 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
437 | mutex_unlock(&dbs_mutex); | 458 | mutex_unlock(&dbs_mutex); |
438 | } | 459 | } |
439 | 460 | ||
440 | static inline void dbs_timer_init(void) | 461 | static inline void dbs_timer_init(void) |
441 | { | 462 | { |
@@ -462,13 +483,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
462 | 483 | ||
463 | switch (event) { | 484 | switch (event) { |
464 | case CPUFREQ_GOV_START: | 485 | case CPUFREQ_GOV_START: |
465 | if ((!cpu_online(cpu)) || | 486 | if ((!cpu_online(cpu)) || (!policy->cur)) |
466 | (!policy->cur)) | ||
467 | return -EINVAL; | 487 | return -EINVAL; |
468 | 488 | ||
469 | if (this_dbs_info->enable) /* Already enabled */ | 489 | if (this_dbs_info->enable) /* Already enabled */ |
470 | break; | 490 | break; |
471 | 491 | ||
472 | mutex_lock(&dbs_mutex); | 492 | mutex_lock(&dbs_mutex); |
473 | 493 | ||
474 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); | 494 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); |
@@ -481,7 +501,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
481 | struct cpu_dbs_info_s *j_dbs_info; | 501 | struct cpu_dbs_info_s *j_dbs_info; |
482 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 502 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
483 | j_dbs_info->cur_policy = policy; | 503 | j_dbs_info->cur_policy = policy; |
484 | 504 | ||
485 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(cpu); | 505 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(cpu); |
486 | j_dbs_info->prev_cpu_idle_down | 506 | j_dbs_info->prev_cpu_idle_down |
487 | = j_dbs_info->prev_cpu_idle_up; | 507 | = j_dbs_info->prev_cpu_idle_up; |
@@ -511,8 +531,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
511 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 531 | dbs_tuners_ins.sampling_rate = def_sampling_rate; |
512 | 532 | ||
513 | dbs_timer_init(); | 533 | dbs_timer_init(); |
534 | cpufreq_register_notifier( | ||
535 | &dbs_cpufreq_notifier_block, | ||
536 | CPUFREQ_TRANSITION_NOTIFIER); | ||
514 | } | 537 | } |
515 | 538 | ||
516 | mutex_unlock(&dbs_mutex); | 539 | mutex_unlock(&dbs_mutex); |
517 | break; | 540 | break; |
518 | 541 | ||
@@ -525,9 +548,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
525 | * Stop the timerschedule work, when this governor | 548 | * Stop the timerschedule work, when this governor |
526 | * is used for first time | 549 | * is used for first time |
527 | */ | 550 | */ |
528 | if (dbs_enable == 0) | 551 | if (dbs_enable == 0) { |
529 | dbs_timer_exit(); | 552 | dbs_timer_exit(); |
530 | 553 | cpufreq_unregister_notifier( | |
554 | &dbs_cpufreq_notifier_block, | ||
555 | CPUFREQ_TRANSITION_NOTIFIER); | ||
556 | } | ||
557 | |||
531 | mutex_unlock(&dbs_mutex); | 558 | mutex_unlock(&dbs_mutex); |
532 | 559 | ||
533 | break; | 560 | break; |
@@ -537,11 +564,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
537 | if (policy->max < this_dbs_info->cur_policy->cur) | 564 | if (policy->max < this_dbs_info->cur_policy->cur) |
538 | __cpufreq_driver_target( | 565 | __cpufreq_driver_target( |
539 | this_dbs_info->cur_policy, | 566 | this_dbs_info->cur_policy, |
540 | policy->max, CPUFREQ_RELATION_H); | 567 | policy->max, CPUFREQ_RELATION_H); |
541 | else if (policy->min > this_dbs_info->cur_policy->cur) | 568 | else if (policy->min > this_dbs_info->cur_policy->cur) |
542 | __cpufreq_driver_target( | 569 | __cpufreq_driver_target( |
543 | this_dbs_info->cur_policy, | 570 | this_dbs_info->cur_policy, |
544 | policy->min, CPUFREQ_RELATION_L); | 571 | policy->min, CPUFREQ_RELATION_L); |
545 | mutex_unlock(&dbs_mutex); | 572 | mutex_unlock(&dbs_mutex); |
546 | break; | 573 | break; |
547 | } | 574 | } |