close
驅動註冊platform_driver(一)

從linux-2.6開始引入了一套新的驅動管理和註冊機制:platform_device和platform_driver.

linux中的大部分設備驅動,都可以使用該機制,設備用platform_device表示,驅動用platform_deriver進行註冊。

platform是linux的一個虛擬的地址總線,主要是用來描述晶片的核心資源,它直接取核心地址進行資源讀寫。
因此和內核相關性不大,像lcd,rtc,watchdog,uart等都是這類。

看看這個: http://www.eetop.cn/blog/html/45/11145-676.html

platform_device結構體用來描述設備的名稱、資源信息等,該結構被定義在include/linux/platform_device.h中

#include //該頭文件就是以前Linux-2.4驅動的頭文件,利用driver_register()進行驅動註冊
struct platform_device { //設備結構體信息
const char * name; //該平台設備的名稱
u32 id;
struct device dev;
u32 num_resources;
struct resource *resource; //定義平台設備的資源
};

其中最重要的是struct resource *resource結構,該結構定義在include/linux/ioport.h中
struct resource {
resource_size_t start; //定義資源的起始地址
resource_size_t end; //定義資源的結束地址
const char *name; //定義資源的名稱
unsigned long flags; //定義資源的類型,例如MEM, IO ,IRQ, DMA類型
struct resource *parent, *sibling, *child; //資源鍊錶指針
};

//設備在內核中也需要註冊,通過調用函數platform_add_devices()向系統添加該設備,在該函數內部會調用platform_device_register()向系統內核進行設備的註冊。
//注意設備的註冊要在驅動的註冊之前,即驅動註冊platform_driver_register()註冊之前,因為驅動註冊時需要匹配內核中所有已經註冊了的設備名。

那麼接下來我們開始驅動的註冊定義:主要結構體是platform_driver,該結構體也是定義在incluce/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 (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (* resume)(struct platform_device *);
struct device_driver driver; //老設備驅動,定義在include/linux/device.h中
};

然後內核提供的platform_driver結構體的註冊函數為platform_driver_register(),該函數定義在driver/base/platform.c中

函數原型:
int platform_driver_register (struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type; //驅動總線類型: IO, IRQ,DMA,MEM類型
if (drv->probe)
drv->driver.probe = platform_drv_probe; //設備探測
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
if (drv->suspend)
drv->driver.suspend = platform_drv_suspend;
if (drv->resume)
drv->driver.resume = platform_drv_resume;
return driver_register(&drv->driver); //這個就是老的設備驅動註冊了
}
EXPORT_SYMBOL_GPL(platform_driver_register);

舉例設備驅動:

static struct platform_driver mxc_kpd_driver = {
.driver = {
.name = "mxc_keypad",
.bus = &platform_bus_type,
},
.suspend = mxc_kpp_suspend,
.resume = mxc_kpp_resume,
.probe = mxc_kpp_probe,
.remove = mxc_kpp_remove
};
arrow
arrow
    全站熱搜

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