diff options
author | Matthias Brugger <matthias.bgg@gmail.com> | 2014-07-18 11:36:39 +0200 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2014-07-23 12:02:30 +0200 |
commit | efd342fb0031a17758571dce42e3f373d94e2fec (patch) | |
tree | 914578b4b0944ae5ca884e18ffe13cd223dccb14 /drivers/of/address.c | |
parent | 7e1391876c8f95df9241deb78fa98e799e7bb05e (diff) | |
download | lwn-efd342fb0031a17758571dce42e3f373d94e2fec.tar.gz lwn-efd342fb0031a17758571dce42e3f373d94e2fec.zip |
of: Provide a function to request and map memory
A call to of_iomap does not request the memory region. This patch adds the
function of_io_request_and_map which requests the memory region before
mapping it.
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Suggested-by: Rob Herring <robh@kernel.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Diffstat (limited to 'drivers/of/address.c')
-rw-r--r-- | drivers/of/address.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c index 5edfcb0da37d..e3718250d66e 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -702,6 +702,42 @@ void __iomem *of_iomap(struct device_node *np, int index) } EXPORT_SYMBOL(of_iomap); +/* + * of_io_request_and_map - Requests a resource and maps the memory mapped IO + * for a given device_node + * @device: the device whose io range will be mapped + * @index: index of the io range + * @name: name of the resource + * + * Returns a pointer to the requested and mapped memory or an ERR_PTR() encoded + * error code on failure. Usage example: + * + * base = of_io_request_and_map(node, 0, "foo"); + * if (IS_ERR(base)) + * return PTR_ERR(base); + */ +void __iomem *of_io_request_and_map(struct device_node *np, int index, + char *name) +{ + struct resource res; + void __iomem *mem; + + if (of_address_to_resource(np, index, &res)) + return IOMEM_ERR_PTR(-EINVAL); + + if (!request_mem_region(res.start, resource_size(&res), name)) + return IOMEM_ERR_PTR(-EBUSY); + + mem = ioremap(res.start, resource_size(&res)); + if (!mem) { + release_mem_region(res.start, resource_size(&res)); + return IOMEM_ERR_PTR(-ENOMEM); + } + + return mem; +} +EXPORT_SYMBOL(of_io_request_and_map); + /** * of_dma_get_range - Get DMA range info * @np: device node to get DMA range info |