用户通用驱动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));
    	}
相关推荐
LaoZhangGong1232 小时前
学习TCP/IP的第8步:紧急数据
网络·stm32·单片机·学习·tcp/ip·以太网
youcans_2 小时前
【动手学STM32G4】(16)PWM 触发 ADC 精确同步采样
stm32·单片机·嵌入式硬件·pwm·adc
嗯嗯=12 小时前
STM32单片机学习篇9
stm32·单片机·学习
小范馆16 小时前
ESP各模组的引脚图-小智接线图
stm32
摆摊的豆丁17 小时前
FreeRTOS Kernel 配置详解
freertos
想放学的刺客20 小时前
单片机嵌入式试题(第23期)嵌入式系统电源管理策略设计、嵌入式系统通信协议栈实现要点两个全新主题。
c语言·stm32·单片机·嵌入式硬件·物联网
猫猫的小茶馆20 小时前
【Linux 驱动开发】五. 设备树
linux·arm开发·驱动开发·stm32·嵌入式硬件·mcu·硬件工程
YouEmbedded21 小时前
解码内部集成电路(IIC)与OLED屏
stm32·0.96寸oled·硬件iic·软件模拟iic·图片取模·汉字取模
意法半导体STM321 天前
【官方原创】如何基于DevelopPackage开启安全启动(MP15x) LAT6036
javascript·stm32·单片机·嵌入式硬件·mcu·安全·stm32开发