歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux驅動程序中的platform總線詳解

Linux驅動程序中的platform總線詳解

日期:2017/2/28 16:27:01   编辑:Linux教程

在設備驅動程序中經常會見到和platform相關的字段,分布在驅動程序的多個角落,這也是2.6內核中比較重要的一種機制,把它的原理弄懂了,對以後分析驅動程序很有幫助,下面簡單介紹一下:

在linux2.6設備模型中,關心總線,設備,驅動這三個實體,總線將設備和驅動綁定,在系統每注冊一個設備的時候,會尋找與之匹配的驅動。相反,在系統每注冊一個驅動的時候,尋找與之匹配的設備,匹配是由總線來完成的。

一個現實的Linux 設備和驅動通常都需要掛接在一種總線上,對於本身依附於PCI、USB、I2C、SPI 等的設備而言,這自然不是問題,但是在嵌入式系統裡面,SoC 系統中集成的獨立的外設控制器、掛接在SoC 內存空間的外設等確不依附於此類總線。基於這一背景,Linux 發明了一種虛擬的總線,稱為platform 總線。

SOC系統中集成的獨立外設單元(I2C,LCD,SPI,RTC等)都被當作平台設備來處理,而它們本身是字符型設備。 【LINUX公社 www.LinuxIDC.com 】

從Linux2.6內核起,引入一套新的驅動管理和注冊機制:platform_device 和 platform_driver 。Linux 中大部分的設備驅動,都可以使用這套機制,設備用 platform_device 表示;驅動用platform_driver 進行注冊。

platform_device 結構體 include/linux/platform_device.h
struct platform_device
{
const char *name; //設備名
u32 id;
struct device dev;
u32 num_resources; //設備所使用的各類資源數量
struct resource *resource; //使用的資源
}

platform_driver 結構體 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 (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct pm_ext_ops *pm;
struct device_driver driver;
};

系統為platform總線定義一個bus_type的實例platform_bus_type,通過其成員函數match(),確定device和driver如何匹配。
匹配platform_device和platform_driver主要看二者的name字段是否相同。(name必須要相同才能匹配)

platform_device_register()函數注冊單個的平台設備。
一般是在平台的BSP文件中定義platform_device,通過platform_add_devices()函數將平台設備注冊到系統中

platform_driver 的注冊與注銷:
platform_driver_register()
platform_driver_unregister()


以s3c2440 LCD驅動為例:
在BSP文件中:
struct platform_device s3c_device_lcd = {
.name = "s3c2410-lcd",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_lcd_resource),
.resource = s3c_lcd_resource,
.dev = {
.dma_mask = &s3c_device_lcd_dmamask,
.coherent_dma_mask = 0xffffffffUL
}
};

為了完成LCD設備的注冊,將其放進/arch/arm/mach-s3c2440/mach-smdk2440.c中定義的smdk2440_devices數組中:
static struct platform_device *smdk2440_devices[] __initdata = {
........
........
&s3c_device_lcd,
};

platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));注冊

Copyright © Linux教程網 All Rights Reserved