对于总线设备驱动,是需要分别创建设备和驱动两个结构体,然后根据name,互相匹配,匹配成功后,调用
驱动的probe函数,然后创建设备文件,实现驱动的业务逻辑。
因此,我们就以设备和驱动的注册,以及匹配来分析。
创建设备
1. 首先在arch/arm/mach-s5pv210/mach-x210.c (我这里用是mach-x210.c不同的bsp,这个文件不一定一样)。
定义我们的spi设备硬件相关的结构体,spi_board_info
然后调用 spi_register_board_info注册。
注意,在我这版内核中,并不是注册spi_board_info了就会创建spi_device(spi设备结构体)
2. 接下来我们看spi控制器驱动的probe函数,spi_device的创建实际是这里创建的
s3c64xx_spi_probe (drivers/spi/spi_s3c64xx.c)
spi_register_master (drivers/spi/spi.c)
scan_boardinfo (drivers/spi/spi.c)
spi_new_device (drivers/spi/spi.c)
驱动注册以及驱动和设备的匹配
1. 在我们的spi设备驱动里的init函数里,调用spi_register_driver来向系统注册spi_driver
2. 驱动与设备的匹配,以及驱动的probe函数
spi_register_driver (drivers/spi/spi.c)
driver_register (drivers/base/driver.c)
bus_add_driver (drivers/base/bus.c)
driver_attach (drivers/base/dd.c)
__driver_attach (drivers/base/dd.c)
driver_match_device (drivers/base/dd.c)
drv->bus->match(dev, drv) (drivers/base/base.h)
spi_match_device (drivers/spi/spi.c)
driver_probe_device (drivers/base/dd.c)
really_probe (drivers/base/dd.c)
drv->probe(dev)
static int spi_match_device(struct device *dev, struct device_driver *drv)
{
const struct spi_device *spi = to_spi_device(dev);
const struct spi_driver *sdrv = to_spi_driver(drv);
if (sdrv->id_table)
return !!spi_match_id(sdrv->id_table, spi);
return strcmp(spi->modalias, drv->name) == 0;
}
从上面这个匹配函数可以看出匹配有两种方式id_table或者modailas和name,匹配成功后,就会调用我们的spi驱动的
probe函数了。