Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9005b650 authored by MyungJoo Ham's avatar MyungJoo Ham Committed by Rafael J. Wysocki
Browse files

PM / devfreq: Add common sysfs interfaces



Device specific sysfs interface /sys/devices/.../power/devfreq_*
- governor	R: name of governor
- cur_freq	R: current frequency
- polling_interval	R: polling interval in ms given with devfreq profile
			W: update polling interval.
- central_polling	R: 1 if polling is managed by devfreq framework

Signed-off-by: default avatarMyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: default avatarMike Turquette <mturquette@ti.com>
Acked-by: default avatarKevin Hilman <khilman@ti.com>
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
--
 Documentation/ABI/testing/sysfs-class-devfreq |   44 ++++++++++++++++
 drivers/devfreq/devfreq.c                     |   69 ++++++++++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-devfreq
parent a3c98b8b
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
What:		/sys/class/devfreq/.../
Date:		September 2011
Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
		Provide a place in sysfs for the devfreq objects.
		This allows accessing various devfreq specific variables.
		The name of devfreq object denoted as ... is same as the
		name of device using devfreq.

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
		governor used by the corresponding devfreq object.

What:		/sys/class/devfreq/.../cur_freq
Date:		September 2011
Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
		The /sys/class/devfreq/.../cur_freq shows the current
		frequency of the corresponding devfreq object.

What:		/sys/class/devfreq/.../central_polling
Date:		September 2011
Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
		The /sys/class/devfreq/.../central_polling shows whether
		the devfreq ojbect is using devfreq-provided central
		polling mechanism or not.

What:		/sys/class/devfreq/.../polling_interval
Date:		September 2011
Contact:	MyungJoo Ham <myungjoo.ham@samsung.com>
Description:
		The /sys/class/devfreq/.../polling_interval shows and sets
		the requested polling interval of the corresponding devfreq
		object. The values are represented in ms. If the value is
		less than 1 jiffy, it is considered to be 0, which means
		no polling. This value is meaningless if the governor is
		not polling; thus. If the governor is not using
		devfreq-provided central polling
		(/sys/class/devfreq/.../central_polling is 0), this value
		may be useless.
+69 −0
Original line number Diff line number Diff line
@@ -437,6 +437,74 @@ int devfreq_remove_device(struct devfreq *devfreq)
	return 0;
}

static ssize_t show_governor(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name);
}

static ssize_t show_freq(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq);
}

static ssize_t show_polling_interval(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", to_devfreq(dev)->profile->polling_ms);
}

static ssize_t store_polling_interval(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct devfreq *df = to_devfreq(dev);
	unsigned int value;
	int ret;

	ret = sscanf(buf, "%u", &value);
	if (ret != 1)
		goto out;

	mutex_lock(&df->lock);
	df->profile->polling_ms = value;
	df->next_polling = df->polling_jiffies
			 = msecs_to_jiffies(value);
	mutex_unlock(&df->lock);

	ret = count;

	if (df->governor->no_central_polling)
		goto out;

	mutex_lock(&devfreq_list_lock);
	if (df->next_polling > 0 && !polling) {
		polling = true;
		queue_delayed_work(devfreq_wq, &devfreq_work,
				   df->next_polling);
	}
	mutex_unlock(&devfreq_list_lock);
out:
	return ret;
}

static ssize_t show_central_polling(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n",
		       !to_devfreq(dev)->governor->no_central_polling);
}

static struct device_attribute devfreq_attrs[] = {
	__ATTR(governor, S_IRUGO, show_governor, NULL),
	__ATTR(cur_freq, S_IRUGO, show_freq, NULL),
	__ATTR(central_polling, S_IRUGO, show_central_polling, NULL),
	__ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval,
	       store_polling_interval),
	{ },
};

/**
 * devfreq_start_polling() - Initialize data structure for devfreq framework and
 *			   start polling registered devfreq devices.
@@ -461,6 +529,7 @@ static int __init devfreq_init(void)
		pr_err("%s: couldn't create class\n", __FILE__);
		return PTR_ERR(devfreq_class);
	}
	devfreq_class->dev_attrs = devfreq_attrs;
	return 0;
}
subsys_initcall(devfreq_init);