S3C2440驱动篇—Linux平台设备驱动

dguthai 2011-08-02

在设备驱动程序中经常会见到和platform相关的字段,分布在驱动程序的多个角落,这也是2.6内核中比较重要的一种机制,把它原理弄懂,对以后分析驱动程序很有帮助:在linux2.6设备模型中,关心总线,设备,驱动这三个实体,总线将设备和驱动绑定,在系统每注册一个设备的时候,会寻找与之匹配的驱动。相反,在系统每注册一个驱动的时候,寻找与之匹配的设备,匹配是由总线来完成的。

一个现实的Linux 设备和驱动通常都需要挂接在一种总线上,对于本身依附于PCI、USB、I2C、SPI 等的设备而言,这自然不是问题,但是在嵌入式系统里面,SoC 系统中集成的独立的外设控制器、挂接在SoC 内存空间的外设等确不依附于此类总线。基于这一背景,Linux 发明了一种虚拟的总线,称为platform 总线。SOC系统中集成的独立外设单元(LCD,RTC,WDT等)都被当作平台设备来处理,而它们本身是字符型设备。

从Linux2.6内核起,引入一套新的驱动管理和注册机制:platform_device 和 platform_driver 。Linux 中大部分的设备驱动,都可以使用这套机制,设备用 platform_device 表示;驱动用platform_driver 进行注册。

一.平台设备

在Linux设备驱动中,有一类设备被称为“平台设备”,通常把SoC系统中集成的独立外设单元都当作平台设备来处理。平台设备用platform_device结构体来描述,在2.6.32.2内核中定义在include/linux/platform_devide.h中,其结构体如下:

struct platform_device {

       const char      * name;

       int           id;

       struct device   dev;

       u32         num_resources;

       struct resource       * resource;   //设备使用的资源

 

       struct platform_device_id      *id_entry;

 

       /* arch specific additions */

       struct pdev_archdata     archdata;

};

struct resource        //位于include/linux/ioport.h

{

     resource_size_t start;

     resource_size_t end;

     const char *name;

     unsigned long flags;

     struct resource *parent, *sibling, *child;

};

       我们通常关心start、end 和flags 这3 个字段,分别标明资源的开始值、结束值和类型,flags可以为IORESOURCE_IO、IORESOURCE_MEM、IORESOURCE_IRQ、IORESOURCE_DMA 等。

       在Linux中定义了许多平台设备,比如在:arch/arm/plat-s3c24xx/devs.c中,下面贴出WatchDog的平台设备定义:

static struct resource s3c_wdt_resource[] = {

       [0] = {  //IO端口资源

              .start = S3C24XX_PA_WATCHDOG,

              .end   = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,

              .flags = IORESOURCE_MEM,

       },

       [1] = {  //中断资源

              .start = IRQ_WDT,

              .end   = IRQ_WDT,

              .flags = IORESOURCE_IRQ,

       }

};

struct platform_device s3c_device_wdt = {

       .name               = "s3c2410-wdt",

       .id             = -1,

       .num_resources       = ARRAY_SIZE(s3c_wdt_resource),

       .resource   = s3c_wdt_resource,

};

EXPORT_SYMBOL(s3c_device_wdt);

相关推荐