platform_device_add最终还是调用老接口device_add,只是多了将resource注册进内核的步骤。

platform_driver_register也是调用driver_register,而且在driver_register中,会调用到driver的probe函数。

 

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)