]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
clk: scu/imx8qxp: do not register driver in probe()
authorDanilo Krummrich <dakr@kernel.org>
Thu, 12 Feb 2026 23:58:11 +0000 (00:58 +0100)
committerDanilo Krummrich <dakr@kernel.org>
Tue, 24 Feb 2026 11:54:17 +0000 (12:54 +0100)
imx_clk_scu_init() registers the imx_clk_scu_driver while commonly being
called from IMX driver's probe() callbacks.

However, it neither makes sense to register drivers from probe()
callbacks of other drivers, nor does the driver core allow registering
drivers with a device lock already being held.

The latter was revealed by commit dc23806a7c47 ("driver core: enforce
device_lock for driver_match_device()") leading to a deadlock condition
described in [1].

Besides that, nothing seems to unregister the imx_clk_scu_driver once
the corresponding driver module is unloaded, which leaves the
driver-core with a dangling pointer.

Also, if there are multiple matching devices for the imx8qxp_clk_driver,
imx8qxp_clk_probe() calls imx_clk_scu_init() multiple times.  However,
any subsequent call after the first one will fail, since the driver-core
does not allow to register the same struct platform_driver multiple
times.

Hence, register the imx_clk_scu_driver from module_init() and unregister
it in module_exit().

Note that we first register the imx8qxp_clk_driver and then call
imx_clk_scu_module_init() to avoid having to call
imx_clk_scu_module_exit() in the unwind path of imx8qxp_clk_init().

Fixes: dc23806a7c47 ("driver core: enforce device_lock for driver_match_device()")
Fixes: 220175cd3979 ("clk: imx: scu: fix build break when compiled as modules")
Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Closes: https://lore.kernel.org/lkml/13955113.uLZWGnKmhe@steina-w/
Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # TQMa8x/MBa8x
Link: https://lore.kernel.org/lkml/DFU7CEPUSG9A.1KKGVW4HIPMSH@kernel.org/
Acked-by: Abel Vesa <abelvesa@kernel.org>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Link: https://patch.msgid.link/20260212235842.85934-1-dakr@kernel.org
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
drivers/clk/imx/clk-imx8qxp.c
drivers/clk/imx/clk-scu.c
drivers/clk/imx/clk-scu.h

index 3ae162625bb1a412a4993747bf86de1cd108b41e..c781425a005ef78640255c7bc26ca221cc07ce68 100644 (file)
@@ -346,7 +346,29 @@ static struct platform_driver imx8qxp_clk_driver = {
        },
        .probe = imx8qxp_clk_probe,
 };
-module_platform_driver(imx8qxp_clk_driver);
+
+static int __init imx8qxp_clk_init(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&imx8qxp_clk_driver);
+       if (ret)
+               return ret;
+
+       ret = imx_clk_scu_module_init();
+       if (ret)
+               platform_driver_unregister(&imx8qxp_clk_driver);
+
+       return ret;
+}
+module_init(imx8qxp_clk_init);
+
+static void __exit imx8qxp_clk_exit(void)
+{
+       imx_clk_scu_module_exit();
+       platform_driver_unregister(&imx8qxp_clk_driver);
+}
+module_exit(imx8qxp_clk_exit);
 
 MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
 MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
index 33e637ad3579373adefcbbf801ff5ac618e81f9f..a85ec48a798b58a12f893587c85709bbd8476310 100644 (file)
@@ -191,6 +191,16 @@ static bool imx_scu_clk_is_valid(u32 rsrc_id)
        return p != NULL;
 }
 
+int __init imx_clk_scu_module_init(void)
+{
+       return platform_driver_register(&imx_clk_scu_driver);
+}
+
+void __exit imx_clk_scu_module_exit(void)
+{
+       return platform_driver_unregister(&imx_clk_scu_driver);
+}
+
 int imx_clk_scu_init(struct device_node *np,
                     const struct imx_clk_scu_rsrc_table *data)
 {
@@ -215,7 +225,7 @@ int imx_clk_scu_init(struct device_node *np,
                rsrc_table = data;
        }
 
-       return platform_driver_register(&imx_clk_scu_driver);
+       return 0;
 }
 
 /*
index af7b697f51cae359b57f7dfb99cb22e41fd71ec8..ca82f2cce89740b8e207f7039b56dfb6ec4eaeec 100644 (file)
@@ -25,6 +25,8 @@ extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl;
 extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp;
 extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm;
 
+int __init imx_clk_scu_module_init(void);
+void __exit imx_clk_scu_module_exit(void);
 int imx_clk_scu_init(struct device_node *np,
                     const struct imx_clk_scu_rsrc_table *data);
 struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,