diff options
author | Gautham R. Shenoy <ego@linux.vnet.ibm.com> | 2014-04-01 13:28:03 +0530 |
---|---|---|
committer | Eli Qiao <taget@linux.vnet.ibm.com> | 2014-04-01 16:10:30 +0800 |
commit | 4042aeb691e65581e20f985e8d687070976ae63b (patch) | |
tree | 49d6e8df8d177230ecb58942d9940825c95e3688 | |
parent | 7f2cc2ee99d283c187fca23b9b7e390e765868b1 (diff) | |
download | powerkvm-4042aeb691e65581e20f985e8d687070976ae63b.tar.gz |
powernv, cpufreq: Export nominal frequency via sysfs.
Create a driver attribute named "cpuinfo_nominal_freq" which will in
turn create a read-only sysfs interface that will be used to export
the nominal frequency to the userspace. This will be necessary for
creating an optimal "performance" policy which should be running the
on-demand governor with "scaling_max_freq" to be set to the value
exported via "cpuinfo_max_freq" and "scaling_min_freq" to be set to
the nominal frequency exported via "cpuinfo_nominal_freq".
The patch caches the values of max, min, nominal pstate ids and
nr_pstates queried from the DT during the initialization of the driver
so that they can be used in other places in the driver for
validatation.
Also, it adds a helper method that returns the frequency corresponding to
a pstate id.
This has been backported from the version posted against mainline
which can be found here:
https://www.mail-archive.com/linuxppc-dev@lists.ozlabs.org/msg76990.html
Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
-rw-r--r-- | drivers/cpufreq/powerpc-book3s-cpufreq.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/cpufreq/powerpc-book3s-cpufreq.c b/drivers/cpufreq/powerpc-book3s-cpufreq.c index 9ab0c80ee4555..60a0520eded58 100644 --- a/drivers/cpufreq/powerpc-book3s-cpufreq.c +++ b/drivers/cpufreq/powerpc-book3s-cpufreq.c @@ -23,6 +23,7 @@ #include <linux/cpufreq.h> #include <linux/delay.h> #include <linux/of_platform.h> +#include <linux/sysfs.h> #include <asm/cputhreads.h> #include <asm/topology.h> @@ -39,6 +40,21 @@ static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; static unsigned long powernv_freqs_data[POWERNV_MAX_PSTATES+1]; /* + * Note: The set of pstates consists of contiguous integers, the + * smallest of which is indicated by powernv_pstate_info.min, the + * largest of which is indicated by powernv_pstate_info.max. + * + * The nominal pstate is the highest non-turbo pstate in this + * platform. This is indicated by powernv_pstate_info.nominal. + */ +static struct powernv_pstate_info { + int min; + int max; + int nominal; + int nr_pstates; +} powernv_pstate_info; + +/* * Initialize the freq table based on data obtained * from the OCC passed via device-tree */ @@ -127,11 +143,42 @@ static int init_powernv_pstates(void) powernv_freqs[i].frequency = CPUFREQ_TABLE_END; powernv_freqs_data[i] = 0; + powernv_pstate_info.min = pstate_min; + powernv_pstate_info.max = pstate_max; + powernv_pstate_info.nominal = pstate_nominal; + powernv_pstate_info.nr_pstates = nr_pstates; + return 0; } -static struct freq_attr* powernv_cpu_freq_attr[] = { +/* Returns the CPU frequency corresponding to the pstate_id. */ +static unsigned int pstate_id_to_freq(int pstate_id) +{ + int i; + + i = powernv_pstate_info.max - pstate_id; + BUG_ON(i >= powernv_pstate_info.nr_pstates || i < 0); + + return powernv_freqs[i].frequency; +} + +/* + * cpuinfo_nominal_freq_show - Show the nominal CPU frequency as indicated by + * the firmware + */ +static ssize_t cpuinfo_nominal_freq_show(struct cpufreq_policy *policy, + char *buf) +{ + return sprintf(buf, "%u\n", + pstate_id_to_freq(powernv_pstate_info.nominal)); +} + +struct freq_attr cpufreq_freq_attr_cpuinfo_nominal_freq = + __ATTR_RO(cpuinfo_nominal_freq); + +static struct freq_attr *powernv_cpu_freq_attr[] = { &cpufreq_freq_attr_scaling_available_freqs, + &cpufreq_freq_attr_cpuinfo_nominal_freq, NULL, }; |