Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux I2C 子系統裝置與驅動綁定機制深度解析:以 AT91 為例

編輯:Linux 教學

Linux I2C 子系統採用標準裝置驅動模型,實現 I2C 控制器驅動與從裝置驅動的自動綁定。本文以 AT91 處理器 I2C 控制器為例,詳細追蹤 platform_driver 註冊流程、bus_add_driver、driver_attach、platform_match 匹配邏輯,以及裝置註冊時的反向綁定過程。

一、平台驅動註冊流程

1.1 at91_i2c_init()


static struct platform_driver at91_i2c_driver = {
    .probe   = at91_i2c_probe,
    .remove  = __devexit_p(at91_i2c_remove),
    .suspend = at91_i2c_suspend,
    .resume  = at91_i2c_resume,
    .driver  = {
        .name = "at91_i2c",
        .owner = THIS_MODULE,
    },
};

static int __init at91_i2c_init(void) {
    return platform_driver_register(&at91_i2c_driver);
}

1.2 platform_driver_register()


int platform_driver_register(struct platform_driver *drv) {
    drv->driver.bus = &platform_bus_type;
    if (drv->probe)
        drv->driver.probe = platform_drv_probe;  // 包裝 probe
    if (drv->remove)
        drv->driver.remove = platform_drv_remove;
    // ... suspend/resume 同理
    return driver_register(&drv->driver);
}

1.3 關鍵匹配函數 platform_match()


static int platform_match(struct device *dev, struct device_driver *drv) {
    struct platform_device *pdev = container_of(dev, struct platform_device, dev);
    return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
}

核心邏輯:比較裝置名稱與驅動名稱是否一致。

二、驅動核心註冊:driver_register()


int driver_register(struct device_driver *drv) {
    klist_init(&drv->klist_devices, NULL, NULL);  // 初始化支援裝置鏈表
    init_completion(&drv->unloaded);              // 完成介面,用於同步
    return bus_add_driver(drv);
}

三、bus_add_driver():掛載到總線並觸發綁定


int bus_add_driver(struct device_driver *drv) {
    struct bus_type *bus = get_bus(drv->bus);
    klist_add_tail(&drv->knode_bus, &bus->klist_drivers);  // 加入總線驅動列表
    driver_attach(drv);  // 遍歷總線上所有裝置,嘗試匹配綁定
    return 0;
}

driver_attach() 會對總線上的每個裝置呼叫 bus->match()(即 platform_match),匹配成功則呼叫驅動的 probe()。

四、裝置註冊時的反向綁定

當裝置註冊(device_register() → bus_add_device() → device_attach())時,同樣會遍歷總線上的所有驅動,呼叫 match() 並觸發 probe()。這實現了雙向自動綁定:

  • 驅動先註冊 → 掃描現有裝置
  • 裝置先註冊 → 掃描現有驅動
  • 熱插拔同樣適用

五、I2C 核心層的進一步綁定

Platform 驅動 probe() 成功後,通常會:

  1. 初始化 I2C 控制器硬體
  2. 分配 struct i2c_adapter,填入 algo(演算法/傳輸實作)
  3. 呼叫 i2c_add_adapter() 註冊到 I2C 核心

I2C 核心再管理掛載在該總線上的從裝置驅動(i2c_driver/i2c_client),形成兩層綁定架構。

Copyright © Windows教程網 All Rights Reserved