From 357c3f0a6c7613f7230fcaf1eb16190ed2a4b0af Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 29 Jun 2012 19:06:32 +0530 Subject: clk: Add support for rate table based dividers 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 and as part of the support adds a new registration function 'clk_register_divider_table()' and a new macro for static definition 'DEFINE_CLK_DIVIDER_TABLE'. Signed-off-by: Rajendra Nayak Signed-off-by: Mike Turquette --- include/linux/clk-private.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'include/linux/clk-private.h') diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h index eb3f84bc532..cc9972d1429 100644 --- a/include/linux/clk-private.h +++ b/include/linux/clk-private.h @@ -103,9 +103,9 @@ struct clk { DEFINE_CLK(_name, clk_gate_ops, _flags, \ _name##_parent_names, _name##_parents); -#define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ +#define _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ _flags, _reg, _shift, _width, \ - _divider_flags, _lock) \ + _divider_flags, _table, _lock) \ static struct clk _name; \ static const char *_name##_parent_names[] = { \ _parent_name, \ @@ -121,11 +121,27 @@ struct clk { .shift = _shift, \ .width = _width, \ .flags = _divider_flags, \ + .table = _table, \ .lock = _lock, \ }; \ DEFINE_CLK(_name, clk_divider_ops, _flags, \ _name##_parent_names, _name##_parents); +#define DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ + _flags, _reg, _shift, _width, \ + _divider_flags, _lock) \ + _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ + _flags, _reg, _shift, _width, \ + _divider_flags, NULL, _lock) + +#define DEFINE_CLK_DIVIDER_TABLE(_name, _parent_name, \ + _parent_ptr, _flags, _reg, \ + _shift, _width, _divider_flags, \ + _table, _lock) \ + _DEFINE_CLK_DIVIDER(_name, _parent_name, _parent_ptr, \ + _flags, _reg, _shift, _width, \ + _divider_flags, _table, _lock) \ + #define DEFINE_CLK_MUX(_name, _parent_names, _parents, _flags, \ _reg, _shift, _width, \ _mux_flags, _lock) \ -- cgit v1.2.3-70-g09d2 From f7d8caadfd2813cbada82ce9041b13c38e8e5282 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 1 Jun 2012 14:02:47 +0530 Subject: clk: Add CLK_IS_BASIC flag to identify basic clocks Most platforms end up using a mix of basic clock types and some which use clk_hw_foo struct for filling in custom platform information when the clocks don't fit into basic types supported. In platform code, its useful to know if a clock is using a basic type or clk_hw_foo, which helps platforms know if they can safely use to_clk_hw_foo to derive the clk_hw_foo pointer from clk_hw. Mark all basic clocks with a CLK_IS_BASIC flag. Signed-off-by: Rajendra Nayak Signed-off-by: Mike Turquette --- drivers/clk/clk-divider.c | 2 +- drivers/clk/clk-fixed-factor.c | 2 +- drivers/clk/clk-fixed-rate.c | 2 +- drivers/clk/clk-gate.c | 2 +- drivers/clk/clk-mux.c | 2 +- include/linux/clk-private.h | 2 +- include/linux/clk-provider.h | 1 + 7 files changed, 7 insertions(+), 6 deletions(-) (limited to 'include/linux/clk-private.h') diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 02a4da98176..a9204c69148 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -253,7 +253,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, init.name = name; init.ops = &clk_divider_ops; - init.flags = flags; + init.flags = flags | CLK_IS_BASIC; init.parent_names = (parent_name ? &parent_name: NULL); init.num_parents = (parent_name ? 1 : 0); diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index c8c003e217a..a4899855c0f 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -82,7 +82,7 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, init.name = name; init.ops = &clk_fixed_factor_ops; - init.flags = flags; + init.flags = flags | CLK_IS_BASIC; init.parent_names = &parent_name; init.num_parents = 1; diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index cbd24622978..7e146456972 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -63,7 +63,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, init.name = name; init.ops = &clk_fixed_rate_ops; - init.flags = flags; + init.flags = flags | CLK_IS_BASIC; init.parent_names = (parent_name ? &parent_name: NULL); init.num_parents = (parent_name ? 1 : 0); diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 578465e04be..15114febfd9 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -130,7 +130,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name, init.name = name; init.ops = &clk_gate_ops; - init.flags = flags; + init.flags = flags | CLK_IS_BASIC; init.parent_names = (parent_name ? &parent_name: NULL); init.num_parents = (parent_name ? 1 : 0); diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index fd36a8ea73d..508c032edce 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -106,7 +106,7 @@ struct clk *clk_register_mux(struct device *dev, const char *name, init.name = name; init.ops = &clk_mux_ops; - init.flags = flags; + init.flags = flags | CLK_IS_BASIC; init.parent_names = parent_names; init.num_parents = num_parents; diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h index cc9972d1429..9c7f5807824 100644 --- a/include/linux/clk-private.h +++ b/include/linux/clk-private.h @@ -64,7 +64,7 @@ struct clk { .parent_names = _parent_names, \ .num_parents = ARRAY_SIZE(_parent_names), \ .parents = _parents, \ - .flags = _flags, \ + .flags = _flags | CLK_IS_BASIC, \ } #define DEFINE_CLK_FIXED_RATE(_name, _flags, _rate, \ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 79caee9f148..0236f58f3e6 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -25,6 +25,7 @@ #define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ #define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ #define CLK_IS_ROOT BIT(4) /* root clk, has no parent */ +#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */ struct clk_hw; -- cgit v1.2.3-70-g09d2