MLK-14957 clk: imx8qm/qxp: delay the clk driver initialization
authorPeng Fan <peng.fan@nxp.com>
Tue, 23 May 2017 09:30:39 +0000 (17:30 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:22:25 +0000 (15:22 -0500)
Using CLK_OF_DECLARE will register clks at very early stage
that AP-SC communication still not ready.

MU driver is registered by early_initcall, so using core_initcall
to delay the registeration of clk driver is ok.

Move channel open function into probe to avoid core_init sequence
not in our expected order. If MU not ready, return defer probe
for clk driver.

Later when we switch to use interrupt driver AP-SC communication,
we could also return defer probe in clk probe function to wait
until AP-SC communication ready.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
drivers/clk/imx/clk-imx8.c
drivers/clk/imx/clk-imx8.h
drivers/clk/imx/clk-imx8qm.c
drivers/clk/imx/clk-imx8qxp.c

index 4d869f2..f13b355 100644 (file)
@@ -13,6 +13,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/errno.h>
 #include <soc/imx8/sc/sci.h>
 
 #include "clk-imx8.h"
@@ -20,7 +21,7 @@
 spinlock_t imx_ccm_lock;
 sc_ipc_t ccm_ipc_handle;
 
-static int __init notify_imx8_clk(void)
+int imx8_clk_mu_init(void)
 {
        uint32_t mu_id;
        sc_err_t sciErr;
@@ -30,16 +31,15 @@ static int __init notify_imx8_clk(void)
        sciErr = sc_ipc_getMuID(&mu_id);
        if (sciErr != SC_ERR_NONE) {
                pr_info("Cannot obtain MU ID\n");
-               return sciErr;
+               return -EPROBE_DEFER;
        }
 
        sciErr = sc_ipc_open(&ccm_ipc_handle, mu_id);
 
        if (sciErr != SC_ERR_NONE) {
                pr_info("Cannot open MU channel to SCU\n");
-               return sciErr;
+               return -EPROBE_DEFER;
        }
 
        return 0;
 }
-core_initcall(notify_imx8_clk);
index 80f559a..0458381 100644 (file)
@@ -9,6 +9,8 @@
 extern spinlock_t imx_ccm_lock;
 extern sc_ipc_t ccm_ipc_handle;
 
+int imx8_clk_mu_init(void);
+
 struct clk *imx_clk_divider_scu(const char *name,
                                        sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type);
 
index 2913595..8c2a674 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/types.h>
 
@@ -113,11 +114,16 @@ static const char *enet_sels[] = {"enet_25MHz", "enet_125MHz",};
 static const char *enet0_rmii_tx_sels[] = {"enet0_ref_div", "dummy",};
 static const char *enet1_rmii_tx_sels[] = {"enet1_ref_div", "dummy",};
 
-static void __init imx8qm_clocks_init(struct device_node *ccm_node)
+static int imx8qm_clk_probe(struct platform_device *pdev)
 {
-       int i;
+       struct device_node *ccm_node = pdev->dev.of_node;
        struct device_node *np_acm;
        void __iomem *base_acm;
+       int i, ret;
+
+       ret = imx8_clk_mu_init();
+       if (ret)
+               return ret;
 
        pr_info("***** imx8qm_clocks_init *****\n");
 
@@ -857,18 +863,24 @@ static void __init imx8qm_clocks_init(struct device_node *ccm_node)
 
        clk_prepare_enable(clks[IMX8QM_A53_DIV]);
        clk_prepare_enable(clks[IMX8QM_A72_DIV]);
+
+       return 0;
 }
 
-static int __init imx8qm_post_clk_init(void)
-{
-       int i;
+static const struct of_device_id imx8qm_match[] = {
+       { .compatible = "fsl,imx8qm-clk", }
+};
 
-       /* Initialize the clk rate for all the possible clocks now. */
-       for (i = 0; i < IMX8QM_CLK_END; i++)
-               clk_get_rate(clks[i]);
+static struct platform_driver imx8qm_clk_driver = {
+       .driver = {
+               .name = "imx8qm-clk",
+               .of_match_table = imx8qm_match,
+       },
+       .probe = imx8qm_clk_probe,
+};
 
-       return 0;
+static int __init imx8qm_clk_init(void)
+{
+       return platform_driver_register(&imx8qm_clk_driver);
 }
-postcore_initcall(imx8qm_post_clk_init);
-
-CLK_OF_DECLARE(imx8qm, "fsl,imx8qm-clk", imx8qm_clocks_init);
+core_initcall(imx8qm_clk_init);
index ea2832e..d127405 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/types.h>
+#include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 
 #include <soc/imx8/imx8qxp/lpcg.h>
@@ -97,11 +98,16 @@ static const char *enet_sels[] = { "enet_25MHz", "enet_125MHz", };
 static const char *enet0_rmii_tx_sels[] = { "enet0_ref_div", "dummy", };
 static const char *enet1_rmii_tx_sels[] = { "enet1_ref_div", "dummy", };
 
-static void __init imx8qxp_clocks_init(struct device_node *ccm_node)
+static int imx8qxp_clk_probe(struct platform_device *pdev)
 {
-       int i;
+       struct device_node *ccm_node = pdev->dev.of_node;
        struct device_node *np_acm;
        void __iomem *base_acm;
+       int i, ret;
+
+       ret = imx8_clk_mu_init();
+       if (ret)
+               return ret;
 
        pr_info("***** imx8qxp_clocks_init *****\n");
 
@@ -564,18 +570,24 @@ static void __init imx8qxp_clocks_init(struct device_node *ccm_node)
        clk_data.clks = clks;
        clk_data.clk_num = ARRAY_SIZE(clks);
        of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
+
+       return 0;
 }
 
-static int __init imx8qxp_post_clk_init(void)
-{
-       int i;
+static const struct of_device_id imx8qxp_match[] = {
+       { .compatible = "fsl,imx8qxp-clk", }
+};
 
-       /* Initialize the clk rate for all the possible clocks now. */
-       for (i = 0; i < IMX8QXP_CLK_END; i++)
-               clk_get_rate(clks[i]);
+static struct platform_driver imx8qxp_clk_driver = {
+       .driver = {
+               .name = "imx8qxp-clk",
+               .of_match_table = imx8qxp_match,
+       },
+       .probe = imx8qxp_clk_probe,
+};
 
-       return 0;
+static int __init imx8qxp_clk_init(void)
+{
+       return platform_driver_register(&imx8qxp_clk_driver);
 }
-postcore_initcall(imx8qxp_post_clk_init);
-
-CLK_OF_DECLARE(imx8qxp, "fsl,imx8qxp-clk", imx8qxp_clocks_init);
+core_initcall(imx8qxp_clk_init);