summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/devfreq/devfreq.c10
-rw-r--r--drivers/devfreq/imx-bus.c2
-rw-r--r--drivers/devfreq/imx8m-ddrc.c2
-rw-r--r--drivers/devfreq/mtk-cci-devfreq.c1
-rw-r--r--drivers/devfreq/tegra30-devfreq.c2
-rw-r--r--tools/power/cpupower/Makefile2
-rw-r--r--tools/power/cpupower/lib/cpupower.c7
-rw-r--r--tools/power/cpupower/lib/cpupower_intern.h1
-rw-r--r--tools/power/cpupower/utils/cpuidle-set.c16
-rw-r--r--tools/power/cpupower/utils/cpupower-set.c65
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h11
-rw-r--r--tools/power/cpupower/utils/helpers/misc.c57
12 files changed, 155 insertions, 21 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index e36cbb920ec8..474d81831ad3 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -472,10 +472,11 @@ static void devfreq_monitor(struct work_struct *work)
* devfreq_monitor_start() - Start load monitoring of devfreq instance
* @devfreq: the devfreq instance.
*
- * Helper function for starting devfreq device load monitoring. By
- * default delayed work based monitoring is supported. Function
- * to be called from governor in response to DEVFREQ_GOV_START
- * event when device is added to devfreq framework.
+ * Helper function for starting devfreq device load monitoring. By default,
+ * deferrable timer is used for load monitoring. But the users can change this
+ * behavior using the "timer" type in devfreq_dev_profile. This function will be
+ * called by devfreq governor in response to the DEVFREQ_GOV_START event
+ * generated while adding a device to the devfreq framework.
*/
void devfreq_monitor_start(struct devfreq *devfreq)
{
@@ -763,6 +764,7 @@ static void devfreq_dev_release(struct device *dev)
dev_pm_opp_put_opp_table(devfreq->opp_table);
mutex_destroy(&devfreq->lock);
+ srcu_cleanup_notifier_head(&devfreq->transition_notifier_list);
kfree(devfreq);
}
diff --git a/drivers/devfreq/imx-bus.c b/drivers/devfreq/imx-bus.c
index a727067980fb..86850b7dea09 100644
--- a/drivers/devfreq/imx-bus.c
+++ b/drivers/devfreq/imx-bus.c
@@ -7,7 +7,7 @@
#include <linux/devfreq.h>
#include <linux/device.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index 16636973eb10..e1348490c8aa 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -3,9 +3,9 @@
* Copyright 2019 NXP
*/
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/device.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/devfreq.h>
#include <linux/pm_opp.h>
diff --git a/drivers/devfreq/mtk-cci-devfreq.c b/drivers/devfreq/mtk-cci-devfreq.c
index 6354622eda65..83a73f0ccd80 100644
--- a/drivers/devfreq/mtk-cci-devfreq.c
+++ b/drivers/devfreq/mtk-cci-devfreq.c
@@ -8,7 +8,6 @@
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/regulator/consumer.h>
diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index 503376b894b6..4a4f0106ab9d 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -13,7 +13,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/reset.h>
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index 59bfa05dec5d..dc531805a570 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -53,7 +53,7 @@ DESTDIR ?=
VERSION:= $(shell ./utils/version-gen.sh)
LIB_MAJ= 0.0.1
-LIB_MIN= 0
+LIB_MIN= 1
PACKAGE = cpupower
PACKAGE_BUGREPORT = linux-pm@vger.kernel.org
diff --git a/tools/power/cpupower/lib/cpupower.c b/tools/power/cpupower/lib/cpupower.c
index 3f7d0c0c5067..7a2ef691b20e 100644
--- a/tools/power/cpupower/lib/cpupower.c
+++ b/tools/power/cpupower/lib/cpupower.c
@@ -14,6 +14,13 @@
#include "cpupower.h"
#include "cpupower_intern.h"
+int is_valid_path(const char *path)
+{
+ if (access(path, F_OK) == -1)
+ return 0;
+ return 1;
+}
+
unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen)
{
ssize_t numread;
diff --git a/tools/power/cpupower/lib/cpupower_intern.h b/tools/power/cpupower/lib/cpupower_intern.h
index ac1112b956ec..5fdb8620d41b 100644
--- a/tools/power/cpupower/lib/cpupower_intern.h
+++ b/tools/power/cpupower/lib/cpupower_intern.h
@@ -7,5 +7,6 @@
#define SYSFS_PATH_MAX 255
+int is_valid_path(const char *path);
unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen);
unsigned int cpupower_write_sysfs(const char *path, char *buf, size_t buflen);
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c
index 46158928f9ad..a551d1d4ac51 100644
--- a/tools/power/cpupower/utils/cpuidle-set.c
+++ b/tools/power/cpupower/utils/cpuidle-set.c
@@ -41,14 +41,6 @@ int cmd_idle_set(int argc, char **argv)
cont = 0;
break;
case 'd':
- if (param) {
- param = -1;
- cont = 0;
- break;
- }
- param = ret;
- idlestate = atoi(optarg);
- break;
case 'e':
if (param) {
param = -1;
@@ -56,7 +48,13 @@ int cmd_idle_set(int argc, char **argv)
break;
}
param = ret;
- idlestate = atoi(optarg);
+ strtol(optarg, &endptr, 10);
+ if (*endptr != '\0') {
+ printf(_("Bad value: %s, Integer expected\n"), optarg);
+ exit(EXIT_FAILURE);
+ } else {
+ idlestate = atoi(optarg);
+ }
break;
case 'D':
if (param) {
diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c
index 180d5ba877e6..0677b58374ab 100644
--- a/tools/power/cpupower/utils/cpupower-set.c
+++ b/tools/power/cpupower/utils/cpupower-set.c
@@ -18,6 +18,9 @@
static struct option set_opts[] = {
{"perf-bias", required_argument, NULL, 'b'},
+ {"epp", required_argument, NULL, 'e'},
+ {"amd-pstate-mode", required_argument, NULL, 'm'},
+ {"turbo-boost", required_argument, NULL, 't'},
{ },
};
@@ -37,11 +40,15 @@ int cmd_set(int argc, char **argv)
union {
struct {
int perf_bias:1;
+ int epp:1;
+ int mode:1;
+ int turbo_boost:1;
};
int params;
} params;
- int perf_bias = 0;
+ int perf_bias = 0, turbo_boost = 1;
int ret = 0;
+ char epp[30], mode[20];
ret = uname(&uts);
if (!ret && (!strcmp(uts.machine, "ppc64le") ||
@@ -55,7 +62,7 @@ int cmd_set(int argc, char **argv)
params.params = 0;
/* parameter parsing */
- while ((ret = getopt_long(argc, argv, "b:",
+ while ((ret = getopt_long(argc, argv, "b:e:m:",
set_opts, NULL)) != -1) {
switch (ret) {
case 'b':
@@ -69,6 +76,38 @@ int cmd_set(int argc, char **argv)
}
params.perf_bias = 1;
break;
+ case 'e':
+ if (params.epp)
+ print_wrong_arg_exit();
+ if (sscanf(optarg, "%29s", epp) != 1) {
+ print_wrong_arg_exit();
+ return -EINVAL;
+ }
+ params.epp = 1;
+ break;
+ case 'm':
+ if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
+ print_wrong_arg_exit();
+ if (params.mode)
+ print_wrong_arg_exit();
+ if (sscanf(optarg, "%19s", mode) != 1) {
+ print_wrong_arg_exit();
+ return -EINVAL;
+ }
+ params.mode = 1;
+ break;
+ case 't':
+ if (params.turbo_boost)
+ print_wrong_arg_exit();
+ turbo_boost = atoi(optarg);
+ if (turbo_boost < 0 || turbo_boost > 1) {
+ printf("--turbo-boost param out of range [0-1]\n");
+ print_wrong_arg_exit();
+ }
+ params.turbo_boost = 1;
+ break;
+
+
default:
print_wrong_arg_exit();
}
@@ -77,6 +116,18 @@ int cmd_set(int argc, char **argv)
if (!params.params)
print_wrong_arg_exit();
+ if (params.mode) {
+ ret = cpupower_set_amd_pstate_mode(mode);
+ if (ret)
+ fprintf(stderr, "Error setting mode\n");
+ }
+
+ if (params.turbo_boost) {
+ ret = cpupower_set_turbo_boost(turbo_boost);
+ if (ret)
+ fprintf(stderr, "Error setting turbo-boost\n");
+ }
+
/* Default is: set all CPUs */
if (bitmask_isallclear(cpus_chosen))
bitmask_setall(cpus_chosen);
@@ -102,6 +153,16 @@ int cmd_set(int argc, char **argv)
break;
}
}
+
+ if (params.epp) {
+ ret = cpupower_set_epp(cpu, epp);
+ if (ret) {
+ fprintf(stderr,
+ "Error setting epp value on CPU %d\n", cpu);
+ break;
+ }
+ }
+
}
return ret;
}
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
index 96e4bede078b..95749b8ee475 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -116,6 +116,10 @@ extern int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val);
extern int cpupower_intel_get_perf_bias(unsigned int cpu);
extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);
+extern int cpupower_set_epp(unsigned int cpu, char *epp);
+extern int cpupower_set_amd_pstate_mode(char *mode);
+extern int cpupower_set_turbo_boost(int turbo_boost);
+
/* Read/Write msr ****************************/
/* PCI stuff ****************************/
@@ -173,6 +177,13 @@ static inline int cpupower_intel_get_perf_bias(unsigned int cpu)
static inline unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu)
{ return 0; };
+static inline int cpupower_set_epp(unsigned int cpu, char *epp)
+{ return -1; };
+static inline int cpupower_set_amd_pstate_mode(char *mode)
+{ return -1; };
+static inline int cpupower_set_turbo_boost(int turbo_boost)
+{ return -1; };
+
/* Read/Write msr ****************************/
static inline int cpufreq_has_boost_support(unsigned int cpu, int *support,
diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c
index 9547b29254a7..76e461ff4f74 100644
--- a/tools/power/cpupower/utils/helpers/misc.c
+++ b/tools/power/cpupower/utils/helpers/misc.c
@@ -87,6 +87,61 @@ int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val)
return 0;
}
+int cpupower_set_epp(unsigned int cpu, char *epp)
+{
+ char path[SYSFS_PATH_MAX];
+ char linebuf[30] = {};
+
+ snprintf(path, sizeof(path),
+ PATH_TO_CPU "cpu%u/cpufreq/energy_performance_preference", cpu);
+
+ if (!is_valid_path(path))
+ return -1;
+
+ snprintf(linebuf, sizeof(linebuf), "%s", epp);
+
+ if (cpupower_write_sysfs(path, linebuf, 30) <= 0)
+ return -1;
+
+ return 0;
+}
+
+int cpupower_set_amd_pstate_mode(char *mode)
+{
+ char path[SYSFS_PATH_MAX];
+ char linebuf[20] = {};
+
+ snprintf(path, sizeof(path), PATH_TO_CPU "amd_pstate/status");
+
+ if (!is_valid_path(path))
+ return -1;
+
+ snprintf(linebuf, sizeof(linebuf), "%s\n", mode);
+
+ if (cpupower_write_sysfs(path, linebuf, 20) <= 0)
+ return -1;
+
+ return 0;
+}
+
+int cpupower_set_turbo_boost(int turbo_boost)
+{
+ char path[SYSFS_PATH_MAX];
+ char linebuf[2] = {};
+
+ snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost");
+
+ if (!is_valid_path(path))
+ return -1;
+
+ snprintf(linebuf, sizeof(linebuf), "%d", turbo_boost);
+
+ if (cpupower_write_sysfs(path, linebuf, 2) <= 0)
+ return -1;
+
+ return 0;
+}
+
bool cpupower_amd_pstate_enabled(void)
{
char *driver = cpufreq_get_driver(0);
@@ -95,7 +150,7 @@ bool cpupower_amd_pstate_enabled(void)
if (!driver)
return ret;
- if (!strcmp(driver, "amd-pstate"))
+ if (!strncmp(driver, "amd", 3))
ret = true;
cpufreq_put_driver(driver);