aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGautham R. Shenoy <ego@linux.vnet.ibm.com>2014-04-01 13:28:03 +0530
committerEli Qiao <taget@linux.vnet.ibm.com>2014-04-01 16:10:30 +0800
commit4042aeb691e65581e20f985e8d687070976ae63b (patch)
tree49d6e8df8d177230ecb58942d9940825c95e3688
parent7f2cc2ee99d283c187fca23b9b7e390e765868b1 (diff)
downloadpowerkvm-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.c49
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,
};