All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dong Aisheng <dongas86@gmail.com>
To: Michael Turquette <mturquette@baylibre.com>
Cc: Dong Aisheng <aisheng.dong@nxp.com>,
	linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org,
	sboyd@codeaurora.org, shawnguo@kernel.org,
	linux-arm-kernel@lists.infradead.org, anson.huang@nxp.com
Subject: Re: [RESEND PATCH 4/8] clk: core: support clocks which requires parents on (part 2)
Date: Wed, 29 Jun 2016 21:59:56 +0800	[thread overview]
Message-ID: <20160629135955.GB29919@shlinux2> (raw)
In-Reply-To: <146681237910.35033.15404158884510204380@resonance>

Hi Mike,

On Fri, Jun 24, 2016 at 04:52:59PM -0700, Michael Turquette wrote:
> Hi Dong,
> 
> Quoting Dong Aisheng (2016-04-20 02:34:36)
> > On Freescale i.MX7D platform, all clocks operations, including
> > enable/disable, rate change and re-parent, requires its parent clock on.
> > Current clock core can not support it well.
> > This patch adding flag CLK_OPS_PARENT_ON to handle this special case in
> > clock core that enable its parent clock firstly for each operation and
> > disable it later after operation complete.
> > 
> > The patch part 2 fixes set clock rate and set parent while its parent
> > is off. The most special case is for set_parent() operation which requires
> > all parents including both old and new one to be enabled at the same time
> > during the operation.
> > 
> > Cc: Michael Turquette <mturquette@baylibre.com>
> > Cc: Stephen Boyd <sboyd@codeaurora.org>
> > Cc: Shawn Guo <shawnguo@kernel.org>
> > Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> > ---
> >  drivers/clk/clk.c | 45 ++++++++++++++++++++++++++++-----------------
> >  1 file changed, 28 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > index 1f054d1a..d6cef61 100644
> > --- a/drivers/clk/clk.c
> > +++ b/drivers/clk/clk.c
> > @@ -1174,7 +1174,7 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core,
> >         struct clk_core *old_parent = core->parent;
> >  
> >         /*
> > -        * Migrate prepare state between parents and prevent race with
> > +        * 1. Migrate prepare state between parents and prevent race with
> >          * clk_enable().
> >          *
> >          * If the clock is not prepared, then a race with
> > @@ -1189,13 +1189,16 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core,
> >          * hardware and software states.
> >          *
> >          * See also: Comment for clk_set_parent() below.
> > +        *
> > +        * 2. enable parent clocks for CLK_OPS_PARENT_ON clock
> >          */
> > -       if (core->prepare_count) {
> > -               clk_core_prepare(parent);
> > -               flags = clk_enable_lock();
> > -               clk_core_enable(parent);
> > -               clk_core_enable(core);
> > -               clk_enable_unlock(flags);
> > +       if (core->prepare_count || core->flags & CLK_OPS_PARENT_ON) {
> > +               clk_core_prepare_enable(parent);
> > +               if (core->prepare_count)
> > +                       clk_core_enable_lock(core);
> > +               else
> > +                       clk_core_prepare_enable(old_parent);
> 
> It took me a few seconds to figure out what I was looking at. The
> set_parent stuff is tricky enough already ... I think we should keep the
> state machine logic very simple. How about:
> 
> 	/* enable old_parent & parent if CLK_OPS_PARENT_ENABLE is set */
> 	if (core->flags & CLK_OPS_PARENT_ENABLE) {
> 		clk_core_prepare_enable(old_parent);
> 		clk_core_prepare_enable(parent);
> 	}
> 
> 	/* migrate prepare count if > 0 */
> 	if (core->prepare_count) {
> 		clk_core_prepare_enable(parent);
> 		clk_core_enable_lock(core);
> 	}
> 

Great suggestion! That looks much clearer.
Will update it in V2.

Thanks

Regards
Dong Aisheng

> > +
> >         }
> >  
> >         /* update the clk tree topology */
> > @@ -1210,18 +1213,16 @@ static void __clk_set_parent_after(struct clk_core *core,
> >                                    struct clk_core *parent,
> >                                    struct clk_core *old_parent)
> >  {
> > -       unsigned long flags;
> > -
> >         /*
> >          * Finish the migration of prepare state and undo the changes done
> >          * for preventing a race with clk_enable().
> >          */
> > -       if (core->prepare_count) {
> > -               flags = clk_enable_lock();
> > -               clk_core_disable(core);
> > -               clk_core_disable(old_parent);
> > -               clk_enable_unlock(flags);
> > -               clk_core_unprepare(old_parent);
> > +       if (core->prepare_count || core->flags & CLK_OPS_PARENT_ON) {
> > +               clk_core_disable_unprepare(old_parent);
> > +               if (core->prepare_count)
> > +                       clk_core_disable_lock(core);
> > +               else
> > +                       clk_core_disable_unprepare(parent);
> 
> Similarly, a more readable solution is:
> 
> 	/*
> 	 * Finish the migration of prepare state and undo the changes done
> 	 * for preventing a race with clk_enable().
> 	 */
> 	if (core->prepare_count) {
> 		clk_core_disable_lock(core);
> 		clk_core_disable_unprepare(old_parent);
> 
> 	/* re-balance ref counting if CLK_OPS_PARENT_ENABLE is set */
> 	if (core->flags & CLK_OPS_PARENT_ENABLE) {
> 		clk_core_disable_unprepare(parent);
> 		clk_core_disable_unprepare(old_parent);
> 	}
> 
> >         }
> >  }
> >  
> > @@ -1468,13 +1469,17 @@ static void clk_change_rate(struct clk_core *core)
> >         unsigned long best_parent_rate = 0;
> >         bool skip_set_rate = false;
> >         struct clk_core *old_parent;
> > +       struct clk_core *parent = NULL;
> >  
> >         old_rate = core->rate;
> >  
> > -       if (core->new_parent)
> > +       if (core->new_parent) {
> > +               parent = core->new_parent;
> >                 best_parent_rate = core->new_parent->rate;
> > -       else if (core->parent)
> > +       } else if (core->parent) {
> > +               parent = core->parent;
> >                 best_parent_rate = core->parent->rate;
> > +       }
> >  
> >         if (core->flags & CLK_SET_RATE_UNGATE) {
> >                 unsigned long flags;
> > @@ -1504,6 +1509,9 @@ static void clk_change_rate(struct clk_core *core)
> >  
> >         trace_clk_set_rate(core, core->new_rate);
> >  
> > +       if (core->flags & CLK_OPS_PARENT_ON)
> > +               clk_core_prepare_enable(parent);
> > +
> >         if (!skip_set_rate && core->ops->set_rate)
> >                 core->ops->set_rate(core->hw, core->new_rate, best_parent_rate);
> >  
> > @@ -1520,6 +1528,9 @@ static void clk_change_rate(struct clk_core *core)
> >                 clk_core_unprepare(core);
> >         }
> >  
> > +       if (core->flags & CLK_OPS_PARENT_ON)
> > +               clk_core_disable_unprepare(parent);
> > +
> 
> This part looks good to me.
> 
> Regards,
> Mike
> 
> >         if (core->notifier_count && old_rate != core->rate)
> >                 __clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
> >  
> > -- 
> > 1.9.1
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-clk" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: dongas86@gmail.com (Dong Aisheng)
To: linux-arm-kernel@lists.infradead.org
Subject: [RESEND PATCH 4/8] clk: core: support clocks which requires parents on (part 2)
Date: Wed, 29 Jun 2016 21:59:56 +0800	[thread overview]
Message-ID: <20160629135955.GB29919@shlinux2> (raw)
In-Reply-To: <146681237910.35033.15404158884510204380@resonance>

Hi Mike,

On Fri, Jun 24, 2016 at 04:52:59PM -0700, Michael Turquette wrote:
> Hi Dong,
> 
> Quoting Dong Aisheng (2016-04-20 02:34:36)
> > On Freescale i.MX7D platform, all clocks operations, including
> > enable/disable, rate change and re-parent, requires its parent clock on.
> > Current clock core can not support it well.
> > This patch adding flag CLK_OPS_PARENT_ON to handle this special case in
> > clock core that enable its parent clock firstly for each operation and
> > disable it later after operation complete.
> > 
> > The patch part 2 fixes set clock rate and set parent while its parent
> > is off. The most special case is for set_parent() operation which requires
> > all parents including both old and new one to be enabled at the same time
> > during the operation.
> > 
> > Cc: Michael Turquette <mturquette@baylibre.com>
> > Cc: Stephen Boyd <sboyd@codeaurora.org>
> > Cc: Shawn Guo <shawnguo@kernel.org>
> > Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> > ---
> >  drivers/clk/clk.c | 45 ++++++++++++++++++++++++++++-----------------
> >  1 file changed, 28 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > index 1f054d1a..d6cef61 100644
> > --- a/drivers/clk/clk.c
> > +++ b/drivers/clk/clk.c
> > @@ -1174,7 +1174,7 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core,
> >         struct clk_core *old_parent = core->parent;
> >  
> >         /*
> > -        * Migrate prepare state between parents and prevent race with
> > +        * 1. Migrate prepare state between parents and prevent race with
> >          * clk_enable().
> >          *
> >          * If the clock is not prepared, then a race with
> > @@ -1189,13 +1189,16 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core,
> >          * hardware and software states.
> >          *
> >          * See also: Comment for clk_set_parent() below.
> > +        *
> > +        * 2. enable parent clocks for CLK_OPS_PARENT_ON clock
> >          */
> > -       if (core->prepare_count) {
> > -               clk_core_prepare(parent);
> > -               flags = clk_enable_lock();
> > -               clk_core_enable(parent);
> > -               clk_core_enable(core);
> > -               clk_enable_unlock(flags);
> > +       if (core->prepare_count || core->flags & CLK_OPS_PARENT_ON) {
> > +               clk_core_prepare_enable(parent);
> > +               if (core->prepare_count)
> > +                       clk_core_enable_lock(core);
> > +               else
> > +                       clk_core_prepare_enable(old_parent);
> 
> It took me a few seconds to figure out what I was looking at. The
> set_parent stuff is tricky enough already ... I think we should keep the
> state machine logic very simple. How about:
> 
> 	/* enable old_parent & parent if CLK_OPS_PARENT_ENABLE is set */
> 	if (core->flags & CLK_OPS_PARENT_ENABLE) {
> 		clk_core_prepare_enable(old_parent);
> 		clk_core_prepare_enable(parent);
> 	}
> 
> 	/* migrate prepare count if > 0 */
> 	if (core->prepare_count) {
> 		clk_core_prepare_enable(parent);
> 		clk_core_enable_lock(core);
> 	}
> 

Great suggestion! That looks much clearer.
Will update it in V2.

Thanks

Regards
Dong Aisheng

> > +
> >         }
> >  
> >         /* update the clk tree topology */
> > @@ -1210,18 +1213,16 @@ static void __clk_set_parent_after(struct clk_core *core,
> >                                    struct clk_core *parent,
> >                                    struct clk_core *old_parent)
> >  {
> > -       unsigned long flags;
> > -
> >         /*
> >          * Finish the migration of prepare state and undo the changes done
> >          * for preventing a race with clk_enable().
> >          */
> > -       if (core->prepare_count) {
> > -               flags = clk_enable_lock();
> > -               clk_core_disable(core);
> > -               clk_core_disable(old_parent);
> > -               clk_enable_unlock(flags);
> > -               clk_core_unprepare(old_parent);
> > +       if (core->prepare_count || core->flags & CLK_OPS_PARENT_ON) {
> > +               clk_core_disable_unprepare(old_parent);
> > +               if (core->prepare_count)
> > +                       clk_core_disable_lock(core);
> > +               else
> > +                       clk_core_disable_unprepare(parent);
> 
> Similarly, a more readable solution is:
> 
> 	/*
> 	 * Finish the migration of prepare state and undo the changes done
> 	 * for preventing a race with clk_enable().
> 	 */
> 	if (core->prepare_count) {
> 		clk_core_disable_lock(core);
> 		clk_core_disable_unprepare(old_parent);
> 
> 	/* re-balance ref counting if CLK_OPS_PARENT_ENABLE is set */
> 	if (core->flags & CLK_OPS_PARENT_ENABLE) {
> 		clk_core_disable_unprepare(parent);
> 		clk_core_disable_unprepare(old_parent);
> 	}
> 
> >         }
> >  }
> >  
> > @@ -1468,13 +1469,17 @@ static void clk_change_rate(struct clk_core *core)
> >         unsigned long best_parent_rate = 0;
> >         bool skip_set_rate = false;
> >         struct clk_core *old_parent;
> > +       struct clk_core *parent = NULL;
> >  
> >         old_rate = core->rate;
> >  
> > -       if (core->new_parent)
> > +       if (core->new_parent) {
> > +               parent = core->new_parent;
> >                 best_parent_rate = core->new_parent->rate;
> > -       else if (core->parent)
> > +       } else if (core->parent) {
> > +               parent = core->parent;
> >                 best_parent_rate = core->parent->rate;
> > +       }
> >  
> >         if (core->flags & CLK_SET_RATE_UNGATE) {
> >                 unsigned long flags;
> > @@ -1504,6 +1509,9 @@ static void clk_change_rate(struct clk_core *core)
> >  
> >         trace_clk_set_rate(core, core->new_rate);
> >  
> > +       if (core->flags & CLK_OPS_PARENT_ON)
> > +               clk_core_prepare_enable(parent);
> > +
> >         if (!skip_set_rate && core->ops->set_rate)
> >                 core->ops->set_rate(core->hw, core->new_rate, best_parent_rate);
> >  
> > @@ -1520,6 +1528,9 @@ static void clk_change_rate(struct clk_core *core)
> >                 clk_core_unprepare(core);
> >         }
> >  
> > +       if (core->flags & CLK_OPS_PARENT_ON)
> > +               clk_core_disable_unprepare(parent);
> > +
> 
> This part looks good to me.
> 
> Regards,
> Mike
> 
> >         if (core->notifier_count && old_rate != core->rate)
> >                 __clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
> >  
> > -- 
> > 1.9.1
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-clk" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2016-06-29 13:59 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-20  9:34 [RESEND PATCH 0/8] clk: core: support clocks which requires parents on Dong Aisheng
2016-04-20  9:34 ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 1/8] clk: introduce clk_core_enable_lock and clk_core_disable_lock functions Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 2/8] clk: move clk_disable_unused after clk_core_disable_unprepare function Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 3/8] clk: core: support clocks which requires parents on (part 1) Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-06-24 23:52   ` Michael Turquette
2016-06-24 23:52     ` Michael Turquette
2016-06-24 23:52     ` Michael Turquette
2016-06-29 13:57     ` Dong Aisheng
2016-06-29 13:57       ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 4/8] clk: core: support clocks which requires parents on (part 2) Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-06-24 23:52   ` Michael Turquette
2016-06-24 23:52     ` Michael Turquette
2016-06-24 23:52     ` Michael Turquette
2016-06-29 13:59     ` Dong Aisheng [this message]
2016-06-29 13:59       ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 5/8] clk: imx: re-order and concentrate the same type of clk api Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 6/8] clk: imx: add clk api for supporting clk_OPS_PARENT_ON clocks Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 7/8] clk: imx7d: using api with flag CLK_OPS_PARENT_ON Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-04-20  9:34 ` [RESEND PATCH 8/8] clk: imx7d: only enable minimum required clocks Dong Aisheng
2016-04-20  9:34   ` Dong Aisheng
2016-06-02 15:20 ` [RESEND PATCH 0/8] clk: core: support clocks which requires parents on Dong Aisheng
2016-06-02 15:20   ` Dong Aisheng
2016-06-12 14:58   ` Dong Aisheng
2016-06-12 14:58     ` Dong Aisheng

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=20160629135955.GB29919@shlinux2 \
    --to=dongas86@gmail.com \
    --cc=aisheng.dong@nxp.com \
    --cc=anson.huang@nxp.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=sboyd@codeaurora.org \
    --cc=shawnguo@kernel.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.