转了个圈,又回来了
分类: 嵌入式
2010-01-01 19:56:13
上面一篇主要是介绍了怎么样用platform_device模型来管理设备,下面介绍下
platform_device和platform_driver的注册函数。这两个注册函数在drivers/base下的platform.c文件里面。
1. 首先来看platform_device_register函数。
platform_device_register-à platform_device_addà device_add
中途就是做了对资源的一些处理。
struct platform_device {
const char * name;
u32 id;
struct device dev;
u32 num_resources;
struct resource * resource;
};
int platform_device_register(struct platform_device * pdev)
{
device_ initialize (&pdev->dev);
return platform_device_add(pdev);
}
首先是完成对dev的initialize。然后调用platform_device_add函数向系统添加一个platform设备。下面对该函数的关键部分注释。
int platform_device_add(struct platform_device *pdev)
{
int i, ret = 0;
if (!pdev)
return -EINVAL;
//让dev的parent指向 platform_bus,platform_bus也是作为一个设备向系统添加的。
if (!pdev->dev.parent)
pdev->dev.parent = &platform_bus;
//dev所连接的总线是platform_bus_type
pdev->dev.bus = &platform_bus_type;
if (pdev->id != -1)
snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%u", pdev->name, pdev->id);
else
strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
if (r->name == NULL)
r->name = pdev->dev.bus_id;
p = r->parent;
if (!p) {
if (r->flags & IORESOURCE_MEM)
p = &iomem_resource;
else if (r->flags & IORESOURCE_IO)
p = &ioport_resource;
}
//向系统注册mem和io两类资源,也就是检测是否与已经注册的资源冲突了。
if (p && insert_resource(p, r)) {
printk(KERN_ERR
"%s: failed to claim resource %d\n",
pdev->dev.bus_id, i);
ret = -EBUSY;
goto failed;
}
}
pr_debug("Registering platform device '%s'. Parent at %s\n",
pdev->dev.bus_id, pdev->dev.parent->bus_id);
//就是将设备注册到指定的bus_type,这个在以后的文章中在详细介绍
ret = device_add(&pdev->dev);
if (ret == 0)
return ret;
failed:
while (--i >= 0)
if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))
release_resource(&pdev->resource[i]);
return ret;
}
2. 下面来看看platform_driver_register的实现。
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 device_driver driver;
};
int platform_driver_register(struct platform_driver *drv)
{
//指定了device_driver所属的总线
drv->driver.bus = &platform_bus_type;
//如果指定了platform的各项接口操作就会赋给对应的driver的接口。
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;
if (drv->suspend)
drv->driver.suspend = platform_drv_suspend;
if (drv->resume)
drv->driver.resume = platform_drv_resume;
//调用driver_register注册驱动
return driver_register(&drv->driver);
}
这样在platform_bus_type总线上面既有设备又有驱动了。这两个注册函数是内核提供的,对于其中调用的device_register以及driver_register函数将会在后面的文章中具体介绍。在上面对pdev->dev.parent = &platform_bus;的解释中,我们得知platform_bus也是一个设备,具体将在下一篇文章里介绍。