mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
bus: fsl-mc: register the object drivers after misc_class exists
Unbinding and re-binding the root DPRC fails with:
sysfs: cannot create duplicate filename '/dev/char/10:256'
misc_register / fsl_mc_uapi_create_device_file /
dprc_setup / dprc_probe
It happens when the fsl-mc bus probe is not deferred, without SMMU:
- the dprc driver is registered at postcore_initcall,
- the DT node is populated at arch_initcall_sync,
- the root DPRC probes right there, before misc_init() has
registered misc_class at subsys_initcall.
misc_register() still succeeds but the device gets
no class, so misc_deregister() at unbind cannot find it:
the minor is freed while the device and its /sys/dev/char/ link leak,
and then the next bind collides on the same minor.
Let's move the dprc and allocator drivers registration, and
platform_driver_register(), to subsys_initcall_sync, after misc_init()
at subsys_initcall.
bus_register() and the platform-bus notifier stay at postcore_initcall
so that fsl_mc_bus_notifier() still pauses the MC before the SMMU is probed.
Cc: stable+noautosel@kernel.org # niche: root DPRC unbind/rebind only
Fixes: 2cf1e703f0 ("bus: fsl-mc: add fsl-mc userspace support")
Signed-off-by: Vincent Jardin <vjardin@free.fr>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Link: https://lore.kernel.org/r/20260909-for-upstream-fsl-mc-initcall-order-v2-1-b7a04634fcf1@free.fr
Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
This commit is contained in:
parent
f85e5ec18e
commit
7e9023a18e
|
|
@ -1265,35 +1265,43 @@ static int __init fsl_mc_bus_driver_init(void)
|
|||
error = bus_register(&fsl_mc_bus_type);
|
||||
if (error < 0) {
|
||||
pr_err("bus type registration failed: %d\n", error);
|
||||
goto error_cleanup_cache;
|
||||
return error;
|
||||
}
|
||||
|
||||
error = platform_driver_register(&fsl_mc_bus_driver);
|
||||
if (error < 0) {
|
||||
pr_err("platform_driver_register() failed: %d\n", error);
|
||||
error = bus_register_notifier(&platform_bus_type, &fsl_mc_nb);
|
||||
if (error < 0)
|
||||
goto error_cleanup_bus;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_cleanup_bus:
|
||||
bus_unregister(&fsl_mc_bus_type);
|
||||
return error;
|
||||
}
|
||||
postcore_initcall(fsl_mc_bus_driver_init);
|
||||
|
||||
static int __init fsl_mc_bus_drivers_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = dprc_driver_init();
|
||||
if (error < 0)
|
||||
goto error_cleanup_driver;
|
||||
return error;
|
||||
|
||||
error = fsl_mc_allocator_driver_init();
|
||||
if (error < 0)
|
||||
goto error_cleanup_dprc_driver;
|
||||
|
||||
return bus_register_notifier(&platform_bus_type, &fsl_mc_nb);
|
||||
error = platform_driver_register(&fsl_mc_bus_driver);
|
||||
if (error < 0) {
|
||||
pr_err("platform_driver_register() failed: %d\n", error);
|
||||
goto error_cleanup_dprc_driver;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_cleanup_dprc_driver:
|
||||
dprc_driver_exit();
|
||||
|
||||
error_cleanup_driver:
|
||||
platform_driver_unregister(&fsl_mc_bus_driver);
|
||||
|
||||
error_cleanup_bus:
|
||||
bus_unregister(&fsl_mc_bus_type);
|
||||
|
||||
error_cleanup_cache:
|
||||
return error;
|
||||
}
|
||||
postcore_initcall(fsl_mc_bus_driver_init);
|
||||
subsys_initcall_sync(fsl_mc_bus_drivers_init);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user