All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] clk: rockchip: implement the fraction divider branch type
@ 2014-08-26 22:54 Heiko Stübner
  2014-08-26 22:54 ` [PATCH 2/2] clk: rockchip: make rockchip_clk_register_branch static Heiko Stübner
  2014-09-02  1:10 ` [PATCH 1/2] clk: rockchip: implement the fraction divider branch type Mike Turquette
  0 siblings, 2 replies; 3+ messages in thread
From: Heiko Stübner @ 2014-08-26 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

Rockchip SoCs may provide fraction dividers for some clocks, mostly for
i2s and uarts. In contrast to the other registers, these do not use
the hiword-mask paradigm, but instead split the register into the upper
16 bit for the nominator and the lower 16 bit for the denominator.

The common clock framework got a generic fractional divider clock type
recently that can accomodate this setting easily. All currently known
fraction dividers have a separate gate too, therefore implement the
divider as composite using the ops-struct from fractional_divider clock
and add the gate if necessary.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/rockchip/clk.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 278cf9d..5db1ecf 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -103,6 +103,54 @@ struct clk *rockchip_clk_register_branch(const char *name,
 	return clk;
 }
 
+static struct clk *rockchip_clk_register_frac_branch(const char *name,
+		const char **parent_names, u8 num_parents, void __iomem *base,
+		int muxdiv_offset, u8 div_flags,
+		int gate_offset, u8 gate_shift, u8 gate_flags,
+		unsigned long flags, spinlock_t *lock)
+{
+	struct clk *clk;
+	struct clk_gate *gate = NULL;
+	struct clk_fractional_divider *div = NULL;
+	const struct clk_ops *div_ops = NULL, *gate_ops = NULL;
+
+	if (gate_offset >= 0) {
+		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+		if (!gate)
+			return ERR_PTR(-ENOMEM);
+
+		gate->flags = gate_flags;
+		gate->reg = base + gate_offset;
+		gate->bit_idx = gate_shift;
+		gate->lock = lock;
+		gate_ops = &clk_gate_ops;
+	}
+
+	if (muxdiv_offset < 0)
+		return ERR_PTR(-EINVAL);
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->flags = div_flags;
+	div->reg = base + muxdiv_offset;
+	div->mshift = 16;
+	div->mmask = 0xffff0000;
+	div->nshift = 0;
+	div->nmask = 0xffff;
+	div->lock = lock;
+	div_ops = &clk_fractional_divider_ops;
+
+	clk = clk_register_composite(NULL, name, parent_names, num_parents,
+				     NULL, NULL,
+				     &div->hw, div_ops,
+				     gate ? &gate->hw : NULL, gate_ops,
+				     flags);
+
+	return clk;
+}
+
 static DEFINE_SPINLOCK(clk_lock);
 static struct clk **clk_table;
 static void __iomem *reg_base;
@@ -197,8 +245,14 @@ void __init rockchip_clk_register_branches(
 					list->div_flags, &clk_lock);
 			break;
 		case branch_fraction_divider:
-			/* unimplemented */
-			continue;
+			/* keep all gates untouched for now */
+			flags |= CLK_IGNORE_UNUSED;
+
+			clk = rockchip_clk_register_frac_branch(list->name,
+				list->parent_names, list->num_parents,
+				reg_base, list->muxdiv_offset, list->div_flags,
+				list->gate_offset, list->gate_shift,
+				list->gate_flags, flags, &clk_lock);
 			break;
 		case branch_gate:
 			flags |= CLK_SET_RATE_PARENT;
-- 
2.0.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] clk: rockchip: make rockchip_clk_register_branch static
  2014-08-26 22:54 [PATCH 1/2] clk: rockchip: implement the fraction divider branch type Heiko Stübner
@ 2014-08-26 22:54 ` Heiko Stübner
  2014-09-02  1:10 ` [PATCH 1/2] clk: rockchip: implement the fraction divider branch type Mike Turquette
  1 sibling, 0 replies; 3+ messages in thread
From: Heiko Stübner @ 2014-08-26 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

It is only used locally in clk/rockchip/clk.c and thus can be static.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/rockchip/clk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 5db1ecf..5c9abd7 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -37,7 +37,7 @@
  *
  * sometimes without one of those components.
  */
-struct clk *rockchip_clk_register_branch(const char *name,
+static struct clk *rockchip_clk_register_branch(const char *name,
 		const char **parent_names, u8 num_parents, void __iomem *base,
 		int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags,
 		u8 div_shift, u8 div_width, u8 div_flags,
-- 
2.0.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 1/2] clk: rockchip: implement the fraction divider branch type
  2014-08-26 22:54 [PATCH 1/2] clk: rockchip: implement the fraction divider branch type Heiko Stübner
  2014-08-26 22:54 ` [PATCH 2/2] clk: rockchip: make rockchip_clk_register_branch static Heiko Stübner
@ 2014-09-02  1:10 ` Mike Turquette
  1 sibling, 0 replies; 3+ messages in thread
From: Mike Turquette @ 2014-09-02  1:10 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Heiko St?bner (2014-08-26 15:54:21)
> Rockchip SoCs may provide fraction dividers for some clocks, mostly for
> i2s and uarts. In contrast to the other registers, these do not use
> the hiword-mask paradigm, but instead split the register into the upper
> 16 bit for the nominator and the lower 16 bit for the denominator.
> 
> The common clock framework got a generic fractional divider clock type
> recently that can accomodate this setting easily. All currently known
> fraction dividers have a separate gate too, therefore implement the
> divider as composite using the ops-struct from fractional_divider clock
> and add the gate if necessary.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

Applied to clk-next.

Regards,
Mike

> ---
>  drivers/clk/rockchip/clk.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 56 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
> index 278cf9d..5db1ecf 100644
> --- a/drivers/clk/rockchip/clk.c
> +++ b/drivers/clk/rockchip/clk.c
> @@ -103,6 +103,54 @@ struct clk *rockchip_clk_register_branch(const char *name,
>         return clk;
>  }
>  
> +static struct clk *rockchip_clk_register_frac_branch(const char *name,
> +               const char **parent_names, u8 num_parents, void __iomem *base,
> +               int muxdiv_offset, u8 div_flags,
> +               int gate_offset, u8 gate_shift, u8 gate_flags,
> +               unsigned long flags, spinlock_t *lock)
> +{
> +       struct clk *clk;
> +       struct clk_gate *gate = NULL;
> +       struct clk_fractional_divider *div = NULL;
> +       const struct clk_ops *div_ops = NULL, *gate_ops = NULL;
> +
> +       if (gate_offset >= 0) {
> +               gate = kzalloc(sizeof(*gate), GFP_KERNEL);
> +               if (!gate)
> +                       return ERR_PTR(-ENOMEM);
> +
> +               gate->flags = gate_flags;
> +               gate->reg = base + gate_offset;
> +               gate->bit_idx = gate_shift;
> +               gate->lock = lock;
> +               gate_ops = &clk_gate_ops;
> +       }
> +
> +       if (muxdiv_offset < 0)
> +               return ERR_PTR(-EINVAL);
> +
> +       div = kzalloc(sizeof(*div), GFP_KERNEL);
> +       if (!div)
> +               return ERR_PTR(-ENOMEM);
> +
> +       div->flags = div_flags;
> +       div->reg = base + muxdiv_offset;
> +       div->mshift = 16;
> +       div->mmask = 0xffff0000;
> +       div->nshift = 0;
> +       div->nmask = 0xffff;
> +       div->lock = lock;
> +       div_ops = &clk_fractional_divider_ops;
> +
> +       clk = clk_register_composite(NULL, name, parent_names, num_parents,
> +                                    NULL, NULL,
> +                                    &div->hw, div_ops,
> +                                    gate ? &gate->hw : NULL, gate_ops,
> +                                    flags);
> +
> +       return clk;
> +}
> +
>  static DEFINE_SPINLOCK(clk_lock);
>  static struct clk **clk_table;
>  static void __iomem *reg_base;
> @@ -197,8 +245,14 @@ void __init rockchip_clk_register_branches(
>                                         list->div_flags, &clk_lock);
>                         break;
>                 case branch_fraction_divider:
> -                       /* unimplemented */
> -                       continue;
> +                       /* keep all gates untouched for now */
> +                       flags |= CLK_IGNORE_UNUSED;
> +
> +                       clk = rockchip_clk_register_frac_branch(list->name,
> +                               list->parent_names, list->num_parents,
> +                               reg_base, list->muxdiv_offset, list->div_flags,
> +                               list->gate_offset, list->gate_shift,
> +                               list->gate_flags, flags, &clk_lock);
>                         break;
>                 case branch_gate:
>                         flags |= CLK_SET_RATE_PARENT;
> -- 
> 2.0.1
> 
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-09-02  1:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-26 22:54 [PATCH 1/2] clk: rockchip: implement the fraction divider branch type Heiko Stübner
2014-08-26 22:54 ` [PATCH 2/2] clk: rockchip: make rockchip_clk_register_branch static Heiko Stübner
2014-09-02  1:10 ` [PATCH 1/2] clk: rockchip: implement the fraction divider branch type Mike Turquette

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.