diff options
author | Nishanth Menon <nm@ti.com> | 2012-10-25 20:48:59 -0400 |
---|---|---|
committer | MyungJoo Ham <myungjoo.ham@samsung.com> | 2012-11-20 01:59:32 -0500 |
commit | d287de855f97c56ca7146ff627e652bd7cd64f3f (patch) | |
tree | a3dbeb4937853cf1e81dca65c97c2dbbda549129 | |
parent | e09651fcc295a7dc802f38d9494f5b860dd90bca (diff) |
PM / devfreq: Add sysfs node to expose available frequencies
devfreq governors such as ondemand are controlled by a min and
max frequency, while governors like userspace governor allow us
to set a specific frequency.
However, for the same specific device, depending on the SoC, the
available frequencies can vary.
So expose the available frequencies as a snapshot over sysfs to
allow informed decisions.
This was inspired by cpufreq framework's equivalent for similar
usage sysfs node: scaling_available_frequencies.
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>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
-rw-r--r-- | Documentation/ABI/testing/sysfs-class-devfreq | 9 | ||||
-rw-r--r-- | drivers/devfreq/devfreq.c | 32 |
2 files changed, 41 insertions, 0 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index e6cf08e6734d..e672ccb02e7f 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq | |||
@@ -51,3 +51,12 @@ Description: | |||
51 | The /sys/class/devfreq/.../userspace/set_freq shows and | 51 | The /sys/class/devfreq/.../userspace/set_freq shows and |
52 | sets the requested frequency for the devfreq object if | 52 | sets the requested frequency for the devfreq object if |
53 | userspace governor is in effect. | 53 | userspace governor is in effect. |
54 | |||
55 | What: /sys/class/devfreq/.../available_frequencies | ||
56 | Date: October 2012 | ||
57 | Contact: Nishanth Menon <nm@ti.com> | ||
58 | Description: | ||
59 | The /sys/class/devfreq/.../available_frequencies shows | ||
60 | the available frequencies of the corresponding devfreq object. | ||
61 | This is a snapshot of available frequencies and not limited | ||
62 | by the min/max frequency restrictions. | ||
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 789af4ff5c9c..c44e562bdfe0 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
@@ -570,9 +570,41 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, | |||
570 | return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq); | 570 | return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq); |
571 | } | 571 | } |
572 | 572 | ||
573 | static ssize_t show_available_freqs(struct device *d, | ||
574 | struct device_attribute *attr, | ||
575 | char *buf) | ||
576 | { | ||
577 | struct devfreq *df = to_devfreq(d); | ||
578 | struct device *dev = df->dev.parent; | ||
579 | struct opp *opp; | ||
580 | ssize_t count = 0; | ||
581 | unsigned long freq = 0; | ||
582 | |||
583 | rcu_read_lock(); | ||
584 | do { | ||
585 | opp = opp_find_freq_ceil(dev, &freq); | ||
586 | if (IS_ERR(opp)) | ||
587 | break; | ||
588 | |||
589 | count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), | ||
590 | "%lu ", freq); | ||
591 | freq++; | ||
592 | } while (1); | ||
593 | rcu_read_unlock(); | ||
594 | |||
595 | /* Truncate the trailing space */ | ||
596 | if (count) | ||
597 | count--; | ||
598 | |||
599 | count += sprintf(&buf[count], "\n"); | ||
600 | |||
601 | return count; | ||
602 | } | ||
603 | |||
573 | static struct device_attribute devfreq_attrs[] = { | 604 | static struct device_attribute devfreq_attrs[] = { |
574 | __ATTR(governor, S_IRUGO, show_governor, NULL), | 605 | __ATTR(governor, S_IRUGO, show_governor, NULL), |
575 | __ATTR(cur_freq, S_IRUGO, show_freq, NULL), | 606 | __ATTR(cur_freq, S_IRUGO, show_freq, NULL), |
607 | __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL), | ||
576 | __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), | 608 | __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), |
577 | __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, | 609 | __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, |
578 | store_polling_interval), | 610 | store_polling_interval), |