linux设备驱动模型 - platform总线

1.


在驱动模型的基础上,就可以构建实际的设备驱动了,这里以platform总线来进行介绍,因为platform总线具有代表性,platform不是一个实际的总线,它是虚拟出来的,所以在设备上的任何硬件驱动都可以挂在这条总线上,最典型的就是设备上的控制器模块都是挂在platform总线上的 ;  platform 总线驱动模式是基于devices_bus_driver 驱动模式基础上演化

2.   platform_bus_type  结构体申明

struct bus_type platform_bus_type = {
 .name  = "platform",
 .dev_attrs = platform_dev_attrs,
 .match  = platform_match,
 .uevent  = platform_uevent,
 .pm  = &platform_dev_pm_ops,
};

platform_bus_rype 总线初始化函数为platform_bus_init,函数初始在linux main启动调用下面看看platform_bus_init实现

int __init platform_bus_init(void)
{
 int error;

 early_platform_cleanup();

 error = device_register(&platform_bus);
 if (error)
  return error;
 error =  bus_register(&platform_bus_type);   // 基于总线注册
 if (error)
  device_unregister(&platform_bus);
 return error;
}

 2.  platform_device   结构体
struct platform_device {
 const char * name;
 int  id;
 struct device dev;
 u32  num_resources;
 struct resource * resource;

 const struct platform_device_id *id_entry;

 /* MFD cell pointer */
 struct mfd_cell *mfd_cell;

 /* arch specific additions */
 struct pdev_archdata archdata;
};

 接口

extern int platform_device_register(struct platform_device *);
extern void platform_device_unregister(struct platform_device *);

 分析platform_device_register() 函数实现

int platform_device_register(struct platform_device *pdev)
{
 device_initialize(&pdev->dev);
 arch_setup_pdev_archdata(pdev);
 return platform_device_add(pdev);
}

int platform_device_add(struct platform_device *pdev)
{
 int i, ret = 0;

 if (!pdev)
  return -EINVAL;

 if (!pdev->dev.parent)
  pdev->dev.parent = &platform_bus;

 pdev->dev.bus = &platform_bus_type;

 if (pdev->id != -1)
  dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
 else
  dev_set_name(&pdev->dev, "%s", pdev->name);

 for (i = 0; i < pdev->num_resources; i++) {
  struct resource *p, *r = &pdev->resource[i];

  if (r->name == NULL)
   r->name = dev_name(&pdev->dev);

  p = r->parent;
  if (!p) {
   if (resource_type(r) == IORESOURCE_MEM)
    p = &iomem_resource;
   else if (resource_type(r) == IORESOURCE_IO)
    p = &ioport_resource;
  }

  if (p && insert_resource(p, r)) {
   printk(KERN_ERR
          "%s: failed to claim resource %d\n",
          dev_name(&pdev->dev), i);
   ret = -EBUSY;
   goto failed;
  }
 }

 pr_debug("Registering platform device '%s'. Parent at %s\n",
   dev_name(&pdev->dev), dev_name(pdev->dev.parent));

 ret = device_add(&pdev->dev);      // 函数device  增加流程一样@cyl
 if (ret == 0)
  return ret;

 failed:
 while (--i >= 0) {
  struct resource *r = &pdev->resource[i];
  unsigned long type = resource_type(r);

  if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
   release_resource(r);
 }

 return ret;
}

3.  struct platform_driver   结构体申明

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;
 const struct platform_device_id *id_table;
};
接口 int platform_driver_register(struct platform_driver *);
extern void platform_driver_unregister(struct platform_driver *);

分析 platform_driver_register(struct platform_driver *) 注册流程函数
int platform_driver_register(struct platform_driver *drv)
{
 drv->driver.bus = &platform_bus_type;
 if (drv->probe)
  drv->driver.probe = platform_drv_probe;
 if (drv->remove)
  drv->driver.remove = platform_drv_remove;
 if (drv->shutdown)
  drv->driver.shutdown = platform_drv_shutdown;

 return driver_register(&drv->driver);    // driver 函数注册一样
}







猜你喜欢

转载自blog.csdn.net/u012794472/article/details/80041998
今日推荐