acpi power button

在drivers/acpi/button.c中会通过
module_acpi_driver(acpi_button_driver);来注册device
module_acpi_driver 定义如下:
#define module_acpi_driver(__acpi_driver) \
    module_driver(__acpi_driver, acpi_bus_register_driver, \
              acpi_bus_unregister_driver)

#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
    return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
    __unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);

可以最终还是调用module_init 来初始化话,在module_init 中会调用acpi_bus_register_driver 住注册device。
int acpi_bus_register_driver(struct acpi_driver *driver)
{
    int ret;

    if (acpi_disabled)
        return -ENODEV;
    driver->drv.name = driver->name;
    driver->drv.bus = &acpi_bus_type;
    driver->drv.owner = driver->owner;

    ret = driver_register(&driver->drv);
    return ret;
}

acpi_bus_register_driver 中最重要的是driver->drv.bus = &acpi_bus_type;
struct bus_type acpi_bus_type = {
    .name        = "acpi",
    .match        = acpi_bus_match,
    .probe        = acpi_device_probe,
    .remove        = acpi_device_remove,
    .uevent        = acpi_device_uevent,
};
我们看看最重要的match函数
static int acpi_bus_match(struct device *dev, struct device_driver *drv)
{
    struct acpi_device *acpi_dev = to_acpi_device(dev);
    struct acpi_driver *acpi_drv = to_acpi_driver(drv);

    return acpi_dev->flags.match_driver
        && !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
}

原来是通过是通过acpi_dev->flags.match_driver 和 acpi_match_device_ids(acpi_dev, acpi_drv->ids); 来让device和driver匹配
其中acpi_match_device_ids->__acpi_match_device
static const struct acpi_device_id *__acpi_match_device(
    struct acpi_device *device,
    const struct acpi_device_id *ids,
    const struct of_device_id *of_ids)
{
    const struct acpi_device_id *id;
    struct acpi_hardware_id *hwid;

    /*
     * If the device is not present, it is unnecessary to load device
     * driver for it.
     */
    if (!device || !device->status.present)
        return NULL;

    list_for_each_entry(hwid, &device->pnp.ids, list) {
        /* First, check the ACPI/PNP IDs provided by the caller. */
        for (id = ids; id->id[0] || id->cls; id++) {
            if (id->id[0] && !strcmp((char *) id->id, hwid->id))
                return id;
            else if (id->cls && __acpi_match_device_cls(id, hwid))
                return id;
        }

        /*
         * Next, check ACPI_DT_NAMESPACE_HID and try to match the
         * "compatible" property if found.
         *
         * The id returned by the below is not valid, but the only
         * caller passing non-NULL of_ids here is only interested in
         * whether or not the return value is NULL.
         */
        if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)
            && acpi_of_match_device(device, of_ids))
            return id;
    }
    return NULL;
}
从__acpi_match_device 中可知原来是通过下面三种方法判断的

第一:id->id == hwid->id
if (id->id[0] && !strcmp((char *) id->id, hwid->id))
    return id;
第二:cls相等
(id->cls && __acpi_match_device_cls(id, hwid))
第三:"compatible" property.相等
if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id)&& acpi_of_match_device(device, of_ids))
我们回到button.c中
static struct acpi_driver acpi_button_driver = {
    .name = "button",
    .class = ACPI_BUTTON_CLASS,
    .ids = button_device_ids,
    .ops = {
        .add = acpi_button_add,
        .remove = acpi_button_remove,
        .notify = acpi_button_notify,
    },
    .drv.pm = &acpi_button_pm,
};
可见button_device_ids 中的cls没有赋值,因此button 的device 和 driver的配对主要是通过id->id == hwid->id 来判断的.
static const struct acpi_device_id button_device_ids[] = {
    {ACPI_BUTTON_HID_LID,    0},
    {ACPI_BUTTON_HID_SLEEP,  0},
    {ACPI_BUTTON_HID_SLEEPF, 0},
    {ACPI_BUTTON_HID_POWER,  0},
    {ACPI_BUTTON_HID_POWERF, 0},
    {"", 0},
};
那具体是哪个device 和power button的driver配对呢?也就是power button的device是什么时候注册的呢?
acpi_bus_scan->acpi_bus_check_add->acpi_add_single_object->acpi_bus_get_power_flags->acpi_bus_init_power_state
->acpi_extract_power_resources->acpi_add_power_resource->acpi_device_add->acpi_device_add
int acpi_device_add(struct acpi_device *device,
            void (*release)(struct device *))
{
    if (device->parent)
        device->dev.parent = &device->parent->dev;
    device->dev.bus = &acpi_bus_type;
    device->dev.release = release;
    result = device_add(&device->dev);
    if (result) {
        dev_err(&device->dev, "Error registering device\n");
        goto err;
    }

    result = acpi_device_setup_files(device);
    if (result)
        printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
               dev_name(&device->dev));

    return 0;

}
acpi_device_add 这个函数会调用device_add 来注册device,注意这个device->dev.bus = &acpi_bus_type 和power button 是同一个bus type
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值