Skip to content

Commit

Permalink
PM / devfreq: Fix available_governor sysfs
Browse files Browse the repository at this point in the history
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: 9961331 ("PM / devfreq: Add new passive governor")
Cc: stable@vger.kernel.org
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
  • Loading branch information
Chanwoo Choi authored and MyungJoo Ham committed Jan 31, 2017
1 parent b0d75c0 commit bcf23c7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
31 changes: 27 additions & 4 deletions drivers/devfreq/devfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
if (df->governor == governor) {
ret = 0;
goto out;
} else if (df->governor->immutable || governor->immutable) {
ret = -EINVAL;
goto out;
}

if (df->governor) {
Expand Down Expand Up @@ -969,13 +972,33 @@ static ssize_t available_governors_show(struct device *d,
struct device_attribute *attr,
char *buf)
{
struct devfreq_governor *tmp_governor;
struct devfreq *df = to_devfreq(d);
ssize_t count = 0;

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);

/* Truncate the trailing space */
Expand Down
1 change: 1 addition & 0 deletions drivers/devfreq/governor_passive.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,

static struct devfreq_governor devfreq_passive = {
.name = "passive",
.immutable = 1,
.get_target_freq = devfreq_passive_get_target_freq,
.event_handler = devfreq_passive_event_handler,
};
Expand Down
3 changes: 3 additions & 0 deletions include/linux/devfreq.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ struct devfreq_dev_profile {
* struct devfreq_governor - Devfreq policy governor
* @node: list node - contains registered devfreq governors
* @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.
* Basically, get_target_freq will run
* devfreq_dev_profile.get_dev_status() to get the
Expand All @@ -121,6 +123,7 @@ struct devfreq_governor {
struct list_head node;

const char name[DEVFREQ_NAME_LEN];
const unsigned int immutable;
int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
int (*event_handler)(struct devfreq *devfreq,
unsigned int event, void *data);
Expand Down

0 comments on commit bcf23c7

Please sign in to comment.