diff options
author | Zoltan Herpai <wigyori@uid0.hu> | 2014-02-05 08:42:28 +0000 |
---|---|---|
committer | Zoltan Herpai <wigyori@uid0.hu> | 2014-02-05 08:42:28 +0000 |
commit | c957af0a0f6a2c45b9b3c84f45f4a3aa44d293c6 (patch) | |
tree | f8e3bda571dab7f80fdd240541ed8bd1d39b179e /target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch | |
parent | 66543935db1d7eab23fc43b381e56dbd4424b499 (diff) | |
download | master-31e0f0ae-c957af0a0f6a2c45b9b3c84f45f4a3aa44d293c6.tar.gz master-31e0f0ae-c957af0a0f6a2c45b9b3c84f45f4a3aa44d293c6.tar.bz2 master-31e0f0ae-c957af0a0f6a2c45b9b3c84f45f4a3aa44d293c6.zip |
sunxi: initial 3.13 support
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
SVN-Revision: 39471
Diffstat (limited to 'target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch')
-rw-r--r-- | target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch b/target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch new file mode 100644 index 0000000000..6a6974e637 --- /dev/null +++ b/target/linux/sunxi/patches-3.13/113-clk-sunxi-register-factors-clocks.patch @@ -0,0 +1,232 @@ +From 9212bc4a3752e9a4db2f73afd99278eb28e5dcff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Emilio=20L=C3=B3pez?= <emilio@elopez.com.ar> +Date: Mon, 23 Dec 2013 00:32:32 -0300 +Subject: [PATCH] clk: sunxi: register factors clocks behind composite +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This commit reworks factors clock registration to be done behind a +composite clock. This allows us to additionally add a gate, mux or +divisors, as it will be needed by some future PLLs. + +Signed-off-by: Emilio López <emilio@elopez.com.ar> +Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> +--- + drivers/clk/sunxi/clk-factors.c | 63 +------------------------------------ + drivers/clk/sunxi/clk-factors.h | 16 +++++----- + drivers/clk/sunxi/clk-sunxi.c | 70 ++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 76 insertions(+), 73 deletions(-) + +diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c +index f05207a..9e23264 100644 +--- a/drivers/clk/sunxi/clk-factors.c ++++ b/drivers/clk/sunxi/clk-factors.c +@@ -30,14 +30,6 @@ + * parent - fixed parent. No clk_set_parent support + */ + +-struct clk_factors { +- struct clk_hw hw; +- void __iomem *reg; +- struct clk_factors_config *config; +- void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); +- spinlock_t *lock; +-}; +- + #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) + + #define SETMASK(len, pos) (((1U << (len)) - 1) << (pos)) +@@ -120,61 +112,8 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + +-static const struct clk_ops clk_factors_ops = { ++const struct clk_ops clk_factors_ops = { + .recalc_rate = clk_factors_recalc_rate, + .round_rate = clk_factors_round_rate, + .set_rate = clk_factors_set_rate, + }; +- +-/** +- * clk_register_factors - register a factors clock with +- * the clock framework +- * @dev: device registering this clock +- * @name: name of this clock +- * @parent_name: name of clock's parent +- * @flags: framework-specific flags +- * @reg: register address to adjust factors +- * @config: shift and width of factors n, k, m and p +- * @get_factors: function to calculate the factors for a given frequency +- * @lock: shared register lock for this clock +- */ +-struct clk *clk_register_factors(struct device *dev, const char *name, +- const char *parent_name, +- unsigned long flags, void __iomem *reg, +- struct clk_factors_config *config, +- void (*get_factors)(u32 *rate, u32 parent, +- u8 *n, u8 *k, u8 *m, u8 *p), +- spinlock_t *lock) +-{ +- struct clk_factors *factors; +- struct clk *clk; +- struct clk_init_data init; +- +- /* allocate the factors */ +- factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); +- if (!factors) { +- pr_err("%s: could not allocate factors clk\n", __func__); +- return ERR_PTR(-ENOMEM); +- } +- +- init.name = name; +- init.ops = &clk_factors_ops; +- init.flags = flags; +- init.parent_names = (parent_name ? &parent_name : NULL); +- init.num_parents = (parent_name ? 1 : 0); +- +- /* struct clk_factors assignments */ +- factors->reg = reg; +- factors->config = config; +- factors->lock = lock; +- factors->hw.init = &init; +- factors->get_factors = get_factors; +- +- /* register the clock */ +- clk = clk_register(dev, &factors->hw); +- +- if (IS_ERR(clk)) +- kfree(factors); +- +- return clk; +-} +diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h +index f49851c..02e1a43 100644 +--- a/drivers/clk/sunxi/clk-factors.h ++++ b/drivers/clk/sunxi/clk-factors.h +@@ -17,11 +17,13 @@ struct clk_factors_config { + u8 pwidth; + }; + +-struct clk *clk_register_factors(struct device *dev, const char *name, +- const char *parent_name, +- unsigned long flags, void __iomem *reg, +- struct clk_factors_config *config, +- void (*get_factors) (u32 *rate, u32 parent_rate, +- u8 *n, u8 *k, u8 *m, u8 *p), +- spinlock_t *lock); ++struct clk_factors { ++ struct clk_hw hw; ++ void __iomem *reg; ++ struct clk_factors_config *config; ++ void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); ++ spinlock_t *lock; ++}; ++ ++extern const struct clk_ops clk_factors_ops; + #endif +diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c +index 492ef0e..7dc39a6 100644 +--- a/drivers/clk/sunxi/clk-sunxi.c ++++ b/drivers/clk/sunxi/clk-sunxi.c +@@ -23,6 +23,9 @@ + + static DEFINE_SPINLOCK(clk_lock); + ++/* Maximum number of parents our clocks have */ ++#define SUNXI_MAX_PARENTS 5 ++ + /** + * sun4i_osc_clk_setup() - Setup function for gatable oscillator + */ +@@ -261,7 +264,11 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, + * sunxi_factors_clk_setup() - Setup function for factor clocks + */ + ++#define SUNXI_FACTORS_MUX_MASK 0x3 ++ + struct factors_data { ++ int enable; ++ int mux; + struct clk_factors_config *table; + void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); + }; +@@ -312,16 +319,71 @@ static void __init sunxi_factors_clk_setup(struct device_node *node, + struct factors_data *data) + { + struct clk *clk; ++ struct clk_factors *factors; ++ struct clk_gate *gate = NULL; ++ struct clk_mux *mux = NULL; ++ struct clk_hw *gate_hw = NULL; ++ struct clk_hw *mux_hw = NULL; + const char *clk_name = node->name; +- const char *parent; ++ const char *parents[SUNXI_MAX_PARENTS]; + void *reg; ++ int i = 0; + + reg = of_iomap(node, 0); + +- parent = of_clk_get_parent_name(node, 0); ++ /* if we have a mux, we will have >1 parents */ ++ while (i < SUNXI_MAX_PARENTS && ++ (parents[i] = of_clk_get_parent_name(node, i)) != NULL) ++ i++; ++ ++ factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); ++ if (!factors) ++ return; ++ ++ /* Add a gate if this factor clock can be gated */ ++ if (data->enable) { ++ gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); ++ if (!gate) { ++ kfree(factors); ++ return; ++ } ++ ++ /* set up gate properties */ ++ gate->reg = reg; ++ gate->bit_idx = data->enable; ++ gate->lock = &clk_lock; ++ gate_hw = &gate->hw; ++ } ++ ++ /* Add a mux if this factor clock can be muxed */ ++ if (data->mux) { ++ mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); ++ if (!mux) { ++ kfree(factors); ++ kfree(gate); ++ return; ++ } ++ ++ /* set up gate properties */ ++ mux->reg = reg; ++ mux->shift = data->mux; ++ mux->mask = SUNXI_FACTORS_MUX_MASK; ++ mux->lock = &clk_lock; ++ mux_hw = &mux->hw; ++ } ++ ++ /* set up factors properties */ ++ factors->reg = reg; ++ factors->config = data->table; ++ factors->get_factors = data->getter; ++ factors->lock = &clk_lock; + +- clk = clk_register_factors(NULL, clk_name, parent, 0, reg, +- data->table, data->getter, &clk_lock); ++ clk = clk_register_composite(NULL, clk_name, ++ parents, i, ++ mux_hw, &clk_mux_ops, ++ &factors->hw, &clk_factors_ops, ++ gate_hw, &clk_gate_ops, ++ i ? 0 : CLK_IS_ROOT); + + if (!IS_ERR(clk)) { + of_clk_add_provider(node, of_clk_src_simple_get, clk); +-- +1.8.5.1 + |