Skip to content

Commit 78437ab

Browse files
author
Danilo Krummrich
committed
clk: scu/imx8qxp: do not register driver in probe()
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 dc23806 ("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: dc23806 ("driver core: enforce device_lock for driver_match_device()") Fixes: 220175c ("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/ [1] 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>
1 parent bfcaf4e commit 78437ab

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

drivers/clk/imx/clk-imx8qxp.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,29 @@ static struct platform_driver imx8qxp_clk_driver = {
346346
},
347347
.probe = imx8qxp_clk_probe,
348348
};
349-
module_platform_driver(imx8qxp_clk_driver);
349+
350+
static int __init imx8qxp_clk_init(void)
351+
{
352+
int ret;
353+
354+
ret = platform_driver_register(&imx8qxp_clk_driver);
355+
if (ret)
356+
return ret;
357+
358+
ret = imx_clk_scu_module_init();
359+
if (ret)
360+
platform_driver_unregister(&imx8qxp_clk_driver);
361+
362+
return ret;
363+
}
364+
module_init(imx8qxp_clk_init);
365+
366+
static void __exit imx8qxp_clk_exit(void)
367+
{
368+
imx_clk_scu_module_exit();
369+
platform_driver_unregister(&imx8qxp_clk_driver);
370+
}
371+
module_exit(imx8qxp_clk_exit);
350372

351373
MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
352374
MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");

drivers/clk/imx/clk-scu.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ static bool imx_scu_clk_is_valid(u32 rsrc_id)
191191
return p != NULL;
192192
}
193193

194+
int __init imx_clk_scu_module_init(void)
195+
{
196+
return platform_driver_register(&imx_clk_scu_driver);
197+
}
198+
199+
void __exit imx_clk_scu_module_exit(void)
200+
{
201+
return platform_driver_unregister(&imx_clk_scu_driver);
202+
}
203+
194204
int imx_clk_scu_init(struct device_node *np,
195205
const struct imx_clk_scu_rsrc_table *data)
196206
{
@@ -215,7 +225,7 @@ int imx_clk_scu_init(struct device_node *np,
215225
rsrc_table = data;
216226
}
217227

218-
return platform_driver_register(&imx_clk_scu_driver);
228+
return 0;
219229
}
220230

221231
/*

drivers/clk/imx/clk-scu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl;
2525
extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp;
2626
extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm;
2727

28+
int __init imx_clk_scu_module_init(void);
29+
void __exit imx_clk_scu_module_exit(void);
2830
int imx_clk_scu_init(struct device_node *np,
2931
const struct imx_clk_scu_rsrc_table *data);
3032
struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,

0 commit comments

Comments
 (0)