From: mturquette@linaro.org (Michael Turquette)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v7 3/5] clk: Supply the critical clock {init, enable, disable} framework
Date: Thu, 30 Jul 2015 15:57:29 -0700 [thread overview]
Message-ID: <20150730225729.23791.68604@quantum> (raw)
In-Reply-To: <20150730092139.GB14642@x1>
Quoting Lee Jones (2015-07-30 02:21:39)
> On Wed, 29 Jul 2015, Michael Turquette wrote:
> > Quoting Lee Jones (2015-07-27 01:53:38)
> > > On Mon, 27 Jul 2015, Maxime Ripard wrote:
> > >
> > > > On Wed, Jul 22, 2015 at 02:04:13PM +0100, Lee Jones wrote:
> > > > > These new API calls will firstly provide a mechanisms to tag a clock as
> > > > > critical and secondly allow any knowledgeable driver to (un)gate clocks,
> > > > > even if they are marked as critical.
> > > > >
> > > > > Suggested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > > > > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > > > > ---
> > > > > drivers/clk/clk.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> > > > > include/linux/clk-provider.h | 2 ++
> > > > > include/linux/clk.h | 30 +++++++++++++++++++++++++++++
> > > > > 3 files changed, 77 insertions(+)
> > > > >
> > > > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > > > > index 61c3fc5..486b1da 100644
> > > > > --- a/drivers/clk/clk.c
> > > > > +++ b/drivers/clk/clk.c
> > > > > @@ -46,6 +46,21 @@ static struct clk_core *clk_core_lookup(const char *name);
> > > > >
> > > > > /*** private data structures ***/
> > > > >
> > > > > +/**
> > > > > + * struct critical - Provides 'play' over critical clocks. A clock can be
> > > > > + * marked as critical, meaning that it should not be
> > > > > + * disabled. However, if a driver which is aware of the
> > > > > + * critical behaviour wants to control it, it can do so
> > > > > + * using clk_enable_critical() and clk_disable_critical().
> > > > > + *
> > > > > + * @enabled Is clock critical? Once set, doesn't change
> > > > > + * @leave_on Self explanatory. Can be disabled by knowledgeable drivers
> > > > > + */
> > > > > +struct critical {
> > > > > + bool enabled;
> > > > > + bool leave_on;
> > > > > +};
> > > > > +
> > > > > struct clk_core {
> > > > > const char *name;
> > > > > const struct clk_ops *ops;
> > > > > @@ -75,6 +90,7 @@ struct clk_core {
> > > > > struct dentry *dentry;
> > > > > #endif
> > > > > struct kref ref;
> > > > > + struct critical critical;
> > > > > };
> > > > >
> > > > > struct clk {
> > > > > @@ -995,6 +1011,10 @@ static void clk_core_disable(struct clk_core *clk)
> > > > > if (WARN_ON(clk->enable_count == 0))
> > > > > return;
> > > > >
> > > > > + /* Refuse to turn off a critical clock */
> > > > > + if (clk->enable_count == 1 && clk->critical.leave_on)
> > > > > + return;
> > > > > +
> > > >
> > > > I think it should be handled by a separate counting. Otherwise, if you
> > > > have two users that marked the clock as critical, and then one of them
> > > > disable it...
> > > >
> > > > > if (--clk->enable_count > 0)
> > > > > return;
> > > > >
> > > > > @@ -1037,6 +1057,13 @@ void clk_disable(struct clk *clk)
> > > > > }
> > > > > EXPORT_SYMBOL_GPL(clk_disable);
> > > > >
> > > > > +void clk_disable_critical(struct clk *clk)
> > > > > +{
> > > > > + clk->core->critical.leave_on = false;
> > > >
> > > > .. you just lost the fact that it was critical in the first place.
> > >
> > > I thought about both of these points, which is why I came up with this
> > > strategy.
> > >
> > > Any device which uses the *_critical() API should a) have knowledge of
> > > what happens when a particular critical clock is gated and b) have
> > > thought about the consequences.
> >
> > If this statement above is true then I fail to see the need for a new
> > api. A driver which has a really great idea of when it is safe or unsafe
> > to gate a clock should call clk_prepare_enable at probe and then only
> > call clk_disable_unprepare once it is safe to do so.
> >
> > The existing bookkeeping in the clock framework will do the rest.
>
> I think you are viewing this particular API back-to-front. The idea
> is to mark all of the critical clocks at start-up by taking a
> reference. Then, if there are no knowledgable drivers who wish to
> turn the clock off, the CCF will leave the clock ungated becuase the
> reference count will always be >0.
Right. So I'll ask the same question here that I asked in the other
patch: is there ever a case where a clock consumer driver would want to
call clk_enable_critical? It seems to me that in you usage of it, that
call would only ever be made by the core framework code (e.g. clk-conf.c
or perhaps somewhere in drivers/clk/clk.c).
>
> The clk_{disable,enable}_critical() calls are to be used by
> knowledgable drivers to say "[disable] I know what I'm doing and it's
> okay for this clock to be turned off" and "[enable] right I'm done
> with this clock now, let's turn it back on and mark it back as
> critical, so no one else can turn it off".
OK, so this almost answers my question above. You have a driver that may
finish using a clock for a while (ie, rmmod knowledgeable_driver), and
you want it (critically) enabled again. Is this a real use case? Who
would come along and disable this clock later on? If the driver is to be
re-loaded then I would suggest never unloading it in the first place.
(Oh and bear in mind when answering my question above that imbalanced
clk_enable/clk_disable calls will not succeed thanks to the vaporware
patch that I have in my local tree)
If you have a second knowledgeable_driver_2 that shares that clock and
can be trusted to manage it (critically) then I would need to see that
example, as it doesn't feel like a real use to me.
>
> To put things simply, the knowledgable driver will _not_ be enabling
> the clock in the first place. The first interaction it has with it is
> to gate it. Then, once it's done, it will enable it again and mark it
> back up as critical.a
I like the first part. Makes sense and fills a real need. I am fully
on-board with a provider-handoff-to-consumer solution. It is all the
weird stuff that comes after it that I'm unsure of.
Regards,
Mike
>
> Still confused ... let's go on another Q in one of your other emails
> for another way of putting it.
>
> > > I don't think we can use reference
> > > counting, because we'd need as many critical clock owners as there are
> > > critical clocks. Cast your mind back to the reasons for this critical
> > > clock API. One of the most important intentions of this API is the
> > > requirement mitigation for each of the critical clocks to have an owner
> > > (driver).
> > >
> > > With regards to your second point, that's what 'critical.enabled'
> > > is for. Take a look at clk_enable_critical().
> > >
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org ? Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
WARNING: multiple messages have this Message-ID (diff)
From: Michael Turquette <mturquette@linaro.org>
To: Lee Jones <lee.jones@linaro.org>
Cc: devicetree@vger.kernel.org, kernel@stlinux.com,
s.hauer@pengutronix.de, sboyd@codeaurora.org,
linux-kernel@vger.kernel.org, geert@linux-m68k.org,
Maxime Ripard <maxime.ripard@free-electrons.com>,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v7 3/5] clk: Supply the critical clock {init, enable, disable} framework
Date: Thu, 30 Jul 2015 15:57:29 -0700 [thread overview]
Message-ID: <20150730225729.23791.68604@quantum> (raw)
In-Reply-To: <20150730092139.GB14642@x1>
Quoting Lee Jones (2015-07-30 02:21:39)
> On Wed, 29 Jul 2015, Michael Turquette wrote:
> > Quoting Lee Jones (2015-07-27 01:53:38)
> > > On Mon, 27 Jul 2015, Maxime Ripard wrote:
> > >
> > > > On Wed, Jul 22, 2015 at 02:04:13PM +0100, Lee Jones wrote:
> > > > > These new API calls will firstly provide a mechanisms to tag a clock as
> > > > > critical and secondly allow any knowledgeable driver to (un)gate clocks,
> > > > > even if they are marked as critical.
> > > > >
> > > > > Suggested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > > > > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > > > > ---
> > > > > drivers/clk/clk.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> > > > > include/linux/clk-provider.h | 2 ++
> > > > > include/linux/clk.h | 30 +++++++++++++++++++++++++++++
> > > > > 3 files changed, 77 insertions(+)
> > > > >
> > > > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > > > > index 61c3fc5..486b1da 100644
> > > > > --- a/drivers/clk/clk.c
> > > > > +++ b/drivers/clk/clk.c
> > > > > @@ -46,6 +46,21 @@ static struct clk_core *clk_core_lookup(const char *name);
> > > > >
> > > > > /*** private data structures ***/
> > > > >
> > > > > +/**
> > > > > + * struct critical - Provides 'play' over critical clocks. A clock can be
> > > > > + * marked as critical, meaning that it should not be
> > > > > + * disabled. However, if a driver which is aware of the
> > > > > + * critical behaviour wants to control it, it can do so
> > > > > + * using clk_enable_critical() and clk_disable_critical().
> > > > > + *
> > > > > + * @enabled Is clock critical? Once set, doesn't change
> > > > > + * @leave_on Self explanatory. Can be disabled by knowledgeable drivers
> > > > > + */
> > > > > +struct critical {
> > > > > + bool enabled;
> > > > > + bool leave_on;
> > > > > +};
> > > > > +
> > > > > struct clk_core {
> > > > > const char *name;
> > > > > const struct clk_ops *ops;
> > > > > @@ -75,6 +90,7 @@ struct clk_core {
> > > > > struct dentry *dentry;
> > > > > #endif
> > > > > struct kref ref;
> > > > > + struct critical critical;
> > > > > };
> > > > >
> > > > > struct clk {
> > > > > @@ -995,6 +1011,10 @@ static void clk_core_disable(struct clk_core *clk)
> > > > > if (WARN_ON(clk->enable_count == 0))
> > > > > return;
> > > > >
> > > > > + /* Refuse to turn off a critical clock */
> > > > > + if (clk->enable_count == 1 && clk->critical.leave_on)
> > > > > + return;
> > > > > +
> > > >
> > > > I think it should be handled by a separate counting. Otherwise, if you
> > > > have two users that marked the clock as critical, and then one of them
> > > > disable it...
> > > >
> > > > > if (--clk->enable_count > 0)
> > > > > return;
> > > > >
> > > > > @@ -1037,6 +1057,13 @@ void clk_disable(struct clk *clk)
> > > > > }
> > > > > EXPORT_SYMBOL_GPL(clk_disable);
> > > > >
> > > > > +void clk_disable_critical(struct clk *clk)
> > > > > +{
> > > > > + clk->core->critical.leave_on = false;
> > > >
> > > > .. you just lost the fact that it was critical in the first place.
> > >
> > > I thought about both of these points, which is why I came up with this
> > > strategy.
> > >
> > > Any device which uses the *_critical() API should a) have knowledge of
> > > what happens when a particular critical clock is gated and b) have
> > > thought about the consequences.
> >
> > If this statement above is true then I fail to see the need for a new
> > api. A driver which has a really great idea of when it is safe or unsafe
> > to gate a clock should call clk_prepare_enable at probe and then only
> > call clk_disable_unprepare once it is safe to do so.
> >
> > The existing bookkeeping in the clock framework will do the rest.
>
> I think you are viewing this particular API back-to-front. The idea
> is to mark all of the critical clocks at start-up by taking a
> reference. Then, if there are no knowledgable drivers who wish to
> turn the clock off, the CCF will leave the clock ungated becuase the
> reference count will always be >0.
Right. So I'll ask the same question here that I asked in the other
patch: is there ever a case where a clock consumer driver would want to
call clk_enable_critical? It seems to me that in you usage of it, that
call would only ever be made by the core framework code (e.g. clk-conf.c
or perhaps somewhere in drivers/clk/clk.c).
>
> The clk_{disable,enable}_critical() calls are to be used by
> knowledgable drivers to say "[disable] I know what I'm doing and it's
> okay for this clock to be turned off" and "[enable] right I'm done
> with this clock now, let's turn it back on and mark it back as
> critical, so no one else can turn it off".
OK, so this almost answers my question above. You have a driver that may
finish using a clock for a while (ie, rmmod knowledgeable_driver), and
you want it (critically) enabled again. Is this a real use case? Who
would come along and disable this clock later on? If the driver is to be
re-loaded then I would suggest never unloading it in the first place.
(Oh and bear in mind when answering my question above that imbalanced
clk_enable/clk_disable calls will not succeed thanks to the vaporware
patch that I have in my local tree)
If you have a second knowledgeable_driver_2 that shares that clock and
can be trusted to manage it (critically) then I would need to see that
example, as it doesn't feel like a real use to me.
>
> To put things simply, the knowledgable driver will _not_ be enabling
> the clock in the first place. The first interaction it has with it is
> to gate it. Then, once it's done, it will enable it again and mark it
> back up as critical.a
I like the first part. Makes sense and fills a real need. I am fully
on-board with a provider-handoff-to-consumer solution. It is all the
weird stuff that comes after it that I'm unsure of.
Regards,
Mike
>
> Still confused ... let's go on another Q in one of your other emails
> for another way of putting it.
>
> > > I don't think we can use reference
> > > counting, because we'd need as many critical clock owners as there are
> > > critical clocks. Cast your mind back to the reasons for this critical
> > > clock API. One of the most important intentions of this API is the
> > > requirement mitigation for each of the critical clocks to have an owner
> > > (driver).
> > >
> > > With regards to your second point, that's what 'critical.enabled'
> > > is for. Take a look at clk_enable_critical().
> > >
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2015-07-30 22:57 UTC|newest]
Thread overview: 92+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-22 13:04 [PATCH v7 0/5] clk: Provide support for always-on clocks Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` [PATCH v7 1/5] ARM: sti: stih407-family: Supply defines for CLOCKGEN A0 Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` [PATCH v7 2/5] ARM: sti: stih410-clocks: Identify critical clocks Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` [PATCH v7 3/5] clk: Supply the critical clock {init, enable, disable} framework Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-27 7:25 ` Maxime Ripard
2015-07-27 7:25 ` Maxime Ripard
2015-07-27 7:25 ` Maxime Ripard
2015-07-27 8:53 ` Lee Jones
2015-07-27 8:53 ` Lee Jones
2015-07-27 8:53 ` Lee Jones
2015-07-28 11:40 ` Maxime Ripard
2015-07-28 11:40 ` Maxime Ripard
2015-07-28 13:00 ` Lee Jones
2015-07-28 13:00 ` Lee Jones
2015-07-28 13:00 ` Lee Jones
2015-07-30 1:19 ` Michael Turquette
2015-07-30 1:19 ` Michael Turquette
2015-07-30 1:19 ` Michael Turquette
2015-07-30 9:50 ` Lee Jones
2015-07-30 9:50 ` Lee Jones
2015-07-30 9:50 ` Lee Jones
2015-07-30 22:47 ` Michael Turquette
2015-07-30 22:47 ` Michael Turquette
2015-07-31 7:30 ` Maxime Ripard
2015-07-31 7:30 ` Maxime Ripard
2015-07-31 7:30 ` Maxime Ripard
2015-07-31 8:32 ` Lee Jones
2015-07-31 8:32 ` Lee Jones
2015-07-31 8:32 ` Lee Jones
2015-07-31 7:03 ` Maxime Ripard
2015-07-31 7:03 ` Maxime Ripard
2015-07-31 7:03 ` Maxime Ripard
2015-07-31 8:48 ` Lee Jones
2015-07-31 8:48 ` Lee Jones
2015-07-30 1:21 ` Michael Turquette
2015-07-30 1:21 ` Michael Turquette
2015-07-30 1:21 ` Michael Turquette
2015-07-30 9:21 ` Lee Jones
2015-07-30 9:21 ` Lee Jones
2015-07-30 9:21 ` Lee Jones
2015-07-30 22:57 ` Michael Turquette [this message]
2015-07-30 22:57 ` Michael Turquette
2015-07-31 8:56 ` Lee Jones
2015-07-31 8:56 ` Lee Jones
2015-07-31 8:56 ` Lee Jones
2015-07-30 1:02 ` Michael Turquette
2015-07-30 1:02 ` Michael Turquette
2015-07-30 1:02 ` Michael Turquette
2015-07-30 11:17 ` Lee Jones
2015-07-30 11:17 ` Lee Jones
2015-07-30 23:35 ` Michael Turquette
2015-07-30 23:35 ` Michael Turquette
2015-07-30 23:35 ` Michael Turquette
2015-07-31 9:02 ` Lee Jones
2015-07-31 9:02 ` Lee Jones
2015-08-01 0:59 ` Michael Turquette
2015-08-01 0:59 ` Michael Turquette
2015-08-01 0:59 ` Michael Turquette
2015-07-22 13:04 ` [PATCH v7 4/5] clk: Provide critical clock support Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-08-17 5:43 ` Barry Song
2015-08-17 5:43 ` Barry Song
2015-08-17 5:43 ` Barry Song
2015-08-17 7:42 ` Lee Jones
2015-08-17 7:42 ` Lee Jones
2015-08-20 13:23 ` Barry Song
2015-08-20 13:23 ` Barry Song
2015-08-20 13:23 ` Barry Song
2015-07-22 13:04 ` [PATCH v7 5/5] clk: dt: Introduce binding for " Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-22 13:04 ` Lee Jones
2015-07-27 7:10 ` Maxime Ripard
2015-07-27 7:10 ` Maxime Ripard
2015-07-27 7:31 ` Lee Jones
2015-07-27 7:31 ` Lee Jones
2015-07-28 9:32 ` Maxime Ripard
2015-07-28 9:32 ` Maxime Ripard
2015-07-30 9:23 ` Lee Jones
2015-07-30 9:23 ` Lee Jones
2015-07-30 0:27 ` [PATCH v7 0/5] clk: Provide support for always-on clocks Michael Turquette
2015-07-30 0:27 ` Michael Turquette
2015-07-30 0:27 ` Michael Turquette
2015-07-30 9:09 ` Lee Jones
2015-07-30 9:09 ` Lee Jones
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=20150730225729.23791.68604@quantum \
--to=mturquette@linaro.org \
--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.