[PATCH v3 04/12] clk: Add regmap core helpers for enable/disable/is_enabled
Mike Turquette
mturquette at linaro.org
Wed Dec 18 23:50:50 EST 2013
Quoting Stephen Boyd (2013-10-16 00:40:06)
> The clock framework already has support for simple gate clocks
> but if drivers want to use the gate clock functionality they need
> to wrap the gate clock in another struct and chain the ops by
> calling the gate ops from their own custom ops. Plus the gate
> clock implementation only supports MMIO accessors so other bus
> type clocks don't benefit from the potential code reuse. Add some
> simple regmap helpers for enable/disable/is_enabled that drivers
> can use as drop in replacements for their clock ops or as simple
> functions they call from their own custom ops.
>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
> drivers/clk/clk.c | 70 ++++++++++++++++++++++++++++++++++++++++++++
> include/linux/clk-provider.h | 13 ++++++++
> 2 files changed, 83 insertions(+)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 8042c00..7cc8cb0 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -742,6 +742,76 @@ out:
> return best;
> }
>
> +/**
> + * clk_is_enabled_regmap - standard is_enabled() for regmap users
> + *
> + * @hw: clk to operate on
> + *
> + * Clocks that use regmap for their register I/O can set the
> + * enable_reg and enable_mask fields in their struct clk_hw and then use
> + * this as their is_enabled operation, saving some code.
> + */
> +int clk_is_enabled_regmap(struct clk_hw *hw)
> +{
> + unsigned int val;
> + int ret;
> +
> + ret = regmap_read(hw->regmap, hw->enable_reg, &val);
> + if (ret != 0)
> + return ret;
> +
> + if (hw->enable_is_inverted)
> + return (val & hw->enable_mask) == 0;
> + else
> + return (val & hw->enable_mask) != 0;
> +}
> +EXPORT_SYMBOL_GPL(clk_is_enabled_regmap);
> +
> +/**
> + * clk_enable_regmap - standard enable() for regmap users
> + *
> + * @hw: clk to operate on
> + *
> + * Clocks that use regmap for their register I/O can set the
> + * enable_reg and enable_mask fields in their struct clk_hw and then use
> + * this as their enable() operation, saving some code.
> + */
> +int clk_enable_regmap(struct clk_hw *hw)
> +{
> + unsigned int val;
> +
> + if (hw->enable_is_inverted)
> + val = 0;
> + else
> + val = hw->enable_mask;
> +
> + return regmap_update_bits(hw->regmap, hw->enable_reg,
> + hw->enable_mask, val);
> +}
> +EXPORT_SYMBOL_GPL(clk_enable_regmap);
> +
> +/**
> + * clk_disable_regmap - standard disable() for regmap users
> + *
> + * @hw: clk to operate on
> + *
> + * Clocks that use regmap for their register I/O can set the
> + * enable_reg and enable_mask fields in their struct clk_hw and then use
> + * this as their disable() operation, saving some code.
> + */
> +void clk_disable_regmap(struct clk_hw *hw)
> +{
> + unsigned int val;
> +
> + if (hw->enable_is_inverted)
> + val = hw->enable_mask;
> + else
> + val = 0;
> +
> + regmap_update_bits(hw->regmap, hw->enable_reg, hw->enable_mask, val);
> +}
> +EXPORT_SYMBOL_GPL(clk_disable_regmap);
> +
> /*** clk api ***/
>
> void __clk_unprepare(struct clk *clk)
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index 6ed62f1..4087a9b 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -177,11 +177,21 @@ struct clk_init_data {
> * with the common clock framework.
> *
> * @regmap: regmap to use for regmap helpers and/or by providers
> + *
> + * @enable_reg: register when using regmap enable/disable ops
> + *
> + * @enable_mask: mask when using regmap enable/disable ops
> + *
> + * @enable_is_inverted: flag to indicate set enable_mask bits to disable
> + * when using clock_enable_regmap and friends APIs.
> */
> struct clk_hw {
> struct clk *clk;
> const struct clk_init_data *init;
> struct regmap *regmap;
> + unsigned int enable_reg;
> + unsigned int enable_mask;
> + bool enable_is_inverted;
Thanks for submitting this patch.
Adding all of this stuff to struct clk_hw makes me a sad panda. You are
essentially sharing a common set of ops for clocks that use regmap as
their io operation back-end, and that is a good thing.
However, why not just do this as drivers/clk/clk-regmap.c, or
drivers/clk/clk-gate-regmap.c? Putting the clk_ops callback functions in
drivers/clk/clk.c is a little weird and putting those struct members
into struct clk_hw is definitely strange.
Regards,
Mike
> };
>
> /*
> @@ -447,6 +457,9 @@ struct clk *__clk_lookup(const char *name);
> long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
> unsigned long *best_parent_rate,
> struct clk **best_parent_p);
> +int clk_is_enabled_regmap(struct clk_hw *hw);
> +int clk_enable_regmap(struct clk_hw *hw);
> +void clk_disable_regmap(struct clk_hw *hw);
>
> /*
> * FIXME clock api without lock protection
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
>
More information about the linux-arm-kernel
mailing list