今天正好有空,研究了一下platformdevice的probe函数时如何被调用的。我觉得这个过程应该可以推广到一般设备的探测函数的调用。
以mini2440中的watchdog为例。
先看配置文件中对watchdog的设置:
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C24XX_PA_WATCHDOG,
.end = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_WDT,
.end = IRQ_WDT,
.flags = IORESOURCE_IRQ,
}
};
struct platform_device s3c_device_wdt = {
.name = "s3c2410-wdt",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_wdt_resource),
.resource = s3c_wdt_resource,
};
在系统启动时 mini2440_machine_init调用了 platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices)); 其中 mini2440_devices 中就包括了s3c_deice_wdt。
int platform_add_devices(struct platform_device **devs, int num)
{
int i, ret = 0;
for (i = 0; i < num; i++) {
ret = platform_device_register(devs[i]);
if (ret) {
while (--i >= 0)
platform_device_unregister(devs[i]);
break;
}
}
return ret;
}
int platform_device_register(struct platform_device *pdev)
{
device_initialize(&pdev->dev);
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 = &iopor