ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年7月20日 星期三

platform_device, platform_driver

  1. platform-device 是 hardware (大概是指 hardware resource - gpio, interrupt number, memory region .. etc)
  2. platform-driver 是 software
各自和 kernel 註冊。

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 用:
  1. platform_device_alloc 取得一塊記憶體,工作 platform_device 的資料存放



並不是從此以後 driver 都要用 platform_device, platform_driver 這樣的方式來作。
舊的 module 實作方式還是可以用,只是沒有 suspend/resume 的 callback 機制了 (還是我找不到?)

把原來的 driver moduel 方式改為 platform_device, platform_driver ,大概就是..
  1. 把 mod_init 改為 mod_probe -- 主要是內容,原來 init 做的事,改在 probe 作
  2. 增加 remove, suspend, resume 這幾個 function
  3. 填寫一個 platform_driver structure
  4. 新增一個 init,內容就是註冊 platform_driver 和 platform_device
  5. 修改 exit,作 unregister platform_driver 和 platform_device
* kernel 提供一個 platform_device_register_simple( ) function call,讓 legacy module 方便改為 platform model. 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

沒有留言:

標籤

網誌存檔