linux-tegra.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: Michael Turquette
	<mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>,
	Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
	Alexandre Courbot
	<gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
	linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH v4] clk: tegra: Add BPMP clock driver
Date: Thu, 17 Nov 2016 16:57:24 +0100	[thread overview]
Message-ID: <20161117155724.GA29604@ulmo.ba.sec> (raw)
In-Reply-To: <20161117095840.GA9843-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 5426 bytes --]

On Thu, Nov 17, 2016 at 10:58:40AM +0100, Thierry Reding wrote:
> On Wed, Nov 16, 2016 at 05:19:15PM -0800, Stephen Boyd wrote:
> > On 11/15, Thierry Reding wrote:
[...]
> > > +static int
> > > +__tegra_bpmp_clk_transfer_atomic(struct tegra_bpmp *bpmp,
> > > +				 struct tegra_bpmp_message *msg)
> > > +{
> > > +	unsigned long flags;
> > > +	int err;
> > > +
> > > +	local_irq_save(flags);
> > > +	err = tegra_bpmp_transfer_atomic(bpmp, msg);
> > > +	local_irq_restore(flags);
> > 
> > Why do we need to disable irqs? Seems like an odd thing for the
> > caller to decide given that there aren't any interrupt handlers
> > in this driver.
> 
> This is there to allow clock operations to succeed very early in boot
> when some of the infrastructure to execute the non-atomic equivalents
> hasn't been brought up yet.
> 
> That said, I'm not sure we actually need it. I'll run some tests and can
> drop this if we don't need it.

Turns out that we don't need this anymore. The need for this must have
gone away somewhere during restructuring of the code.

> > > +static int tegra_bpmp_clk_enable(struct clk_hw *hw)
> > 
> > Maybe this should be called tegra_bpmp_clk_prepare() so as to not
> > confuse the reader.
> 
> Well, the function does implement an enable of the clock. The reason why
> it is later assigned to the ->prepare() operation is merely because that
> is what the CCF requires, given that this may sleep.
> 
> Bus if you prefer I can change this and also...
> 
> > > +{
> > > +	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
> > > +	struct tegra_bpmp_clk_message msg;
> > > +
> > > +	memset(&msg, 0, sizeof(msg));
> > > +	msg.cmd = CMD_CLK_ENABLE;
> > > +	msg.clk = clk->id;
> > > +
> > > +	return tegra_bpmp_clk_transfer(clk->bpmp, &msg);
> > > +}
> > > +
> > > +static void tegra_bpmp_clk_disable(struct clk_hw *hw)
> 
> ... this to tegra_bpmp_clk_unprepare().
> 
> > > +{
> > > +	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
> > > +	struct tegra_bpmp_clk_message msg;
> > > +	int err;
> > > +
> > > +	memset(&msg, 0, sizeof(msg));
> > > +	msg.cmd = CMD_CLK_DISABLE;
> > > +	msg.clk = clk->id;
> > > +
> > > +	err = tegra_bpmp_clk_transfer(clk->bpmp, &msg);
> > > +	if (err < 0)
> > > +		dev_err(clk->bpmp->dev, "failed to disable clock %s: %d\n",
> > > +			clk_hw_get_name(hw), err);
> > > +}
> > > +
> > > +static int tegra_bpmp_clk_is_enabled(struct clk_hw *hw)
> > 
> > Why not *_is_prepared()?
> 
> Yes, given the above that makes sense.
> 
> > > +{
> > > +	struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
> > > +	struct cmd_clk_is_enabled_response response;
> > > +	struct tegra_bpmp_clk_message msg;
> > > +	int err;
> > > +
> > > +	memset(&msg, 0, sizeof(msg));
> > > +	msg.cmd = CMD_CLK_IS_ENABLED;
> > > +	msg.clk = clk->id;
> > > +	msg.rx.data = &response;
> > > +	msg.rx.size = sizeof(response);
> > > +
> > > +	err = tegra_bpmp_clk_transfer_atomic(clk->bpmp, &msg);
> > 
> > And then I presume this wouldn't need to worry about being called
> > in atomic situations.
> 
> I'll go test if that works. If it does, I agree that this would be
> preferable.

Turns out this works out fine. This sent me on a wild goose chase for a
while because after the conversion the kernel would simply hang at some
point. This turned out to be caused by the UART's clock getting
unprepared because it wasn't properly wired up in the DT. With the
original code I wasn't seeing this because the mix of ->is_enabled()
with ->prepare() and ->unprepared() would cause all of the unused clocks
to remain on across clk_disable_unused().

Perhaps this would be worth sanity checking somewhere during clock
registration? Specifically, providing ->is_enabled() but not ->enable()
or ->disable() or ->is_prepared() but not ->prepare() or ->unprepare()
seems like a bad idea.

> > > +static struct clk_hw *tegra_bpmp_clk_of_xlate(struct of_phandle_args *clkspec,
> > > +					      void *data)
> > > +{
> > > +	unsigned int id = clkspec->args[0], i;
> > > +	struct tegra_bpmp *bpmp = data;
> > > +	struct tegra_bpmp_clk *clk;
> > > +
> > > +	for (i = 0; i < bpmp->num_clocks; i++) {
> > > +		clk = to_tegra_bpmp_clk(bpmp->clocks[i]);
> > > +		if (clk->id == id)
> > > +			return bpmp->clocks[i];
> > > +	}
> > 
> >  	for (i = 0; i < bpmp->num_clocks; i++) {
> > 		hw = bpmp->clocks[i];
> > 		clk = to_tegra_bpmp_clk(hw);
> > 		if (clk->id == id)
> > 			return hw;
> > 	}
> > 
> > Uses another local variable but is much clearer.
> 
> Really? I think it's pretty clear in the original that we upcast,
> compare and return the original pointer. Even if bpmp->clocks[i] is a
> little longer than hw, the two occurrences are close enough together to
> make this immediately obvious.
> 
> Maybe yet another alternative would be to make bpmp->clocks an array to
> struct tegra_bpmp_clk instead of struct clk_hw. That way the ->xlate()
> becomes simpler to handle at the expense of a slightly more complicated
> implementation for tegra_bpmp_unregister_clocks(). Given that
> unregistering clocks is a one-time operation but ->xlate() may be called
> very often, this might be advantageous.

So I implemented this alternative and it ends up looking better than
either of the options above, at least in my opinion.

I've sent a v2, let me know what you think.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

  parent reply	other threads:[~2016-11-17 15:57 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-15 16:11 [PATCH v4] clk: tegra: Add BPMP clock driver Thierry Reding
     [not found] ` <20161115161129.29722-1-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-11-17  1:19   ` Stephen Boyd
     [not found]     ` <20161117011915.GN25626-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2016-11-17  9:58       ` Thierry Reding
     [not found]         ` <20161117095840.GA9843-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2016-11-17 15:57           ` Thierry Reding [this message]
2016-11-17 15:47   ` [PATCH v2] " Thierry Reding
2017-01-25  7:41     ` Thierry Reding
     [not found]       ` <20170125074112.GC13025-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2017-02-03 20:43         ` Stephen Boyd
     [not found]           ` <20170203204302.GF25384-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-02-06 11:13             ` Thierry Reding
     [not found]               ` <20170206111342.GI27607-EkSeR96xj6Pcmrwk2tT4+A@public.gmane.org>
2017-02-06 22:52                 ` Stephen Boyd
     [not found]                   ` <20170206225224.GI25384-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-02-07 10:52                     ` Thierry Reding

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=20161117155724.GA29604@ulmo.ba.sec \
    --to=thierry.reding-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=gnurou-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    --cc=linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org \
    --cc=sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.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).