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 /drivers/devfreq | |
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>
Diffstat (limited to 'drivers/devfreq')
-rw-r--r-- | drivers/devfreq/devfreq.c | 32 |
1 files changed, 32 insertions, 0 deletions
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), |