Comprehensive Guide to Linux Driver Types

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:

  • Device Tree integration
  • Resource management (IORESOURCE_MEM, IORESOURCE_IRQ)


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:

  • BAR (Base Address Register) mapping
  • MSI/MSI-X interrupt handling


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:

  • Endpoint management (usb_find_common_endpoints)
  • Bulk/Interrupt transfers


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:

  • Unified parent device for multiple sub-devices
  • Shared resource management (e.g., interrupts, registers)


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:

  • Scatter-gather transfers
  • Cyclic DMA support
  • Synchronization APIs (dma_sync_*)


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:

  • DRM/KMS (Kernel Mode Setting) integration
  • Memory management (GEM/TTM)
  • Shader compiler integration (e.g., Mesa Gallium)


Other Driver Types

7. TTY Drivers

Purpose: Manage serial/terminal devices (e.g., /dev/ttyS0). Key Features:

  • Line discipline configuration
  • UART baud rate control


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:

  • Buffer management for continuous data
  • Triggered sampling support


10. VFIO Drivers (Userspace Device Access)

Purpose: Allow userspace to directly control devices (e.g., GPU passthrough). Key Features:

  • IOMMU group management
  • Device isolation for virtualization


11. DMA-BUF Drivers

Purpose: Share memory buffers between devices/drivers. Key Features:

  • Cross-device zero-copy transfers
  • Synchronization fences


Conclusion

Linux drivers form a hierarchical ecosystem:

  • Low-Level: Platform/PCI/USB drivers handle hardware discovery.
  • Mid-Level: DMA/Regmap abstract hardware operations.
  • High-Level: GPU/IIO/VFIO provide domain-specific functionality.

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.

要查看或添加评论,请登录

David Zhu的更多文章