- platform-device 是 hardware (大概是指 hardware resource - gpio, interrupt number, memory region .. etc)
- platform-driver 是 software
device 要比 driver 先註冊。
因為 driver 向 kernel 註冊時, kernel 會去 registered device list中,找出 name 和 driver 的 name 一樣的 device 和 driver 配對。
如果找不到,就 driver register 會 fail。
要改用 platform device, driver 的方式,大概是因為要有 suspend, resume callback 的機會。
include/linux/platform_device.h
struct platform_driver {
int (*probe) (struct platform_device *);
int (*remove) (struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend) (struct platform_device *, pm_message_t state);
int (*resume) (struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
};
填好這個 struct 後,kernel 註冊 (platform_driver_register),kernel 就會在 suspend , resume 時,call 對應的 callback function.* 其中 的
struct device_driver driver.name 就是用來找對應的 platform_device 的 name
device_driver 宣告在 include/linux/device.h又是一個很大的 階層 式結構..
platform_device_XXX 和 platforma_driver_XXX 的 function 都 implement 在
driver/base/platform.c
platform_add_devices -- call platform_device_register
int platform_add_devices(struct platform_device **devs, int num)
{
int i, ret = 0;
for (i = 0; i < num; i++) {
ret = platform_device_register(devs[i]);
if (ret) {
while (--i >= 0)
platform_device_unregister(devs[i]);
break;
}
}
return ret;
}
platform_device_register-- call platform_device_add.
int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
還有動態 alloc 的 device 用:
- platform_device_alloc 取得一塊記憶體,工作 platform_device 的資料存放
並不是從此以後 driver 都要用 platform_device, platform_driver 這樣的方式來作。
舊的 module 實作方式還是可以用,只是沒有 suspend/resume 的 callback 機制了 (還是我找不到?)
把原來的 driver moduel 方式改為 platform_device, platform_driver ,大概就是..
- 把 mod_init 改為 mod_probe -- 主要是內容,原來 init 做的事,改在 probe 作
- 增加 remove, suspend, resume 這幾個 function
- 填寫一個 platform_driver structure
- 新增一個 init,內容就是註冊 platform_driver 和 platform_device
- 修改 exit,作 unregister platform_driver 和 platform_device
mydevicep = platform_device_register_simple("mydriver",0,NULL,0);
這個 mydevicep 要存起來,exit 作 unregister 時藥用。platform, device, driver model 相關的 code 都在 drivers/base:
bus.c
driver.c
platform.c
沒有留言:
張貼留言