diff --git a/lib/devres.c b/lib/devres.c index 5f2aedd58bc5..5bec1120b392 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -5,6 +5,12 @@ #include #include +enum devm_ioremap_type { + DEVM_IOREMAP = 0, + DEVM_IOREMAP_NC, + DEVM_IOREMAP_WC, +}; + void devm_ioremap_release(struct device *dev, void *res) { iounmap(*(void __iomem **)res); @@ -15,6 +21,37 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data) return *(void **)res == match_data; } +static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset, + resource_size_t size, + enum devm_ioremap_type type) +{ + void __iomem **ptr, *addr = NULL; + + ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return NULL; + + switch (type) { + case DEVM_IOREMAP: + addr = ioremap(offset, size); + break; + case DEVM_IOREMAP_NC: + addr = ioremap_nocache(offset, size); + break; + case DEVM_IOREMAP_WC: + addr = ioremap_wc(offset, size); + break; + } + + if (addr) { + *ptr = addr; + devres_add(dev, ptr); + } else + devres_free(ptr); + + return addr; +} + /** * devm_ioremap - Managed ioremap() * @dev: Generic device to remap IO address for @@ -26,20 +63,7 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data) void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, resource_size_t size) { - void __iomem **ptr, *addr; - - ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - addr = ioremap(offset, size); - if (addr) { - *ptr = addr; - devres_add(dev, ptr); - } else - devres_free(ptr); - - return addr; + return __devm_ioremap(dev, offset, size, DEVM_IOREMAP); } EXPORT_SYMBOL(devm_ioremap); @@ -55,20 +79,7 @@ EXPORT_SYMBOL(devm_ioremap); void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, resource_size_t size) { - void __iomem **ptr, *addr; - - ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - addr = ioremap_nocache(offset, size); - if (addr) { - *ptr = addr; - devres_add(dev, ptr); - } else - devres_free(ptr); - - return addr; + return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NC); } EXPORT_SYMBOL(devm_ioremap_nocache); @@ -83,20 +94,7 @@ EXPORT_SYMBOL(devm_ioremap_nocache); void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset, resource_size_t size) { - void __iomem **ptr, *addr; - - ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return NULL; - - addr = ioremap_wc(offset, size); - if (addr) { - *ptr = addr; - devres_add(dev, ptr); - } else - devres_free(ptr); - - return addr; + return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_WC); } EXPORT_SYMBOL(devm_ioremap_wc);