Initial commit: Uploaded everything from abs/core
[arch-rock.git] / base / kernel26 / linux-phc-0.3.0-kernel-vanilla-2.6.23rc3.patch
blob0686694fda32ec6847d3d876a09cb09b6bb2b6f0
1 diff --new-file -a --unified=5 --recursive linux-2.6.23-rc3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c linux-source-2.6.23-rc3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
2 --- linux-2.6.23-rc3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-08-13 06:25:24.000000000 +0200
3 +++ linux-source-2.6.23-rc3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-08-14 15:33:30.000000000 +0200
4 @@ -23,10 +23,15 @@
5 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 */
10 +/* This file has been patched with Linux PHC: https://www.dedigentoo.org/trac/linux-phc
11 + * Patch version: linux-phc-0.3.0-kernel-vanilla-2.6.23.patch
12 + */
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/smp.h>
19 #include <linux/sched.h>
20 @@ -57,16 +62,22 @@
23 #define INTEL_MSR_RANGE (0xffff)
24 #define CPUID_6_ECX_APERFMPERF_CAPABILITY (0x1)
26 +#define INTEL_MSR_VID_MASK (0x00ff)
27 +#define INTEL_MSR_FID_MASK (0xff00)
28 +#define INTEL_MSR_FID_SHIFT (0x8)
29 +#define PHC_VERSION_STRING "0.3.0"
31 struct acpi_cpufreq_data {
32 struct acpi_processor_performance *acpi_data;
33 struct cpufreq_frequency_table *freq_table;
34 unsigned int max_freq;
35 unsigned int resume;
36 unsigned int cpu_feature;
37 + acpi_integer *original_controls;
40 static struct acpi_cpufreq_data *drv_data[NR_CPUS];
41 /* acpi_perf_data is a pointer to percpu data. */
42 static struct acpi_processor_performance *acpi_perf_data;
43 @@ -101,17 +112,19 @@
46 static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
48 int i;
49 + u32 fid;
50 struct acpi_processor_performance *perf;
52 - msr &= INTEL_MSR_RANGE;
53 + fid = msr & INTEL_MSR_FID_MASK;
54 perf = data->acpi_data;
56 for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
57 - if (msr == perf->states[data->freq_table[i].index].status)
58 + if (fid == (perf->states[data->freq_table[i].index].status &
59 + INTEL_MSR_FID_MASK))
60 return data->freq_table[i].frequency;
62 return data->freq_table[0].frequency;
65 @@ -729,10 +742,12 @@
66 if (data) {
67 cpufreq_frequency_table_put_attr(policy->cpu);
68 drv_data[policy->cpu] = NULL;
69 acpi_processor_unregister_performance(data->acpi_data,
70 policy->cpu);
71 + if (data->original_controls)
72 + kfree(data->original_controls);
73 kfree(data);
76 return 0;
78 @@ -746,12 +761,452 @@
79 data->resume = 1;
81 return 0;
87 +/* sysfs interface to change operating points voltages */
89 +static unsigned int extract_fid_from_control(unsigned int control)
91 + return ((control & INTEL_MSR_FID_MASK) >> INTEL_MSR_FID_SHIFT);
94 +static unsigned int extract_vid_from_control(unsigned int control)
96 + return (control & INTEL_MSR_VID_MASK);
99 +static ssize_t check_origial_table (struct acpi_cpufreq_data *data)
101 + struct acpi_processor_performance *acpi_data;
102 + struct cpufreq_frequency_table *freq_table;
103 + unsigned int state_index;
105 + acpi_data = data->acpi_data;
106 + freq_table = data->freq_table;
108 + if (data->original_controls == NULL) {
109 + // Backup original control values
110 + data->original_controls = kcalloc(acpi_data->state_count,
111 + sizeof(acpi_integer), GFP_KERNEL);
112 + if (data->original_controls == NULL) {
113 + printk("failed to allocate memory for original control values\n");
114 + return -ENOMEM;
116 + for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
117 + data->original_controls[state_index] = acpi_data->states[state_index].control;
120 + return 0;
123 +static ssize_t show_freq_attr_vids(struct cpufreq_policy *policy, char *buf)
125 + struct acpi_cpufreq_data *data = drv_data[policy->cpu];
126 + struct acpi_processor_performance *acpi_data;
127 + struct cpufreq_frequency_table *freq_table;
128 + unsigned int i;
129 + unsigned int vid;
130 + ssize_t count = 0;
132 + if (unlikely(data == NULL ||
133 + data->acpi_data == NULL ||
134 + data->freq_table == NULL ||
135 + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
136 + return -ENODEV;
139 + acpi_data = data->acpi_data;
140 + freq_table = data->freq_table;
142 + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
143 + vid = extract_vid_from_control(acpi_data->states[freq_table[i].index].control);
144 + count += sprintf(&buf[count], "%u ", vid);
146 + count += sprintf(&buf[count], "\n");
148 + return count;
151 +static ssize_t show_freq_attr_default_vids(struct cpufreq_policy *policy, char *buf)
153 + struct acpi_cpufreq_data *data = drv_data[policy->cpu];
154 + struct cpufreq_frequency_table *freq_table;
155 + unsigned int i;
156 + unsigned int vid;
157 + ssize_t count = 0;
158 + ssize_t retval;
160 + if (unlikely(data == NULL ||
161 + data->acpi_data == NULL ||
162 + data->freq_table == NULL ||
163 + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
164 + return -ENODEV;
167 + retval = check_origial_table(data);
168 + if (0 != retval)
169 + return retval;
171 + freq_table = data->freq_table;
173 + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
174 + vid = extract_vid_from_control(data->original_controls[freq_table[i].index]);
175 + count += sprintf(&buf[count], "%u ", vid);
177 + count += sprintf(&buf[count], "\n");
179 + return count;
182 +static ssize_t show_freq_attr_fids(struct cpufreq_policy *policy, char *buf)
184 + struct acpi_cpufreq_data *data = drv_data[policy->cpu];
185 + struct acpi_processor_performance *acpi_data;
186 + struct cpufreq_frequency_table *freq_table;
187 + unsigned int i;
188 + unsigned int fid;
189 + ssize_t count = 0;
191 + if (unlikely(data == NULL ||
192 + data->acpi_data == NULL ||
193 + data->freq_table == NULL ||
194 + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
195 + return -ENODEV;
198 + acpi_data = data->acpi_data;
199 + freq_table = data->freq_table;
201 + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
202 + fid = extract_fid_from_control(acpi_data->states[freq_table[i].index].control);
203 + count += sprintf(&buf[count], "%u ", fid);
205 + count += sprintf(&buf[count], "\n");
207 + return count;
210 +static ssize_t show_freq_attr_controls(struct cpufreq_policy *policy, char *buf)
212 + struct acpi_cpufreq_data *data = drv_data[policy->cpu];
213 + struct acpi_processor_performance *acpi_data;
214 + struct cpufreq_frequency_table *freq_table;
215 + unsigned int i;
216 + unsigned int fid;
217 + unsigned int vid;
218 + ssize_t count = 0;
220 + if (unlikely(data == NULL ||
221 + data->acpi_data == NULL ||
222 + data->freq_table == NULL ||
223 + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
224 + return -ENODEV;
227 + acpi_data = data->acpi_data;
228 + freq_table = data->freq_table;
230 + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
231 + fid = extract_fid_from_control(acpi_data->states[freq_table[i].index].control);
232 + vid = extract_vid_from_control(acpi_data->states[freq_table[i].index].control);
233 + count += sprintf(&buf[count], "%u:%u ", fid, vid);
235 + count += sprintf(&buf[count], "\n");
237 + return count;
240 +static ssize_t show_freq_attr_default_controls(struct cpufreq_policy *policy, char *buf)
242 + struct acpi_cpufreq_data *data = drv_data[policy->cpu];
243 + struct cpufreq_frequency_table *freq_table;
244 + unsigned int i;
245 + unsigned int fid;
246 + unsigned int vid;
247 + ssize_t count = 0;
248 + ssize_t retval;
250 + if (unlikely(data == NULL ||
251 + data->acpi_data == NULL ||
252 + data->freq_table == NULL ||
253 + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
254 + return -ENODEV;
257 + retval = check_origial_table(data);
258 + if (0 != retval)
259 + return retval;
261 + freq_table = data->freq_table;
263 + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
264 + fid = extract_fid_from_control(data->original_controls[freq_table[i].index]);
265 + vid = extract_vid_from_control(data->original_controls[freq_table[i].index]);
266 + count += sprintf(&buf[count], "%u:%u ", fid, vid);
268 + count += sprintf(&buf[count], "\n");
270 + return count;
274 +static ssize_t store_freq_attr_vids(struct cpufreq_policy *policy, const char *buf, size_t count)
276 + struct acpi_cpufreq_data *data = drv_data[policy->cpu];
277 + struct acpi_processor_performance *acpi_data;
278 + struct cpufreq_frequency_table *freq_table;
279 + unsigned int freq_index;
280 + unsigned int state_index;
281 + unsigned int new_vid;
282 + unsigned int original_vid;
283 + unsigned int new_control;
284 + unsigned int original_control;
285 + const char *curr_buf = buf;
286 + char *next_buf;
287 + ssize_t retval;
289 + if (unlikely(data == NULL ||
290 + data->acpi_data == NULL ||
291 + data->freq_table == NULL ||
292 + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
293 + return -ENODEV;
296 + retval = check_origial_table(data);
297 + if (0 != retval)
298 + return retval;
300 + acpi_data = data->acpi_data;
301 + freq_table = data->freq_table;
303 + for (freq_index = 0; freq_table[freq_index].frequency != CPUFREQ_TABLE_END; freq_index++) {
304 + new_vid = simple_strtoul(curr_buf, &next_buf, 10);
305 + if (next_buf == curr_buf) {
306 + if ((curr_buf - buf == count - 1) && (*curr_buf == '\n')) {
307 + curr_buf++;
308 + break;
310 + printk("failed to parse vid value at %i (%s)\n", freq_index, curr_buf);
311 + return -EINVAL;
314 + state_index = freq_table[freq_index].index;
315 + original_control = data->original_controls[state_index];
316 + original_vid = original_control & INTEL_MSR_VID_MASK;
317 + if (new_vid <= original_vid) {
318 + new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
319 + dprintk("setting control at %i to %x (default is %x)\n",
320 + freq_index, new_control, original_control);
321 + acpi_data->states[state_index].control = new_control;
323 + } else {
324 + printk("skipping vid at %i, %u is greater than default %u\n",
325 + freq_index, new_vid, original_vid);
328 + curr_buf = next_buf;
329 + while ((curr_buf - buf < count) && ((*curr_buf == ' ') || (*curr_buf == ','))) {
330 + curr_buf++;
334 + /* set new voltage at current frequency */
335 + data->resume = 1;
336 + acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
338 + return curr_buf - buf;
341 +static ssize_t store_freq_attr_controls(struct cpufreq_policy *policy, const char *buf, size_t count)
343 + struct acpi_cpufreq_data *data = drv_data[policy->cpu];
344 + struct acpi_processor_performance *acpi_data;
345 + struct cpufreq_frequency_table *freq_table;
346 + const char *curr_buf;
347 + unsigned int op_count;
348 + unsigned int state_index;
349 + int isok;
350 + char *next_buf;
351 + ssize_t retval;
352 + unsigned int new_vid;
353 + unsigned int original_vid;
354 + unsigned int new_fid;
355 + unsigned int old_fid;
356 + unsigned int original_control;
357 + unsigned int old_control;
358 + unsigned int new_control;
359 + int found;
361 + if (unlikely(data == NULL ||
362 + data->acpi_data == NULL ||
363 + data->freq_table == NULL ||
364 + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
365 + return -ENODEV;
368 + retval = check_origial_table(data);
369 + if (0 != retval)
370 + return retval;
372 + acpi_data = data->acpi_data;
373 + freq_table = data->freq_table;
375 + op_count = 0;
376 + curr_buf = buf;
377 + next_buf = NULL;
378 + isok = 1;
380 + while ( (isok) && (curr_buf != NULL) )
382 + op_count++;
383 + // Parse fid
384 + new_fid = simple_strtoul(curr_buf, &next_buf, 10);
385 + if ((next_buf != curr_buf) && (next_buf != NULL))
387 + // Parse separator between frequency and voltage
388 + curr_buf = next_buf;
389 + next_buf = NULL;
390 + if (*curr_buf==':')
392 + curr_buf++;
393 + // Parse vid
394 + new_vid = simple_strtoul(curr_buf, &next_buf, 10);
395 + if ((next_buf != curr_buf) && (next_buf != NULL))
397 + found = 0;
398 + for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
399 + old_control = acpi_data->states[state_index].control;
400 + old_fid = extract_fid_from_control(old_control);
401 + if (new_fid == old_fid)
403 + found = 1;
404 + original_control = data->original_controls[state_index];
405 + original_vid = extract_vid_from_control(original_control);
406 + if (new_vid <= original_vid)
408 + new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
409 + dprintk("setting control at %i to %x (default is %x)\n",
410 + state_index, new_control, original_control);
411 + acpi_data->states[state_index].control = new_control;
413 + } else {
414 + printk("skipping vid at %i, %u is greater than default %u\n",
415 + state_index, new_vid, original_vid);
420 + if (found == 0)
422 + printk("operating point # %u not found (FID = %u)\n", op_count, new_fid);
423 + isok = 0;
426 + // Parse seprator before next operating point, if any
427 + curr_buf = next_buf;
428 + next_buf = NULL;
429 + if ((*curr_buf == ',') || (*curr_buf == ' '))
430 + curr_buf++;
431 + else
432 + curr_buf = NULL;
434 + else
436 + printk("failed to parse VID of operating point # %u (%s)\n", op_count, curr_buf);
437 + isok = 0;
440 + else
442 + printk("failed to parse operating point # %u (%s)\n", op_count, curr_buf);
443 + isok = 0;
446 + else
448 + printk("failed to parse FID of operating point # %u (%s)\n", op_count, curr_buf);
449 + isok = 0;
453 + if (isok)
455 + retval = count;
456 + /* set new voltage at current frequency */
457 + data->resume = 1;
458 + acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
460 + else
462 + retval = -EINVAL;
465 + return retval;
468 +static ssize_t show_freq_attr_phc_version(struct cpufreq_policy *policy, char *buf)
470 + ssize_t count = 0;
471 + count += sprintf(&buf[count], "%s\n", PHC_VERSION_STRING);
472 + return count;
475 +static struct freq_attr cpufreq_freq_attr_phc_version =
477 + .attr = { .name = "phc_version", .mode = 0444, .owner = THIS_MODULE },
478 + .show = show_freq_attr_phc_version,
479 + .store = NULL,
482 +static struct freq_attr cpufreq_freq_attr_vids =
484 + .attr = { .name = "phc_vids", .mode = 0644, .owner = THIS_MODULE },
485 + .show = show_freq_attr_vids,
486 + .store = store_freq_attr_vids,
489 +static struct freq_attr cpufreq_freq_attr_default_vids =
491 + .attr = { .name = "phc_default_vids", .mode = 0444, .owner = THIS_MODULE },
492 + .show = show_freq_attr_default_vids,
493 + .store = NULL,
496 +static struct freq_attr cpufreq_freq_attr_fids =
498 + .attr = { .name = "phc_fids", .mode = 0444, .owner = THIS_MODULE },
499 + .show = show_freq_attr_fids,
500 + .store = NULL,
503 +static struct freq_attr cpufreq_freq_attr_controls =
505 + .attr = { .name = "phc_controls", .mode = 0644, .owner = THIS_MODULE },
506 + .show = show_freq_attr_controls,
507 + .store = store_freq_attr_controls,
510 +static struct freq_attr cpufreq_freq_attr_default_controls =
512 + .attr = { .name = "phc_default_controls", .mode = 0444, .owner = THIS_MODULE },
513 + .show = show_freq_attr_default_controls,
514 + .store = NULL,
518 static struct freq_attr *acpi_cpufreq_attr[] = {
519 + &cpufreq_freq_attr_phc_version,
520 &cpufreq_freq_attr_scaling_available_freqs,
521 + &cpufreq_freq_attr_vids,
522 + &cpufreq_freq_attr_default_vids,
523 + &cpufreq_freq_attr_fids,
524 + &cpufreq_freq_attr_controls,
525 + &cpufreq_freq_attr_default_controls,
526 NULL,
529 static struct cpufreq_driver acpi_cpufreq_driver = {
530 .verify = acpi_cpufreq_verify,