在完成platform_device的添加之后,i2c子系统将进行platform_driver的注册过程。
platform_driver的注册通过调用初始化函数i2c_adapter_s3c_init函数来完成。
i2c_adap_s3c_init()函数体如下:
static int __init i2c_adap_s3c_init(void) { return platform_driver_register(&s3c24xx_i2c_driver); }
platform_driver_register(&s3c24xx_i2c_driver),将完成向platform_bus总线注册platform_driver类型驱动s3c24xx_i2c_driver的工作。s3c24xx_i2c_driver如下:
static struct platform_driver s3c24xx_i2c_driver = { .probe = s3c24xx_i2c_probe, .remove = s3c24xx_i2c_remove, .id_table = s3c24xx_driver_ids, .driver = { .owner = THIS_MODULE, .name = "s3c-i2c", .pm = S3C24XX_DEV_PM_OPS, }, };
id_table被初始化为s3c24xx_driver_ids:static struct platform_device_id s3c24xx_driver_ids[] = { { .name = "s3c2410-i2c", .driver_data = TYPE_S3C2410, }, { .name = "s3c2440-i2c", .driver_data = TYPE_S3C2440, }, { }, };
platform_driver在注册到platform_bus总线的过程中会尝试将已注册的platform_driver
与已注册到platform_bus上的所有platform_device进行配对。
platform_bus总线的相关操作如下:
struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, .match = platform_match, .uevent = platform_uevent, .pm = &platform_dev_pm_ops, };
配对过程通过调用总线的match方法实现,即platform_match函数。如下:static int platform_match(struct device *dev, struct device_driver *drv) { struct platform_device *pdev = to_platform_device(dev); struct platform_driver *pdrv = to_platform_driver(drv); /* Attempt an OF style match first */ if (of_driver_match_device(dev, drv)) return 1; /* Then try to match against the id table */ if (pdrv->id_table) return platform_match_id(pdrv->id_table, pdev) != NULL; /* fall-back to driver name match */ return (strcmp(pdev->name, drv->name) == 0); }
可以看到函数中有