acpi_create_platform_device 这个函数会为没有platform_driver 自动创建platform_device设备。只有当用户只调用register_platform_driver就可以匹配device和driver
其源码分析如下:
struct platform_device *acpi_create_platform_device(struct acpi_device *adev,
                    struct property_entry *properties)
{
    struct platform_device *pdev = NULL;
    struct platform_device_info pdevinfo;
    struct resource_entry *rentry;
    struct list_head resource_list;
    struct resource *resources = NULL;
    int count;
    /* If the ACPI node already has a physical device attached, skip it. */
    #如果这个设备已经有一个物理节点attach了,则退出。简单说一个设备只能调用一次这个函数
    if (adev->physical_node_count)
        return NULL;
    #保存在forbidden_id_list 中的设备是禁止加载的。如果遇到这种设备则退出
    if (!acpi_match_device_ids(adev, forbidden_id_list))
        return ERR_PTR(-EINVAL);
    #初始化保存设备资源的链表
    INIT_LIST_HEAD(&resource_list);
    #获取这个device的资源,如果count小于零说明获取资源失败,则退出
    count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
    if (count < 0) {
        return NULL;
    } else if (count > 0) {
        #根据count数来申请内存老保存资源
        resources = kzalloc(count * sizeof(struct resource),
                    GFP_KERNEL);
        if (!resources) {
            dev_err(&adev->dev, "No memory for resources\n");
            acpi_dev_free_resource_list(&resource_list);
            return ERR_PTR(-ENOMEM);
        }
        count = 0;
        #将所有的资源保存在resource中
        list_for_each_entry(rentry, &resource_list, node)
            acpi_platform_fill_resource(adev, rentry->res,
                            &resources[count++]);
        acpi_dev_free_resource_list(&resource_list);
    }
    #清空pdevinfo 结构体
    memset(&pdevinfo, 0, sizeof(pdevinfo));
    /*
     * If the ACPI node has a parent and that parent has a physical device
     * attached to it, that physical device should be the parent of the
     * platform device we are about to create.
     */
     #给pdeinfo 赋值
    pdevinfo.parent = adev->parent ?
        acpi_get_first_physical_node(adev->parent) : NULL;
    pdevinfo.name = dev_name(&adev->dev);
    pdevinfo.id = -1;
    pdevinfo.res = resources;
    pdevinfo.num_res = count;
    pdevinfo.fwnode = acpi_fwnode_handle(adev);
    pdevinfo.properties = properties;
    #检车这个device是否支持dma,如果支持的话,把dma mask设置为32bit
    if (acpi_dma_supported(adev))
        pdevinfo.dma_mask = DMA_BIT_MASK(32);
    else
        pdevinfo.dma_mask = 0;
    #前面的准备工作结束后,调用下面这个函数把pdevinfo注册给kernel
    #platform_device_register_full->platform_device_add->device_add 
    pdev = platform_device_register_full(&pdevinfo);
    if (IS_ERR(pdev))
        dev_err(&adev->dev, "platform device creation failed: %ld\n",
            PTR_ERR(pdev));
    else {
        set_dev_node(&pdev->dev, acpi_get_node(adev->handle));
        dev_dbg(&adev->dev, "created platform device %s\n",
            dev_name(&pdev->dev));
    }
    kfree(resources);
    return pdev;
}
acpi_create_platform_device
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
 平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 代码啥也没改,就报了这个错。 Appnium报错: Error getting device API level....
 - 在Linux内核启动时,内核通过of_platform_populate()函数,将dts中的device nod...
 - 参考:https://my.oschina.net/felixliang/blog/80960[https://m...
 - PaddlePaddle 飞桨 FAQ合集 - 安装配置19 Question: 训练遇到报错CUDNN_STAT...