//--------------------------------------------------------------------
#include /include/linux/platform_device.h
struct platform_device {
const char *name;
int id;
struct device dev;
u32 num_resources;
struct resource *resource;
const struct platform_device_id *id_entry;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
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;
};
//--------------------------------------------------------------------

Platform device 是在 Linux 2.6 引入的 driver 管理和註冊機制,Platform device 是掛在虛擬的 bus 上 (Platform bus)。

在 Linux 中大部分的 device 都可以包成 Platform device 來做註冊,其中可能還會包含了介面的註冊(例如I2C,SPI),因為有些裝置在傳輸 command 和傳輸 data 的時候所用的介面會不同。

好比Display device的時候,假若command是使用I2C介面傳輸,而RGB data是使用MDDI介面傳輸,那麼在註冊MDDI的Platform device時會一併註冊傳輸command的I2C介面,接著才能使用I2C傳輸command到裝置上去控制暫存器來完成初始化的動作(當然這並不是初始化一個device的完整流程)。

Platform driver 的移植,就軟體來說主要是 driver 和 device 兩個部分。

在board-xxx.c中可以看到所有platform device的註冊。

static void __init Board_init(void) {
...
//platform_add_devices註冊,devices struct中所帶的platform device,第二個參數表示該struct的大小
platform_add_devices(devices, ARRAY_SIZE(devices));
...
}

回頭去找devices這個struct如下:
static struct platform_device *devices[] __initdata = {
...
&aaa_device,
&bbb_device,
...
};
可以看到該struct的內容是蒐集了所有要註冊的platform device的資訊。

每個device的型別仍然是platform_device,platform_device struct如下所示:
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
const struct platform_device_id *id_entry;
/* arch specific additions */
struct pdev_archdata archdata;
};
一般常用到的包含了name, id, dev, resource,dev可以帶platform_data,提供在probe的時候使用。

以上是device的註冊,要完成driver的porting,還需要driver的register。

關於device register和driver register,常見的順序都是先register device再register driver,因為board_xxx.c中的xxx_init通常會比之後採用module_init而掛載的driver來的早執行到,因此一般來說都是device先註冊。

以下是之前的誤解。
因為這樣的機制,所以認為driver在註冊的時候,都必須先是device先註冊才可以註冊driver。
後來發現反過來也是可以的,所以稍微在網路上搜尋了一下兩者的關聯性,因為過去單從platform_register_driver()來往下trace,看到內部的code有去做match來配對device和driver,match的話就會做really_probe()來執行driver probe函示。
其實在platform_device_register()也會做同樣的動作去媒合device和driver。之前沒有注意到platform_device_register()的部分,因為他被包在platform_add_device()裡面。因此platform_device_register()和platform_driver_register()誰先做並不會影響結果。

從網路上找到關於兩者的關係:

1. platform_device_register()
|
|
---------------------------------------------------------------------------------------------------------
bus type (Platform, I2C, SPI) 在bus driver中會作match()和呼叫driver probe()的動作,若有match的話
---------------------------------------------------------------------------------------------------------
|
|
2. platform_driver_register()

這邊分成兩個部分解釋:
1. 當device透過platform_device_register()時,會透過.match提供的API在bus上找尋name相同的driver是否已經被掛載了,若成立,則會call bus或driver所提供的probe函式來做driver的初始化動作。若不成立,則只是將該device掛到bus上就return。

2. 相同的,當driver透過platform_driver_register()註冊時,也是利用.match的方式在bus上尋找name相同的device是否已經掛接在bus上,若是,則啟動probe的函式完成driver的初始化。若否,則將drvier掛接在bus上就return。

綜合以上,可以得知device和driver的掛接沒有誰先誰後的副作用,唯一的先決條件就是bus driver已經被註冊好。故platform bus是第一個要備系統給註冊起來,接著的device和driver就是透過platform_device_register()和platform_driver_register()將三者牽上關係。


//----------------------------------------------------------------------------------------

platform_driver_register()與platform_device_register()

設備與驅動的兩種綁定方式:在設備註冊時進行綁定及在驅動註冊時進行綁定。以一個USB設備為例,有兩種情形:
(1)先插上USB設備並掛到總線中,然後在安裝USB驅動程序過程中從總線上遍歷各個設備,看驅動程序是否與其相匹配,如果匹配就將兩者邦定。這就是platform_driver_register()
(2)先安裝USB驅動程序,然後當有USB設備插入時,那麼就遍歷總線上的各個驅動,看兩者是否匹配,如果匹配就將其綁定。這就是platform_device_register()函數
//----------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------
arrow
arrow
    全站熱搜

    BB 發表在 痞客邦 留言(0) 人氣()