`
isiqi
  • 浏览: 16047167 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

platform _device和platform_driver注册过程

 
阅读更多

platform _deviceplatform_driver注册过程

platform_device_register()注册过程

/* arch/arm/mach-s3c2410/mach-smdk2410.c */

struct platform_device s3c_device_i2c = {

.name = "s3c2410-i2c",

.id = -1,

.num_resources = ARRAY_SIZE(s3c_i2c_resource),

.resource = s3c_i2c_resource,

};

/*

* platform_device_register - add a platform-level device

* @pdev: platform device we're adding

*

*/

int platform_device_register(struct platform_device * pdev)

{

device_initialize(&pdev->dev); //初始化设备结构

return platform_device_add(pdev); //添加一个片上的设备到设备层

}

/**

* platform_device_add - add a platform device to device hierarchy

* @pdev: platform device we're adding

*

* This is part 2 of platform_device_register(), though may be called

* separately _iff_ pdev was allocated by platform_device_alloc().

*/

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)

snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name,

pdev->id); /* 若支持同类多个设备,则用pdev->name和pdev->id在总线上标识该设备 */

else

strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE); /* 否则,用pdev->name(如"s3c2410-i2c")在总线上标识该设备 */

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; /* 作为IO内存资源分配 */

else if (r->flags & IORESOURCE_IO)

p = &ioport_resource; /* 作为IO Port资源分配 */

}

if (p && insert_resource(p, r)) { /* 将新的resource插入内核resource tree */

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);

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;

}

这里发现,添加device到内核最终还是调用的device_add函数。Platform_device_add和device_add最主要的区别是多了一步insert_resource(p, r)即将platform资源(resource)添加进内核,由内核统一管理。

platform_driver_register()注册过程

--------------------------------------
static struct platform_driver s3c2410_i2c_driver = {

.probe = s3c24xx_i2c_probe,

.remove = s3c24xx_i2c_remove,

.resume = s3c24xx_i2c_resume,

.driver = {

.owner = THIS_MODULE,

.name = "s3c2410-i2c",

},

};

platform_driver_register(&s3c2410fb_driver)----->
driver_register(&drv->driver)----->
bus_add_driver(drv)----->
driver_attach(drv)----->
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach)----->
__driver_attach(struct device * dev, void * data)----->
driver_probe_device(drv, dev)----->
really_probe(dev, drv)----->

在really_probe()中:为设备指派管理该设备的驱动:dev->driver = drv, 调用probe()函数初始化设备:drv->probe(dev)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics