zoukankan      html  css  js  c++  java
  • 关于platform_device和platform_driver的匹配【转】

    转自:http://blog.csdn.net/dfysy/article/details/5959451

    版权声明:本文为博主原创文章,未经博主允许不得转载。
    
    说句老实话,我不太喜欢现在Linux 2.6这套bus, platform, device,device driver 的模式。我觉得这种模式破坏了Linux的“简单就是美”的哲学,原来那套驱动已经可以包容所有驱动,也可以直接注册驱动文件和管理,而且以前的驱动在现在的结构上也还可以使用,把它在注册到bus这棵树上又有什么用呢?虽然可以看到一点对于移植性和平台管理方面的优点,但是我认为现在这种驱动编程的风格越来越像Windows的风格,很不直观和简约,让人理解起来相当的困惑。
    
    牢骚发完了,bus结构还得继续,说说platform_device和platform_driver的匹配吧!一般来说系统上来在init_init_machine的对应函数ap_init中注册一些这个平台的设备,如下:
    
    static struct resource cbp_sdmmc_resource[]=
    {
       [0]={
             .start=HWD_MMC_BASE,
             .end=HWD_MMC_BASE+0xff0,
             .flags=IORESOURCE_MEM
           },
       [1]={
             .start=IRQ_SDMMC,
             .end=IRQ_SDMMC,
             .flags=IORESOURCE_IRQ
           },
       [2]={
             .start=IRQ_SDMMC_CD,
             .end=IRQ_SDMMC_CD,
             .flags=IORESOURCE_IRQ
           }
    };
    
    struct platform_device cbp_device_sdmmc = {
     .name    = "cbp-sdmmc",
     .id    = -1,
     .num_resources   = ARRAY_SIZE(cbp_sdmmc_resource),
     .resource   = cbp_sdmmc_resource,
            .dev              = {
                    .coherent_dma_mask = 0xffffffffUL
            }
    };
    static struct platform_device * cbp_devices[] __initdata = {
       &cbp_device_sdmmc
    };
    static void __init ap_init(void)
    {
       platform_add_devices(cbp_devices,ARRAY_SIZE(cbp_devices));
    
    }
    说明这个平台使用的SD/MMC驱动的名字叫"cbp-sdmmc",然后在驱动中用platform_driver_register声明对应的platform_driver来使用上面声明的平台资源,如下:
    
    static int __init cbpmci_init(void)
    {
        return platform_driver_register(&cbpmci_driver);
    }
    platform_driver和platform_driver的匹配方式有两种:
    
    1)直接根据名字来进行匹配,这种方式是比较常用的方式,比如如下申明cbpmci_driver:
    
    static struct platform_driver cbpmci_driver = {
     .probe = cbpmci_probe,
     .driver = {
      .name = "cbp-sdmmc",
     },
    };
    2)通过id_talbe来实现,这种实现的最终还是通过名字对应来匹配,但是匹配的名字被列在一个表中,platform_device的name和这个表中的每一个值进行比较,知道找到相同的那一个,如下申明:
    
     static struct platform_device_id cbpmci_driver_ids[] = {
     {
      .name = "other-sdmmc",
      .driver_data = 0,
     },
     {
      .name = "cbp-sdmmc",
      .driver_data = 1,
     },
     { }
    };
    
    static struct platform_driver cbpmci_driver = {
     .driver = {
      .name = "vtc_sdmmc",
      .owner = THIS_MODULE,
      .pm = &cbpmci_pm_ops,
     },
     .id_table = cbpmci_driver_ids,
     .probe  = cbpmci_probe,
     .remove  = __devexit_p(cbpmci_remove),
     .shutdown = cbpmci_shutdown,
    };
    当id_table不为空的时候,.driver.name中的名字“vtc_sdmmc”就不管用了,会按照id_table中的内容进行匹配,同时匹配后的会把匹配上的platform_device_id保存在platform_device结构的id_entry中,在probe的时候就可以通过id_entry中的driver_data判断匹配的到底是cbpmci_driver_ids中的哪一组ID,
    
    比如上面例子中的"cbp-sdmmc"中匹配的是第二组,这样就可以再Probe的判断到底是什么平台了
    
    if(platform_get_device_id(pdev)->driver_data==1) printk("cgp SD/MMC support/n");
    
    这种匹配方式在三星的SD/MMC中有使用,由于2412和2440的地址是一样的,而2410不一样,所以通过driver_data 是否为1来区分。
    
    static struct platform_device_id s3cmci_driver_ids[] = {
     {
      .name = "s3c2410-sdi",
      .driver_data = 0,
     }, {
      .name = "s3c2412-sdi",
      .driver_data = 1,
     }, {
      .name = "s3c2440-sdi",
      .driver_data = 1,
     },
     { }
    };
    
     
    
    一下是Linux匹配的源代码,在platform.c中,一看就一目了然了,当然要跟到这步,中间还有好多指针要走:
    
    static int platform_match(struct device *dev, struct device_driver *drv)
    {
     struct platform_device *pdev = to_platform_device(dev);
     struct platform_driver *pdrv = to_platform_driver(drv);
    
     /* match against the id table first */
     if (pdrv->id_table)
      return platform_match_id(pdrv->id_table, pdev) != NULL;
    
     /* fall-back to driver name match */
     return (strcmp(pdev->name, drv->name) == 0);
    }
    
    此外platform_add_devices最终会调用platform_device_register,而platform_device_register和platform_driver_register应该先调用哪一个理论上讲是先调用device然后driver,但其实是无所谓的,最后都会调用device_attach()来probe。
  • 相关阅读:
    [洛谷P3674]小清新人渣的本愿
    [洛谷P2698][USACO12MAR]花盆Flowerpot
    [洛谷P4329][COCI2006-2007#1] Bond
    [洛谷P3203][HNOI2010]弹飞绵羊
    [洛谷P1407][国家集训队]稳定婚姻
    [洛谷P3388]【模板】割点(割顶)
    TX2_安装view_team
    tx2的一些系统命令
    tensorflow-cnnn-mnist
    mnist数据集tensorflow实现
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/6869591.html
Copyright © 2011-2022 走看看