Device Model
On this page
A device may appear in sysfs while its driver remains unbound; after driver unbinding, the device object might still be referenced. To read the device model, locate the relevant sections along discovery, matching, functional registration, and final release.
| Target | Reading Location |
|---|---|
| Objects and probe | Sections 1–2 |
| References and managed resources | Section 3 |
| User-space view and read-only experiments | Sections 4–5 |
1. What problem does each object solve?
| Object | Question it addresses | Example |
|---|---|---|
device | Which device is this? Who is the parent? What resources does it have? | A PCI function, a USB interface |
device_driver | Which implementation can operate it? | PCI network driver, USB serial driver |
bus_type | How to discover, match, and organize devices and drivers? | PCI, USB, platform |
class | From what functional perspective does the user look up devices? | net, block, tty |
Buses and classes represent different viewpoints. A PCI network card is first a device on the PCI bus; its network interface then provides functional objects via the network subsystem. You cannot treat /sys/class/net/eth0 as a simple rename of the PCI device object. A single physical device may also expose multiple functional objects.
kobject is the lower-level foundation for naming, hierarchy, and reference counting, which is embedded within device. kset organizes related kobjects and participates in event management. They do not constitute a replacement for the bus model's driver interface. Typically, you should use the device API provided by existing subsystems rather than building your own kobject tree for a driver.
Kernel structures change across versions; when reading include/linux/device.h and include/linux/kobject.h, focus on member responsibilities. kobject.sd points to a kernfs node, not a VFS dentry; final object release depends on the release callback and its container management. Reference counting reaching zero does not automatically imply how to release the outer structure.
2. From hardware information to probe
Whether the device registers first or the driver registers first, matching can be triggered. The bus is responsible for matching rules: PCI commonly uses vendor/device/class, USB can match by device or interface descriptors, and platform drivers can match via firmware match tables, among other methods.
match only indicates that a candidate driver might support the device; probe must also acquire resources such as clocks, power supplies, registers, and interrupts, initialize the hardware, and register with the functional subsystem. If any step fails, no partially initialized device should be left running.
If a dependent regulator, clock, or other supplier is not yet ready, you can return -EPROBE_DEFER. The core will retry when subsequent conditions are met. This indicates a temporary lack of dependencies and should not be used to mask permanently unsupported hardware or erroneous parameters. Device links can also express supplier/consumer relationships, affecting the order of probing and power management.
Deferred probing retries initialization, it does not prolong a half-initialized state
Suppose a sensor consumer has been enumerated, but the regulator driver it references has not finished registering. The first probe might have already established a private context, but then obtaining the regulator returns -EPROBE_DEFER. This probe must exit and clean up the resources attempted in this instance; when subsequent probing occurs due to changes in dependency conditions, it should restart from a consistent unbound state.
| Moment | Consumer State | Resources for this attempt |
|---|---|---|
| Enumerated, not yet probed | Device exists, unbound | No successful driver instance |
| First probe fails to acquire supplier | Returns EPROBE_DEFER, binding not completed | Reclaim managed resources; handle manual resources as well |
| Supplier becomes ready later | Can trigger subsequent probing paths | Cannot assume previous private buffers are still valid |
| Subsequent probe succeeds | Driver binding and functional registration completed | Resources from this new attempt persist until unbinding |
Therefore, repeated probe logs may indicate retries due to dependencies, not necessarily that the device was enumerated multiple times. Conversely, rewriting unsupported devices or incorrect firmware parameters uniformly as EPROBE_DEFER makes real errors look like permanently missing dependencies. Drivers should preserve the error semantics of resource APIs and locate issues by combining device links, deferred reasons, and original return values; initialization order should not rely on adding fixed sleep times to accidentally succeed.
How firmware descriptions and bus enumeration cooperate
- Device Tree: Describes addresses, interrupts, clocks, and device connections;
compatibleindicates compatible interfaces. Common on ARM and RISC-V, but not exclusive to these architectures. - ACPI: Provides device identity, resources, and power management methods; common on x86, and also used by arm64 servers.
- PCI/USB Enumeration: Discovers devices and reads identifiers via bus protocols. PCI root bridges, configuration space access methods, and interrupt routing may still rely on ACPI or DT; it cannot be summarized as "self-enumerating devices completely do not need firmware descriptions."
The platform bus is often used for on-chip devices that cannot self-enumerate via such bus protocols. A platform device is a real object in the device model, which does not mean the hardware is simulated; DT nodes do not all become platform devices, and the bus to which the node belongs determines the instantiation method.
3. Object lifetime and driver binding lifetime
get_device() / put_device() manage device references. device_unregister() revokes registration and releases the registrant's reference; if references remain, the object can continue to exist until the final put triggers the ultimate release.
| Boundary | What ends |
|---|---|
| remove | Driver service and binding relationship |
| release | Memory lifetime of the device object itself |
| References still exist | Only indicates that object memory can continue to exist |
References do not bring unplugged hardware back online, nor do they guarantee that registers are still accessible.
device_register() includes initialization and addition steps. Even if registration fails, the caller usually needs put_device() to return the reference obtained during initialization; you cannot casually kfree() an object already managed by the device model. Allocation and release rules for specific containers should follow the rules of the owning subsystem.
Saving struct device does not mean saving driver private data
Suppose the registrant holds a device reference, and an asynchronous user obtains another reference. When the driver unbinds, devm private memory can be released, but the device reference held by the asynchronous user keeps the device object itself alive. If the asynchronous user saved an old drvdata pointer and subsequently dereferences it, they may access already released driver data.
Below, we only count references from the registrant and one external holder, omitting all temporary internal kernel references. The state model separates registration, binding, private resources, and object release, making it easier to observe which guarantees end with which step.
= 1 # Reference obtained during initialization, to be returned by the registrant
= False
= False
= False
= 0
+= 1
assert > 0
-= 1
assert not and not
+= 1
assert > 0 and not
= = = True
assert
= False
= False
assert
= False
return
=
assert == 2 and ==
assert and == 2 and not
pass
assert == 1 and == 0
# Return the last external reference
assert == 0 and == 1
pass
= # Initialized, but addition step failed
assert == 1
The real get_device() only performs reference operations; it does not safely retrieve an object from a potentially invalid raw pointer for the caller. Obtaining the initial reference requires relying on lock-protected lookups, existing references, or the acquisition protocol specified by the owning subsystem. An obtained reference protects the object's memory lifetime but does not replace unbinding synchronization or the reference rules for private state.
Local kernel implementations can see in drivers/base/core.c that device_unregister first calls device_del and then put_device; unbinding cleanup is contained in drivers/base/dd.c including devres_release_all and clearing drvdata. The responsibilities of these two paths differ, and driver design should clearly specify which layer of object the asynchronous user actually holds. Device Object Lifecycle, devres Release Semantics
devres manages resource release order
Managed APIs like devm_kzalloc() attach resources to the device, and they are typically cleaned up in reverse order upon probe failure or unbinding. This reduces error branches but does not automatically solve all asynchronous activities:
- Prevent new requests from entering.
- Stop DMA and disable interrupt sources according to hardware protocols.
- Wait for or cancel running work items, callbacks, and requests.
- Only then release resources that these paths might still access.
Waiting operations must not hold locks required by completion callbacks. Managed and unmanaged APIs can be used together, but you must clearly understand who releases each resource to avoid double-freeing after manual release. Refer to Device Lifecycle and the devres documentation.
Take a caller reference before unbinding or unregistering. A live device object and usable driver resources are separate conditions.
A device object can outlive its driver binding. get_device retains object memory, not unbound devres or offline hardware.
4. Division of labor among sysfs, devtmpfs, and udev
/sys/devices displays the device hierarchy; /sys/bus/.../devices and /sys/class/... provide other lookup perspectives, often containing symbolic links. sysfs files are kernel-exported attribute interfaces, not ordinary disk files, and not every file corresponds to a device_attribute.
Device attribute show methods commonly use sysfs_emit() for output, and store methods can use kstrto*() to parse input. Attributes still require correct locking, permissions, and device state checks; once stably exported, user-space ABI considerations must be taken into account, and units and meanings cannot be changed arbitrarily.
For devices with device numbers registered using the appropriate mechanism, devtmpfs can create basic device nodes from within the kernel. udev receives uevents, reads attributes, and then sets permissions, creates stable symbolic links based on rules, and can trigger module loading based on modalias. Built-in drivers do not need to load modules, and many devices do not have /dev nodes at all; for example, network interfaces are typically used via sockets and netlink.
| When the expected device is not visible | Next layer of evidence |
|---|---|
| Is it discovered? | Bus enumeration and device object |
| Is it bound? | Driver association, matching, and probe results |
| Can it provide functionality? | Registration of subsystem functional objects |
| Is the name/access correct? | User-space naming, permissions, and rules |
The mere absence of a specific /dev name does not directly prove that probe was not executed.
5. Read-only view of a PCI device
Below, we only read sysfs without unbinding the device or modifying resources. Hot-plug events may cause files to disappear during traversal, so read exceptions are handled.
=
=
= /
= .
For example, the name 0000:03:00.0 contains the PCI domain, bus, device, and function. The absence of a driver link only indicates that no driver is currently bound; the reason requires analysis combining match tables, modules, probe logs, and device status.
Continue Reading
- PCIe and USB Driver Model: Data transfer and hot-plug for these two buses.
- IOMMU and DMA API: How buffers are mapped and handed over after the device starts transferring.
- Kernel Device Model Overview, Driver Binding.