Commit 0359d1af authored by Nishanth Menon's avatar Nishanth Menon Committed by MyungJoo Ham
Browse files

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: default avatarNishanth Menon <nm@ti.com>
Acked-by: default avatarMyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: default avatarMyungJoo Ham <myungjoo.ham@samsung.com>
parent eff607fd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+44 −1
Original line number Diff line number Diff line
@@ -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),