Commit f1aa0ed6 authored by Chanwoo Choi's avatar Chanwoo Choi Committed by Greg Kroah-Hartman

PM / devfreq: Fix available_governor sysfs

commit bcf23c79 upstream.

The devfreq using passive governor is not able to change the governor.
So, the user can not change the governor through 'available_governor' sysfs
entry. Also, the devfreq which don't use the passive governor is not able to
change to 'passive' governor on the fly.

Fixes: 99613311 ("PM / devfreq: Add new passive governor")
Signed-off-by: default avatarChanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: default avatarMyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 45c01d51
...@@ -939,6 +939,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, ...@@ -939,6 +939,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
if (df->governor == governor) { if (df->governor == governor) {
ret = 0; ret = 0;
goto out; goto out;
} else if (df->governor->immutable || governor->immutable) {
ret = -EINVAL;
goto out;
} }
if (df->governor) { if (df->governor) {
...@@ -968,13 +971,33 @@ static ssize_t available_governors_show(struct device *d, ...@@ -968,13 +971,33 @@ static ssize_t available_governors_show(struct device *d,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct devfreq_governor *tmp_governor; struct devfreq *df = to_devfreq(d);
ssize_t count = 0; ssize_t count = 0;
mutex_lock(&devfreq_list_lock); mutex_lock(&devfreq_list_lock);
list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), /*
"%s ", tmp_governor->name); * The devfreq with immutable governor (e.g., passive) shows
* only own governor.
*/
if (df->governor->immutable) {
count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
"%s ", df->governor_name);
/*
* The devfreq device shows the registered governor except for
* immutable governors such as passive governor .
*/
} else {
struct devfreq_governor *governor;
list_for_each_entry(governor, &devfreq_governor_list, node) {
if (governor->immutable)
continue;
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
"%s ", governor->name);
}
}
mutex_unlock(&devfreq_list_lock); mutex_unlock(&devfreq_list_lock);
/* Truncate the trailing space */ /* Truncate the trailing space */
......
...@@ -179,6 +179,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq, ...@@ -179,6 +179,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
static struct devfreq_governor devfreq_passive = { static struct devfreq_governor devfreq_passive = {
.name = "passive", .name = "passive",
.immutable = 1,
.get_target_freq = devfreq_passive_get_target_freq, .get_target_freq = devfreq_passive_get_target_freq,
.event_handler = devfreq_passive_event_handler, .event_handler = devfreq_passive_event_handler,
}; };
......
...@@ -104,6 +104,8 @@ struct devfreq_dev_profile { ...@@ -104,6 +104,8 @@ struct devfreq_dev_profile {
* struct devfreq_governor - Devfreq policy governor * struct devfreq_governor - Devfreq policy governor
* @node: list node - contains registered devfreq governors * @node: list node - contains registered devfreq governors
* @name: Governor's name * @name: Governor's name
* @immutable: Immutable flag for governor. If the value is 1,
* this govenror is never changeable to other governor.
* @get_target_freq: Returns desired operating frequency for the device. * @get_target_freq: Returns desired operating frequency for the device.
* Basically, get_target_freq will run * Basically, get_target_freq will run
* devfreq_dev_profile.get_dev_status() to get the * devfreq_dev_profile.get_dev_status() to get the
...@@ -121,6 +123,7 @@ struct devfreq_governor { ...@@ -121,6 +123,7 @@ struct devfreq_governor {
struct list_head node; struct list_head node;
const char name[DEVFREQ_NAME_LEN]; const char name[DEVFREQ_NAME_LEN];
const unsigned int immutable;
int (*get_target_freq)(struct devfreq *this, unsigned long *freq); int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
int (*event_handler)(struct devfreq *devfreq, int (*event_handler)(struct devfreq *devfreq,
unsigned int event, void *data); unsigned int event, void *data);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment