linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] clk_phase error caching problems
@ 2020-02-05 23:27 Stephen Boyd
  2020-02-05 23:27 ` [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase() Stephen Boyd
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-05 23:27 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

This patch series is a follow up to[1] which I sent out a few months
ago. We no longer cache the clk phase if it's an error value, so that
things like debugfs don't return us nonsense values for the phase.

Futhermore, the last patch fixes up the locking so that debugfs code
can avoid doing a recursive prepare lock because we know what we're
doing in that case. While we get some more functions, we avoid taking
the lock again.

Changes from v1:
 * A pile of new patches
 * Rebased to clk-next
 * New patch to bail out of registration if getting the phase fails

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Jerome Brunet <jbrunet@baylibre.com>

Stephen Boyd (4):
  clk: Don't cache errors from clk_ops::get_phase()
  clk: Use 'parent' to shorten lines in __clk_core_init()
  clk: Move rate and accuracy recalc to mostly consumer APIs
  clk: Bail out when calculating phase fails during clk registration

 drivers/clk/clk.c | 119 +++++++++++++++++++++++++++-------------------
 1 file changed, 70 insertions(+), 49 deletions(-)

[1] https://lkml.kernel.org/r/20191001174439.182435-1-sboyd@kernel.org

base-commit: 5df867145f8adad9e5cdf9d67db1fbc0f71351e9
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase()
  2020-02-05 23:27 [PATCH v2 0/4] clk_phase error caching problems Stephen Boyd
@ 2020-02-05 23:27 ` Stephen Boyd
  2020-02-06  8:26   ` Jerome Brunet
  2020-02-12 23:28   ` Stephen Boyd
  2020-02-05 23:28 ` [PATCH v2 2/4] clk: Use 'parent' to shorten lines in __clk_core_init() Stephen Boyd
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-05 23:27 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

We don't check for errors from clk_ops::get_phase() before storing away
the result into the clk_core::phase member. This can lead to some fairly
confusing debugfs information if these ops do return an error. Let's
skip the store when this op fails to fix this. While we're here, move
the locking outside of clk_core_get_phase() to simplify callers from
the debugfs side.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/clk.c | 48 +++++++++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index d529ad67805c..26213e82f5f9 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2660,12 +2660,14 @@ static int clk_core_get_phase(struct clk_core *core)
 {
 	int ret;
 
-	clk_prepare_lock();
+	lockdep_assert_held(&prepare_lock);
+	if (!core->ops->get_phase)
+		return 0;
+
 	/* Always try to update cached phase if possible */
-	if (core->ops->get_phase)
-		core->phase = core->ops->get_phase(core->hw);
-	ret = core->phase;
-	clk_prepare_unlock();
+	ret = core->ops->get_phase(core->hw);
+	if (ret >= 0)
+		core->phase = ret;
 
 	return ret;
 }
@@ -2679,10 +2681,16 @@ static int clk_core_get_phase(struct clk_core *core)
  */
 int clk_get_phase(struct clk *clk)
 {
+	int ret;
+
 	if (!clk)
 		return 0;
 
-	return clk_core_get_phase(clk->core);
+	clk_prepare_lock();
+	ret = clk_core_get_phase(clk->core);
+	clk_prepare_unlock();
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(clk_get_phase);
 
@@ -2896,13 +2904,21 @@ static struct hlist_head *orphan_list[] = {
 static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
 				 int level)
 {
-	seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n",
+	int phase;
+
+	seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ",
 		   level * 3 + 1, "",
 		   30 - level * 3, c->name,
 		   c->enable_count, c->prepare_count, c->protect_count,
-		   clk_core_get_rate(c), clk_core_get_accuracy(c),
-		   clk_core_get_phase(c),
-		   clk_core_get_scaled_duty_cycle(c, 100000));
+		   clk_core_get_rate(c), clk_core_get_accuracy(c));
+
+	phase = clk_core_get_phase(c);
+	if (phase >= 0)
+		seq_printf(s, "%5d", phase);
+	else
+		seq_puts(s, "-----");
+
+	seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000));
 }
 
 static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
@@ -2939,6 +2955,7 @@ DEFINE_SHOW_ATTRIBUTE(clk_summary);
 
 static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
 {
+	int phase;
 	unsigned long min_rate, max_rate;
 
 	clk_core_get_boundaries(c, &min_rate, &max_rate);
@@ -2952,7 +2969,9 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
 	seq_printf(s, "\"min_rate\": %lu,", min_rate);
 	seq_printf(s, "\"max_rate\": %lu,", max_rate);
 	seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
-	seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c));
+	phase = clk_core_get_phase(c);
+	if (phase >= 0)
+		seq_printf(s, "\"phase\": %d,", phase);
 	seq_printf(s, "\"duty_cycle\": %u",
 		   clk_core_get_scaled_duty_cycle(c, 100000));
 }
@@ -3434,14 +3453,11 @@ static int __clk_core_init(struct clk_core *core)
 		core->accuracy = 0;
 
 	/*
-	 * Set clk's phase.
+	 * Set clk's phase by clk_core_get_phase() caching the phase.
 	 * Since a phase is by definition relative to its parent, just
 	 * query the current clock phase, or just assume it's in phase.
 	 */
-	if (core->ops->get_phase)
-		core->phase = core->ops->get_phase(core->hw);
-	else
-		core->phase = 0;
+	clk_core_get_phase(core);
 
 	/*
 	 * Set clk's duty cycle.
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 2/4] clk: Use 'parent' to shorten lines in __clk_core_init()
  2020-02-05 23:27 [PATCH v2 0/4] clk_phase error caching problems Stephen Boyd
  2020-02-05 23:27 ` [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase() Stephen Boyd
@ 2020-02-05 23:28 ` Stephen Boyd
  2020-02-12 23:28   ` Stephen Boyd
  2020-02-05 23:28 ` [PATCH v2 3/4] clk: Move rate and accuracy recalc to mostly consumer APIs Stephen Boyd
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2020-02-05 23:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

Some lines are getting long in this function. Let's move 'parent' up to
the top of the function and use it in many places whenever there is a
parent for a clk. This shortens some lines by avoiding core->parent->
indirections.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/clk.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 26213e82f5f9..9ad950178d10 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3342,6 +3342,7 @@ static void clk_core_reparent_orphans_nolock(void)
 static int __clk_core_init(struct clk_core *core)
 {
 	int ret;
+	struct clk_core *parent;
 	unsigned long rate;
 
 	if (!core)
@@ -3413,7 +3414,7 @@ static int __clk_core_init(struct clk_core *core)
 			goto out;
 	}
 
-	core->parent = __clk_init_parent(core);
+	parent = core->parent = __clk_init_parent(core);
 
 	/*
 	 * Populate core->parent if parent has already been clk_core_init'd. If
@@ -3425,10 +3426,9 @@ static int __clk_core_init(struct clk_core *core)
 	 * clocks and re-parent any that are children of the clock currently
 	 * being clk_init'd.
 	 */
-	if (core->parent) {
-		hlist_add_head(&core->child_node,
-				&core->parent->children);
-		core->orphan = core->parent->orphan;
+	if (parent) {
+		hlist_add_head(&core->child_node, &parent->children);
+		core->orphan = parent->orphan;
 	} else if (!core->num_parents) {
 		hlist_add_head(&core->child_node, &clk_root_list);
 		core->orphan = false;
@@ -3446,9 +3446,9 @@ static int __clk_core_init(struct clk_core *core)
 	 */
 	if (core->ops->recalc_accuracy)
 		core->accuracy = core->ops->recalc_accuracy(core->hw,
-					__clk_get_accuracy(core->parent));
-	else if (core->parent)
-		core->accuracy = core->parent->accuracy;
+					__clk_get_accuracy(parent));
+	else if (parent)
+		core->accuracy = parent->accuracy;
 	else
 		core->accuracy = 0;
 
@@ -3472,9 +3472,9 @@ static int __clk_core_init(struct clk_core *core)
 	 */
 	if (core->ops->recalc_rate)
 		rate = core->ops->recalc_rate(core->hw,
-				clk_core_get_rate_nolock(core->parent));
-	else if (core->parent)
-		rate = core->parent->rate;
+				clk_core_get_rate_nolock(parent));
+	else if (parent)
+		rate = parent->rate;
 	else
 		rate = 0;
 	core->rate = core->req_rate = rate;
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 3/4] clk: Move rate and accuracy recalc to mostly consumer APIs
  2020-02-05 23:27 [PATCH v2 0/4] clk_phase error caching problems Stephen Boyd
  2020-02-05 23:27 ` [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase() Stephen Boyd
  2020-02-05 23:28 ` [PATCH v2 2/4] clk: Use 'parent' to shorten lines in __clk_core_init() Stephen Boyd
@ 2020-02-05 23:28 ` Stephen Boyd
  2020-02-12 23:28   ` Stephen Boyd
  2020-02-05 23:28 ` [PATCH v2 4/4] clk: Bail out when calculating phase fails during clk registration Stephen Boyd
  2020-02-06  8:27 ` [PATCH v2 0/4] clk_phase error caching problems Jerome Brunet
  4 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2020-02-05 23:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

There's some confusion about when recalc is done for the rate and
accuracy clk consumer APIs in relation to the prepare lock being taken.
Oddly enough, we take the lock again in debugfs APIs so that we can call
the internal "clk_core" APIs to get these fields with any necessary
recalculations. Instead of having this confusion, let's introduce a
recalc variant of these two consumer APIs as internal helpers and call
them from the consumer APIs and the debugfs code so that we don't take
the lock more than once.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/clk.c | 48 +++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 9ad950178d10..87532e2d124a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -488,7 +488,7 @@ unsigned long clk_hw_get_rate(const struct clk_hw *hw)
 }
 EXPORT_SYMBOL_GPL(clk_hw_get_rate);
 
-static unsigned long __clk_get_accuracy(struct clk_core *core)
+static unsigned long clk_core_get_accuracy_no_lock(struct clk_core *core)
 {
 	if (!core)
 		return 0;
@@ -1517,18 +1517,12 @@ static void __clk_recalc_accuracies(struct clk_core *core)
 		__clk_recalc_accuracies(child);
 }
 
-static long clk_core_get_accuracy(struct clk_core *core)
+static long clk_core_get_accuracy_recalc(struct clk_core *core)
 {
-	unsigned long accuracy;
-
-	clk_prepare_lock();
 	if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE))
 		__clk_recalc_accuracies(core);
 
-	accuracy = __clk_get_accuracy(core);
-	clk_prepare_unlock();
-
-	return accuracy;
+	return clk_core_get_accuracy_no_lock(core);
 }
 
 /**
@@ -1542,10 +1536,16 @@ static long clk_core_get_accuracy(struct clk_core *core)
  */
 long clk_get_accuracy(struct clk *clk)
 {
+	long accuracy;
+
 	if (!clk)
 		return 0;
 
-	return clk_core_get_accuracy(clk->core);
+	clk_prepare_lock();
+	accuracy = clk_core_get_accuracy_recalc(clk->core);
+	clk_prepare_unlock();
+
+	return accuracy;
 }
 EXPORT_SYMBOL_GPL(clk_get_accuracy);
 
@@ -1599,19 +1599,12 @@ static void __clk_recalc_rates(struct clk_core *core, unsigned long msg)
 		__clk_recalc_rates(child, msg);
 }
 
-static unsigned long clk_core_get_rate(struct clk_core *core)
+static unsigned long clk_core_get_rate_recalc(struct clk_core *core)
 {
-	unsigned long rate;
-
-	clk_prepare_lock();
-
 	if (core && (core->flags & CLK_GET_RATE_NOCACHE))
 		__clk_recalc_rates(core, 0);
 
-	rate = clk_core_get_rate_nolock(core);
-	clk_prepare_unlock();
-
-	return rate;
+	return clk_core_get_rate_nolock(core);
 }
 
 /**
@@ -1624,10 +1617,16 @@ static unsigned long clk_core_get_rate(struct clk_core *core)
  */
 unsigned long clk_get_rate(struct clk *clk)
 {
+	unsigned long rate;
+
 	if (!clk)
 		return 0;
 
-	return clk_core_get_rate(clk->core);
+	clk_prepare_lock();
+	rate = clk_core_get_rate_recalc(clk->core);
+	clk_prepare_unlock();
+
+	return rate;
 }
 EXPORT_SYMBOL_GPL(clk_get_rate);
 
@@ -2910,7 +2909,8 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
 		   level * 3 + 1, "",
 		   30 - level * 3, c->name,
 		   c->enable_count, c->prepare_count, c->protect_count,
-		   clk_core_get_rate(c), clk_core_get_accuracy(c));
+		   clk_core_get_rate_recalc(c),
+		   clk_core_get_accuracy_recalc(c));
 
 	phase = clk_core_get_phase(c);
 	if (phase >= 0)
@@ -2965,10 +2965,10 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
 	seq_printf(s, "\"enable_count\": %d,", c->enable_count);
 	seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
 	seq_printf(s, "\"protect_count\": %d,", c->protect_count);
-	seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
+	seq_printf(s, "\"rate\": %lu,", clk_core_get_rate_recalc(c));
 	seq_printf(s, "\"min_rate\": %lu,", min_rate);
 	seq_printf(s, "\"max_rate\": %lu,", max_rate);
-	seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
+	seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy_recalc(c));
 	phase = clk_core_get_phase(c);
 	if (phase >= 0)
 		seq_printf(s, "\"phase\": %d,", phase);
@@ -3446,7 +3446,7 @@ static int __clk_core_init(struct clk_core *core)
 	 */
 	if (core->ops->recalc_accuracy)
 		core->accuracy = core->ops->recalc_accuracy(core->hw,
-					__clk_get_accuracy(parent));
+					clk_core_get_accuracy_no_lock(parent));
 	else if (parent)
 		core->accuracy = parent->accuracy;
 	else
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 4/4] clk: Bail out when calculating phase fails during clk registration
  2020-02-05 23:27 [PATCH v2 0/4] clk_phase error caching problems Stephen Boyd
                   ` (2 preceding siblings ...)
  2020-02-05 23:28 ` [PATCH v2 3/4] clk: Move rate and accuracy recalc to mostly consumer APIs Stephen Boyd
@ 2020-02-05 23:28 ` Stephen Boyd
  2020-02-12 23:28   ` Stephen Boyd
  2020-02-06  8:27 ` [PATCH v2 0/4] clk_phase error caching problems Jerome Brunet
  4 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2020-02-05 23:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

Bail out of clk registration if we fail to get the phase for a clk that
has a clk_ops::get_phase() callback. Print a warning too so that driver
authors can easily figure out that some clk is unable to read back phase
information at boot.

Cc: Douglas Anderson <dianders@chromium.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Suggested-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
 drivers/clk/clk.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 87532e2d124a..e9e83f7ae9e0 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3457,7 +3457,12 @@ static int __clk_core_init(struct clk_core *core)
 	 * Since a phase is by definition relative to its parent, just
 	 * query the current clock phase, or just assume it's in phase.
 	 */
-	clk_core_get_phase(core);
+	ret = clk_core_get_phase(core);
+	if (ret < 0) {
+		pr_warn("%s: Failed to get phase for clk '%s'\n", __func__,
+			core->name);
+		goto out;
+	}
 
 	/*
 	 * Set clk's duty cycle.
-- 
Sent by a computer, using git, on the internet


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase()
  2020-02-05 23:27 ` [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase() Stephen Boyd
@ 2020-02-06  8:26   ` Jerome Brunet
  2020-02-12 23:27     ` Stephen Boyd
  2020-02-12 23:28   ` Stephen Boyd
  1 sibling, 1 reply; 12+ messages in thread
From: Jerome Brunet @ 2020-02-06  8:26 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner


On Thu 06 Feb 2020 at 00:27, Stephen Boyd <sboyd@kernel.org> wrote:

> We don't check for errors from clk_ops::get_phase() before storing away
> the result into the clk_core::phase member. This can lead to some fairly
> confusing debugfs information if these ops do return an error. Let's
> skip the store when this op fails to fix this. While we're here, move
> the locking outside of clk_core_get_phase() to simplify callers from
> the debugfs side.
>
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> ---
>  drivers/clk/clk.c | 48 +++++++++++++++++++++++++++++++----------------
>  1 file changed, 32 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index d529ad67805c..26213e82f5f9 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2660,12 +2660,14 @@ static int clk_core_get_phase(struct clk_core *core)
>  {
>  	int ret;
>  
> -	clk_prepare_lock();

Should the function name get the "_nolock" suffix then ?

> +	lockdep_assert_held(&prepare_lock);
> +	if (!core->ops->get_phase)
> +		return 0;
> +
>  	/* Always try to update cached phase if possible */
> -	if (core->ops->get_phase)
> -		core->phase = core->ops->get_phase(core->hw);
> -	ret = core->phase;
> -	clk_prepare_unlock();
> +	ret = core->ops->get_phase(core->hw);
> +	if (ret >= 0)
> +		core->phase = ret;
>  
>  	return ret;
>  }
> @@ -2679,10 +2681,16 @@ static int clk_core_get_phase(struct clk_core *core)
>   */
>  int clk_get_phase(struct clk *clk)
>  {
> +	int ret;
> +
>  	if (!clk)
>  		return 0;
>  
> -	return clk_core_get_phase(clk->core);
> +	clk_prepare_lock();
> +	ret = clk_core_get_phase(clk->core);
> +	clk_prepare_unlock();
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL_GPL(clk_get_phase);
>  
> @@ -2896,13 +2904,21 @@ static struct hlist_head *orphan_list[] = {
>  static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
>  				 int level)
>  {
> -	seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n",
> +	int phase;
> +
> +	seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ",
>  		   level * 3 + 1, "",
>  		   30 - level * 3, c->name,
>  		   c->enable_count, c->prepare_count, c->protect_count,
> -		   clk_core_get_rate(c), clk_core_get_accuracy(c),
> -		   clk_core_get_phase(c),
> -		   clk_core_get_scaled_duty_cycle(c, 100000));
> +		   clk_core_get_rate(c), clk_core_get_accuracy(c));
> +
> +	phase = clk_core_get_phase(c);
> +	if (phase >= 0)
> +		seq_printf(s, "%5d", phase);
> +	else
> +		seq_puts(s, "-----");
> +
> +	seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000));
>  }
>  
>  static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
> @@ -2939,6 +2955,7 @@ DEFINE_SHOW_ATTRIBUTE(clk_summary);
>  
>  static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
>  {
> +	int phase;
>  	unsigned long min_rate, max_rate;
>  
>  	clk_core_get_boundaries(c, &min_rate, &max_rate);
> @@ -2952,7 +2969,9 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
>  	seq_printf(s, "\"min_rate\": %lu,", min_rate);
>  	seq_printf(s, "\"max_rate\": %lu,", max_rate);
>  	seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
> -	seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c));
> +	phase = clk_core_get_phase(c);
> +	if (phase >= 0)
> +		seq_printf(s, "\"phase\": %d,", phase);
>  	seq_printf(s, "\"duty_cycle\": %u",
>  		   clk_core_get_scaled_duty_cycle(c, 100000));
>  }
> @@ -3434,14 +3453,11 @@ static int __clk_core_init(struct clk_core *core)
>  		core->accuracy = 0;
>  
>  	/*
> -	 * Set clk's phase.
> +	 * Set clk's phase by clk_core_get_phase() caching the phase.
>  	 * Since a phase is by definition relative to its parent, just
>  	 * query the current clock phase, or just assume it's in phase.
>  	 */
> -	if (core->ops->get_phase)
> -		core->phase = core->ops->get_phase(core->hw);
> -	else
> -		core->phase = 0;
> +	clk_core_get_phase(core);
>  
>  	/*
>  	 * Set clk's duty cycle.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/4] clk_phase error caching problems
  2020-02-05 23:27 [PATCH v2 0/4] clk_phase error caching problems Stephen Boyd
                   ` (3 preceding siblings ...)
  2020-02-05 23:28 ` [PATCH v2 4/4] clk: Bail out when calculating phase fails during clk registration Stephen Boyd
@ 2020-02-06  8:27 ` Jerome Brunet
  4 siblings, 0 replies; 12+ messages in thread
From: Jerome Brunet @ 2020-02-06  8:27 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner


On Thu 06 Feb 2020 at 00:27, Stephen Boyd <sboyd@kernel.org> wrote:

> This patch series is a follow up to[1] which I sent out a few months
> ago. We no longer cache the clk phase if it's an error value, so that
> things like debugfs don't return us nonsense values for the phase.
>
> Futhermore, the last patch fixes up the locking so that debugfs code
> can avoid doing a recursive prepare lock because we know what we're
> doing in that case. While we get some more functions, we avoid taking
> the lock again.
>
> Changes from v1:
>  * A pile of new patches
>  * Rebased to clk-next
>  * New patch to bail out of registration if getting the phase fails

Series look good - comment on patch 1 is just a nitpick

Acked-by: Jerome Brunet <jbrunet@baylibre.com>

>
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
>
> Stephen Boyd (4):
>   clk: Don't cache errors from clk_ops::get_phase()
>   clk: Use 'parent' to shorten lines in __clk_core_init()
>   clk: Move rate and accuracy recalc to mostly consumer APIs
>   clk: Bail out when calculating phase fails during clk registration
>
>  drivers/clk/clk.c | 119 +++++++++++++++++++++++++++-------------------
>  1 file changed, 70 insertions(+), 49 deletions(-)
>
> [1] https://lkml.kernel.org/r/20191001174439.182435-1-sboyd@kernel.org
>
> base-commit: 5df867145f8adad9e5cdf9d67db1fbc0f71351e9


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase()
  2020-02-06  8:26   ` Jerome Brunet
@ 2020-02-12 23:27     ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-12 23:27 UTC (permalink / raw)
  To: Jerome Brunet, Michael Turquette
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner

Quoting Jerome Brunet (2020-02-06 00:26:06)
> 
> On Thu 06 Feb 2020 at 00:27, Stephen Boyd <sboyd@kernel.org> wrote:
> 
> > We don't check for errors from clk_ops::get_phase() before storing away
> > the result into the clk_core::phase member. This can lead to some fairly
> > confusing debugfs information if these ops do return an error. Let's
> > skip the store when this op fails to fix this. While we're here, move
> > the locking outside of clk_core_get_phase() to simplify callers from
> > the debugfs side.
> >
> > Cc: Douglas Anderson <dianders@chromium.org>
> > Cc: Heiko Stuebner <heiko@sntech.de>
> > Cc: Jerome Brunet <jbrunet@baylibre.com>
> > Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> > ---
> >  drivers/clk/clk.c | 48 +++++++++++++++++++++++++++++++----------------
> >  1 file changed, 32 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > index d529ad67805c..26213e82f5f9 100644
> > --- a/drivers/clk/clk.c
> > +++ b/drivers/clk/clk.c
> > @@ -2660,12 +2660,14 @@ static int clk_core_get_phase(struct clk_core *core)
> >  {
> >       int ret;
> >  
> > -     clk_prepare_lock();
> 
> Should the function name get the "_nolock" suffix then ?
> 

I figure we can add such a one if clk_core_ prefix isn't enough to
differentiate.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase()
  2020-02-05 23:27 ` [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase() Stephen Boyd
  2020-02-06  8:26   ` Jerome Brunet
@ 2020-02-12 23:28   ` Stephen Boyd
  1 sibling, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-12 23:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

Quoting Stephen Boyd (2020-02-05 15:27:59)
> We don't check for errors from clk_ops::get_phase() before storing away
> the result into the clk_core::phase member. This can lead to some fairly
> confusing debugfs information if these ops do return an error. Let's
> skip the store when this op fails to fix this. While we're here, move
> the locking outside of clk_core_get_phase() to simplify callers from
> the debugfs side.
> 
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 2/4] clk: Use 'parent' to shorten lines in __clk_core_init()
  2020-02-05 23:28 ` [PATCH v2 2/4] clk: Use 'parent' to shorten lines in __clk_core_init() Stephen Boyd
@ 2020-02-12 23:28   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-12 23:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

Quoting Stephen Boyd (2020-02-05 15:28:00)
> Some lines are getting long in this function. Let's move 'parent' up to
> the top of the function and use it in many places whenever there is a
> parent for a clk. This shortens some lines by avoiding core->parent->
> indirections.
> 
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/4] clk: Move rate and accuracy recalc to mostly consumer APIs
  2020-02-05 23:28 ` [PATCH v2 3/4] clk: Move rate and accuracy recalc to mostly consumer APIs Stephen Boyd
@ 2020-02-12 23:28   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-12 23:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

Quoting Stephen Boyd (2020-02-05 15:28:01)
> There's some confusion about when recalc is done for the rate and
> accuracy clk consumer APIs in relation to the prepare lock being taken.
> Oddly enough, we take the lock again in debugfs APIs so that we can call
> the internal "clk_core" APIs to get these fields with any necessary
> recalculations. Instead of having this confusion, let's introduce a
> recalc variant of these two consumer APIs as internal helpers and call
> them from the consumer APIs and the debugfs code so that we don't take
> the lock more than once.
> 
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/4] clk: Bail out when calculating phase fails during clk registration
  2020-02-05 23:28 ` [PATCH v2 4/4] clk: Bail out when calculating phase fails during clk registration Stephen Boyd
@ 2020-02-12 23:28   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2020-02-12 23:28 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Douglas Anderson, Heiko Stuebner, Jerome Brunet

Quoting Stephen Boyd (2020-02-05 15:28:02)
> Bail out of clk registration if we fail to get the phase for a clk that
> has a clk_ops::get_phase() callback. Print a warning too so that driver
> authors can easily figure out that some clk is unable to read back phase
> information at boot.
> 
> Cc: Douglas Anderson <dianders@chromium.org>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Suggested-by: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
> ---

Applied to clk-next

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-02-12 23:28 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-05 23:27 [PATCH v2 0/4] clk_phase error caching problems Stephen Boyd
2020-02-05 23:27 ` [PATCH v2 1/4] clk: Don't cache errors from clk_ops::get_phase() Stephen Boyd
2020-02-06  8:26   ` Jerome Brunet
2020-02-12 23:27     ` Stephen Boyd
2020-02-12 23:28   ` Stephen Boyd
2020-02-05 23:28 ` [PATCH v2 2/4] clk: Use 'parent' to shorten lines in __clk_core_init() Stephen Boyd
2020-02-12 23:28   ` Stephen Boyd
2020-02-05 23:28 ` [PATCH v2 3/4] clk: Move rate and accuracy recalc to mostly consumer APIs Stephen Boyd
2020-02-12 23:28   ` Stephen Boyd
2020-02-05 23:28 ` [PATCH v2 4/4] clk: Bail out when calculating phase fails during clk registration Stephen Boyd
2020-02-12 23:28   ` Stephen Boyd
2020-02-06  8:27 ` [PATCH v2 0/4] clk_phase error caching problems Jerome Brunet

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).