用户通用驱动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));
    	}
相关推荐
Lester_110111 小时前
STM32 高级定时器PWM互补输出模式--如果没有死区,突然关闭PWM有产生瞬间导通的可能吗
stm32·单片机·嵌入式硬件·嵌入式软件
小李独爱秋13 小时前
“bootmgr is compressed”错误:根源、笔记本与台式机差异化解决方案深度指南
运维·stm32·单片机·嵌入式硬件·文件系统·电脑故障
宵时待雨19 小时前
STM32笔记归纳8:时钟
笔记·stm32·单片机·嵌入式硬件
JJRainbow20 小时前
SN75176 芯片设计RS-232 转 RS-485 通信模块设计原理图
stm32·单片机·嵌入式硬件·fpga开发·硬件工程
不做无法实现的梦~20 小时前
PX4编译环境配置和qgc配置安装教程(2)
linux·stm32
宁静致远202120 小时前
STM32模拟IIC读取PCF8563
stm32·单片机·嵌入式硬件
听风吹雨yu21 小时前
STM32F407-MD5码计算/Digest认证计算
stm32·单片机·嵌入式硬件
youcans_1 天前
【STM32-MBD】(15)Simulink 模型开发之三相互补 PWM
stm32·单片机·嵌入式硬件·matlab·foc
hrw_embedded1 天前
基于CH395Q网卡移植ftplib的FTP客户端
网络·stm32·ftp·linux库
逐步前行1 天前
STM32_内部结构
网络·stm32·嵌入式硬件