LINUX SPI设备驱动模型分析之二 SPI总线模块分析

    上一篇文章我们简要介绍了SPI驱动模块,本章我们详细说明一下spi总线、设备、驱动模块的注册、注销以及这几个模块之间的关联。

 

 

SPI总线的注册

     spi模块也是基于LINUX设备-总线-驱动模型进行开发的,因此其spi总线,也是需要注册到LINUX系统的总线模块的,调用的接口为是bus_register,我们看下spi总线都定义了哪些内容,如下是spi_bus_type的定义:

struct bus_type spi_bus_type = {
	.name		= "spi",
	.dev_attrs	= spi_dev_attrs,
	.match		= spi_match_device,
	.uevent		= spi_uevent,
	.pm		= &spi_pm,
};

现在我们分析一下spi总线实现的成员变量:

  • 定义了该总线的名称为spi;
  • 定义了spi总线上注册设备时在sysfs中所需要创建的默认属性文件(即注册到spi总线上的设备,均需要在其设备目录下创建默认的属性文件),spi_dev_attr的定义如下,即每一个注册在spi总线上的spi设备,在挂载的sysfs文件系统对应目录下均会创建modalias的属性文件,该文件只有读权限,主要读取spi设备的名称(格式为“spi:spi->modalias”)
	static struct device_attribute spi_dev_attrs[] = {
		__ATTR_RO(modalias),
		__ATTR_NULL,
};
  • 该spi的match接口为spi_match_device,该接口主要用于spi设备与spi驱动的匹配检测;
  • spi_uevent主要是在spi设备与spi驱动完成绑定时,发送给应用层的uevent条目,此处主要是增加“MODALIAS=spi:spi->modalias”的uevent条目。
  • spi_pm为spi总线模块电源管理相关的接口(这块我还不熟悉,暂时就不展开了)

spi_match_device接口分析

该接口主要进行spi设备与驱动的匹配检测,该接口目前支持基于OF模块的匹配、基于spi设备与驱动名称的匹配检测、acpi模块的匹配检测。主要功能如下:

  1. 若LINUX系统支持OF,则调用of_driver_match_device进行OF部分的匹配接口,这是使用LINUX设备-总线-驱动模型中device类型变量与device_driver类型变量的成员间的匹配(device->of_node、device_driver->of_match_table这两个成员变量完成匹配);
  2. 若该spi设备或驱动支持acpi,则调用acpi_driver_match_device,进行acpi模块的匹配;
  3. 否则则调用spi_match_id,进行设备与驱动的匹配(这主要是将spi 设备的modalias变量与spi驱动的id_table中的参数进行比较)
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);

	/* Attempt an OF style match */
	if (of_driver_match_device(dev, drv))
		return 1;

	/* Then try ACPI */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	if (sdrv->id_table)
		return !!spi_match_id(sdrv->id_table, spi);

	return strcmp(spi->modalias, drv->name) == 0;
}

spi总线注册

        当调用bus_register完成spi总线的注册后,spi总线与LINUX系统bus_kset、已注册到LINUX系统的总线以及spi总线与sysfs中的各结构体的关联图如下所示:

  1. 针对spi总线而言,其对应kobject在sysfs系统下对应一个sysfs_dirent类型的变量,通过该类型的变量即可在sysfs目录下创建一个目录(针对spi总线而言即为/sys/bus/spi),而spi总线对应kobject其kobj_type中的sysfs_ops则指向了总线的处理接口,通过这些接口即可对spi总线的属性文件进行读写操作(即可向/sys/bus/spi/下的普通文件进行读写操作)。
  2. 而注册到LINUX系统上的总线,通过其kset->kobject成员中的list变量,即完成了各注册的总线的关联。

(针对下图中各结构体的关联,建议读者查看我之前分析的LINUX设备-总线-驱动模型,我认为只要对LINUX设备-总线-驱动模型熟悉了以后,对各具体总线驱动模块的实现即可快速掌握)

 

 

   本篇文章主要介绍spi 总线的注册以及相关模块间的关联等内容。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/103226389
今日推荐