summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2022-10-05 21:41:08 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2022-10-06 10:42:34 +0200
commitac33f77ac47ffb2c1de4029ae1083d6f4e421e32 (patch)
treeec861acedf3b64d8cfe4f87adad849c8237c4a37
parent8a805a26bc724f4193c79037c1d0c1d2c87dd06e (diff)
downloadbarebox-ac33f77ac47ffb2c1de4029ae1083d6f4e421e32.tar.gz
barebox-ac33f77ac47ffb2c1de4029ae1083d6f4e421e32.tar.xz
clks: imx7: fix initial clock setup with deep probe enabled
We register the i.MX7 clock controller driver at core_initcall level and then do some initial clock setup/reparenting at postcore_initcall level. This doesn't work as expected when deep probe is enabled, because while the driver is registered at core_initcall level, it's only probed later on, currently at postcore_initcall level because it's a dependency of the timer for which of_ensure_device_probed is called. As the initial clock setup is also at postcore_initcall level, it's no longer guaranteed that the code executes in the same order. Fix this by directly doing the setup at the end of the probe function for the deep probe case. In non-deep-probe systems, we maintain the existing initcall ordering to avoid regressions. Co-developed-by: Johannes Zink <j.zink@pengutronix.de> Signed-off-by: Johannes Zink <j.zink@pengutronix.de> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20221005194108.3380781-1-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--drivers/clk/imx/clk-imx7.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/clk/imx/clk-imx7.c b/drivers/clk/imx/clk-imx7.c
index ffa39d17b0..588e9cbe5c 100644
--- a/drivers/clk/imx/clk-imx7.c
+++ b/drivers/clk/imx/clk-imx7.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <init.h>
#include <driver.h>
+#include <deep-probe.h>
#include <linux/clk.h>
#include <io.h>
#include <of.h>
@@ -358,7 +359,9 @@ static int const clks_init_on[] __initconst = {
static struct clk_onecell_data clk_data;
-static int imx7_clk_initialized;
+static struct device_node *ccm_np;
+
+static int imx7_clk_setup(void);
static int imx7_ccm_probe(struct device_d *dev)
{
@@ -806,19 +809,35 @@ static int imx7_ccm_probe(struct device_d *dev)
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data);
- imx7_clk_initialized = 1;
+ ccm_np = dev->device_node;
+
+ /*
+ * imx7_clk_setup() requires both the CCM and fixed-clock osc devices
+ * to be available.
+ * With deep probe enabled, we can instead just directly call
+ * imx7_clk_setup because the osc fixed-clock will just be probed
+ * on demand if not yet available. Otherwise, the imx7_clk_setup
+ * will run at postcore_initcall level.
+ */
+ if (deep_probe_is_supported())
+ return imx7_clk_setup();
return 0;
}
static int imx7_clk_setup(void)
{
+ struct clk *clk;
int i;
- if (!imx7_clk_initialized)
+ if (!ccm_np)
return 0;
- clks[IMX7D_OSC_24M_CLK] = clk_lookup("osc");
+ clk = of_clk_get_by_name(ccm_np, "osc");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ clks[IMX7D_OSC_24M_CLK] = clk;
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
clk_enable(clks[clks_init_on[i]]);
@@ -840,6 +859,8 @@ static int imx7_clk_setup(void)
clk_set_rate(clks[IMX7D_ENET1_TIME_ROOT_CLK], 25000000);
clk_set_rate(clks[IMX7D_ENET2_TIME_ROOT_CLK], 25000000);
+ ccm_np = NULL;
+
return 0;
}
postcore_initcall(imx7_clk_setup);