用户通用驱动spidev.c与设备匹配问题

用户通用驱动spidev.c与设备匹配问题

发现了一个奇怪的现象:

  1. 匹配成功了 :驱动确实跑起来了,probe 函数被调用了。
  2. 代码却说不匹配spidev_dt_ids 里明明没有 "spidev",而且 probe 函数里还打印了"Buggy DT"警告。

设备树定义:

shell 复制代码
&ecspi1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi1>;

    fsl,spi-num-chipselects = <2>;
    cs-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>, <&gpio4 24 GPIO_ACTIVE_LOW>;
    status = "okay";

    dac: dac {
        compatible = "spidev";
        reg = <0>;
        spi-max-frequency = <2000000>;
    };
};

spi_driver定义:

c 复制代码
static struct spi_driver spidev_spi_driver = {
	.driver = {
		.name =		"spidev",
		.of_match_table = of_match_ptr(spidev_dt_ids),
		.acpi_match_table = ACPI_PTR(spidev_acpi_ids),
	},
	.probe =	spidev_probe,
	.remove =	spidev_remove,
};

转入of_match_table的设备列表:

c 复制代码
static const struct of_device_id spidev_dt_ids = {
	{ .compatible = "rohm,dh2228fv" },
	{ .compatible = "lineartechnology,ltc2488" },
	{},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);

发现spidev_dt_ids中并没有定义{ .compatible = "spidev" },,但最后还是能匹配成功。

  1. 先去看spi总线类型结构体:

    c 复制代码
    struct bus_type spi_bus_type = {
    	.name		= "spi",
    	.dev_groups	= spi_dev_groups,
    	.match		= spi_match_device,
    	.uevent		= spi_uevent,
    };
  2. 找到match函数spi_match_device

    c 复制代码
    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;
    }
    • 第 1 关:OF (设备树) 匹配
      • 代码:of_driver_match_device(dev, drv)
      • 动作:内核拿着你的 compatible = "spidev"spidev_dt_ids 列表里找。
      • 结果:失败 。列表里只有 "rohm,dh2228fv""lineartechnology,ltc2488"
    • 第 2 关:ACPI 匹配
      • 动作:x86 架构用的。
      • 结果:失败
    • 第 3 关:ID Table 匹配
      • 动作:检查传统 ID 表。
      • 结果:失败
    • 第 4 关:名称 (Name) 匹配(在这里匹配成功)
      • 代码:return strcmp(spi->modalias, drv->name) == 0;
      • 核心逻辑
        1. 驱动名字 drv->name"spidev"
        2. 内核 SPI 核心层在解析设备树时,发现 compatible = "spidev",会将其设为该设备的 modalias
        3. strcmp("spidev", "spidev") 相等。
      • 结果:匹配成功
  • 为什么能匹配?

    靠的是 spi_match_device 最后的字符串名称硬匹配机制(Fallback)。

  • 为什么有警告?

    复制代码
    [root@100ask:~]# dmesg | grep "DT"
    [ 2146.942455] spidev spi0.0: buggy DT: spidev listed directly in DT

    spidev_probe做了检查:

    c 复制代码
    	if (spi->dev.of_node && !of_match_device(spidev_dt_ids, &spi->dev)) {
    		dev_err(&spi->dev, "buggy DT: spidev listed directly in DT\n");
    		WARN_ON(spi->dev.of_node &&
    			!of_match_device(spidev_dt_ids, &spi->dev));
    	}
相关推荐
爱分享的阿Q16 小时前
STM32现代化AI开发环境搭建:从Keil到VSCode+AI的范式转移
人工智能·vscode·stm32
bubiyoushang88819 小时前
利用STM32实现Modbus通信(RTU从机方案)
stm32·单片机·嵌入式硬件
杰杰桀桀桀19 小时前
4*4无时延矩阵键盘(非阻塞)--附代码链接
stm32·单片机·嵌入式硬件·矩阵·计算机外设·无时延矩阵键盘
cmpxr_20 小时前
【单片机】STM32Fxx启动模式怎么接
stm32·单片机·嵌入式硬件
篮子里的玫瑰20 小时前
STM32 时序计算指南:时钟周期与波特率深入剖析
stm32·单片机·嵌入式硬件
feifeigo12320 小时前
基于STM32F407和WM8978的MP3播放程序设计与实现
stm32·单片机·嵌入式硬件
不做无法实现的梦~1 天前
STM32 上部署 MAVLink 协议教程
stm32·单片机·嵌入式硬件
HIZYUAN1 天前
AG32 MCU可以替代STM32+CPLD吗 (二)
stm32·单片机·嵌入式硬件·fpga开发·agm ag32·国产mcu+fpga·低成本soc
LCG元2 天前
STM32实战:基于STM32F103的LCD1602液晶屏(并口/模拟时序)驱动
stm32·单片机·嵌入式硬件
匿名了匿名了2 天前
直流无刷与直流有刷电机
stm32·嵌入式硬件·mcu