Magellan Linux

Annotation of /trunk/kernel26-magellan-server/patches-2.6.24-r3/0156-2.6.24-linux-phc-0.3.0.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 500 - (hide annotations) (download)
Sat Mar 15 12:32:27 2008 UTC (16 years, 2 months ago) by niro
File size: 14814 byte(s)
kernel-2.6.24-magellan-r3:
- updated to linux-2.6.24.3

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