Explore struct device, struct device_driver, and struct bus_type from the Linux driver model, plus sysfs layout, power management ops, and device links.
Use this file to discover all available pages before exploring further.
The Linux Device Model (LDM) is a unified data model that describes every device in the system and the relationships between devices, the buses they sit on, and the drivers that manage them. Introduced to replace the collection of ad-hoc per-bus data structures that existed before kernel 2.6, the LDM gives the kernel a single coherent view of the hardware tree. It powers sysfs, hot-plug events, power management, and driver binding from one shared infrastructure.
struct device is the fundamental object representing a hardware or virtual device. Every higher-level device structure — struct pci_dev, struct platform_device, struct usb_device — embeds a struct device inside it. The bus or subsystem layer owns the outer structure; the driver core owns the embedded struct device.
/* From include/linux/device.h (lines 628–743) */struct device { struct kobject kobj; struct device *parent; struct device_private *p; const char *init_name; /* initial name of the device */ const struct device_type *type; const struct bus_type *bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ void *platform_data; /* platform-specific data */ void *driver_data; /* driver data, use dev_set/get_drvdata() */ struct mutex mutex; struct dev_links_info links; struct dev_pm_info power; struct dev_pm_domain *pm_domain; u64 *dma_mask; u64 coherent_dma_mask; struct device_node *of_node; /* associated device tree node */ struct fwnode_handle *fwnode; /* firmware device node */ dev_t devt; /* creates the sysfs "dev" */ const struct class *class; const struct attribute_group **groups; void (*release)(struct device *dev);};
Key fields to understand:
parent — the device higher in the hierarchy (e.g., the USB hub for a USB device).
bus — the bus type this device belongs to; set by the bus layer.
driver — populated by the driver core when a driver is successfully bound.
platform_data — board-specific data supplied before probe() runs.
driver_data — private data stored by the driver, accessed with dev_set_drvdata() and dev_get_drvdata().
of_node — the Device Tree node, used to read hardware description properties.
release — called when the device’s reference count drops to zero; always set this before registering a device.
Use device_register() to add a device to the model and device_unregister() to remove it.
struct device_driver represents a driver as a whole — not a specific device instance. It is a statically allocated structure. All bus-specific driver structures (e.g., struct pci_driver, struct platform_driver) embed a struct device_driver.
Bus-specific drivers should use their bus’s registration function (e.g., platform_driver_register(), pci_register_driver()) rather than calling driver_register() directly. These wrappers fill in the bus field and handle bus-specific setup automatically.
sysfs is a virtual filesystem that reflects the kernel’s device hierarchy. It is mounted at /sys and is populated automatically by the driver core whenever you register a device or driver.The physical device hierarchy appears under /sys/devices/. Every struct device gets its own directory, nested under its parent:
The match() callback is the most important field. It receives a device and a driver and returns a positive value when they are compatible. For example, the platform bus matches by comparing platform_device.name against platform_driver.driver.name or entries in the driver’s of_match_table.You can iterate over all devices or drivers on a bus using:
struct dev_pm_ops defines the full set of power management callbacks a driver can implement. You attach a dev_pm_ops to a driver via device_driver.pm or, for bus-level control, via bus_type.pm.
/* From include/linux/pm.h (lines 288–312) */struct dev_pm_ops { int (*prepare)(struct device *dev); void (*complete)(struct device *dev); int (*suspend)(struct device *dev); int (*resume)(struct device *dev); int (*freeze)(struct device *dev); int (*thaw)(struct device *dev); int (*poweroff)(struct device *dev); int (*restore)(struct device *dev); int (*suspend_late)(struct device *dev); int (*resume_early)(struct device *dev); /* ... noirq variants ... */ int (*runtime_suspend)(struct device *dev); int (*runtime_resume)(struct device *dev); int (*runtime_idle)(struct device *dev);};
For most drivers, you only need suspend and resume. The DEFINE_SIMPLE_DEV_PM_OPS() macro constructs a dev_pm_ops that uses the same callbacks for system sleep and hibernation:
Device links express supplier–consumer relationships between devices. They ensure that a supplier device is probed before its consumers and is not removed while consumers are still active.You create a link from the consumer to the supplier inside the consumer’s probe():
The DL_FLAG_AUTOREMOVE_CONSUMER flag automatically removes the link when the consumer is unbound. The DL_FLAG_PM_RUNTIME flag integrates the link into runtime PM so that the supplier is resumed before the consumer.
Prefer device links over open-coding dependency checks in probe(). Links integrate with deferred probing: if the supplier is not yet probed, adding the link returns an error that you can convert into -EPROBE_DEFER.
Driver model overview
Learn about driver types, the probe/remove lifecycle, and the key headers every driver includes.
Write your first driver
Implement a character device driver and a platform driver with complete code examples.