devres: combine function devm_ioremap*

When I tried to use devm_ioremap function and review related
code, I found devm_ioremap_* almost have the similar realize
with each other, which can be combined.

In the former version, I have tried to kill ioremap_cache to
reduce the size of devres, which can not work for ioremap is
not the same as ioremap_nocache in some ARCHs likes ia64.
Therefore, as the suggestion of Christophe, I introduce a help
function __devm_ioremap, let devm_ioremap* inline and call
__devm_ioremap with different devm_ioremap_type.

After apply the patch, the size of devres.o can be reduce from
8216 Bytes to 8052 Bytes in my compile environment.

Suggested-by: Greg KH <gregkh@linuxfoundation.org>
Suggested-by: Christophe LEROY <christophe.leroy@c-s.fr>
Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com>
Reviewed-by: Christophe LEROY <christophe.leroy@c-s.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Yisheng Xie 2018-01-29 19:48:16 +08:00 committed by Greg Kroah-Hartman
parent f87deada80
commit 1b723413aa
1 changed files with 40 additions and 42 deletions

View File

@ -5,6 +5,12 @@
#include <linux/gfp.h>
#include <linux/export.h>
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);