summaryrefslogtreecommitdiffstats
path: root/drivers/devfreq
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2012-10-29 15:01:47 -0500
committerMyungJoo Ham <myungjoo.ham@samsung.com>2012-11-20 18:46:23 +0900
commit0359d1afe4013d1a216908b6be4c6695a1db6fd6 (patch)
treef74ac1331ed6c40ce36aa35414ad05f53ce699e6 /drivers/devfreq
parenteff607fdb1f787da1fedf46ab6e64adc2afd1c5a (diff)
downloadlinux-0359d1afe4013d1a216908b6be4c6695a1db6fd6.tar.bz2
PM / devfreq: allow sysfs governor node to switch governor
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>
Diffstat (limited to 'drivers/devfreq')
-rw-r--r--drivers/devfreq/devfreq.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 0d7be03d561f..ff960f084c11 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -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)
{
@@ -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),