linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2] arm: imx: correct the hardware clock gate setting for shared nodes
@ 2014-12-10  8:51 Anson Huang
  2014-12-10  9:13 ` Uwe Kleine-König
  0 siblings, 1 reply; 2+ messages in thread
From: Anson Huang @ 2014-12-10  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

For those clk gates which hold share count, since its is_enabled
callback is only checking the share count rather than reading
the hardware register setting, in the late phase of kernel bootup,
the clk_disable_unused action will NOT handle the scenario of
share_count is 0 but the hardware setting is enabled, actually,
uboot normally enables all clk gates, then those shared clk gates
will be always enabled until they are used by some modules.

So the problem would be: when kernel boot up, the usecount cat
from clk tree is 0, but the clk gates actually is enabled in
hardware register, it will confuse user and bring unnecessary power
consumption.

This patch adds .disable_unused callback to handle such scenario in
late phase of kernel boot up, then the hardware status will match the
clk tree info.

Signed-off-by: Anson Huang <b20788@freescale.com>
---
changes from V1:
	handle such issue via clk-gate2 framework to fulfill all
i.mx6 platforms, introduced .disable_unused callback.
 arch/arm/mach-imx/clk-gate2.c |   24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
index 5a75cdc..18204db 100644
--- a/arch/arm/mach-imx/clk-gate2.c
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -96,15 +96,31 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
 {
 	struct clk_gate2 *gate = to_clk_gate2(hw);
 
-	if (gate->share_count)
-		return !!__clk_get_enable_count(hw->clk);
-	else
-		return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
+	return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
+}
+
+static void clk_gate2_disable_unused(struct clk_hw *hw)
+{
+	struct clk_gate2 *gate = to_clk_gate2(hw);
+	unsigned long flags = 0;
+	u32 reg;
+
+	spin_lock_irqsave(gate->lock, flags);
+
+	if ((gate->share_count && *gate->share_count == 0) ||
+		!gate->share_count) {
+		reg = readl(gate->reg);
+		reg &= ~(3 << gate->bit_idx);
+		writel(reg, gate->reg);
+	}
+
+	spin_unlock_irqrestore(gate->lock, flags);
 }
 
 static struct clk_ops clk_gate2_ops = {
 	.enable = clk_gate2_enable,
 	.disable = clk_gate2_disable,
+	.disable_unused = clk_gate2_disable_unused,
 	.is_enabled = clk_gate2_is_enabled,
 };
 
-- 
1.7.9.5

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

* [PATCH V2] arm: imx: correct the hardware clock gate setting for shared nodes
  2014-12-10  8:51 [PATCH V2] arm: imx: correct the hardware clock gate setting for shared nodes Anson Huang
@ 2014-12-10  9:13 ` Uwe Kleine-König
  0 siblings, 0 replies; 2+ messages in thread
From: Uwe Kleine-König @ 2014-12-10  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Wed, Dec 10, 2014 at 04:51:20PM +0800, Anson Huang wrote:
> For those clk gates which hold share count, since its is_enabled
> callback is only checking the share count rather than reading
> the hardware register setting, in the late phase of kernel bootup,
> the clk_disable_unused action will NOT handle the scenario of
> share_count is 0 but the hardware setting is enabled, actually,
> uboot normally enables all clk gates, then those shared clk gates
still s/uboot/U-Boot/

> will be always enabled until they are used by some modules.
> 
> So the problem would be: when kernel boot up, the usecount cat
> from clk tree is 0, but the clk gates actually is enabled in
> hardware register, it will confuse user and bring unnecessary power
> consumption.
> 
> This patch adds .disable_unused callback to handle such scenario in
> late phase of kernel boot up, then the hardware status will match the
> clk tree info.
> 
> Signed-off-by: Anson Huang <b20788@freescale.com>
> ---
> changes from V1:
> 	handle such issue via clk-gate2 framework to fulfill all
> i.mx6 platforms, introduced .disable_unused callback.
>  arch/arm/mach-imx/clk-gate2.c |   24 ++++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
> index 5a75cdc..18204db 100644
> --- a/arch/arm/mach-imx/clk-gate2.c
> +++ b/arch/arm/mach-imx/clk-gate2.c
> @@ -96,15 +96,31 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
>  {
>  	struct clk_gate2 *gate = to_clk_gate2(hw);
>  
> -	if (gate->share_count)
> -		return !!__clk_get_enable_count(hw->clk);
> -	else
> -		return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
> +	return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
point out in the commit log that this is changed.

> +}
> +
> +static void clk_gate2_disable_unused(struct clk_hw *hw)
> +{
> +	struct clk_gate2 *gate = to_clk_gate2(hw);
> +	unsigned long flags = 0;
> +	u32 reg;
> +
> +	spin_lock_irqsave(gate->lock, flags);
> +
> +	if ((gate->share_count && *gate->share_count == 0) ||
> +		!gate->share_count) {
That's equivalent to the simpler expression
	if (!gate->share_count || *gate->share_count == 0)

Other than that it doesn't make the status quo worse, still I'd prefer
a nicer model for these shared clocks.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

end of thread, other threads:[~2014-12-10  9:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-10  8:51 [PATCH V2] arm: imx: correct the hardware clock gate setting for shared nodes Anson Huang
2014-12-10  9:13 ` Uwe Kleine-König

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