From 7e9023a18eec88b716d8d46a29c4207186fbd828 Mon Sep 17 00:00:00 2001 From: Vincent Jardin Date: Wed, 9 Sep 2026 19:04:40 +0200 Subject: [PATCH] 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: 2cf1e703f066 ("bus: fsl-mc: add fsl-mc userspace support") Signed-off-by: Vincent Jardin Reviewed-by: Ioana Ciornei 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) --- drivers/bus/fsl-mc/fsl-mc-bus.c | 40 ++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 0766ccb68629..5878eafd8d44 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -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);