Gentoo Archives: gentoo-commits

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