Magellan Linux

Annotation of /trunk/kernel26-magellan/patches-2.6.25-r4/0156-2.6.25-linux-phc-0.3.1-teknohog.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 664 - (hide annotations) (download)
Thu Jul 10 13:03:47 2008 UTC (15 years, 10 months ago) by niro
File size: 15454 byte(s)
-2.6.25-magellan-r4; updated to linux-2.6.25.10

1 niro 664 patch comming from:
2     http://hoo.homeunix.net/~teknohog/hacks/linux-phc-kernel-vanilla-2.6.25-teknohog.patch
3    
4     --- linux-2.6.25/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-04-17 05:49:44.000000000 +0300
5     +++ linux-2.6.25-teknohog/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-04-21 01:13:12.000000000 +0300
6     @@ -23,10 +23,16 @@
7     * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
8     *
9     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10     */
11    
12     +/* This file has been patched with Linux PHC: https://www.dedigentoo.org/trac/linux-phc
13     + * Patch version: linux-phc-0.3.1-kernel-vanilla-2.6.23.patch
14     + * Updated for Linux 2.6.25 by Risto A. Paju, teknohog at iki.fi
15     + */
16     +
17     +
18     #include <linux/kernel.h>
19     #include <linux/module.h>
20     #include <linux/init.h>
21     #include <linux/smp.h>
22     #include <linux/sched.h>
23     @@ -57,16 +63,22 @@
24     };
25    
26     #define INTEL_MSR_RANGE (0xffff)
27     #define CPUID_6_ECX_APERFMPERF_CAPABILITY (0x1)
28    
29     +#define INTEL_MSR_VID_MASK (0x00ff)
30     +#define INTEL_MSR_FID_MASK (0xff00)
31     +#define INTEL_MSR_FID_SHIFT (0x8)
32     +#define PHC_VERSION_STRING "0.3.1:1"
33     +
34     struct acpi_cpufreq_data {
35     struct acpi_processor_performance *acpi_data;
36     struct cpufreq_frequency_table *freq_table;
37     unsigned int max_freq;
38     unsigned int resume;
39     unsigned int cpu_feature;
40     + acpi_integer *original_controls;
41     };
42    
43     static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
44    
45     /* acpi_perf_data is a pointer to percpu data. */
46     @@ -102,17 +114,19 @@
47     }
48    
49     static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
50     {
51     int i;
52     + u32 fid;
53     struct acpi_processor_performance *perf;
54    
55     - msr &= INTEL_MSR_RANGE;
56     + fid = msr & INTEL_MSR_FID_MASK;
57     perf = data->acpi_data;
58    
59     for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
60     - if (msr == perf->states[data->freq_table[i].index].status)
61     + if (fid == (perf->states[data->freq_table[i].index].status &
62     + INTEL_MSR_FID_MASK))
63     return data->freq_table[i].frequency;
64     }
65     return data->freq_table[0].frequency;
66     }
67    
68     @@ -729,10 +743,12 @@
69     if (data) {
70     cpufreq_frequency_table_put_attr(policy->cpu);
71     per_cpu(drv_data, policy->cpu) = NULL;
72     acpi_processor_unregister_performance(data->acpi_data,
73     policy->cpu);
74     + if (data->original_controls)
75     + kfree(data->original_controls);
76     kfree(data);
77     }
78    
79     return 0;
80     }
81     @@ -746,12 +762,452 @@
82     data->resume = 1;
83    
84     return 0;
85     }
86    
87     +
88     +
89     +
90     +/* sysfs interface to change operating points voltages */
91     +
92     +static unsigned int extract_fid_from_control(unsigned int control)
93     +{
94     + return ((control & INTEL_MSR_FID_MASK) >> INTEL_MSR_FID_SHIFT);
95     +}
96     +
97     +static unsigned int extract_vid_from_control(unsigned int control)
98     +{
99     + return (control & INTEL_MSR_VID_MASK);
100     +}
101     +
102     +static ssize_t check_origial_table (struct acpi_cpufreq_data *data)
103     +{
104     + struct acpi_processor_performance *acpi_data;
105     + struct cpufreq_frequency_table *freq_table;
106     + unsigned int state_index;
107     +
108     + acpi_data = data->acpi_data;
109     + freq_table = data->freq_table;
110     +
111     + if (data->original_controls == NULL) {
112     + // Backup original control values
113     + data->original_controls = kcalloc(acpi_data->state_count,
114     + sizeof(acpi_integer), GFP_KERNEL);
115     + if (data->original_controls == NULL) {
116     + printk("failed to allocate memory for original control values\n");
117     + return -ENOMEM;
118     + }
119     + for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
120     + data->original_controls[state_index] = acpi_data->states[state_index].control;
121     + }
122     + }
123     + return 0;
124     +}
125     +
126     +static ssize_t show_freq_attr_vids(struct cpufreq_policy *policy, char *buf)
127     +{
128     + struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
129     + struct acpi_processor_performance *acpi_data;
130     + struct cpufreq_frequency_table *freq_table;
131     + unsigned int i;
132     + unsigned int vid;
133     + ssize_t count = 0;
134     +
135     + if (unlikely(data == NULL ||
136     + data->acpi_data == NULL ||
137     + data->freq_table == NULL ||
138     + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
139     + return -ENODEV;
140     + }
141     +
142     + acpi_data = data->acpi_data;
143     + freq_table = data->freq_table;
144     +
145     + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
146     + vid = extract_vid_from_control(acpi_data->states[freq_table[i].index].control);
147     + count += sprintf(&buf[count], "%u ", vid);
148     + }
149     + count += sprintf(&buf[count], "\n");
150     +
151     + return count;
152     +}
153     +
154     +static ssize_t show_freq_attr_default_vids(struct cpufreq_policy *policy, char *buf)
155     +{
156     + struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
157     + struct cpufreq_frequency_table *freq_table;
158     + unsigned int i;
159     + unsigned int vid;
160     + ssize_t count = 0;
161     + ssize_t retval;
162     +
163     + if (unlikely(data == NULL ||
164     + data->acpi_data == NULL ||
165     + data->freq_table == NULL ||
166     + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
167     + return -ENODEV;
168     + }
169     +
170     + retval = check_origial_table(data);
171     + if (0 != retval)
172     + return retval;
173     +
174     + freq_table = data->freq_table;
175     +
176     + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
177     + vid = extract_vid_from_control(data->original_controls[freq_table[i].index]);
178     + count += sprintf(&buf[count], "%u ", vid);
179     + }
180     + count += sprintf(&buf[count], "\n");
181     +
182     + return count;
183     +}
184     +
185     +static ssize_t show_freq_attr_fids(struct cpufreq_policy *policy, char *buf)
186     +{
187     + struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
188     + struct acpi_processor_performance *acpi_data;
189     + struct cpufreq_frequency_table *freq_table;
190     + unsigned int i;
191     + unsigned int fid;
192     + ssize_t count = 0;
193     +
194     + if (unlikely(data == NULL ||
195     + data->acpi_data == NULL ||
196     + data->freq_table == NULL ||
197     + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
198     + return -ENODEV;
199     + }
200     +
201     + acpi_data = data->acpi_data;
202     + freq_table = data->freq_table;
203     +
204     + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
205     + fid = extract_fid_from_control(acpi_data->states[freq_table[i].index].control);
206     + count += sprintf(&buf[count], "%u ", fid);
207     + }
208     + count += sprintf(&buf[count], "\n");
209     +
210     + return count;
211     +}
212     +
213     +static ssize_t show_freq_attr_controls(struct cpufreq_policy *policy, char *buf)
214     +{
215     + struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
216     + struct acpi_processor_performance *acpi_data;
217     + struct cpufreq_frequency_table *freq_table;
218     + unsigned int i;
219     + unsigned int fid;
220     + unsigned int vid;
221     + ssize_t count = 0;
222     +
223     + if (unlikely(data == NULL ||
224     + data->acpi_data == NULL ||
225     + data->freq_table == NULL ||
226     + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
227     + return -ENODEV;
228     + }
229     +
230     + acpi_data = data->acpi_data;
231     + freq_table = data->freq_table;
232     +
233     + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
234     + fid = extract_fid_from_control(acpi_data->states[freq_table[i].index].control);
235     + vid = extract_vid_from_control(acpi_data->states[freq_table[i].index].control);
236     + count += sprintf(&buf[count], "%u:%u ", fid, vid);
237     + }
238     + count += sprintf(&buf[count], "\n");
239     +
240     + return count;
241     +}
242     +
243     +static ssize_t show_freq_attr_default_controls(struct cpufreq_policy *policy, char *buf)
244     +{
245     + struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
246     + struct cpufreq_frequency_table *freq_table;
247     + unsigned int i;
248     + unsigned int fid;
249     + unsigned int vid;
250     + ssize_t count = 0;
251     + ssize_t retval;
252     +
253     + if (unlikely(data == NULL ||
254     + data->acpi_data == NULL ||
255     + data->freq_table == NULL ||
256     + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
257     + return -ENODEV;
258     + }
259     +
260     + retval = check_origial_table(data);
261     + if (0 != retval)
262     + return retval;
263     +
264     + freq_table = data->freq_table;
265     +
266     + for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
267     + fid = extract_fid_from_control(data->original_controls[freq_table[i].index]);
268     + vid = extract_vid_from_control(data->original_controls[freq_table[i].index]);
269     + count += sprintf(&buf[count], "%u:%u ", fid, vid);
270     + }
271     + count += sprintf(&buf[count], "\n");
272     +
273     + return count;
274     +}
275     +
276     +
277     +static ssize_t store_freq_attr_vids(struct cpufreq_policy *policy, const char *buf, size_t count)
278     +{
279     + struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
280     + struct acpi_processor_performance *acpi_data;
281     + struct cpufreq_frequency_table *freq_table;
282     + unsigned int freq_index;
283     + unsigned int state_index;
284     + unsigned int new_vid;
285     + unsigned int original_vid;
286     + unsigned int new_control;
287     + unsigned int original_control;
288     + const char *curr_buf = buf;
289     + char *next_buf;
290     + ssize_t retval;
291     +
292     + if (unlikely(data == NULL ||
293     + data->acpi_data == NULL ||
294     + data->freq_table == NULL ||
295     + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
296     + return -ENODEV;
297     + }
298     +
299     + retval = check_origial_table(data);
300     + if (0 != retval)
301     + return retval;
302     +
303     + acpi_data = data->acpi_data;
304     + freq_table = data->freq_table;
305     +
306     + for (freq_index = 0; freq_table[freq_index].frequency != CPUFREQ_TABLE_END; freq_index++) {
307     + new_vid = simple_strtoul(curr_buf, &next_buf, 10);
308     + if (next_buf == curr_buf) {
309     + if ((curr_buf - buf == count - 1) && (*curr_buf == '\n')) {
310     + curr_buf++;
311     + break;
312     + }
313     + printk("failed to parse vid value at %i (%s)\n", freq_index, curr_buf);
314     + return -EINVAL;
315     + }
316     +
317     + state_index = freq_table[freq_index].index;
318     + original_control = data->original_controls[state_index];
319     + original_vid = original_control & INTEL_MSR_VID_MASK;
320     + if (new_vid <= original_vid) {
321     + new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
322     + dprintk("setting control at %i to %x (default is %x)\n",
323     + freq_index, new_control, original_control);
324     + acpi_data->states[state_index].control = new_control;
325     +
326     + } else {
327     + printk("skipping vid at %i, %u is greater than default %u\n",
328     + freq_index, new_vid, original_vid);
329     + }
330     +
331     + curr_buf = next_buf;
332     + while ((curr_buf - buf < count) && ((*curr_buf == ' ') || (*curr_buf == ','))) {
333     + curr_buf++;
334     + }
335     + }
336     +
337     + /* set new voltage at current frequency */
338     + data->resume = 1;
339     + acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
340     +
341     + return curr_buf - buf;
342     +}
343     +
344     +static ssize_t store_freq_attr_controls(struct cpufreq_policy *policy, const char *buf, size_t count)
345     +{
346     + struct acpi_cpufreq_data *data = per_cpu(drv_data, policy->cpu);
347     + struct acpi_processor_performance *acpi_data;
348     + struct cpufreq_frequency_table *freq_table;
349     + const char *curr_buf;
350     + unsigned int op_count;
351     + unsigned int state_index;
352     + int isok;
353     + char *next_buf;
354     + ssize_t retval;
355     + unsigned int new_vid;
356     + unsigned int original_vid;
357     + unsigned int new_fid;
358     + unsigned int old_fid;
359     + unsigned int original_control;
360     + unsigned int old_control;
361     + unsigned int new_control;
362     + int found;
363     +
364     + if (unlikely(data == NULL ||
365     + data->acpi_data == NULL ||
366     + data->freq_table == NULL ||
367     + data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
368     + return -ENODEV;
369     + }
370     +
371     + retval = check_origial_table(data);
372     + if (0 != retval)
373     + return retval;
374     +
375     + acpi_data = data->acpi_data;
376     + freq_table = data->freq_table;
377     +
378     + op_count = 0;
379     + curr_buf = buf;
380     + next_buf = NULL;
381     + isok = 1;
382     +
383     + while ( (isok) && (curr_buf != NULL) )
384     + {
385     + op_count++;
386     + // Parse fid
387     + new_fid = simple_strtoul(curr_buf, &next_buf, 10);
388     + if ((next_buf != curr_buf) && (next_buf != NULL))
389     + {
390     + // Parse separator between frequency and voltage
391     + curr_buf = next_buf;
392     + next_buf = NULL;
393     + if (*curr_buf==':')
394     + {
395     + curr_buf++;
396     + // Parse vid
397     + new_vid = simple_strtoul(curr_buf, &next_buf, 10);
398     + if ((next_buf != curr_buf) && (next_buf != NULL))
399     + {
400     + found = 0;
401     + for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
402     + old_control = acpi_data->states[state_index].control;
403     + old_fid = extract_fid_from_control(old_control);
404     + if (new_fid == old_fid)
405     + {
406     + found = 1;
407     + original_control = data->original_controls[state_index];
408     + original_vid = extract_vid_from_control(original_control);
409     + if (new_vid <= original_vid)
410     + {
411     + new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
412     + dprintk("setting control at %i to %x (default is %x)\n",
413     + state_index, new_control, original_control);
414     + acpi_data->states[state_index].control = new_control;
415     +
416     + } else {
417     + printk("skipping vid at %i, %u is greater than default %u\n",
418     + state_index, new_vid, original_vid);
419     + }
420     + }
421     + }
422     +
423     + if (found == 0)
424     + {
425     + printk("operating point # %u not found (FID = %u)\n", op_count, new_fid);
426     + isok = 0;
427     + }
428     +
429     + // Parse seprator before next operating point, if any
430     + curr_buf = next_buf;
431     + next_buf = NULL;
432     + if ((*curr_buf == ',') || (*curr_buf == ' '))
433     + curr_buf++;
434     + else
435     + curr_buf = NULL;
436     + }
437     + else
438     + {
439     + printk("failed to parse VID of operating point # %u (%s)\n", op_count, curr_buf);
440     + isok = 0;
441     + }
442     + }
443     + else
444     + {
445     + printk("failed to parse operating point # %u (%s)\n", op_count, curr_buf);
446     + isok = 0;
447     + }
448     + }
449     + else
450     + {
451     + printk("failed to parse FID of operating point # %u (%s)\n", op_count, curr_buf);
452     + isok = 0;
453     + }
454     + }
455     +
456     + if (isok)
457     + {
458     + retval = count;
459     + /* set new voltage at current frequency */
460     + data->resume = 1;
461     + acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
462     + }
463     + else
464     + {
465     + retval = -EINVAL;
466     + }
467     +
468     + return retval;
469     +}
470     +
471     +static ssize_t show_freq_attr_phc_version(struct cpufreq_policy *policy, char *buf)
472     +{
473     + ssize_t count = 0;
474     + count += sprintf(&buf[count], "%s\n", PHC_VERSION_STRING);
475     + return count;
476     +}
477     +
478     +static struct freq_attr cpufreq_freq_attr_phc_version =
479     +{
480     + .attr = { .name = "phc_version", .mode = 0444, .owner = THIS_MODULE },
481     + .show = show_freq_attr_phc_version,
482     + .store = NULL,
483     +};
484     +
485     +static struct freq_attr cpufreq_freq_attr_vids =
486     +{
487     + .attr = { .name = "phc_vids", .mode = 0644, .owner = THIS_MODULE },
488     + .show = show_freq_attr_vids,
489     + .store = store_freq_attr_vids,
490     +};
491     +
492     +static struct freq_attr cpufreq_freq_attr_default_vids =
493     +{
494     + .attr = { .name = "phc_default_vids", .mode = 0444, .owner = THIS_MODULE },
495     + .show = show_freq_attr_default_vids,
496     + .store = NULL,
497     +};
498     +
499     +static struct freq_attr cpufreq_freq_attr_fids =
500     +{
501     + .attr = { .name = "phc_fids", .mode = 0444, .owner = THIS_MODULE },
502     + .show = show_freq_attr_fids,
503     + .store = NULL,
504     +};
505     +
506     +static struct freq_attr cpufreq_freq_attr_controls =
507     +{
508     + .attr = { .name = "phc_controls", .mode = 0644, .owner = THIS_MODULE },
509     + .show = show_freq_attr_controls,
510     + .store = store_freq_attr_controls,
511     +};
512     +
513     +static struct freq_attr cpufreq_freq_attr_default_controls =
514     +{
515     + .attr = { .name = "phc_default_controls", .mode = 0444, .owner = THIS_MODULE },
516     + .show = show_freq_attr_default_controls,
517     + .store = NULL,
518     +};
519     +
520     +
521     static struct freq_attr *acpi_cpufreq_attr[] = {
522     + &cpufreq_freq_attr_phc_version,
523     &cpufreq_freq_attr_scaling_available_freqs,
524     + &cpufreq_freq_attr_vids,
525     + &cpufreq_freq_attr_default_vids,
526     + &cpufreq_freq_attr_fids,
527     + &cpufreq_freq_attr_controls,
528     + &cpufreq_freq_attr_default_controls,
529     NULL,
530     };
531    
532     static struct cpufreq_driver acpi_cpufreq_driver = {
533     .verify = acpi_cpufreq_verify,