本文共 2479 字,大约阅读时间需要 8 分钟。
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;}
转载地址:http://idnmi.baihongyu.com/