From: maxime.ripard@free-electrons.com (Maxime Ripard)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 4/7] clk: sunxi: unify sun6i AHB1 clock with proper PLL6 pre-divider
Date: Tue, 30 Sep 2014 17:54:15 +0200 [thread overview]
Message-ID: <20140930155415.GO4081@lukather> (raw)
In-Reply-To: <1411807795-6575-5-git-send-email-wens@csie.org>
On Sat, Sep 27, 2014 at 04:49:52PM +0800, Chen-Yu Tsai wrote:
> This patch unifies the sun6i AHB1 clock, originally supported
> with separate mux and divider clks. It also adds support for
> the pre-divider on the PLL6 input, thus allowing the clock to
> be muxed to PLL6 with proper clock rate calculation.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> Documentation/devicetree/bindings/clock/sunxi.txt | 2 +-
> drivers/clk/sunxi/clk-sunxi.c | 209 ++++++++++++++++++++++
> 2 files changed, 210 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index 0d84f4b..e862818 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -23,7 +23,7 @@ Required properties:
> "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
> "allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
> "allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31
> - "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31
> + "allwinner,sun6i-a31-ahb1-clk" - for the AHB1 clock on A31
> "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
> "allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
> "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 9caebff..7151e2c 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -19,6 +19,7 @@
> #include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/reset-controller.h>
> +#include <linux/log2.h>
>
> #include "clk-factors.h"
>
> @@ -1357,3 +1358,211 @@ static void __init sun6i_init_clocks(struct device_node *node)
> }
> CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
> CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
> +
> +
Drop the extra newline
> +/**
> + * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk
> + */
> +
> +#define SUN6I_AHB1_MAX_PARENTS 4
> +#define SUN6I_AHB1_MUX_PARENT_PLL6 3
> +#define SUN6I_AHB1_MUX_SHIFT 12
> +#define SUN6I_AHB1_MUX_MASK 0x3
> +#define SUN6I_AHB1_MUX_GET_PARENT(reg) ((reg >> SUN6I_AHB1_MUX_SHIFT) & \
> + SUN6I_AHB1_MUX_MASK)
> +#define SUN6I_AHB1_DIV_SHIFT 4
> +#define SUN6I_AHB1_DIV_MASK 0x3
> +#define SUN6I_AHB1_DIV_GET(reg) ((reg >> SUN6I_AHB1_DIV_SHIFT) & \
> + SUN6I_AHB1_DIV_MASK)
> +#define SUN6I_AHB1_DIV_SET(reg, div) ((reg & ~(SUN6I_AHB1_DIV_MASK << \
> + SUN6I_AHB1_DIV_SHIFT)) | \
> + (div << SUN6I_AHB1_DIV_SHIFT))
> +#define SUN6I_AHB1_PLL6_DIV_SHIFT 6
> +#define SUN6I_AHB1_PLL6_DIV_MASK 0x3
> +#define SUN6I_AHB1_PLL6_DIV_GET(reg) ((reg >> SUN6I_AHB1_PLL6_DIV_SHIFT) & \
> + SUN6I_AHB1_PLL6_DIV_MASK)
> +#define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & \
> + ~(SUN6I_AHB1_PLL6_DIV_MASK << \
> + SUN6I_AHB1_PLL6_DIV_SHIFT)) | \
> + (div << SUN6I_AHB1_PLL6_DIV_SHIFT))
Your indentation looks really odd, and the masks you have should
really point to the actual mask, and not just the number of bits.
> +
> +struct sun6i_ahb1_clk {
> + struct clk_hw hw;
> + void __iomem *reg;
> +};
> +
> +#define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw)
> +
> +static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
> + unsigned long rate;
> + u32 reg;
> +
> + /* Fetch the register value */
> + reg = readl(ahb1->reg);
> +
> + /* apply pre-divider first if parent is pll6 */
> + if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6)
> + parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1;
> +
> + /* clk divider */
> + rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg);
> +
> + return rate;
> +}
> +
> +static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp,
> + u8 parent, unsigned long parent_rate)
> +{
> + u8 div, calcp, calcm = 1;
> +
> + /* clock can only divide, so we will never be able to achieve
> + * frequencies higher than the parent frequency */
Wrong multiline comment style
> + if (parent_rate && rate > parent_rate)
> + rate = parent_rate;
> +
> + div = DIV_ROUND_UP(parent_rate, rate);
> +
> + /* calculate pre-divider if parent is pll6 */
> + if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) {
> + if (div < 4)
> + calcp = 0;
> + else if (div / 2 < 4)
> + calcp = 1;
> + else if (div / 4 < 4)
> + calcp = 2;
> + else
> + calcp = 3;
> +
> + calcm = DIV_ROUND_UP(div, 1 << calcp);
> + } else {
> + calcp = __roundup_pow_of_two(div);
> + calcp = calcp > 3 ? 3 : calcp;
> + }
> +
> + if (divp) {
> + *divp = calcp;
> + *pre_divp = calcm - 1;
> + }
> +
> + return (parent_rate / calcm) >> calcp;
> +}
> +
> +static long sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *best_parent_rate,
> + struct clk **best_parent_clk)
> +{
> + struct clk *clk = hw->clk, *parent, *best_parent = NULL;
> + int i, num_parents;
> + unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
> +
> + /* find the parent that can help provide the fastest rate <= rate */
> + num_parents = __clk_get_num_parents(clk);
> + for (i = 0; i < num_parents; i++) {
> + parent = clk_get_parent_by_index(clk, i);
> + if (!parent)
> + continue;
> + if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
> + parent_rate = __clk_round_rate(parent, rate);
> + else
> + parent_rate = __clk_get_rate(parent);
> +
> + child_rate = sun6i_ahb1_clk_round(rate, NULL, NULL, i,
> + parent_rate);
> +
> + if (child_rate <= rate && child_rate > best_child_rate) {
> + best_parent = parent;
> + best = parent_rate;
> + best_child_rate = child_rate;
> + }
> + }
> +
> + if (best_parent)
> + *best_parent_clk = best_parent;
> + *best_parent_rate = best;
> +
> + return best_child_rate;
> +}
> +
> +static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
> + unsigned long flags;
> + u8 div, pre_div, parent;
> + u32 reg;
> +
> + spin_lock_irqsave(&clk_lock, flags);
Isn't that already taken by the composite clock?
> +
> + reg = readl(ahb1->reg);
> +
> + /* need to know which parent is used to apply pre-divider */
> + parent = SUN6I_AHB1_MUX_GET_PARENT(reg);
> + sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate);
Haven't you called that already in determine_rate?
> +
> + reg = SUN6I_AHB1_DIV_SET(reg, div);
> + reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div);
> + writel(reg, ahb1->reg);
> +
> + spin_unlock_irqrestore(&clk_lock, flags);
> +
> + return 0;
> +}
> +
> +static const struct clk_ops sun6i_ahb1_clk_ops = {
> + .determine_rate = sun6i_ahb1_clk_determine_rate,
> + .recalc_rate = sun6i_ahb1_clk_recalc_rate,
> + .set_rate = sun6i_ahb1_clk_set_rate,
> +};
> +
> +static void __init sun6i_ahb1_clk_setup(struct device_node *node)
> +{
> + struct clk *clk;
> + struct sun6i_ahb1_clk *ahb1;
> + struct clk_mux *mux;
> + const char *clk_name = node->name;
> + const char *parents[SUN6I_AHB1_MAX_PARENTS];
> + void __iomem *reg;
> + int i = 0;
> +
> + reg = of_iomap(node, 0);
of_io_request_and_map please :)
> +
> + /* we have a mux, we will have >1 parents */
> + while (i < SUN6I_AHB1_MAX_PARENTS &&
> + (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
> + i++;
> +
> + of_property_read_string(node, "clock-output-names", &clk_name);
> +
> + ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL);
> + if (!ahb1)
> + return;
> +
> + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
> + if (!mux) {
> + kfree(ahb1);
> + return;
> + }
> +
> + /* set up clock properties */
> + mux->reg = reg;
> + mux->shift = SUN6I_AHB1_MUX_SHIFT;
> + mux->mask = SUN6I_AHB1_MUX_MASK;
> + mux->lock = &clk_lock;
> + ahb1->reg = reg;
> +
> + clk = clk_register_composite(NULL, clk_name, parents, i,
> + &mux->hw, &clk_mux_ops,
> + &ahb1->hw, &sun6i_ahb1_clk_ops,
> + NULL, NULL, 0);
> +
> + if (!IS_ERR(clk)) {
> + of_clk_add_provider(node, of_clk_src_simple_get, clk);
> + clk_register_clkdev(clk, clk_name, NULL);
> + }
> +}
> +
> +CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk",
> + sun6i_ahb1_clk_setup);
> --
> 2.1.1
>
Thanks,
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140930/c0d611b5/attachment-0001.sig>
WARNING: multiple messages have this Message-ID (diff)
From: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
To: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Cc: Mike Turquette
<mturquette-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
Emilio Lopez <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>,
Dan Williams
<dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Grant Likely
<grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v2 4/7] clk: sunxi: unify sun6i AHB1 clock with proper PLL6 pre-divider
Date: Tue, 30 Sep 2014 17:54:15 +0200 [thread overview]
Message-ID: <20140930155415.GO4081@lukather> (raw)
In-Reply-To: <1411807795-6575-5-git-send-email-wens-jdAy2FN1RRM@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 8900 bytes --]
On Sat, Sep 27, 2014 at 04:49:52PM +0800, Chen-Yu Tsai wrote:
> This patch unifies the sun6i AHB1 clock, originally supported
> with separate mux and divider clks. It also adds support for
> the pre-divider on the PLL6 input, thus allowing the clock to
> be muxed to PLL6 with proper clock rate calculation.
>
> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> ---
> Documentation/devicetree/bindings/clock/sunxi.txt | 2 +-
> drivers/clk/sunxi/clk-sunxi.c | 209 ++++++++++++++++++++++
> 2 files changed, 210 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
> index 0d84f4b..e862818 100644
> --- a/Documentation/devicetree/bindings/clock/sunxi.txt
> +++ b/Documentation/devicetree/bindings/clock/sunxi.txt
> @@ -23,7 +23,7 @@ Required properties:
> "allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
> "allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
> "allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31
> - "allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31
> + "allwinner,sun6i-a31-ahb1-clk" - for the AHB1 clock on A31
> "allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
> "allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
> "allwinner,sun4i-a10-apb0-clk" - for the APB0 clock
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index 9caebff..7151e2c 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -19,6 +19,7 @@
> #include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/reset-controller.h>
> +#include <linux/log2.h>
>
> #include "clk-factors.h"
>
> @@ -1357,3 +1358,211 @@ static void __init sun6i_init_clocks(struct device_node *node)
> }
> CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks);
> CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks);
> +
> +
Drop the extra newline
> +/**
> + * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk
> + */
> +
> +#define SUN6I_AHB1_MAX_PARENTS 4
> +#define SUN6I_AHB1_MUX_PARENT_PLL6 3
> +#define SUN6I_AHB1_MUX_SHIFT 12
> +#define SUN6I_AHB1_MUX_MASK 0x3
> +#define SUN6I_AHB1_MUX_GET_PARENT(reg) ((reg >> SUN6I_AHB1_MUX_SHIFT) & \
> + SUN6I_AHB1_MUX_MASK)
> +#define SUN6I_AHB1_DIV_SHIFT 4
> +#define SUN6I_AHB1_DIV_MASK 0x3
> +#define SUN6I_AHB1_DIV_GET(reg) ((reg >> SUN6I_AHB1_DIV_SHIFT) & \
> + SUN6I_AHB1_DIV_MASK)
> +#define SUN6I_AHB1_DIV_SET(reg, div) ((reg & ~(SUN6I_AHB1_DIV_MASK << \
> + SUN6I_AHB1_DIV_SHIFT)) | \
> + (div << SUN6I_AHB1_DIV_SHIFT))
> +#define SUN6I_AHB1_PLL6_DIV_SHIFT 6
> +#define SUN6I_AHB1_PLL6_DIV_MASK 0x3
> +#define SUN6I_AHB1_PLL6_DIV_GET(reg) ((reg >> SUN6I_AHB1_PLL6_DIV_SHIFT) & \
> + SUN6I_AHB1_PLL6_DIV_MASK)
> +#define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & \
> + ~(SUN6I_AHB1_PLL6_DIV_MASK << \
> + SUN6I_AHB1_PLL6_DIV_SHIFT)) | \
> + (div << SUN6I_AHB1_PLL6_DIV_SHIFT))
Your indentation looks really odd, and the masks you have should
really point to the actual mask, and not just the number of bits.
> +
> +struct sun6i_ahb1_clk {
> + struct clk_hw hw;
> + void __iomem *reg;
> +};
> +
> +#define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw)
> +
> +static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
> + unsigned long rate;
> + u32 reg;
> +
> + /* Fetch the register value */
> + reg = readl(ahb1->reg);
> +
> + /* apply pre-divider first if parent is pll6 */
> + if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6)
> + parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1;
> +
> + /* clk divider */
> + rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg);
> +
> + return rate;
> +}
> +
> +static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp,
> + u8 parent, unsigned long parent_rate)
> +{
> + u8 div, calcp, calcm = 1;
> +
> + /* clock can only divide, so we will never be able to achieve
> + * frequencies higher than the parent frequency */
Wrong multiline comment style
> + if (parent_rate && rate > parent_rate)
> + rate = parent_rate;
> +
> + div = DIV_ROUND_UP(parent_rate, rate);
> +
> + /* calculate pre-divider if parent is pll6 */
> + if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) {
> + if (div < 4)
> + calcp = 0;
> + else if (div / 2 < 4)
> + calcp = 1;
> + else if (div / 4 < 4)
> + calcp = 2;
> + else
> + calcp = 3;
> +
> + calcm = DIV_ROUND_UP(div, 1 << calcp);
> + } else {
> + calcp = __roundup_pow_of_two(div);
> + calcp = calcp > 3 ? 3 : calcp;
> + }
> +
> + if (divp) {
> + *divp = calcp;
> + *pre_divp = calcm - 1;
> + }
> +
> + return (parent_rate / calcm) >> calcp;
> +}
> +
> +static long sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *best_parent_rate,
> + struct clk **best_parent_clk)
> +{
> + struct clk *clk = hw->clk, *parent, *best_parent = NULL;
> + int i, num_parents;
> + unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0;
> +
> + /* find the parent that can help provide the fastest rate <= rate */
> + num_parents = __clk_get_num_parents(clk);
> + for (i = 0; i < num_parents; i++) {
> + parent = clk_get_parent_by_index(clk, i);
> + if (!parent)
> + continue;
> + if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT)
> + parent_rate = __clk_round_rate(parent, rate);
> + else
> + parent_rate = __clk_get_rate(parent);
> +
> + child_rate = sun6i_ahb1_clk_round(rate, NULL, NULL, i,
> + parent_rate);
> +
> + if (child_rate <= rate && child_rate > best_child_rate) {
> + best_parent = parent;
> + best = parent_rate;
> + best_child_rate = child_rate;
> + }
> + }
> +
> + if (best_parent)
> + *best_parent_clk = best_parent;
> + *best_parent_rate = best;
> +
> + return best_child_rate;
> +}
> +
> +static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw);
> + unsigned long flags;
> + u8 div, pre_div, parent;
> + u32 reg;
> +
> + spin_lock_irqsave(&clk_lock, flags);
Isn't that already taken by the composite clock?
> +
> + reg = readl(ahb1->reg);
> +
> + /* need to know which parent is used to apply pre-divider */
> + parent = SUN6I_AHB1_MUX_GET_PARENT(reg);
> + sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate);
Haven't you called that already in determine_rate?
> +
> + reg = SUN6I_AHB1_DIV_SET(reg, div);
> + reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div);
> + writel(reg, ahb1->reg);
> +
> + spin_unlock_irqrestore(&clk_lock, flags);
> +
> + return 0;
> +}
> +
> +static const struct clk_ops sun6i_ahb1_clk_ops = {
> + .determine_rate = sun6i_ahb1_clk_determine_rate,
> + .recalc_rate = sun6i_ahb1_clk_recalc_rate,
> + .set_rate = sun6i_ahb1_clk_set_rate,
> +};
> +
> +static void __init sun6i_ahb1_clk_setup(struct device_node *node)
> +{
> + struct clk *clk;
> + struct sun6i_ahb1_clk *ahb1;
> + struct clk_mux *mux;
> + const char *clk_name = node->name;
> + const char *parents[SUN6I_AHB1_MAX_PARENTS];
> + void __iomem *reg;
> + int i = 0;
> +
> + reg = of_iomap(node, 0);
of_io_request_and_map please :)
> +
> + /* we have a mux, we will have >1 parents */
> + while (i < SUN6I_AHB1_MAX_PARENTS &&
> + (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
> + i++;
> +
> + of_property_read_string(node, "clock-output-names", &clk_name);
> +
> + ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL);
> + if (!ahb1)
> + return;
> +
> + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
> + if (!mux) {
> + kfree(ahb1);
> + return;
> + }
> +
> + /* set up clock properties */
> + mux->reg = reg;
> + mux->shift = SUN6I_AHB1_MUX_SHIFT;
> + mux->mask = SUN6I_AHB1_MUX_MASK;
> + mux->lock = &clk_lock;
> + ahb1->reg = reg;
> +
> + clk = clk_register_composite(NULL, clk_name, parents, i,
> + &mux->hw, &clk_mux_ops,
> + &ahb1->hw, &sun6i_ahb1_clk_ops,
> + NULL, NULL, 0);
> +
> + if (!IS_ERR(clk)) {
> + of_clk_add_provider(node, of_clk_src_simple_get, clk);
> + clk_register_clkdev(clk, clk_name, NULL);
> + }
> +}
> +
> +CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk",
> + sun6i_ahb1_clk_setup);
> --
> 2.1.1
>
Thanks,
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
next prev parent reply other threads:[~2014-09-30 15:54 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-27 8:49 [PATCH v2 0/6] clk: sun6i: Unify AHB1 clock and fix rate calculation Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-27 8:49 ` [PATCH v2 1/7] clk: sunxi: Specify number of child clocks for divs clocks Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-30 15:40 ` Maxime Ripard
2014-09-30 15:40 ` Maxime Ripard
2014-09-30 15:56 ` Chen-Yu Tsai
2014-09-30 15:56 ` Chen-Yu Tsai
2014-10-03 14:05 ` Maxime Ripard
2014-10-03 14:05 ` Maxime Ripard
2014-09-27 8:49 ` [PATCH v2 2/7] clk: sunxi: Implement A31 PLL6 as a divs clock for 2x output Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-30 15:39 ` Maxime Ripard
2014-09-30 15:39 ` Maxime Ripard
2014-09-30 15:50 ` Chen-Yu Tsai
2014-09-30 15:50 ` Chen-Yu Tsai
2014-09-27 8:49 ` [PATCH v2 3/7] ARM: sun6i: DT: Add PLL6 multiple outputs Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-27 8:49 ` [PATCH v2 4/7] clk: sunxi: unify sun6i AHB1 clock with proper PLL6 pre-divider Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-30 15:54 ` Maxime Ripard [this message]
2014-09-30 15:54 ` Maxime Ripard
2014-10-06 12:58 ` Chen-Yu Tsai
2014-10-06 12:58 ` Chen-Yu Tsai
2014-10-06 13:44 ` Chen-Yu Tsai
2014-10-06 13:44 ` Chen-Yu Tsai
2014-09-27 8:49 ` [PATCH v2 5/7] ARM: dts: sun6i: Unify ahb1 clock nodes Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-27 8:49 ` [PATCH v2 6/7] ARM: dts: sun8i: " Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-27 8:49 ` [PATCH v2 7/7] ARM: dts: sun6i: Add required ahb1 clock parent and rates for dma controller Chen-Yu Tsai
2014-09-27 8:49 ` Chen-Yu Tsai
2014-09-30 15:55 ` Maxime Ripard
2014-09-30 15:55 ` Maxime Ripard
2014-10-09 3:01 ` Chen-Yu Tsai
2014-10-09 3:01 ` Chen-Yu Tsai
2014-10-13 10:02 ` Maxime Ripard
2014-10-13 10:02 ` Maxime Ripard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140930155415.GO4081@lukather \
--to=maxime.ripard@free-electrons.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.