Magellan Linux

Annotation of /trunk/kernel26-magellan/patches-2.6.30-r1/0156-2.6.30-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, 8 months ago) by niro
File size: 16253 byte(s)
-added

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