LWN.net Logo

Reworking system devices

"System" devices, as seen by the Linux device model, are components wired deeply into the core of the system, and which do not sit on a separate bus. Such devices include the CPUs, interrupt controller, timer, etc. They do not behave like most other devices (for example, you cannot open and write to them), and they are usually a vital part of the system as a whole. System devices are easily confused with "platform" devices - things like serial and parallel ports which usually are found on the system motherboard, but which act more like regular peripherals.

Up through 2.5.70, the Linux device model has treated system devices like most other devices. There is a fake "system bus" to which system devices "attach", and the usual driver methods are expected to be present. But, as Patrick Mochel noted in his patch reorganizing the system device API, "System devices are special, and after two years of listening to Linus preach this, it finally sunk in enough to do something about."

System devices are special in a number of ways. You generally know that they have to be present (you don't have to go probing for them), and there is little point in trying to load a driver for them. When dealing with power transitions (suspending or resuming the system), system devices need to be the last to shut down and the first to restart. They have weird interfaces that no other devices have; consider, for example, controlling CPU frequency policy. System devices, in other words, need to be treated in their own, particular way.

So, as of 2.5.71, there is a new API and user-space interface for working with system devices. There is a new include file (<linux/sysdev.h>) which defines a class type for system devices:

struct sysdev_class {
	struct list_head	drivers;

	/* Default operations for these types of devices */
	int	(*shutdown)(struct sys_device *);
	int	(*save)(struct sys_device *, u32 state);
	int	(*suspend)(struct sys_device *, u32 state);
	int	(*resume)(struct sys_device *);
	int	(*restore)(struct sys_device *);
	struct kset		kset;
};

A new type of system device is set up by filling in one of those structures and passing it to sysdev_class_register(). An actual system device is then created by filling in one of:

struct sys_device {
	u32		id;
	struct sysdev_class	* cls;
	struct kobject		kobj;
};

and passing it to sys_device_register(). The class-specific suspend and resume functions will now be called at the right times for that device, and a new sysfs directory will show up under /sys/devices/system with a default set of attributes.

For more complicated sorts of devices, it is still possible to register one or more "drivers" which add functionality. There is yet another structure to fill in:

struct sysdev_driver {
	struct list_head	entry;
	int	(*add)(struct sys_device *);
	int	(*remove)(struct sys_device *);
	int	(*shutdown)(struct sys_device *);
	int	(*save)(struct sys_device *, u32 state);
	int	(*suspend)(struct sys_device *, u32 state);
	int	(*resume)(struct sys_device *);
	int	(*restore)(struct sys_device *);
};

A call to sysdev_driver_register() will associate this driver with a specific system device class. Multiple drivers can be registered; each will be given a chance to respond to events involving devices in the given class. The add() and remove() methods allow the driver to respond to the creation or destruction of system devices - generally by adding or removing attributes to their sysfs entries. Thus, "drivers" in this context take on the functions handled by "interfaces" elsewhere in the driver model.

The new system device mechanism is thus a sort of hybrid combination of the device, driver, bus, and class structures used by "regular" devices. The new code is, perhaps, a step in the right direction, but it clearly illustrates one thing: the Linux device model still has not stabilized, and may not for a while yet. The device model is a major change to how things are done in the kernel, and the developers are still feeling around for the best way of doing things.


(Log in to post comments)

Reworking system devices

Posted Jun 14, 2003 14:06 UTC (Sat) by DancingProg (subscriber, #4816) [Link]

I'm a little bit confused. You say that they are generally expected to be there, but then
there's add and remove functions. Does that support hot-pluggable cpus and memory?

Copyright © 2003, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds