mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
Merge branches 'pm-devfreq' and 'pm-tools'
Merge devfreq changes and power management tools changes for 6.6-rc1: - Fix memory leak in devfreq_dev_release() (Boris Brezillon). - Rewrite devfreq_monitor_start() kerneldoc comment (Manivannan Sadhasivam). - Explicitly include correct DT includes in devfreq (Rob Herring). - Add turbo-boost support to cpupower (Wyes Karny). - Add support for amd_pstate mode change to cpupower (Wyes Karny). - Fix 'cpupower idle_set' command to accept only numeric values of arguments (Likhitha Korrapati). * pm-devfreq: PM / devfreq: Fix leak in devfreq_dev_release() PM / devfreq: Reword the kernel-doc comment for devfreq_monitor_start() API PM / devfreq: Explicitly include correct DT includes * pm-tools: cpupower: Fix cpuidle_set to accept only numeric values for idle-set operation. cpupower: Add turbo-boost support in cpupower cpupower: Add support for amd_pstate mode change cpupower: Add EPP value change support cpupower: Add is_valid_path API cpupower: Recognise amd-pstate active mode driver cpupower: Bump soname version
This commit is contained in:
commit
885c429e06
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user