|
@@ -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);
|