msm: clock: Move to per-clock voltage class support in the top-level driver
Generalize the voltage voting logic so that it lives in the
top-level clock.c driver. This has a couple of advantages:
- Voltage voting is no longer restricted to clock-local drivers
and need not be duplicated for different driver types.
- Different clocks may specify requirements on different power rails
by using different voltage_class implementations.
- Fmax data (maximum frequency allowed at a given voltage level)
is separated from the frequency tables and captured as a
property of each clock, so that difference SoCs may share the
same frequency tables even if their voltage requirements differ.
- The per-clock lock can be managed entirely at the clock.c level
Change-Id: I2bbd16096c14cedefa2b7fdf77d9f20d842b1e4d
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index c0af9b5..4e0d3e9 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -170,10 +170,25 @@
static int list_rates_show(struct seq_file *m, void *unused)
{
struct clk *clock = m->private;
- int rate, i = 0;
+ int rate, level, fmax = 0, i = 0;
- while ((rate = clock->ops->list_rate(clock, i++)) >= 0)
- seq_printf(m, "%d\n", rate);
+ /* Find max frequency supported within voltage constraints. */
+ if (!clock->vdd_class) {
+ fmax = ULONG_MAX;
+ } else {
+ for (level = 0; level < ARRAY_SIZE(clock->fmax); level++)
+ if (clock->fmax[level])
+ fmax = clock->fmax[level];
+ }
+
+ /*
+ * List supported frequencies <= fmax. Higher frequencies may appear in
+ * the frequency table, but are not valid and should not be listed.
+ */
+ while ((rate = clock->ops->list_rate(clock, i++)) >= 0) {
+ if (rate <= fmax)
+ seq_printf(m, "%u\n", rate);
+ }
return 0;
}