您的位置:首页 > 运维架构 > Linux

linux platform 设备驱动之 match 自动匹配

2017-01-17 11:04 405 查看
[cpp] view
plain copy

<span style="font-size:14px;">struct platform_device {   // linux/platform_device.h  

    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;  

};</span>  

还有一个比较重要的结构体resource比较关键,通常定义一个platform_device一般需要初始化两个方面的内容:设备占用的资源resource和设备私有数据dev.platform_data。最重要的是resource,设备占用的资源主要是两个方面:IO内存和irq资源。实际上是对地址范围及其属性的一个描述。最后几个用于树型结构的指针是内核用于管理所有资源的。

[cpp] view
plain copy

struct resource {   //linux/ioports  

    resource_size_t start;  

    resource_size_t end;  

    const char *name;  

    unsigned long flags;  

    struct resource *parent, *sibling, *child;  

};  

[cpp] view
plain copy

static struct resource Myled_resource[] = {  

        [0] = {  

                .start = 0x56000010,  

                .end   = 0x56000010 + 16,  

                .flags = IORESOURCE_MEM  

        },  

};  

[cpp] view
plain copy

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 (*resume)(struct platform_device *);  

    struct device_driver driver;  

    struct platform_device_id *id_table;  

};  

[cpp] view
plain copy

//系统中为platform总线定义了一个bus_type的实例platform_bus_type,  

struct bus_type platform_bus_type = {  

    .name = “platform”,  

    .dev_attrs = platform_dev_attrs,  

    .match = platform_match,  

    .uevent = platform_uevent,  

    .pm = PLATFORM_PM_OPS_PTR,  

};  

EXPORT_SYMBOL_GPL(platform_bus_type);  

   

//这里要重点关注其match()成员函数,正是此成员表明了platform_device和platform_driver之间如何匹配。  

static int platform_match(struct device *dev, struct device_driver *drv)  

{  

    struct platform_device *pdev;  

  

    pdev = container_of(dev, struct platform_device, dev);  

    return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);  

}  

//匹配platform_device和platform_driver主要看二者的name字段是否相同。  

//对platform_device的定义通常在BSP的板文件中实现,在板文件中,将platform_device归纳为一个数组,最终通过platform_add_devices()函数统一注册。  

//platform_add_devices()函数可以将平台设备添加到系统中,这个函数的 原型为:  

int platform_add_devices(struct platform_device **devs, int num);  

//该函数的第一个参数为平台设备数组的指针,第二个参数为平台设备的数量,它内部调用了platform_device_register()函 数用于注册单个的平台设备。  

//example

Myled.c 设备

[cpp] view
plain copy

static struct platform_device Myledplatform_device_led = {  

        .name           = "Myled_platform_device_driver",  

        .id             = -1,  

        .num_resources  = ARRAY_SIZE(Myled_resource),  

        .resource       = Myled_resource,  

        .dev            = {  

              .release  = Myled_platform_device_release,  

        },  

};  

Myled_drv.c 设备驱动

[cpp] view
plain copy

static struct platform_driver Myled_platform_driver = {  

    .probe  = Myled_probe,  

    .remove = __devexit_p(Myled_remove),  

    .driver = {  

        .name = "Myled_platform_device_driver",  

        .owner = THIS_MODULE,  

    }  

};  

我们只要把platform_device 和 platform_driver 中的driver.name 设置成一样,platform总线的match会自动匹配platform_device 和 platform_driver。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux