acpi bus 的scan

在acpi子系统中一般我们首先通过下面的方式来注册handler
static struct acpi_scan_handler amba_handler = {
    .ids = amba_id_list,
    .attach = amba_handler_attach,
};

void __init acpi_amba_init(void)
{
    amba_register_dummy_clk();
    acpi_scan_add_handler(&amba_handler);
}
而acpi_scan_add_handler 只是将当前的amba_handler 加入到acpi_scan_handlers_list 这个列表中。
int acpi_scan_add_handler(struct acpi_scan_handler *handler)
{
    if (!handler)
        return -EINVAL;

    list_add_tail(&handler->list_node, &acpi_scan_handlers_list);
    return 0;
}
当kernel 开始parse uefi传递的acpi表是会调用
acpi_bus_scan->acpi_bus_attach->acpi_scan_attach_handler 来和acpi_scan_handlers_list 表中的driver配对,所以这里也可以看出
acpi_amba_init的执行是在kernel parse acpi之前的
static int acpi_scan_attach_handler(struct acpi_device *device)
{
    struct acpi_hardware_id *hwid;
    int ret = 0;

    list_for_each_entry(hwid, &device->pnp.ids, list) {
        const struct acpi_device_id *devid;
        struct acpi_scan_handler *handler;

        handler = acpi_scan_match_handler(hwid->id, &devid);
        if (handler) {
            if (!handler->attach) {
                device->pnp.type.platform_id = 0;
                continue;
            }
            device->handler = handler;
            ret = handler->attach(device, devid);
            if (ret > 0)
                break;

            device->handler = NULL;
            if (ret < 0)
                break;
        }
    }

    return ret;
}
acpi_scan_attach_handler 首先会调用acpi_scan_match_handler 匹配并拿到handler,如果handler不是空的话就执行attach函数,例如本来中juice会执行amba_handler_attach
static struct acpi_scan_handler *acpi_scan_match_handler(const char *idstr,
                    const struct acpi_device_id **matchid)
{
    struct acpi_scan_handler *handler;

    list_for_each_entry(handler, &acpi_scan_handlers_list, list_node)
        if (acpi_scan_handler_matching(handler, idstr, matchid))
            return handler;

    return NULL;
}
acpi_scan_handler 中就可以看到是遍历acpi_scan_handlers_list ,然后通过acpi_scan_handler_matching来判断是否匹配
static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
                       const char *idstr,
                       const struct acpi_device_id **matchid)
{
    const struct acpi_device_id *devid;

    if (handler->match)
        return handler->match(idstr, matchid);

    for (devid = handler->ids; devid->id[0]; devid++)
        if (!strcmp((char *)devid->id, idstr)) {
            if (matchid)
                *matchid = devid;

            return true;
        }

    return false;
}
在acpi_scan_handler_matching 中如果handler->match 不会空的话,会先执行,也就是对handler而言match会比attach优先执行,即使id不匹配也会执行,后面的for循环就是通过strcmp来比较id这个字符串是否相等.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值