Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
phc-intel and latest kernels
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Kernel & Hardware
View previous topic :: View next topic  
Author Message
skunk
l33t
l33t


Joined: 28 May 2003
Posts: 646
Location: granada, spain

PostPosted: Sat Oct 20, 2012 3:26 pm    Post subject: phc-intel and latest kernels Reply with quote

somebody else has not working phc-intel module since 3.5 kernel?
the module loads fine like it did with 3.4 kernel but no phc stuff shows up:
Code:
$ ls /sys/devices/system/cpu/*/cpufreq/
/sys/devices/system/cpu/cpu0/cpufreq/:
affected_cpus     cpuinfo_max_freq            related_cpus                   scaling_cur_freq  scaling_max_freq  stats
bios_limit        cpuinfo_min_freq            scaling_available_frequencies  scaling_driver    scaling_min_freq
cpuinfo_cur_freq  cpuinfo_transition_latency  scaling_available_governors    scaling_governor  scaling_setspeed

/sys/devices/system/cpu/cpu1/cpufreq/:
affected_cpus     cpuinfo_max_freq            related_cpus                   scaling_cur_freq  scaling_max_freq  stats
bios_limit        cpuinfo_min_freq            scaling_available_frequencies  scaling_driver    scaling_min_freq
cpuinfo_cur_freq  cpuinfo_transition_latency  scaling_available_governors    scaling_governor  scaling_setspeed

any clue?
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sat Oct 20, 2012 3:44 pm    Post subject: Re: phc-intel and latest kernels Reply with quote

skunk wrote:
somebody else has not working phc-intel module since 3.5 kernel? the module loads fine like it did with 3.4 kernel but no phc stuff shows up:

skunk ... no issue here with 3.6.2 (nor can I remember any issue with 3.5)
Code:
# uname -r
3.6.2-geek-gnu
# equery -q l phc-intel
sys-power/phc-intel-0.3.2.12.1-r3:0
# ls /sys/devices/system/cpu/cpu1/cpufreq/phc_*
phc_controls
phc_default_controls
phc_default_vids
phc_fids
phc_version
phc_vids

best ... khay
Back to top
View user's profile Send private message
albright
Advocate
Advocate


Joined: 16 Nov 2003
Posts: 2588
Location: Near Toronto

PostPosted: Sat Oct 20, 2012 5:13 pm    Post subject: Reply with quote

FWIW, also no problem here, pf-sources-3.6.3
_________________
.... there is nothing - absolutely nothing - half so much worth
doing as simply messing about with Linux ...
(apologies to Kenneth Graeme)
Back to top
View user's profile Send private message
skunk
l33t
l33t


Joined: 28 May 2003
Posts: 646
Location: granada, spain

PostPosted: Sat Oct 20, 2012 5:14 pm    Post subject: Reply with quote

strange, even after reconfiguring the kernel starting from a fresh seed, no joy :(
did you mind posting your config and processor type?
anyone else with a core2 duo (T7300)?
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sat Oct 20, 2012 5:56 pm    Post subject: Reply with quote

skunk wrote:
did you mind posting your config and processor type?

skunk ... T2500 (core duo) and the config for 3.6.2 (geek-sources). Note that acpi_cpufreq is blacklisted in /etc/modprobe.d/blacklist.conf and that /etc/modprobe.d/phc-intel.conf is removed/commented.

HTH & best ... khay
Back to top
View user's profile Send private message
skunk
l33t
l33t


Joined: 28 May 2003
Posts: 646
Location: granada, spain

PostPosted: Sat Oct 20, 2012 6:17 pm    Post subject: Reply with quote

khayyam wrote:
Note that acpi_cpufreq is blacklisted in /etc/modprobe.d/blacklist.conf and that /etc/modprobe.d/phc-intel.conf is removed/commented.

the same here... do you know any option to make the module more verbose?
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sat Oct 20, 2012 7:15 pm    Post subject: Reply with quote

skunk wrote:
khayyam wrote:
Note that acpi_cpufreq is blacklisted in /etc/modprobe.d/blacklist.conf and that /etc/modprobe.d/phc-intel.conf is removed/commented.

the same here... do you know any option to make the module more verbose?

skunk ... there isn't any debug switch ... modinfo only provides one option 'acpi_pstate_strict' ...

Code:
# modinfo phc-intel
filename:       /lib/modules/3.6.2-geek-gnu/misc/phc-intel.ko
alias:          acpi
license:        GPL
description:    ACPI Processor P-States Driver
author:         Paul Diefenbaugh, Dominik Brodowski
depends:        mperf
vermagic:       3.6.2-geek-gnu SMP preempt mod_unload CORE2
parm:           acpi_pstate_strict:value 0 or non-zero. non-zero -> strict ACPI checks are performed during frequency changes. (uint)

best ... khay
Back to top
View user's profile Send private message
skunk
l33t
l33t


Joined: 28 May 2003
Posts: 646
Location: granada, spain

PostPosted: Sat Oct 20, 2012 9:09 pm    Post subject: Reply with quote

amen... thank you anyway :)
if somebody has a clue about what can be wrong, just knock...
as i said the only thing that changes is the kernel version: working till 3.4.14 and not working starting from 3.5.2
thank you.
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sun Oct 21, 2012 1:35 pm    Post subject: Reply with quote

skunk wrote:
[...] if somebody has a clue about what can be wrong, just knock...

skunk ... the only thing I can think of is the rules that the documentation for phc-intel suggests to add to /etc/modprobe.d/phc-intel.conf ... I noticed myself that at some point these stopped working and so I commented the rules and added 'blacklist acpi_cpufreq' (also cpufreq_stats if you have it) to /etc/modprobe.d/blacklist.conf. So I would check there and make sure that no rules are in place (other than the blacklisting).

skunk wrote:
as i said the only thing that changes is the kernel version: working till 3.4.14 and not working starting from 3.5.2

It was probably about 3.5.2 when I noticed the suggested phc-intel.conf caused some issues.

best ... khay
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sun Oct 21, 2012 1:36 pm    Post subject: Reply with quote

skunk wrote:
[...] if somebody has a clue about what can be wrong, just knock...

skunk ... the only thing I can think of is the rules that the documentation for phc-intel suggests to add to /etc/modprobe.d/phc-intel.conf ... I noticed myself that at some point these stopped working and so I commented the rules and added 'blacklist acpi_cpufreq' (also cpufreq_stats if you have it) to /etc/modprobe.d/blacklist.conf. So I would check there and make sure that no rules are in place (other than the blacklisting).

skunk wrote:
as i said the only thing that changes is the kernel version: working till 3.4.14 and not working starting from 3.5.2

It was probably about 3.5.2 when I noticed the suggested phc-intel.conf caused some issues.

best ... khay
Back to top
View user's profile Send private message
skunk
l33t
l33t


Joined: 28 May 2003
Posts: 646
Location: granada, spain

PostPosted: Sun Oct 21, 2012 2:50 pm    Post subject: Reply with quote

khay, there is no /etc/modprobe.d/phc-intel.conf file on my system and the only modprobe rule related to this is the blacklisting of acpi_cpufreq...
Back to top
View user's profile Send private message
albright
Advocate
Advocate


Joined: 16 Nov 2003
Posts: 2588
Location: Near Toronto

PostPosted: Sun Oct 21, 2012 3:22 pm    Post subject: Reply with quote

this is just grasping at straws, but you could unmerge
phc-intel and then build the module manually from
the phc-intel sources; maybe there will be some hint
from the result ...
_________________
.... there is nothing - absolutely nothing - half so much worth
doing as simply messing about with Linux ...
(apologies to Kenneth Graeme)
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sun Oct 21, 2012 3:40 pm    Post subject: Reply with quote

skunk wrote:
there is no /etc/modprobe.d/phc-intel.conf file on my system and the only modprobe rule related to this is the blacklisting of acpi_cpufreq...

skunk ... I just want to make sure, you had said as much above but I thought perhaps you had read the reference to /etc/modprobe.d and thought of blacklist.conf, and perhaps not considered the phc-intel.conf. Thats why I said that would be the only thing that comes to mind, and you should check.

best ... khay
Back to top
View user's profile Send private message
i13m
n00b
n00b


Joined: 26 Jun 2003
Posts: 46
Location: UK / China PR

PostPosted: Sat Oct 27, 2012 8:23 am    Post subject: Reply with quote

I can not remember 3.4 or 3.5, the kernel implements auto module load function. So you dont have to use modprobe. But you know phc-intel and acpi_cpufreq can not be loaded at the same time. So you have to change one line of kernel source

@ drivers/acpi/processor_perflib.c
Code:

void acpi_processor_load_module(struct acpi_processor *pr)
{
   static int requested;
   acpi_status status = 0;
   struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };

   if (!arch_has_acpi_pdc() || requested)
      return;
   status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
   if (!ACPI_FAILURE(status)) {
      printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n");
-->      request_module_nowait("phc-intel");
      requested = 1;
   }
   kfree(buffer.pointer);
}


You have to change the line from acpi_cpufreq to phc-intel

This is what I have solved this issue
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sat Oct 27, 2012 11:49 am    Post subject: Reply with quote

i13m wrote:
You have to change the line from acpi_cpufreq to phc-intel

i13m ... interesting, but in my case I have both acpi_cpufreq and phc-intel as modules (with the former blacklisted) and phc-intel is loaded without any change having been made to the kernel. This has been the case all through 3.4.x, 3.5.x and now 3.6.x.

best ... khay
Back to top
View user's profile Send private message
skunk
l33t
l33t


Joined: 28 May 2003
Posts: 646
Location: granada, spain

PostPosted: Sat Oct 27, 2012 6:06 pm    Post subject: Reply with quote

i13m wrote:
You have to change the line from acpi_cpufreq to phc-intel

tried, but unfortunately it doesn't work...
the phc-intel module doesn't even get loaded, however after boot i can modprobe it, but again, no phc* files are created...
i went back to acpi-cpufreq removing it from /etc/modprobe.d/blacklist.conf and i noted it doesn't get automatically loaded after reboot (which was happening before and because of this i'd to blacklist it).
i wonder if this behavior has something to do with my phc issue...
Back to top
View user's profile Send private message
i13m
n00b
n00b


Joined: 26 Jun 2003
Posts: 46
Location: UK / China PR

PostPosted: Sun Oct 28, 2012 8:04 am    Post subject: Reply with quote

I normally do following procedures for a new gentoo-sources, i.e. 3.5 3.6 3.6.1

1 -
Code:
emerge -av gentoo-sources

2 - modify the processor_perflib.c file as above
3 - make && make install && make module_install
4 - make sure
Code:
modules_3="${modules_3} phc-intel"
module_phc_intel_args_3=""

is in /etc/conf.d/modules
5 - reboot (of course there is a error for phc-intel)
6 - module-rebuild rebuild (for phc-intel) or just
Code:
emerge -1v phc-intel

6a- or you can recompile and re-install the kernel, but I am not sure whether or not it makes any difference
7 - reboot again

And normally for me, phc-intel is working again for a new kernel source.

PS: I am trying to make sure all steps are listed here. Maybe there are some other minor steps I forget.
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sun Oct 28, 2012 3:09 pm    Post subject: Reply with quote

i13m wrote:
2 - modify the processor_perflib.c file as above

i13m ... I don't think this has anything to do with the problem, and as I said above the module loads without this and as acpi_cpufreq is blacklisted the above changes won't make any difference.

i13m wrote:
4 - make sure
Code:
modules_3="${modules_3} phc-intel"
module_phc_intel_args_3=""

is in /etc/conf.d/modules

The module is loaded, its the phc_* under /sys that don't materialise.

i13m wrote:
5 - reboot (of course there is a error for phc-intel)
6 - module-rebuild rebuild (for phc-intel) or just
Code:
emerge -1v phc-intel

Why not 'module-rebuild rebuild' prior to reboot? The ebuild looks to /usr/src/linux so as long as this symlink points to the current sources then there should be no need to reboot.

i13m wrote:
6a- or you can recompile and re-install the kernel, but I am not sure whether or not it makes any difference
7 - reboot again

It makes no difference at all, and why are we rebooting again, its a module and can be modprobed.

best ... khay
Back to top
View user's profile Send private message
skunk
l33t
l33t


Joined: 28 May 2003
Posts: 646
Location: granada, spain

PostPosted: Sun Nov 18, 2012 5:37 pm    Post subject: Reply with quote

with sys-power/phc-intel-0.3.2.12.1-r4 it's fine again (at least with kernel 3.6.7)...
Back to top
View user's profile Send private message
Alloha
n00b
n00b


Joined: 22 Jul 2013
Posts: 1

PostPosted: Mon Jul 22, 2013 3:34 pm    Post subject: Reply with quote

Hi All!

For those willing to test latest RC kernels (also might be helpful to maintainer) and be able to use phc-intel here is a slightly updated patch for PHC-intel to build against 3.11-rc linux kernels. Tested on my Dell Latitude E6400 with Core 2 Duo P8600 CPU for more than a week already.

If you are as lazy as me, and don't want to modify the .ebuild, just replace the original phc-intel-0.3.2.12.1-r5-3.7.patch with the file below and re-digest the .ebuild.

phc-intel-0.3.2.12.1-r5-3.11.patch:
Code:
--- acpi-cpufreq.c
+++ phc-intel.c
@@ -25,6 +25,10 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+/* This file has been patched with Linux PHC: www.linux-phc.org
+* Patch version: linux-phc-0.3.2
+*/
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -61,6 +65,10 @@
 };
 
 #define INTEL_MSR_RANGE      (0xffff)
+#define INTEL_MSR_VID_MASK   (0x00ff)
+#define INTEL_MSR_FID_MASK   (0xff00)
+#define INTEL_MSR_FID_SHIFT   (0x8)
+#define PHC_VERSION_STRING   "0.3.2:2"
 #define AMD_MSR_RANGE      (0x7)
 
 #define MSR_K7_HWCR_CPB_DIS   (1ULL << 25)
@@ -71,6 +79,7 @@
    unsigned int resume;
    unsigned int cpu_feature;
    cpumask_var_t freqdomain_cpus;
+   acpi_integer *original_controls;
 };
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
@@ -232,17 +241,18 @@
 static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
 {
    int i;
+   u32 fid;
    struct acpi_processor_performance *perf;
 
    if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
       msr &= AMD_MSR_RANGE;
    else
-      msr &= INTEL_MSR_RANGE;
+      fid = msr & INTEL_MSR_FID_MASK;
 
    perf = data->acpi_data;
 
    for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-      if (msr == perf->states[data->freq_table[i].driver_data].status)
+      if (fid == (perf->states[data->freq_table[i].driver_data].status & INTEL_MSR_FID_MASK))
          return data->freq_table[i].frequency;
    }
    return data->freq_table[0].frequency;
@@ -884,6 +894,8 @@
    return result;
 
 err_freqfree:
+   if (data->original_controls)
+      kfree(data->original_controls);
    kfree(data->freq_table);
 err_unreg:
    acpi_processor_unregister_performance(perf, cpu);
@@ -926,9 +938,474 @@
    return 0;
 }
 
+/* sysfs interface to change operating points voltages */
+
+static unsigned int extract_fid_from_control(unsigned int control)
+{
+   return ((control & INTEL_MSR_FID_MASK) >> INTEL_MSR_FID_SHIFT);
+}
+
+static unsigned int extract_vid_from_control(unsigned int control)
+{
+   return (control & INTEL_MSR_VID_MASK);
+}
+
+
+static bool check_cpu_control_capability(struct acpi_cpufreq_data *data) {
+ /* check if the cpu we are running on is capable of setting new control data
+  *
+  */
+   if (unlikely(data == NULL ||
+                data->acpi_data == NULL ||
+                data->freq_table == NULL ||
+                data->cpu_feature != SYSTEM_INTEL_MSR_CAPABLE)) {
+      return false;
+   } else {
+      return true;
+   };
+}
+
+
+static ssize_t check_origial_table (struct acpi_cpufreq_data *data)
+{
+
+   struct acpi_processor_performance *acpi_data;
+   struct cpufreq_frequency_table *freq_table;
+   unsigned int state_index;
+
+   acpi_data = data->acpi_data;
+   freq_table = data->freq_table;
+
+   if (data->original_controls == NULL) {
+      // Backup original control values
+      data->original_controls = kcalloc(acpi_data->state_count,
+                                        sizeof(acpi_integer), GFP_KERNEL);
+      if (data->original_controls == NULL) {
+         printk("failed to allocate memory for original control values\n");
+         return -ENOMEM;
+      }
+      for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
+         data->original_controls[state_index] = acpi_data->states[state_index].control;
+      }
+   }
+   return 0;
+}
+
+static ssize_t show_freq_attr_vids(struct cpufreq_policy *policy, char *buf)
+ /* display phc's voltage id's
+  *
+  */
+{
+   struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+   struct acpi_processor_performance *acpi_data;
+   struct cpufreq_frequency_table *freq_table;
+   unsigned int i;
+   unsigned int vid;
+   ssize_t count = 0;
+
+   if (!check_cpu_control_capability(data)) return -ENODEV; //check if CPU is capable of changing controls
+
+   acpi_data = data->acpi_data;
+   freq_table = data->freq_table;
+
+   for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+      vid = extract_vid_from_control(acpi_data->states[freq_table[i].driver_data].control);
+      count += sprintf(&buf[count], "%u ", vid);
+   }
+   count += sprintf(&buf[count], "\n");
+
+   return count;
+}
+
+static ssize_t show_freq_attr_default_vids(struct cpufreq_policy *policy, char *buf)
+ /* display acpi's default voltage id's
+  *
+  */
+{
+   struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+   struct cpufreq_frequency_table *freq_table;
+   unsigned int i;
+   unsigned int vid;
+   ssize_t count = 0;
+   ssize_t retval;
+
+   if (!check_cpu_control_capability(data)) return -ENODEV; //check if CPU is capable of changing controls
+
+   retval = check_origial_table(data);
+        if (0 != retval)
+      return retval;
+
+   freq_table = data->freq_table;
+
+   for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+      vid = extract_vid_from_control(data->original_controls[freq_table[i].driver_data]);
+      count += sprintf(&buf[count], "%u ", vid);
+   }
+   count += sprintf(&buf[count], "\n");
+
+   return count;
+}
+
+static ssize_t show_freq_attr_fids(struct cpufreq_policy *policy, char *buf)
+ /* display phc's frequeny id's
+  *
+  */
+{
+   struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+   struct acpi_processor_performance *acpi_data;
+   struct cpufreq_frequency_table *freq_table;
+   unsigned int i;
+   unsigned int fid;
+   ssize_t count = 0;
+
+   if (!check_cpu_control_capability(data)) return -ENODEV; //check if CPU is capable of changing controls
+
+   acpi_data = data->acpi_data;
+   freq_table = data->freq_table;
+
+   for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+      fid = extract_fid_from_control(acpi_data->states[freq_table[i].driver_data].control);
+      count += sprintf(&buf[count], "%u ", fid);
+   }
+   count += sprintf(&buf[count], "\n");
+
+   return count;
+}
+
+static ssize_t show_freq_attr_controls(struct cpufreq_policy *policy, char *buf)
+ /* display phc's controls for the cpu (frequency id's and related voltage id's)
+  *
+  */
+{
+   struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+   struct acpi_processor_performance *acpi_data;
+   struct cpufreq_frequency_table *freq_table;
+   unsigned int i;
+   unsigned int fid;
+   unsigned int vid;
+   ssize_t count = 0;
+
+   if (!check_cpu_control_capability(data)) return -ENODEV; //check if CPU is capable of changing controls
+
+   acpi_data = data->acpi_data;
+   freq_table = data->freq_table;
+
+   for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+      fid = extract_fid_from_control(acpi_data->states[freq_table[i].driver_data].control);
+      vid = extract_vid_from_control(acpi_data->states[freq_table[i].driver_data].control);
+      if (count)
+         count += sprintf(&buf[count], " ");
+      count += sprintf(&buf[count], "%u:%u", fid, vid);
+   }
+   count += sprintf(&buf[count], "\n");
+
+   return count;
+}
+
+static ssize_t show_freq_attr_default_controls(struct cpufreq_policy *policy, char *buf)
+ /* display acpi's default controls for the cpu (frequency id's and related voltage id's)
+  *
+  */
+{
+   struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+   struct cpufreq_frequency_table *freq_table;
+   unsigned int i;
+   unsigned int fid;
+   unsigned int vid;
+   ssize_t count = 0;
+   ssize_t retval;
+
+   if (!check_cpu_control_capability(data)) return -ENODEV; //check if CPU is capable of changing controls
+
+   retval = check_origial_table(data);
+        if (0 != retval)
+      return retval;
+
+   freq_table = data->freq_table;
+
+   for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+      fid = extract_fid_from_control(data->original_controls[freq_table[i].driver_data]);
+      vid = extract_vid_from_control(data->original_controls[freq_table[i].driver_data]);
+      count += sprintf(&buf[count], "%u:%u ", fid, vid);
+   }
+   count += sprintf(&buf[count], "\n");
+
+   return count;
+}
+
+
+static ssize_t store_freq_attr_vids(struct cpufreq_policy *policy, const char *buf, size_t count)
+ /* store the voltage id's for the related frequency
+  * We are going to do some sanity checks here to prevent users
+  * from setting higher voltages than the default one.
+  */
+{
+   struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+   struct acpi_processor_performance *acpi_data;
+   struct cpufreq_frequency_table *freq_table;
+   unsigned int freq_index;
+   unsigned int state_index;
+   unsigned int new_vid;
+   unsigned int original_vid;
+   unsigned int new_control;
+   unsigned int original_control;
+   const char *curr_buf = buf;
+   char *next_buf;
+   ssize_t retval;
+
+   if (!check_cpu_control_capability(data)) return -ENODEV; //check if CPU is capable of changing controls
+
+   retval = check_origial_table(data);
+        if (0 != retval)
+      return retval;
+
+   acpi_data = data->acpi_data;
+   freq_table = data->freq_table;
+
+   /* for each value taken from the sysfs interfalce (phc_vids) get entrys and convert them to unsigned long integers*/
+   for (freq_index = 0; freq_table[freq_index].frequency != CPUFREQ_TABLE_END; freq_index++) {
+      new_vid = simple_strtoul(curr_buf, &next_buf, 10);
+      if (next_buf == curr_buf) {
+         if ((curr_buf - buf == count - 1) && (*curr_buf == '\n')) {   //end of line?
+            curr_buf++;
+            break;
+         }
+         //if we didn't got end of line but there is nothing more to read something went wrong...
+         printk("failed to parse vid value at %i (%s)\n", freq_index, curr_buf);
+         return -EINVAL;
+      }
+
+      state_index = freq_table[freq_index].driver_data;
+      original_control = data->original_controls[state_index];
+      original_vid = original_control & INTEL_MSR_VID_MASK;
+      
+      /* before we store the values we do some checks to prevent
+       * users to set up values higher than the default one
+       */
+      if (new_vid <= original_vid) {
+         new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
+         pr_debug("setting control at %i to %x (default is %x)\n",
+                 freq_index, new_control, original_control);
+         acpi_data->states[state_index].control = new_control;
+
+      } else {
+         pr_debug("skipping vid at %i, %u is greater than default %u\n",
+                freq_index, new_vid, original_vid);
+      }
+
+      curr_buf = next_buf;
+      /* jump over value seperators (space or comma).
+       * There could be more than one space or comma character
+       * to separate two values so we better do it using a loop.
+       */
+      while ((curr_buf - buf < count) && ((*curr_buf == ' ') || (*curr_buf == ','))) {
+         curr_buf++;
+      }
+   }
+
+   /* set new voltage for current frequency */
+   data->resume = 1;
+   acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
+
+   return curr_buf - buf;
+}
+
+static ssize_t store_freq_attr_controls(struct cpufreq_policy *policy, const char *buf, size_t count)
+ /* store the controls (frequency id's and related voltage id's)
+  * We are going to do some sanity checks here to prevent users
+  * from setting higher voltages than the default one.
+  */
+{
+   struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+   struct acpi_processor_performance *acpi_data;
+   struct cpufreq_frequency_table *freq_table;
+   const char   *curr_buf;
+   unsigned int  op_count;
+   unsigned int  state_index;
+   int           isok;
+   char         *next_buf;
+   ssize_t       retval;
+   unsigned int  new_vid;
+   unsigned int  original_vid;
+   unsigned int  new_fid;
+   unsigned int  old_fid;
+   unsigned int  original_control;
+   unsigned int  old_control;
+   unsigned int  new_control;
+   int           found;
+
+   if (!check_cpu_control_capability(data)) return -ENODEV;
+
+   retval = check_origial_table(data);
+        if (0 != retval)
+      return retval;
+
+   acpi_data = data->acpi_data;
+   freq_table = data->freq_table;
+
+   op_count = 0;
+   curr_buf = buf;
+   next_buf = NULL;
+   isok     = 1;
+   
+   while ( (isok) && (curr_buf != NULL) )
+   {
+      op_count++;
+      // Parse fid
+      new_fid = simple_strtoul(curr_buf, &next_buf, 10);
+      if ((next_buf != curr_buf) && (next_buf != NULL))
+      {
+         // Parse separator between frequency and voltage
+         curr_buf = next_buf;
+         next_buf = NULL;
+         if (*curr_buf==':')
+         {
+            curr_buf++;
+            // Parse vid
+            new_vid = simple_strtoul(curr_buf, &next_buf, 10);
+            if ((next_buf != curr_buf) && (next_buf != NULL))
+            {
+               found = 0;
+               for (state_index = 0; state_index < acpi_data->state_count; state_index++) {
+                  old_control = acpi_data->states[state_index].control;
+                  old_fid = extract_fid_from_control(old_control);
+                  if (new_fid == old_fid)
+                  {
+                     found = 1;
+                     original_control = data->original_controls[state_index];
+                     original_vid = extract_vid_from_control(original_control);
+                     if (new_vid <= original_vid)
+                     {
+                        new_control = (original_control & ~INTEL_MSR_VID_MASK) | new_vid;
+                        pr_debug("setting control at %i to %x (default is %x)\n",
+                                state_index, new_control, original_control);
+                        acpi_data->states[state_index].control = new_control;
+
+                     } else {
+                        printk("skipping vid at %i, %u is greater than default %u\n",
+                               state_index, new_vid, original_vid);
+                     }
+                  }
+               }
+
+               if (found == 0)
+               {
+                  printk("operating point # %u not found (FID = %u)\n", op_count, new_fid);
+                  isok = 0;
+               }
+
+               // Parse seprator before next operating point, if any
+               curr_buf = next_buf;
+               next_buf = NULL;
+               if ((*curr_buf == ',') || (*curr_buf == ' '))
+                  curr_buf++;
+               else
+                  curr_buf = NULL;
+            }
+            else
+            {
+               printk("failed to parse VID of operating point # %u (%s)\n", op_count, curr_buf);
+               isok = 0;
+            }
+         }
+         else
+         {
+            printk("failed to parse operating point # %u (%s)\n", op_count, curr_buf);
+            isok = 0;
+         }
+      }
+      else
+      {
+         printk("failed to parse FID of operating point # %u (%s)\n", op_count, curr_buf);
+         isok = 0;
+      }
+   }
+
+   if (isok)
+   {
+      retval = count;
+      /* set new voltage at current frequency */
+      data->resume = 1;
+      acpi_cpufreq_target(policy, get_cur_freq_on_cpu(policy->cpu), CPUFREQ_RELATION_L);
+   }
+   else
+   {
+      retval = -EINVAL;
+   }
+
+   return retval;
+}
+
+static ssize_t show_freq_attr_phc_version(struct cpufreq_policy *policy, char *buf)
+ /* print out the phc version string set at the beginning of that file
+  */
+{
+   ssize_t count = 0;
+   count += sprintf(&buf[count], "%s\n", PHC_VERSION_STRING);
+   return count;
+}
+
+
+
+static struct freq_attr cpufreq_freq_attr_phc_version =
+{
+   /*display phc's version string*/
+       .attr = { .name = "phc_version", .mode = 0444 },
+       .show = show_freq_attr_phc_version,
+       .store = NULL,
+};
+
+static struct freq_attr cpufreq_freq_attr_vids =
+{
+   /*display phc's voltage id's for the cpu*/
+       .attr = { .name = "phc_vids", .mode = 0644 },
+       .show = show_freq_attr_vids,
+       .store = store_freq_attr_vids,
+};
+
+static struct freq_attr cpufreq_freq_attr_default_vids =
+{
+   /*display acpi's default frequency id's for the cpu*/
+       .attr = { .name = "phc_default_vids", .mode = 0444 },
+       .show = show_freq_attr_default_vids,
+       .store = NULL,
+};
+
+static struct freq_attr cpufreq_freq_attr_fids =
+{
+   /*display phc's default frequency id's for the cpu*/
+       .attr = { .name = "phc_fids", .mode = 0444 },
+       .show = show_freq_attr_fids,
+       .store = NULL,
+};
+
+static struct freq_attr cpufreq_freq_attr_controls =
+{
+   /*display phc's current voltage/frequency controls for the cpu*/
+       .attr = { .name = "phc_controls", .mode = 0644 },
+       .show = show_freq_attr_controls,
+       .store = store_freq_attr_controls,
+};
+
+static struct freq_attr cpufreq_freq_attr_default_controls =
+{
+   /*display acpi's default voltage/frequency controls for the cpu*/
+       .attr = { .name = "phc_default_controls", .mode = 0444 },
+       .show = show_freq_attr_default_controls,
+       .store = NULL,
+};
+
+
+
 static struct freq_attr *acpi_cpufreq_attr[] = {
    &cpufreq_freq_attr_scaling_available_freqs,
    &freqdomain_cpus,
+   &cpufreq_freq_attr_phc_version,
+   &cpufreq_freq_attr_vids,
+   &cpufreq_freq_attr_default_vids,
+   &cpufreq_freq_attr_fids,
+   &cpufreq_freq_attr_controls,
+   &cpufreq_freq_attr_default_controls,
    NULL,   /* this is a placeholder for cpb, do not remove */
    NULL,
 };
Back to top
View user's profile Send private message
TeknoHog
n00b
n00b


Joined: 30 Apr 2004
Posts: 5
Location: Jyvaskyla, Finland

PostPosted: Wed Sep 04, 2013 12:04 pm    Post subject: Reply with quote

Alloha wrote:
Hi All!

For those willing to test latest RC kernels (also might be helpful to maintainer) and be able to use phc-intel here is a slightly updated patch for PHC-intel to build against 3.11-rc linux kernels. Tested on my Dell Latitude E6400 with Core 2 Duo P8600 CPU for more than a week already.

If you are as lazy as me, and don't want to modify the .ebuild, just replace the original phc-intel-0.3.2.12.1-r5-3.7.patch with the file below and re-digest the .ebuild.

phc-intel-0.3.2.12.1-r5-3.11.patch:


Thanks! This didn't work on 3.11 as such, but it could just be a forum formatting issue. After applying this more manually, it works fine, and I have an updated ebuild+patch here: https://github.com/teknohog/ebuilds/tree/master/sys-power/phc-intel
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Kernel & Hardware All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum