Magellan Linux

Contents of /trunk/kernel26-magellan/patches-2.6.24-r5/0156-2.6.24-linux-phc-0.3.0.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 574 - (show annotations) (download)
Mon Apr 21 17:56:37 2008 UTC (16 years ago) by niro
File size: 14814 byte(s)
- 2.6.24-magellan-r5: updated to linux-2.6.24.5

1 --- 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