From: pgaikwad@nvidia.com (Prashant Gaikwad)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V2] clk: Add composite clock type
Date: Wed, 6 Feb 2013 08:25:00 +0530 [thread overview]
Message-ID: <5111C604.8070104@nvidia.com> (raw)
In-Reply-To: <20130205.122252.570646990867457667.hdoyu@nvidia.com>
On Tuesday 05 February 2013 03:52 PM, Hiroshi Doyu wrote:
> Prashant Gaikwad <pgaikwad@nvidia.com> wrote @ Tue, 5 Feb 2013 09:33:41 +0100:
>
>>> The members of "clk_composite_ops" seems to be always assigned
>>> statically. Istead of dynamically allocating/assigning, can't we just
>>> have "clk_composite_ops" statically as below?
>>>
>>> static struct clk_ops clk_composite_ops = {
>>> .get_parent = clk_composite_get_parent;
>>> .set_parent = clk_composite_set_parent;
>>> .recalc_rate = clk_composite_recalc_rate;
>>> .round_rate = clk_composite_round_rate;
>>> .set_rate = clk_composite_set_rate;
>>> .is_enabled = clk_composite_is_enabled;
>>> .enable = clk_composite_enable;
>>> .disable = clk_composite_disable;
>>> };
>>>
>>> struct clk *clk_register_composite(struct device *dev, const char *name,
>>> const char **parent_names, int num_parents,
>>> struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
>>> struct clk_hw *div_hw, const struct clk_ops *div_ops,
>>> struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
>>> unsigned long flags)
>>> {
>>> .....
>>>
>>> init.ops = &clk_composite_ops;
>> No, clk_ops depends on the clocks you are using. There could be a clock
>> with mux and gate while another one with mux and div.
> You are right. What about the following? We don't have to have similar
> copy of clk_composite_ops for each instances.
Clock framework takes decision depending on the ops availability and it
does not know if the clock is mux or gate.
For example,
if (clk->ops->enable) {
ret = clk->ops->enable(clk->hw);
if (ret) {
__clk_disable(clk->parent);
return ret;
}
}
in above case if clk_composite does not have gate clock then as per your
suggestion if it returns error value then it will fail and it is wrong.
Hence clock ops are populated depending on the clock types.
> diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
> index f30fb4b..8f88805 100644
> --- a/drivers/clk/clk-composite.c
> +++ b/drivers/clk/clk-composite.c
> @@ -27,6 +27,9 @@ static u8 clk_composite_get_parent(struct clk_hw *hw)
> const struct clk_ops *mux_ops = composite->mux_ops;
> struct clk_hw *mux_hw = composite->mux_hw;
>
> + if (!mux_hw->clk)
> + return -EINVAL;
> +
> mux_hw->clk = hw->clk;
>
It is wrong.
> return mux_ops->get_parent(mux_hw);
> @@ -38,6 +41,9 @@ static int clk_composite_set_parent(struct clk_hw *hw, u8 index)
> const struct clk_ops *mux_ops = composite->mux_ops;
> struct clk_hw *mux_hw = composite->mux_hw;
>
> + if (!mux_hw->clk)
> + return -EINVAL;
> +
> mux_hw->clk = hw->clk;
>
> return mux_ops->set_parent(mux_hw, index);
> @@ -50,6 +56,9 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
> const struct clk_ops *div_ops = composite->div_ops;
> struct clk_hw *div_hw = composite->div_hw;
>
> + if (!div_hw->clk)
> + return -EINVAL;
> +
> div_hw->clk = hw->clk;
>
> return div_ops->recalc_rate(div_hw, parent_rate);
> @@ -62,6 +71,9 @@ static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
> const struct clk_ops *div_ops = composite->div_ops;
> struct clk_hw *div_hw = composite->div_hw;
>
> + if (!div_hw->clk)
> + return -EINVAL;
> +
> div_hw->clk = hw->clk;
>
> return div_ops->round_rate(div_hw, rate, prate);
> @@ -74,6 +86,9 @@ static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
> const struct clk_ops *div_ops = composite->div_ops;
> struct clk_hw *div_hw = composite->div_hw;
>
> + if (!div_hw->clk)
> + return -EINVAL;
> +
> div_hw->clk = hw->clk;
>
> return div_ops->set_rate(div_hw, rate, parent_rate);
> @@ -85,6 +100,9 @@ static int clk_composite_is_enabled(struct clk_hw *hw)
> const struct clk_ops *gate_ops = composite->gate_ops;
> struct clk_hw *gate_hw = composite->gate_hw;
>
> + if (!gate_hw->clk)
> + return -EINVAL;
> +
> gate_hw->clk = hw->clk;
>
> return gate_ops->is_enabled(gate_hw);
> @@ -96,6 +114,9 @@ static int clk_composite_enable(struct clk_hw *hw)
> const struct clk_ops *gate_ops = composite->gate_ops;
> struct clk_hw *gate_hw = composite->gate_hw;
>
> + if (!gate_hw->clk)
> + return -EINVAL;
> +
> gate_hw->clk = hw->clk;
>
> return gate_ops->enable(gate_hw);
> @@ -107,11 +128,25 @@ static void clk_composite_disable(struct clk_hw *hw)
> const struct clk_ops *gate_ops = composite->gate_ops;
> struct clk_hw *gate_hw = composite->gate_hw;
>
> + if (!gate_hw->clk)
> + return -EINVAL;
> +
> gate_hw->clk = hw->clk;
>
> gate_ops->disable(gate_hw);
> }
>
> +static struct clk_ops clk_composite_ops = {
> + .get_parent = clk_composite_get_parent,
> + .set_parent = clk_composite_set_parent,
> + .recalc_rate = clk_composite_recalc_rate,
> + .round_rate = clk_composite_round_rate,
> + .set_rate = clk_composite_set_rate,
> + .is_enabled = clk_composite_is_enabled,
> + .enable = clk_composite_enable,
> + .disable = clk_composite_disable,
> +};
> +
> struct clk *clk_register_composite(struct device *dev, const char *name,
> const char **parent_names, int num_parents,
> struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
> @@ -135,14 +170,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
> init.parent_names = parent_names;
> init.num_parents = num_parents;
>
> - /* allocate the clock ops */
> - clk_composite_ops = kzalloc(sizeof(*clk_composite_ops), GFP_KERNEL);
> - if (!clk_composite_ops) {
> - pr_err("%s: could not allocate clk ops\n", __func__);
> - kfree(composite);
> - return ERR_PTR(-ENOMEM);
> - }
> -
> if (mux_hw && mux_ops) {
> if (!mux_ops->get_parent || !mux_ops->set_parent) {
> clk = ERR_PTR(-EINVAL);
> @@ -151,8 +178,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
>
> composite->mux_hw = mux_hw;
> composite->mux_ops = mux_ops;
> - clk_composite_ops->get_parent = clk_composite_get_parent;
> - clk_composite_ops->set_parent = clk_composite_set_parent;
> }
>
> if (div_hw && div_ops) {
> @@ -164,9 +189,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
>
> composite->div_hw = div_hw;
> composite->div_ops = div_ops;
> - clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
> - clk_composite_ops->round_rate = clk_composite_round_rate;
> - clk_composite_ops->set_rate = clk_composite_set_rate;
> }
>
> if (gate_hw && gate_ops) {
> @@ -178,12 +200,9 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
>
> composite->gate_hw = gate_hw;
> composite->gate_ops = gate_ops;
> - clk_composite_ops->is_enabled = clk_composite_is_enabled;
> - clk_composite_ops->enable = clk_composite_enable;
> - clk_composite_ops->disable = clk_composite_disable;
> }
>
> - init.ops = clk_composite_ops;
> + init.ops = &clk_composite_ops;
> composite->hw.init = &init;
>
> clk = clk_register(dev, &composite->hw);
> @@ -202,7 +221,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
> return clk;
>
> err:
> - kfree(clk_composite_ops);
> kfree(composite);
> return clk;
> }
next prev parent reply other threads:[~2013-02-06 2:55 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-04 8:11 [PATCH V2] clk: Add composite clock type Prashant Gaikwad
2013-02-04 9:37 ` Hiroshi Doyu
2013-02-05 8:33 ` Prashant Gaikwad
2013-02-05 10:22 ` Hiroshi Doyu
2013-02-05 10:38 ` Tomasz Figa
2013-02-05 11:15 ` Russell King - ARM Linux
2013-02-06 2:55 ` Prashant Gaikwad [this message]
2013-02-06 6:10 ` Hiroshi Doyu
2013-02-06 9:52 ` Prashant Gaikwad
2013-02-06 10:00 ` Hiroshi Doyu
2013-02-06 10:02 ` Tomasz Figa
2013-02-05 10:15 ` Tomasz Figa
2013-02-06 3:04 ` Prashant Gaikwad
2013-02-06 10:06 ` Tomasz Figa
2013-02-28 7:58 ` Prashant Gaikwad
2013-02-28 18:20 ` Stephen Warren
2013-03-13 16:30 ` Tomasz Figa
2013-03-19 12:04 ` Prashant Gaikwad
2013-02-05 10:50 ` Hiroshi Doyu
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=5111C604.8070104@nvidia.com \
--to=pgaikwad@nvidia.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).