Skip to content

Commit

Permalink
devres: add devm_memremap
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Hellwig <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
  • Loading branch information
Christoph Hellwig authored and djbw committed Aug 14, 2015
1 parent e836a25 commit 7d3dcf2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/linux/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ int check_signature(const volatile void __iomem *io_addr,
const unsigned char *signature, int length);
void devm_ioremap_release(struct device *dev, void *res);

void *devm_memremap(struct device *dev, resource_size_t offset,
size_t size, unsigned long flags);
void devm_memunmap(struct device *dev, void *addr);

/*
* Some systems do not have legacy ISA devices.
* /dev/port is not a valid interface on these systems.
Expand Down
39 changes: 39 additions & 0 deletions kernel/memremap.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/device.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/mm.h>
Expand Down Expand Up @@ -96,3 +97,41 @@ void memunmap(void *addr)
iounmap((void __iomem *) addr);
}
EXPORT_SYMBOL(memunmap);

static void devm_memremap_release(struct device *dev, void *res)
{
memunmap(res);
}

static int devm_memremap_match(struct device *dev, void *res, void *match_data)
{
return *(void **)res == match_data;
}

void *devm_memremap(struct device *dev, resource_size_t offset,
size_t size, unsigned long flags)
{
void **ptr, *addr;

ptr = devres_alloc(devm_memremap_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return NULL;

addr = memremap(offset, size, flags);
if (addr) {
*ptr = addr;
devres_add(dev, ptr);
} else
devres_free(ptr);

return addr;
}
EXPORT_SYMBOL(devm_memremap);

void devm_memunmap(struct device *dev, void *addr)
{
WARN_ON(devres_destroy(dev, devm_memremap_release, devm_memremap_match,
addr));
memunmap(addr);
}
EXPORT_SYMBOL(devm_memunmap);

0 comments on commit 7d3dcf2

Please sign in to comment.