2003-06-11 22:09:13

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: sysfs: Initialization order and system devices

With the current system device changes (I picked them up in 2.5.70-mm8),
the system device class assumes that all system device drivers are
registered before any system devices are registered.

Unfortunately, this is often not the case. CPU devices are registered
very early, but cpufreq registers drivers for them; since cpufreq
drivers can be loaded as modules, they clearly can't be registered
before the device is.

This patch keeps a list of all registered devices hanging off the system
device class. When a new driver is registered, it calls the driver's
add() function with all existing devices.

Conversely, when a driver is unregistered, it calls the driver's
remove() function for all existing devices so the driver can clean up.

J


Attachments:
sysdev-init-order.patch (3.70 kB)

2003-06-11 22:15:48

by Patrick Mochel

[permalink] [raw]
Subject: Re: sysfs: Initialization order and system devices


On 11 Jun 2003, Jeremy Fitzhardinge wrote:

> With the current system device changes (I picked them up in 2.5.70-mm8),
> the system device class assumes that all system device drivers are
> registered before any system devices are registered.
>
> Unfortunately, this is often not the case. CPU devices are registered
> very early, but cpufreq registers drivers for them; since cpufreq
> drivers can be loaded as modules, they clearly can't be registered
> before the device is.
>
> This patch keeps a list of all registered devices hanging off the system
> device class. When a new driver is registered, it calls the driver's
> add() function with all existing devices.
>
> Conversely, when a driver is unregistered, it calls the driver's
> remove() function for all existing devices so the driver can clean up.

D'oh. I meant to add this piece for precisely this reason. Thanks, though
there is one thing:

+
+ /* If devices of this class already exist, tell the driver */
+ if (drv->add) {
+ struct sys_device *dev;
+ list_for_each_entry(dev, &cls->devices, entry)
+ drv->add(dev);
+ }
+

in sysdev_driver_register(). You must check that cls is not NULL. I've
fixed it up and applied it.

Thanks,


-pat