[3.16.y-ckt stable] Patch "clk: at91: keep slow clk enabled to prevent system hang" has been added to staging queue

Luis Henriques luis.henriques at canonical.com
Mon Jan 26 14:32:50 UTC 2015


This is a note to let you know that I have just added a patch titled

    clk: at91: keep slow clk enabled to prevent system hang

to the linux-3.16.y-queue branch of the 3.16.y-ckt extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.16.y-queue

This patch is scheduled to be released in version 3.16.7-ckt5.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.16.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

------

>From eb601e470d507073f5de315113c60182ee7b0bf3 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon at free-electrons.com>
Date: Tue, 13 Jan 2015 15:44:06 +0100
Subject: clk: at91: keep slow clk enabled to prevent system hang

commit dca1a4b5ff6e2c25adeff366eb06270dadeab3db upstream.

All slow clk users are not properly claiming it (get + prepare + enable)
before using it.
If all users properly claiming this clock release it, the clock is
disabled, but faulty users still depends on it, and the system hangs.

This fix prevents the slow clock from being disabled, and should solve the
hanging issue, but offending drivers should be patched to properly claim
this clock.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Reported-by: Bo Shen <voice.shen at atmel.com>
Signed-off-by: Michael Turquette <mturquette at linaro.org>
Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
---
 drivers/clk/at91/clk-slow.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
index 0300c46ee247..ef8d458cd74a 100644
--- a/drivers/clk/at91/clk-slow.c
+++ b/drivers/clk/at91/clk-slow.c
@@ -70,6 +70,7 @@ struct clk_sam9x5_slow {

 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)

+static struct clk *slow_clk;

 static int clk_slow_osc_prepare(struct clk_hw *hw)
 {
@@ -357,6 +358,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
 	clk = clk_register(NULL, &slowck->hw);
 	if (IS_ERR(clk))
 		kfree(slowck);
+	else
+		slow_clk = clk;

 	return clk;
 }
@@ -433,6 +436,8 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
 	clk = clk_register(NULL, &slowck->hw);
 	if (IS_ERR(clk))
 		kfree(slowck);
+	else
+		slow_clk = clk;

 	return clk;
 }
@@ -465,3 +470,25 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np,

 	of_clk_add_provider(np, of_clk_src_simple_get, clk);
 }
+
+/*
+ * FIXME: All slow clk users are not properly claiming it (get + prepare +
+ * enable) before using it.
+ * If all users properly claiming this clock decide that they don't need it
+ * anymore (or are removed), it is disabled while faulty users are still
+ * requiring it, and the system hangs.
+ * Prevent this clock from being disabled until all users are properly
+ * requesting it.
+ * Once this is done we should remove this function and the slow_clk variable.
+ */
+static int __init of_at91_clk_slow_retain(void)
+{
+	if (!slow_clk)
+		return 0;
+
+	__clk_get(slow_clk);
+	clk_prepare_enable(slow_clk);
+
+	return 0;
+}
+arch_initcall(of_at91_clk_slow_retain);
--
2.1.4





More information about the kernel-team mailing list