aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/devfreq/devfreq.c
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2012-10-29 16:01:47 -0400
committerMyungJoo Ham <myungjoo.ham@samsung.com>2012-11-20 04:46:23 -0500
commit0359d1afe4013d1a216908b6be4c6695a1db6fd6 (patch)
treef74ac1331ed6c40ce36aa35414ad05f53ce699e6 /drivers/devfreq/devfreq.c
parenteff607fdb1f787da1fedf46ab6e64adc2afd1c5a (diff)
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/devfreq.c')
-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,
688 return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name); 688 return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name);
689} 689}
690 690
691static ssize_t store_governor(struct device *dev, struct device_attribute *attr,
692 const char *buf, size_t count)
693{
694 struct devfreq *df = to_devfreq(dev);
695 int ret;
696 char str_governor[DEVFREQ_NAME_LEN + 1];
697 struct devfreq_governor *governor;
698
699 ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
700 if (ret != 1)
701 return -EINVAL;
702
703 mutex_lock(&devfreq_list_lock);
704 governor = find_devfreq_governor(str_governor);
705 if (IS_ERR(governor)) {
706 ret = PTR_ERR(governor);
707 goto out;
708 }
709 if (df->governor == governor)
710 goto out;
711
712 if (df->governor) {
713 ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
714 if (ret) {
715 dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
716 __func__, df->governor->name, ret);
717 goto out;
718 }
719 }
720 df->governor = governor;
721 strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
722 ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
723 if (ret)
724 dev_warn(dev, "%s: Governor %s not started(%d)\n",
725 __func__, df->governor->name, ret);
726out:
727 mutex_unlock(&devfreq_list_lock);
728
729 if (!ret)
730 ret = count;
731 return ret;
732}
733
691static ssize_t show_freq(struct device *dev, 734static ssize_t show_freq(struct device *dev,
692 struct device_attribute *attr, char *buf) 735 struct device_attribute *attr, char *buf)
693{ 736{
@@ -873,7 +916,7 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att
873} 916}
874 917
875static struct device_attribute devfreq_attrs[] = { 918static struct device_attribute devfreq_attrs[] = {
876 __ATTR(governor, S_IRUGO, show_governor, NULL), 919 __ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor),
877 __ATTR(cur_freq, S_IRUGO, show_freq, NULL), 920 __ATTR(cur_freq, S_IRUGO, show_freq, NULL),
878 __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL), 921 __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL),
879 __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), 922 __ATTR(target_freq, S_IRUGO, show_target_freq, NULL),