Magellan Linux

Annotation of /trunk/kernel26-magellan/patches-2.6.29-r8/0156-2.6.29-linux-phc-0.3.2.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1114 - (hide annotations) (download)
Sun Aug 22 17:59:15 2010 UTC (13 years, 9 months ago) by niro
File size: 16865 byte(s)
-added

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