acpi 自动注册platform_device

来源:互联网 发布:mac版adobe flash cs6 编辑:程序博客网 时间:2024/06/09 18:14
在使用ACPI传递参数给kernel的时候,针对buildin的driver现在只要在调用
module_platform_driver(v2_driver);
其实现如下:
#define module_platform_driver(__platform_driver) \
    module_driver(__platform_driver, platform_driver_register, \
            platform_driver_unregister)
继续看
#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中已经帮忙调用了platform_driver_register,多好啊,
那问题来了,到底是在哪里调用platform_device_register呢?
答案就是在acpi_create_platform_device
acpi_create_platform_device 一开始会调用(!acpi_match_device_ids(adev, forbidden_id_list)) 屏蔽某些driver,即不会
为这些driver 创建device.这些driver如下:
static const struct acpi_device_id forbidden_id_list[] = {
    {"PNP0000", 0},    /* PIC */
    {"PNP0100", 0},    /* Timer */
    {"PNP0200", 0},    /* AT DMA Controller */
    {"", 0},
};
其次会调用count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
来得到resource
int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
               int (*preproc)(struct acpi_resource *, void *),
               void *preproc_data)
{
    struct res_proc_context c;
    acpi_status status;

    if (!adev || !adev->handle || !list_empty(list))
        return -EINVAL;

    if (!acpi_has_method(adev->handle, METHOD_NAME__CRS))
        return 0;

    c.list = list;
    c.preproc = preproc;
    c.preproc_data = preproc_data;
    c.count = 0;
    c.error = 0;
    c.adev = adev;
    status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
                     acpi_dev_process_resource, &c);
    if (ACPI_FAILURE(status)) {
        acpi_dev_free_resource_list(list);
        return c.error ? c.error : -EIO;
    }

    return c.count;
}
可见也是通过acpi_walk_resources 来找_CRS,找到后调用acpi_dev_process_resource
static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
                         void *context)
{
    struct res_proc_context *c = context;
    struct resource_win win;
    struct resource *res = &win.res;
    int i;

    if (c->preproc) {
        int ret;

        ret = c->preproc(ares, c->preproc_data);
        if (ret < 0) {
            c->error = ret;
            return AE_CTRL_TERMINATE;
        } else if (ret > 0) {
            return AE_OK;
        }
    }

    memset(&win, 0, sizeof(win));

    if (acpi_dev_resource_memory(ares, res)
        || acpi_dev_resource_io(ares, res)
        || acpi_dev_resource_address_space(ares, &win)
        || acpi_dev_resource_ext_address_space(ares, &win))
        return acpi_dev_new_resource_entry(&win, c);

    for (i = 0; __acpi_dev_resource_interrupt(c->adev, ares, i, res); i++) {
        acpi_status status;

        status = acpi_dev_new_resource_entry(&win, c);
        if (ACPI_FAILURE(status))
            return status;
    }

    return AE_OK;
}
从acpi_dev_process_resource 中可以看出resource 基本分为两类
第一类是memory/io/address_space/ext_address_space 这类resource 会调用acpi_dev_new_resource_entry 来parse
第二类就是interrupt,调用acpi_dev_new_resource_entry 来parse
acpi_create_platform_device 中资源parse完成后填充platform_device_info
最后调用platform_device_register_full 来注册platform_device.这个返回返回的结果就是platform_device
0 0
原创粉丝点击