Hi Ben,
On Monday 21 May 2012 03:17 PM, Ben Dooks wrote:On 17/05/12 11:22, Rajendra Nayak wrote:Some divider clks do not have any obvious relationship
between the divider and the value programmed in the
register. For instance, say a value of 1 could signify divide
by 6 and a value of 2 could signify divide by 4 etc.
Also there are dividers where not all values possible
based on the bitfield width are valid. For instance
a 3 bit wide bitfield can be used to program a value
from 0 to 7. However its possible that only 0 to 4
are valid values.
All these cases need the platform code to pass a simple
table of divider/value tuple, so the framework knows
the exact value to be written based on the divider
calculation and can also do better error checking.
This patch adds support for such rate table based
dividers.
I was considering the idea that you simply pass a
pointer to a set of routines and a data pointer to
the clk-divider code so that any new cases don't
require changing the drivers/clk/clk-divider.c
I don;t know if I understand your comment completely.
Are you suggesting the get min/max etc be function pointers
passed by platform code (and implemented in platform code?)
so clk-divider does not need an update every time a new divider
type is added?
The idea of extending clk-divider was so its useful for more
than just OMAP, so the code in clk-divider can be reused across
multiple platforms. Did I understand your comment right?
regards,
Rajendra
This would make the get max / min / special just
a function call through a struct.
Signed-off-by: Rajendra Nayak<rnayak@xxxxxx>
---
drivers/clk/clk-divider.c | 67
++++++++++++++++++++++++++++++++++++++++--
include/linux/clk-private.h | 3 +-
include/linux/clk-provider.h | 10 +++++-
3 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index e548c43..e4911ee 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -32,30 +32,69 @@
#define div_mask(d) ((1<< (d->width)) - 1)
#define is_power_of_two(i) !(i& ~i)
+static unsigned int _get_table_maxdiv(const struct clk_div_table
*table)
+{
+ unsigned int maxdiv;
+ const struct clk_div_table *clkt;
+
+ for (clkt = table; clkt->div; clkt++)
+ if (clkt->div> maxdiv)
+ maxdiv = clkt->div;
+ return maxdiv;
+}
+
static unsigned int _get_maxdiv(struct clk_divider *divider)
{
if (divider->flags& CLK_DIVIDER_ONE_BASED)
return div_mask(divider);
if (divider->flags& CLK_DIVIDER_POWER_OF_TWO)
return 1<< div_mask(divider);