From: Mike Turquette <mturquette@linaro.org> To: Hans de Goede <hdegoede@redhat.com>, Emilio Lopez <emilio@elopez.com.ar>, chris@printf.net, david.lanzendoerfer@o2s.ch, ulf.hansson@linaro.org Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mmc@vger.kernel.org, Maxime Ripard <maxime.ripard@free-electrons.com> Subject: Re: [PATCH v2 03/12] clk: Add a function to retrieve phase Date: Mon, 01 Sep 2014 12:00:54 -0700 [thread overview] Message-ID: <20140901190054.5251.56409@quantum> (raw) In-Reply-To: <1409428991-2442-4-git-send-email-maxime.ripard@free-electrons.com> Quoting Maxime Ripard (2014-08-30 13:03:02) > The current phase API doesn't look into the actual hardware to get the phase > value, but will rather get it from a variable only set by the set_phase > function. > > This will cause issue when the client driver will never call the set_phase > function, where we can end up having a reported phase that will not match what > the hardware has been programmed to by the bootloader or what phase is > programmed out of reset. > > Add a new get_phase function for the drivers to implement so that we can get > this value. > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > --- > drivers/clk/clk.c | 17 ++++++++++++++--- > include/linux/clk-provider.h | 5 +++++ > 2 files changed, 19 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > index d87661af0c72..7dbceca694f1 100644 > --- a/drivers/clk/clk.c > +++ b/drivers/clk/clk.c > @@ -1797,8 +1797,8 @@ out: > * clk_get_phase - return the phase shift of a clock signal > * @clk: clock signal source > * > - * Returns the phase shift of a clock node in degrees, otherwise returns > - * -EERROR. > + * Returns the phase shift of a clock node in degrees. Any negative > + * values are errors. > */ > int clk_get_phase(struct clk *clk) > { > @@ -1808,7 +1808,18 @@ int clk_get_phase(struct clk *clk) > goto out; > > clk_prepare_lock(); > - ret = clk->phase; > + > + if (clk->phase) { So if a phase is zero, then we fall through and query the hardware? Seems like this case might be hit a lot for clocks that implement .get_phase but never have their phase shifted, and accesses to the registers may be much slower than to memory. Do you expect the phase to be changed behind our backs? E.g. firmware changes it, or coming in and out of idle state, etc. If not then we can store the phase at clock registration time and use a cached value. See how the CLK_GET_RATE_NOCACHE and CLK_GET_ACCURACY_NOCACHE flags are used for details on how we can handle the case where the phase might change behind our back. Regards, Mike > + ret = clk->phase; > + goto out_unlock; > + } > + > + if (!clk->ops->get_phase) > + goto out_unlock; > + > + ret = clk->ops->get_phase(clk->hw); > + > +out_unlock: > clk_prepare_unlock(); > > out: > diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h > index 69b20d4c1e1a..abec961092a7 100644 > --- a/include/linux/clk-provider.h > +++ b/include/linux/clk-provider.h > @@ -130,6 +130,10 @@ struct dentry; > * set then clock accuracy will be initialized to parent accuracy > * or 0 (perfect clock) if clock has no parent. > * > + * @get_phase: Queries the hardware to get the current phase of a clock. > + * Returned values are 0-359 degrees on success, negative > + * error codes on failure. > + * > * @set_phase: Shift the phase this clock signal in degrees specified > * by the second argument. Valid values for degrees are > * 0-359. Return 0 on success, otherwise -EERROR. > @@ -182,6 +186,7 @@ struct clk_ops { > unsigned long parent_rate, u8 index); > unsigned long (*recalc_accuracy)(struct clk_hw *hw, > unsigned long parent_accuracy); > + int (*get_phase)(struct clk_hw *hw); > int (*set_phase)(struct clk_hw *hw, int degrees); > void (*init)(struct clk_hw *hw); > int (*debug_init)(struct clk_hw *hw, struct dentry *dentry); > -- > 2.0.2 >
WARNING: multiple messages have this Message-ID (diff)
From: mturquette@linaro.org (Mike Turquette) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 03/12] clk: Add a function to retrieve phase Date: Mon, 01 Sep 2014 12:00:54 -0700 [thread overview] Message-ID: <20140901190054.5251.56409@quantum> (raw) In-Reply-To: <1409428991-2442-4-git-send-email-maxime.ripard@free-electrons.com> Quoting Maxime Ripard (2014-08-30 13:03:02) > The current phase API doesn't look into the actual hardware to get the phase > value, but will rather get it from a variable only set by the set_phase > function. > > This will cause issue when the client driver will never call the set_phase > function, where we can end up having a reported phase that will not match what > the hardware has been programmed to by the bootloader or what phase is > programmed out of reset. > > Add a new get_phase function for the drivers to implement so that we can get > this value. > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> > --- > drivers/clk/clk.c | 17 ++++++++++++++--- > include/linux/clk-provider.h | 5 +++++ > 2 files changed, 19 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > index d87661af0c72..7dbceca694f1 100644 > --- a/drivers/clk/clk.c > +++ b/drivers/clk/clk.c > @@ -1797,8 +1797,8 @@ out: > * clk_get_phase - return the phase shift of a clock signal > * @clk: clock signal source > * > - * Returns the phase shift of a clock node in degrees, otherwise returns > - * -EERROR. > + * Returns the phase shift of a clock node in degrees. Any negative > + * values are errors. > */ > int clk_get_phase(struct clk *clk) > { > @@ -1808,7 +1808,18 @@ int clk_get_phase(struct clk *clk) > goto out; > > clk_prepare_lock(); > - ret = clk->phase; > + > + if (clk->phase) { So if a phase is zero, then we fall through and query the hardware? Seems like this case might be hit a lot for clocks that implement .get_phase but never have their phase shifted, and accesses to the registers may be much slower than to memory. Do you expect the phase to be changed behind our backs? E.g. firmware changes it, or coming in and out of idle state, etc. If not then we can store the phase at clock registration time and use a cached value. See how the CLK_GET_RATE_NOCACHE and CLK_GET_ACCURACY_NOCACHE flags are used for details on how we can handle the case where the phase might change behind our back. Regards, Mike > + ret = clk->phase; > + goto out_unlock; > + } > + > + if (!clk->ops->get_phase) > + goto out_unlock; > + > + ret = clk->ops->get_phase(clk->hw); > + > +out_unlock: > clk_prepare_unlock(); > > out: > diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h > index 69b20d4c1e1a..abec961092a7 100644 > --- a/include/linux/clk-provider.h > +++ b/include/linux/clk-provider.h > @@ -130,6 +130,10 @@ struct dentry; > * set then clock accuracy will be initialized to parent accuracy > * or 0 (perfect clock) if clock has no parent. > * > + * @get_phase: Queries the hardware to get the current phase of a clock. > + * Returned values are 0-359 degrees on success, negative > + * error codes on failure. > + * > * @set_phase: Shift the phase this clock signal in degrees specified > * by the second argument. Valid values for degrees are > * 0-359. Return 0 on success, otherwise -EERROR. > @@ -182,6 +186,7 @@ struct clk_ops { > unsigned long parent_rate, u8 index); > unsigned long (*recalc_accuracy)(struct clk_hw *hw, > unsigned long parent_accuracy); > + int (*get_phase)(struct clk_hw *hw); > int (*set_phase)(struct clk_hw *hw, int degrees); > void (*init)(struct clk_hw *hw); > int (*debug_init)(struct clk_hw *hw, struct dentry *dentry); > -- > 2.0.2 >
next prev parent reply other threads:[~2014-09-01 19:00 UTC|newest] Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-08-30 20:02 [PATCH v2 00/12] clk: sunxi: Improve MMC clocks support Maxime Ripard 2014-08-30 20:02 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 01/12] clk: introduce clk_set_phase function & callback Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 02/12] clk: Include of.h in clock-provider.h Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 03/12] clk: Add a function to retrieve phase Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-31 10:15 ` Hans de Goede 2014-08-31 10:15 ` Hans de Goede 2014-09-01 10:20 ` Maxime Ripard 2014-09-01 10:20 ` Maxime Ripard 2014-09-01 11:27 ` Hans de Goede 2014-09-01 11:27 ` Hans de Goede 2014-09-02 9:50 ` Maxime Ripard 2014-09-02 9:50 ` Maxime Ripard 2014-09-02 11:03 ` David Lanzendörfer 2014-09-02 11:03 ` David Lanzendörfer 2014-09-01 19:00 ` Mike Turquette [this message] 2014-09-01 19:00 ` Mike Turquette 2014-09-02 9:34 ` Maxime Ripard 2014-09-02 9:34 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 04/12] clk: sunxi: factors: Invert the probing logic Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 05/12] clk: sunxi: Introduce mbus compatible Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 06/12] ARM: sunxi: dt: Switch to the new " Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 07/12] clk: sunxi: Move mod0 clock to a file of its own Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 08/12] clk: sunxi: Move mbus to mod0 file Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 09/12] ARM: sunxi: dt: Add sample and output mmc clocks Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-09-04 7:31 ` Chen-Yu Tsai 2014-08-30 20:03 ` [PATCH v2 10/12] clk: sunxi: mod0: Introduce MMC proper phase handling Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-09-01 21:39 ` Mike Turquette 2014-09-01 21:39 ` Mike Turquette 2014-09-02 7:52 ` Maxime Ripard 2014-09-02 7:52 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 11/12] mmc: sunxi: Convert MMC driver to the standard clock phase API Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard 2014-08-30 20:03 ` [PATCH v2 12/12] clk: sunxi: Remove custom phase function Maxime Ripard 2014-08-30 20:03 ` Maxime Ripard
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=20140901190054.5251.56409@quantum \ --to=mturquette@linaro.org \ --cc=chris@printf.net \ --cc=david.lanzendoerfer@o2s.ch \ --cc=devicetree@vger.kernel.org \ --cc=emilio@elopez.com.ar \ --cc=hdegoede@redhat.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-mmc@vger.kernel.org \ --cc=maxime.ripard@free-electrons.com \ --cc=ulf.hansson@linaro.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: linkBe 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.