linux总线驱动程序,Linux驱动程序中的platform总线详解

Linux驱动程序中的platform总线详解

在设备驱动程序中经常会见到和platform相关的字段,分布在驱动程序的多个角落,这也是2.6内核中比较重要的一种机制,把它的原理弄懂了,对以后分析驱动程序很有帮助,下面简单介绍一下:

在linux2.6设备模型中,关心总线,设备,驱动这三个实体,总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动。相反,在系统每注册一个驱动的时候,寻找与之匹配的设备,匹配是由总线来完成的。

一个现实的Linux 设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、USB、I2C、SPI 等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC 系统中集成的独立的外设控制器、挂接在SoC 内存空间的外设等确不依附于此类总线。基于这一背景,Linux 发明了一种虚拟的总线,称为platform 总线。

SOC系统中集成的独立外设单元(I2C,LCD,SPI,RTC等)都被当作平台设备来处理,而它们本身是字符型设备。

从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));注册

Linux驱动程序中的platform总线详解

[日期:2010-12-04]来源:Ubuntu社区  作者:xgc94418297[字体:大 中 小]

在设备驱动程序中经常会见到和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));注册

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值