从源代码看devm_ioremap_resource多了
if (!devm_request_mem_region(dev, res->start, size, name)) {
dev_err(dev, "can't request region for resource %pR\n", res);
return IOMEM_ERR_PTR(-EBUSY);
}
从driver 代码中可以看到有时间用devm_ioremap_resource, 而有时直接用devm_ioremap
#define devm_request_mem_region(dev,start,n,name) \
__devm_request_region(dev, &iomem_resource, (start), (n), (name))
struct resource * __devm_request_region(struct device *dev,
struct resource *parent, resource_size_t start,
resource_size_t n, const char *name)
{
struct region_devres *dr = NULL;
struct resource *res;
dr = devres_alloc(devm_region_release, sizeof(struct region_devres),
GFP_KERNEL);
if (!dr)
return NULL;
dr->parent = parent;
dr->start = start;
dr->n = n;
res = __request_region(parent, start, n, name, 0);
if (res)
devres_add(dev, dr);
else
devres_free(dr);
return res;
}
EXPORT_SYMBOL(__devm_request_region);
总结来说,devm_ioremap 就是直接映射, devm_ioremap_resource 是先申请,后映射。
比如
cat /proc/iomem
40300000-5fffffff : /soc/qcom,pcie@1c08000
40300000-405fffff : PCI Bus 0001:01
40300000-40301fff : 0001:01:00.0
40302000-403020ff : 0001:01:00.0
40302100-403021ff : 0001:01:00.0
40600000-407fffff : PCI Bus 0001:01
40800000-40800fff : 0001:00:00.0
这些就是已经申请并映射的device resource. 在使用时直接devm_ioremap 就可以。
但要是直接devm_ioremap,应该也可以,但没有 devm_request_mem_region, 应该在/proc/iomem 查不到。这个我没做实验。
但如果一个device resource 已经申请过了,在调用devm_request_mem_region就会出现下面错误
can't request region for resource ...
因为这个device resource 已经申请过了。