On 2017-03-09 10:39, Peter Rosin wrote: *snip* *snip*
>> Per the above use case (minimal vmlinux) the unload isn't so important, >> and in many cases it may be racy or simply not make sense. If that is >> the case, you don't need to provide a module_exit, and in the past I >> think we used to bump the module use count at a successful load to >> prevent unloading ; there might be a more elegant method now; google is >> your friend here. Also, I don't think name reuse/confusion is an issue. > > Ok, I thought it all boiled down to making the mux-core Kconfig a tristate > option and changing subsys_initcall(...) to module_init(...). > > But if I do that, I cannot be sure that the mux-core has been initialized > before drivers and clients start to use it in the non-modular case (if > things are modules, the dependencies should ensure that the mux-core is > loaded/initialized before any users are loaded). But there is no > topological sorting going on for ordering init calls in the non-modular > case. > > In short, I get: > > WARNING: CPU: 0 PID: 1 at drivers/base/class.c:438: > class_find_device+0xac/0xb8 > class_find_device called for class 'mux' before it was initialized > CPU:0 PID: 1 Comm: swapper Not tainted 4.11-rc1+ #1243 > Hardware name: Atmel SAMA5 > [<c010d24c>] (unwind_backtrace) from [<c010b1ec>] (show_stack+0x10/0x14) > [<c010b1ec>] (show_stack) from [<c0115290>] (__warn+0xe0/0xf8) > [<c0115290>] (__warn) from [<c01152e0>] (warn_slowpath_fmt+0x38/0x48) > [<c01152e0>] (warn_slowpath_fmt) from [<c034715c>] > (class_find_device+0xac/0xb8) > [<c034715c>] (class_find_device) from [<c0434230>] > (mux_control_get+0xa0/0x1bc) > [<c0434230>] (mux_control_get) from [<c0434394>] > (devm_mux_control_get+0x3c/0x78) > [<c0434394>] (devm_mux_control_get) from [<c04060f0>] > (i2c_mux_probe+0x44/0x294) > [<c04060f0>] (i2c_mux_probe) from [<c03475ac>] (platform_drv_probe+0x4c/0xb0) > [<c03475ac>] (platform_drv_probe) from [<c0345e30>] > (driver_probe_device+0x26c/0x464) > [<c0345e30>] (driver_probe_device) from [<c0346128>] > (__driver_attach+0x100/0x11c) > [<c0346128>] (__driver_attach) from [<c034403c>] (bus_for_each_dev+0x6c/0xa0) > [<c034403c>] (bus_for_each_dev) from [<c0344a94>] (bus_add_driver+0x1c8/0x260) > [<c0344a94>] (bus_add_driver) from [<c0346a7c>] (driver_register+0x78/0xf8) > [<c0346a7c>] (driver_register) from [<c0800d50>] (do_one_initcall+0xb0/0x15c) > [<c0800d50>] (do_one_initcall) from [<c0800f38>] > (kernel_init_freeable+0x13c/0x1d8) > [<c0800f38>] (kernel_init_freeable) from [<c057ab60>] (kernel_init+0x8/0x10c) > [<c057ab60>] (kernel_init) from [<c0107fb8>] (ret_from_fork+0x14/0x3c) > ---[ end trace d97274a16af7ef1c ]--- > > So, it appears that I also have to determine if the core has been > initialized in all its entry points and return -EPROBE_DEFER (or something) > when not. I suppose I could instead initialize on-demand, but that seems > more difficult the do without races... > > Am I missing something? I did some digging and e.g. drivers/uwb was moved before drivers/usb in commit ae5d82cb8d60 ("uwb: build UWB before USB/WUSB") to resolve what appears to be a similar situation. I suppose I could just move mux up in drivers/Makefile so that it is before both i2c and iio. Cheers, peda