- Bus probes all devices
- Bus registers all drivers usable for the bus
- Bus then 'binds' driver to each device discovered:
- When device_register is called for a device, it is inserted into the end of this list.
- The bus object also contains a list of all drivers of that bus type.
- These are the two events which trigger driver binding.
- If a match is found, the device's driver field is set to the driver and the driver's probe callback is called.
- This gives the driver a chance to verify that it really does support the hardware, and that it's in a working state.
- When a driver is attached to a device, the device is inserted into the driver's list of devices.
- Upon the successful completion of probe, the device is registered with the class to which it belongs
- Device drivers belong to one and only one class, and that is set in the driver's devclass field.
- devclass_add_device() is called to enumerate the device within the class and actually register it with the class
 
- The bus's list of devices is iterated over to find a match
- Devices that already have a driver are skipped.
- When a device is removed, the reference count for it will eventually go to 0.
- When it does, the remove callback of the driver is called.
When a bus driver probes and finds devices, it registers the device:
int device_register(struct device * dev);
struct device {
        struct list_head g_list;              // Node in the global device list.
        struct list_head node;                // Node in device's parent's children list.
        struct list_head bus_list;            // Node in device's bus's devices list.
        struct list_head driver_list;         // Node in device's driver's devices list.
        struct list_head intf_list;           // List of intf_data. Each interface supported
        struct list_head children;            // List of child devices.
        struct device   * parent;
        char    name[DEVICE_NAME_SIZE];       // ASCII description of device. 
        char    bus_id[BUS_ID_SIZE];          // ASCII representation of device's bus position <bus>:<slot>.<id>
        spinlock_t      lock;                 // Spinlock for the device.
        atomic_t        refcount;             // Reference count on the device.
        struct bus_type * bus;                // Pointer to struct bus_type that device belongs to.
        struct driver_dir_entry dir;          // Device's sysfs directory.
	u32		class_num;                            // Class-enumerated value of the device.
        struct device_driver *driver;         // Pointer to struct device_driver that controls the device.
        void            *driver_data;         // Driver-specific data.
        void            *platform_data;       // Bus, GPIO etc.. pre-DTS?
        u32             current_state;        // Current power state of the device.
        unsigned char *saved_state;           // Pointer to saved state of the device.
        void    (*release)(struct device * dev);
};A device class describes a type of device, like an audio or network device. Device classes are agnostic with respect to what bus a device resides on. There is no list of devices in the device class. Only list of drivers, which then have a list of devices
Adding a device to it
- Each time a device is added to the class, the class's devnum field is incremented and assigned to the device.
- The field is never decremented, so if the device is removed from the class and re-added, it will receive a different enumerated value.
class struct:
struct device_class {
	char			* name;
	rwlock_t		lock;
	u32			devnum;
	struct list_head	node;
	struct list_head	drivers;
	struct list_head	intf_list;
	struct driver_dir_entry	dir;
	struct driver_dir_entry	device_dir;
	struct driver_dir_entry	driver_dir;
	devclass_add		add_device;
	devclass_remove		remove_device;
};Example class:
struct device_class input_devclass = {
        .name		= "input",
        .add_device	= input_add_device,
	.remove_device	= input_remove_device,
};Adding/removing device classes:
int devclass_register(struct device_class * cls);
void devclass_unregister(struct device_class * cls);A kobject is an object of type struct kobject Kobjects have a name and a reference count. A kobject also has a parent pointer (allowing objects to be arranged into hierarchies), a specific type, and, usually, a representation in the sysfs virtual filesystem. No structure should EVER have more than one kobject embedded within it. A ktype is the type of object that embeds a kobject. The ktype controls what happens to the kobject when it is created and destroyed.
A kset is a group of kobjects. When you see a sysfs directory full of other directories, generally each of those directories corresponds to a kobject in the same kset.
devres is basically linked list of arbitrarily sized memory areas associated with a struct device. Each devres entry is associated with a release function. Managed interface is created for resources commonly used by device drivers using devres. For example, coherent DMA memory is acquired using dma_alloc_coherent(). The managed version is called dmam_alloc_coherent(). It is identical to dma_alloc_coherent() except for the DMA memory allocated using it is managed and will be automatically released on driver detach.
- Devres is memory types usable for drivers
- Alloc is all managed so it is automatically released
Example:
  struct dma_devres {
	size_t		size;
	void		*vaddr;
	dma_addr_t	dma_handle;
  };
  static void dmam_coherent_release(struct device *dev, void *res)
  {
	struct dma_devres *this = res;
	dma_free_coherent(dev, this->size, this->vaddr, this->dma_handle);
  }
  dmam_alloc_coherent(dev, size, dma_handle, gfp)
  {
	struct dma_devres *dr;
	void *vaddr;
	dr = devres_alloc(dmam_coherent_release, sizeof(*dr), gfp);
	...
	/* alloc DMA memory as usual */
	vaddr = dma_alloc_coherent(...);
	...
	/* record size, vaddr, dma_handle in dr */
	dr->vaddr = vaddr;
	...
	devres_add(dev, dr);
	return vaddr;
  }Step 0: Read include/linux/device.h for object and function definitions
Step 1: Registering the bus driver.
struct bus_type pci_bus_type = {
  .name           = "pci",
};- Register the bus type.
static int __init pci_driver_init(void)
{
        return bus_register(&pci_bus_type);
}
subsys_initcall(pci_driver_init);- Export the bus type for others to use.
extern struct bus_type pci_bus_type;
EXPORT_SYMBOL(pci_bus_type);- This will cause the bus to show up in /sys/bus/pci/ with two subdirectories: 'devices' and 'drivers'.
Step 2: Registering Devices.
struct pci_dev {
       ...
       struct  device  dev;            /* Generic device interface */
       ...
};- 
Initialize the device on registration. 
- 
Register the device. Once the generic device has been initialized, it can be registered with the driver model core by doing: 
device_register(&dev->dev);Step 3: Registering Drivers.
struct pci_driver {
       ...
       struct device_driver    driver;
};- After initializing thedriver, register it:
driver_register(&drv->driver);Step 4: Define Generic Methods for Drivers.
/* initialize common driver fields */
        drv->driver.name = drv->name;
        drv->driver.bus = &pci_bus_type;
        drv->driver.probe = pci_device_probe;
        drv->driver.resume = pci_device_resume;
        drv->driver.suspend = pci_device_suspend;
        drv->driver.remove = pci_device_remove;
        /* register with core */
        driver_register(&drv->driver);