Re: [PATCH] bus: fsl-mc: register the object drivers after misc_class exists

From: Vincent Jardin

Date: Mon Sep 07 2026 - 12:35:16 EST


Hi Ioana,

> Do you mean that the above error messages are triggered by an unbind and
> bind sequence like below?
>
> $ echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/unbind
> $ echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/bind

Yes, same sequence on the root DPRC

> I am asking this because I cannot seem to trigger it myself. There is a
> misc_deregister() which should remove the char device upon unbinding the
> root DPRC.

It does for every normal misc device, but not for this one, because the
root DPRC's misc device is created classless.

You can check the states with:
grep dprc /proc/misc # e.g. "256 dprc.1" -> registered
ls /sys/class/misc/ | grep dprc

If dprc.1 shows in /proc/misc but is absent from /sys/class/misc, its
misc device is classless and the unbind/bind should collide. If it is
present under /sys/class/misc, it was created after misc_class and the
sequence is clean on your setup.

fsl_mc_bus_driver_init() is a postcore_initcall, it registers both the
platform and the dprc drivers.

The fsl-mc DT node is populated at arch_initcall_sync, so the root DPRC
probes synchronously.

dprc_setup() -> fsl_mc_uapi_create_device_file() -> misc_register() runs
before misc_init() does class_register(&misc_class) at subsys_initcall.

misc_register() does not fail in that window: device_create_with_groups()
with an unregistered class creates the device with no misc_class
membership and still returns 0.

-> So at unbind, misc_deregister() -> device_destroy(&misc_class, devt)
cannot find the device within misc_class, it returns without removing it,
and then it leaks the device + its /sys/dev/char/10:<minor> link while freeing
the minor. The next bind reuses the minor and dies on the
duplicate /sys/dev/char/ entry.

I guess, from my setup, it happens when the root DPRC's misc device is
created during the early probe, which needs CONFIG_FSL_MC_UAPI_SUPPORT=y,
fsl-mc built in (not a module), and the root DPRC probe not going through
EPROBE_DEFER.

If it defers, the retry runs after subsys_initcall, misc_class exists,
and unbind/bind is clean -> which is probably what you are seeing.

I started to face this issue when I did try to restart
the MC from Linux userland instead of uboot in order to be able to adapt
with some DPC changes during the runtime.
see https://github.com/vjardin/lx2160-sdx/blob/main/src/lx2160-mc.c
But I guess this issue should be quite generic.

best regards,
Vincent