diff options
author | James <> | 2015-11-04 11:49:21 +0000 |
---|---|---|
committer | James <> | 2015-11-04 11:49:21 +0000 |
commit | 716ca530e1c4515d8683c9d5be3d56b301758b66 (patch) | |
tree | 700eb5bcc1a462a5f21dcec15ce7c97ecfefa772 /target/linux/ipq806x/patches-4.1/134-clk-mux-Split-out-register-accessors-for-reuse.patch | |
download | trunk-47381-master.tar.gz trunk-47381-master.tar.bz2 trunk-47381-master.zip |
Diffstat (limited to 'target/linux/ipq806x/patches-4.1/134-clk-mux-Split-out-register-accessors-for-reuse.patch')
-rw-r--r-- | target/linux/ipq806x/patches-4.1/134-clk-mux-Split-out-register-accessors-for-reuse.patch | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches-4.1/134-clk-mux-Split-out-register-accessors-for-reuse.patch b/target/linux/ipq806x/patches-4.1/134-clk-mux-Split-out-register-accessors-for-reuse.patch new file mode 100644 index 0000000..3a475fb --- /dev/null +++ b/target/linux/ipq806x/patches-4.1/134-clk-mux-Split-out-register-accessors-for-reuse.patch @@ -0,0 +1,192 @@ +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3,02/13] clk: mux: Split out register accessors for reuse +From: Stephen Boyd <sboyd@codeaurora.org> +X-Patchwork-Id: 6063111 +Message-Id: <1426920332-9340-3-git-send-email-sboyd@codeaurora.org> +To: Mike Turquette <mturquette@linaro.org>, Stephen Boyd <sboyd@codeaurora.org> +Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, + linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, + Viresh Kumar <viresh.kumar@linaro.org> +Date: Fri, 20 Mar 2015 23:45:21 -0700 + +We want to reuse the logic in clk-mux.c for other clock drivers +that don't use readl as register accessors. Fortunately, there +really isn't much to the mux code besides the table indirection +and quirk flags if you assume any bit shifting and masking has +been done already. Pull that logic out into reusable functions +that operate on an optional table and some flags so that other +drivers can use the same logic. + +Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> + +--- +drivers/clk/clk-mux.c | 76 +++++++++++++++++++++++++++----------------- + include/linux/clk-provider.h | 9 ++++-- + 2 files changed, 54 insertions(+), 31 deletions(-) + +--- a/drivers/clk/clk-mux.c ++++ b/drivers/clk/clk-mux.c +@@ -29,35 +29,24 @@ + + #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) + +-static u8 clk_mux_get_parent(struct clk_hw *hw) ++unsigned int clk_mux_get_parent(struct clk_hw *hw, unsigned int val, ++ unsigned int *table, unsigned long flags) + { +- struct clk_mux *mux = to_clk_mux(hw); + int num_parents = __clk_get_num_parents(hw->clk); +- u32 val; + +- /* +- * FIXME need a mux-specific flag to determine if val is bitwise or numeric +- * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1 +- * to 0x7 (index starts at one) +- * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so +- * val = 0x4 really means "bit 2, index starts at bit 0" +- */ +- val = clk_readl(mux->reg) >> mux->shift; +- val &= mux->mask; +- +- if (mux->table) { ++ if (table) { + int i; + + for (i = 0; i < num_parents; i++) +- if (mux->table[i] == val) ++ if (table[i] == val) + return i; + return -EINVAL; + } + +- if (val && (mux->flags & CLK_MUX_INDEX_BIT)) ++ if (val && (flags & CLK_MUX_INDEX_BIT)) + val = ffs(val) - 1; + +- if (val && (mux->flags & CLK_MUX_INDEX_ONE)) ++ if (val && (flags & CLK_MUX_INDEX_ONE)) + val--; + + if (val >= num_parents) +@@ -65,24 +54,53 @@ static u8 clk_mux_get_parent(struct clk_ + + return val; + } ++EXPORT_SYMBOL_GPL(clk_mux_get_parent); + +-static int clk_mux_set_parent(struct clk_hw *hw, u8 index) ++static u8 _clk_mux_get_parent(struct clk_hw *hw) + { + struct clk_mux *mux = to_clk_mux(hw); + u32 val; +- unsigned long flags = 0; + +- if (mux->table) +- index = mux->table[index]; ++ /* ++ * FIXME need a mux-specific flag to determine if val is bitwise or numeric ++ * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1 ++ * to 0x7 (index starts at one) ++ * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so ++ * val = 0x4 really means "bit 2, index starts at bit 0" ++ */ ++ val = clk_readl(mux->reg) >> mux->shift; ++ val &= mux->mask; ++ ++ return clk_mux_get_parent(hw, val, mux->table, mux->flags); ++} + +- else { +- if (mux->flags & CLK_MUX_INDEX_BIT) +- index = 1 << index; ++unsigned int clk_mux_reindex(u8 index, unsigned int *table, ++ unsigned long flags) ++{ ++ unsigned int val = index; + +- if (mux->flags & CLK_MUX_INDEX_ONE) +- index++; ++ if (table) { ++ val = table[val]; ++ } else { ++ if (flags & CLK_MUX_INDEX_BIT) ++ val = 1 << index; ++ ++ if (flags & CLK_MUX_INDEX_ONE) ++ val++; + } + ++ return val; ++} ++EXPORT_SYMBOL_GPL(clk_mux_reindex); ++ ++static int clk_mux_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct clk_mux *mux = to_clk_mux(hw); ++ u32 val; ++ unsigned long flags = 0; ++ ++ index = clk_mux_reindex(index, mux->table, mux->flags); ++ + if (mux->lock) + spin_lock_irqsave(mux->lock, flags); + +@@ -102,21 +120,21 @@ static int clk_mux_set_parent(struct clk + } + + const struct clk_ops clk_mux_ops = { +- .get_parent = clk_mux_get_parent, ++ .get_parent = _clk_mux_get_parent, + .set_parent = clk_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, + }; + EXPORT_SYMBOL_GPL(clk_mux_ops); + + const struct clk_ops clk_mux_ro_ops = { +- .get_parent = clk_mux_get_parent, ++ .get_parent = _clk_mux_get_parent, + }; + EXPORT_SYMBOL_GPL(clk_mux_ro_ops); + + struct clk *clk_register_mux_table(struct device *dev, const char *name, + const char **parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, +- u8 clk_mux_flags, u32 *table, spinlock_t *lock) ++ u8 clk_mux_flags, unsigned int *table, spinlock_t *lock) + { + struct clk_mux *mux; + struct clk *clk; +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -409,7 +409,7 @@ void clk_unregister_divider(struct clk * + struct clk_mux { + struct clk_hw hw; + void __iomem *reg; +- u32 *table; ++ unsigned int *table; + u32 mask; + u8 shift; + u8 flags; +@@ -425,6 +425,11 @@ struct clk_mux { + extern const struct clk_ops clk_mux_ops; + extern const struct clk_ops clk_mux_ro_ops; + ++unsigned int clk_mux_get_parent(struct clk_hw *hw, unsigned int val, ++ unsigned int *table, unsigned long flags); ++unsigned int clk_mux_reindex(u8 index, unsigned int *table, ++ unsigned long flags); ++ + struct clk *clk_register_mux(struct device *dev, const char *name, + const char **parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, +@@ -433,7 +438,7 @@ struct clk *clk_register_mux(struct devi + struct clk *clk_register_mux_table(struct device *dev, const char *name, + const char **parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, +- u8 clk_mux_flags, u32 *table, spinlock_t *lock); ++ u8 clk_mux_flags, unsigned int *table, spinlock_t *lock); + + void clk_unregister_mux(struct clk *clk); + |