Skip to content

Commit

Permalink
PM / devfreq: allow sysfs governor node to switch governor
Browse files Browse the repository at this point in the history
This allows us to select governor runtime from the
default configuration without having to rebuild kernel
or the devfreq driver using the sysfs node:
/sys/class/devfreq/.../governor
cat of the governor will return valid governor
and an echo 'governor_name'>governor will switch
governor

Cc: Rajagopal Venkat <rajagopal.venkat@linaro.org>
Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Kevin Hilman <khilman@ti.com>
Cc: linux-pm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

Signed-off-by: Nishanth Menon <nm@ti.com>
Acked-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
  • Loading branch information
Nishanth Menon authored and MyungJoo Ham committed Nov 20, 2012
1 parent eff607f commit 0359d1a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Documentation/ABI/testing/sysfs-class-devfreq
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ What: /sys/class/devfreq/.../governor
Date: September 2011
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
The /sys/class/devfreq/.../governor shows the name of the
The /sys/class/devfreq/.../governor show or set the name of the
governor used by the corresponding devfreq object.

What: /sys/class/devfreq/.../cur_freq
Expand Down
45 changes: 44 additions & 1 deletion drivers/devfreq/devfreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,49 @@ static ssize_t show_governor(struct device *dev,
return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name);
}

static ssize_t store_governor(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct devfreq *df = to_devfreq(dev);
int ret;
char str_governor[DEVFREQ_NAME_LEN + 1];
struct devfreq_governor *governor;

ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
if (ret != 1)
return -EINVAL;

mutex_lock(&devfreq_list_lock);
governor = find_devfreq_governor(str_governor);
if (IS_ERR(governor)) {
ret = PTR_ERR(governor);
goto out;
}
if (df->governor == governor)
goto out;

if (df->governor) {
ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
if (ret) {
dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
__func__, df->governor->name, ret);
goto out;
}
}
df->governor = governor;
strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
if (ret)
dev_warn(dev, "%s: Governor %s not started(%d)\n",
__func__, df->governor->name, ret);
out:
mutex_unlock(&devfreq_list_lock);

if (!ret)
ret = count;
return ret;
}

static ssize_t show_freq(struct device *dev,
struct device_attribute *attr, char *buf)
{
Expand Down Expand Up @@ -873,7 +916,7 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att
}

static struct device_attribute devfreq_attrs[] = {
__ATTR(governor, S_IRUGO, show_governor, NULL),
__ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor),
__ATTR(cur_freq, S_IRUGO, show_freq, NULL),
__ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL),
__ATTR(target_freq, S_IRUGO, show_target_freq, NULL),
Expand Down

0 comments on commit 0359d1a

Please sign in to comment.