Comprehensive Guide to Linux Driver Types
Linux supports a wide range of device drivers to interface with hardware components. This article categorizes driver types from common to specialized, with expanded explanations for MFD, DMA, and GPU drivers.
Core Driver Types
1. Platform Drivers
Purpose: Manage on-chip peripherals without discovery mechanisms (e.g., UART, timers). Example:
static int my_platform_probe(struct platform_device *pdev) {
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
void __iomem *regs = devm_ioremap_resource(&pdev->dev, res);
return 0;
}
static struct platform_driver my_driver = {
.probe = my_platform_probe,
.driver = { .name = "my-platform" },
};
module_platform_driver(my_driver);
Key Features:
2. PCI/PCIe Drivers
Purpose: Control PCI/PCIe devices (e.g., network cards, GPUs). Example:
static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id) {
pci_enable_device(dev);
return 0;
}
static struct pci_device_id pci_ids[] = {
{ PCI_DEVICE(0x10de, 0x1c03) }, /* NVIDIA GPU */ {}
};
MODULE_DEVICE_TABLE(pci, pci_ids);
static struct pci_driver pci_drv = {
.name = "my-pci",
.id_table = pci_ids,
.probe = pci_probe,
};
module_pci_driver(pci_drv);
Key Features:
3. USB Drivers
Purpose: Manage USB devices (e.g., storage, input devices). Example:
static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) {
struct usb_device *udev = interface_to_usbdev(intf);
usb_set_intfdata(intf, my_data);
return 0;
}
static struct usb_device_id usb_ids[] = {
{ USB_DEVICE(0x046d, 0xc52b) }, /* Logitech Unifying Receiver */ {}
};
MODULE_DEVICE_TABLE(usb, usb_ids);
static struct usb_driver usb_drv = {
.name = "my-usb",
.id_table = usb_ids,
.probe = usb_probe,
};
module_usb_driver(usb_drv);
Key Features:
Specialized Driver Types
4. MFD Drivers (Multi-Function Devices)
Purpose: Handle chips integrating multiple functions (e.g., PMICs with ADC/GPIO/PWM). Example:
static struct mfd_cell my_mfd_devs[] = {
{ .name = "my-gpio", .of_compatible = "vendor,gpio" },
{ .name = "my-pwm", .of_compatible = "vendor,pwm" },
};
static int mfd_probe(struct platform_device *pdev) {
return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
my_mfd_devs, ARRAY_SIZE(my_mfd_devs), NULL, 0, NULL);
}
static struct platform_driver mfd_drv = {
.probe = mfd_probe,
.driver = { .name = "my-mfd" },
};
module_platform_driver(mfd_drv);
Key Features:
5. DMA Drivers (Direct Memory Access)
Purpose: Enable peripheral-to-memory transfers without CPU involvement. Example:
static void dma_callback(void *data) {
printk("DMA transfer complete!");
}
static int dma_transfer(struct device *dev) {
struct dma_chan *chan;
struct dma_async_tx_descriptor *desc;
dma_addr_t dma_addr;
chan = dma_request_chan(dev, "tx");
dma_addr = dma_map_single(dev, buffer, size, DMA_TO_DEVICE);
desc = dmaengine_prep_slave_single(chan, dma_addr, size,
DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
desc->callback = dma_callback;
dmaengine_submit(desc);
dma_async_issue_pending(chan);
return 0;
}
Key Features:
6. GPU Drivers
Purpose: Manage graphics processing units (e.g., rendering, display output). Example (Simplified DRM Driver):
static const struct drm_driver my_gpu_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM,
.gem_create_object = my_gem_create,
.dumb_create = my_dumb_create,
};
static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) {
struct drm_device *dev = drm_dev_alloc(&my_gpu_driver, &pdev->dev);
pci_enable_device(pdev);
drm_dev_register(dev, 0);
return 0;
}
static struct pci_driver gpu_pci_drv = {
.name = "my-gpu",
.id_table = pci_ids,
.probe = gpu_probe,
};
module_pci_driver(gpu_pci_drv);
Key Features:
Other Driver Types
7. TTY Drivers
Purpose: Manage serial/terminal devices (e.g., /dev/ttyS0). Key Features:
8. Regmap Drivers
Purpose: Abstract register I/O operations across buses (I2C/SPI/MMIO). Example:
static const struct regmap_config my_regmap = {
.reg_bits = 8,
.val_bits = 8,
};
static int regmap_probe(struct i2c_client *client) {
struct regmap *map = devm_regmap_init_i2c(client, &my_regmap);
regmap_write(map, 0x00, 0xFF);
return 0;
}
9. IIO Drivers (Industrial I/O)
Purpose: Interface with sensors (e.g., accelerometers, ADCs). Key Features:
10. VFIO Drivers (Userspace Device Access)
Purpose: Allow userspace to directly control devices (e.g., GPU passthrough). Key Features:
11. DMA-BUF Drivers
Purpose: Share memory buffers between devices/drivers. Key Features:
Conclusion
Linux drivers form a hierarchical ecosystem:
MFD drivers unify multi-function chips, while GPU drivers leverage the DRM subsystem for complex rendering tasks. DMA drivers optimize performance-critical data transfers, demonstrating Linux's flexibility in balancing hardware control and system efficiency.