daily pastebin goal
42%
SHARE
TWEET

linux-phc-0.3.2_3.0.7.patch

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