You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ACPI环境下SPI客户端驱动内核模块自动加载故障求助

问题

在Linux内核中,通过ACPI SSDT获取设备配置数据的SPI客户端驱动无法自动加载(probe函数未执行),但platform_driver的内核模块自动加载功能正常(可成功从_DSD获取属性)。已知需要定义spi_device_id,且驱动仅能通过spi_device_id实现自动加载,现咨询:

  1. 是否有已知的解决方法?
  2. spi_device_id结构体是否关联有ACPI命名对象?
相关代码与操作

ACPI SSDT表

DefinitionBlock ("ili9488.aml", "SSDT", 5, "", "ILI9488", 0x1)
{
    Device (TFTD)
    {
        Name (_HID, "ILI9488")  // _HID: 硬件ID
        Name (_CID, "ILI9488")  // _CID: 兼容ID
        Name (_UID, One)        // _UID: 唯一ID

        Name (_DSD, Package() { // 设备特定数据 - 用于向驱动返回EC静态资源(定义于_CRS)
            /*
             * 设备属性UUID
             * Linux内核ACPI子系统可识别的通用UUID,会自动处理关联的数据包,并将数据作为"设备属性"提供给驱动
             */
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package()
            {
                // 定义compatible属性(实际未启用CONFIG_OF,所以没用)
                Package () { "compatible", Package () { "garosa,garosanvkr25fawd" } },
            }
        })

        Method (_CRS, 0, Serialized) {
            local0 = ResourceTemplate() { // 当前资源设置(ACPI资源转Buffer函数)
                SpiSerialBus(
                    0,                    // 片选
                    PolarityLow,          // 片选低电平有效
                    FourWireMode,         // 全双工模式(MISO未使用)
                    8,                    // 每字8位(1字节)
                    ControllerInitiated,  // 从模式
                    32000000,             // 32 MHz
                    ClockPolarityLow,     // SPI模式0
                    ClockPhaseFirst,      // SPI模式0
                    "\\EC17.SPI0",        // SPI总线主机控制器名称(未确认)
                    0                     // 资源索引,应为0
                )
                // _SB.GPIO: GPIO总线主机控制器(未确认)
                GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionOutputOnly, "\\_SB.GPI0", 0, ResourceConsumer, , ) { 40 } // 引脚13
                GpioIo (Exclusive, PullUp,   0, 0, IoRestrictionOutputOnly, "\\_SB.GPI0", 0, ResourceConsumer, , ) { 45 } // 引脚15
            }
            Return(local0)
        }
    }
}

驱动代码片段

static int ili9488_probe(struct spi_device *spidev)
{
    struct device *device;
    const char *compatible_propery;

    device = &spidev->dev;
    device_property_read_string(device, "compatible", &compatible_propery);
    dev_warn(device, "compatible: %s", compatible_propery);

    return 0;
}

static void ili9488_remove(struct spi_device *spidev)
{
    dev_warn(&spidev->dev, "ENTER ili9488_remove function driver bound to ACPI table");
    return;
}

/* 兼容的设备树节点 */
static const struct of_device_id ili9488_of_match[] = {
    { .compatible = "garosa,garosanvkr25fawd" },
    {},
};

MODULE_DEVICE_TABLE(of, ili9488_of_match);

/*
 * 通过兼容ID(_CID)命名对象适配ACPI SSDT
 */
static const struct acpi_device_id ili9488_acpi_match[] = {
    { "ILI9488", 0 },
    { }
};

MODULE_DEVICE_TABLE(acpi, ili9488_acpi_match);

static const struct spi_device_id ili9488_spi_devid[] = {
    { "ILI9488", 0 },
    { }
};

MODULE_DEVICE_TABLE(spi, ili9488_spi_devid);

/* 驱动声明 */
static struct spi_driver ili9488_spi_driver = {
    .driver = {
        .name = "ili9488",
        .acpi_match_table = ili9488_acpi_match,
        .of_match_table = ili9488_of_match, // 没必要,CONFIG_OF甚至没开启
    },
    .id_table = ili9488_spi_devid,
    .probe    = ili9488_probe,
    .remove   = ili9488_remove,
};

module_spi_driver(ili9488_spi_driver);

操作步骤与报错

编译ACPI表和内核模块后执行以下操作:

$ mount -t configfs none /sys/kernel/config
$ modprobe acpi-configfs
$ mkdir -p /sys/kernel/config/acpi/table/ili9488
$ cat "ili9488.aml" > "/sys/kernel/config/acpi/table/ili9488/aml"

加载模块时出现报错:

$ insmod ili9488.ko ; rmmod ili9488.ko 
SPI driver ili9488 has no spi_device_id for garosa,garosanvkr25fawd

注:添加ACPI_PTR或移除of_match_table后不会出现该警告。

解决方法与解答

1. 解决方法

针对当前问题,有几个可行的处理方式:

  • 移除无用的of_match_table:既然内核未开启CONFIG_OF,设备树匹配表完全没必要存在。移除后内核不会尝试从ACPI的_DSD中读取compatible属性去匹配设备树ID,也就不会触发警告,同时ACPI匹配可以正常工作。
  • 添加ACPI_PTR标记:给acpi_match_table添加ACPI_PTR宏(即.acpi_match_table = ACPI_PTR(ili9488_acpi_match)),告知内核该匹配表是针对ACPI的,避免和设备树匹配逻辑混淆,解决警告问题并触发ACPI匹配流程。
  • 检查SPI控制器路径:确认ACPI表中\\EC17.SPI0的路径是否正确,只有SPI主机控制器被内核正确识别,挂载在该总线上的设备才能被枚举并匹配驱动。

2. spi_device_id与ACPI命名对象的关联

spi_device_id本身不直接关联ACPI命名对象,它是用于传统SPI设备的匹配逻辑(如基于平台数据的旧版匹配方式)。但在ACPI场景下,内核会通过以下逻辑建立间接关联:

  • ACPI设备枚举时,优先通过acpi_match_table匹配设备的_HID/_CID。
  • 如果驱动同时提供了spi_device_id表,内核会尝试将ACPI设备的_HID/_CID与spi_device_id中的name字段做匹配,作为 fallback 机制。
  • 当前报错的本质是设备树匹配逻辑与ACPI匹配逻辑的冲突:内核读取了_DSD中的compatible属性,尝试匹配of_match_table,但该值没有对应的spi_device_id,因此触发警告,并非spi_device_id与ACPI命名对象直接关联的问题。

内容的提问来源于stack exchange,提问作者EasyIP2023

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:45:00