下面這個結構 體,對於移植過系統的來說已經不陌生了,而系統也正是通過這個結構體加載相關驅動,下面這個結構體只列出比較的幾個驅動程序,其實系統中遠不只如此。
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_lcd,
&s3c_device_bl,
&s3c_device_wdt,
&s3c_device_i2c,//下面的案例
&s3c_device_adc,
&s3c_device_nand,
&s3c_device_ts,
&s3c_device_buttons,
&s3c_device_rtc,
};
下面就以一個 s3c2440的I2C驅動爲例進行說明:
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C24XX_PA_IIC,//內存資源
.end = S3C24XX_PA_IIC + S3C24XX_SZ_IIC - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IIC, //中斷資源,只有一箇中斷
.end = IRQ_IIC,
.flags = IORESOURCE_IRQ,
}
};
這裏定義了兩組resource,它描述了一個I2C設備的資源,第1組描 述了這個I2C設備所佔用的總線地址範圍, IORESOURCE_MEM表示第1組描述的是內存類型的資源信息,第2組描述了這個I2C設備的中斷號, IORESOURCE_IRQ表示第2組描述的是中斷資源信息。設備驅動會根據flags來獲取相應的資源信息。有了resource信息,就可以定義platform_device了:
struct platform_device s3c_device_i2c
= {//這個名稱是在static struct
platform_device *smdk2410_devices[] __initdata中,系統加載時調用
.name
= "s3c2410-i2c",//這個名是實現device與driver匹配的關鍵,與後面的driver將相同
.id = -1,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),//可用資源數
.resource = s3c_i2c_resource,//前面出現的資源
};
定義好了platform_device結構體後就可以調用函數platform_add_devices向系統中添加該設備了,之後可以調用platform_driver_register()進行設備註冊。要注意的是,這裏的platform_device設備的註冊過程必須在相應設備驅動加載之前被調用,即執行platform_driver_register之前,原因是因爲驅動註冊時需要匹配內核中所以已註冊的設備名。
static struct platform_driver s3c2410_i2c_driver = {
.probe = s3c24xx_i2c_probe,
.remove = s3c24xx_i2c_remove,
.resume = s3c24xx_i2c_resume,
.driver = {
.owner = THIS_MODULE,
.name = "s3c2410-i2c",
},
};
在驅動初始化函數中調用函數platform_driver_register()註冊platform_driver,需要注意的是s3c_device_i2c結構中name元素和s3c2410_i2c_driver結構中driver.name必須是相同的,這樣在platform_driver_register()註冊時會對所有已註冊的所有platform_device中的name和當前註冊的platform_driver的driver.name進行比較,只有找到相同的名稱的platfomr_device才能註冊成功,當註冊成功時會調用platform_driver結構元素probe函數指針,這裏就是s3c24xx_i2c_probe,當進入probe函數後,需要獲取設備的資源信息,常用獲取資源的函數主要是:
struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
根據參數type所指定類型,例如IORESOURCE_MEM,來獲取指定的資源。
struct int platform_get_irq(struct platform_device *dev, unsigned int num);獲取資源中的中斷號。