Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Matthias Brugger and committed by
Daniel Lezcano
efd342fb 7e139187

+49 -2
+36
drivers/of/address.c
··· 702 702 } 703 703 EXPORT_SYMBOL(of_iomap); 704 704 705 + /* 706 + * of_io_request_and_map - Requests a resource and maps the memory mapped IO 707 + * for a given device_node 708 + * @device: the device whose io range will be mapped 709 + * @index: index of the io range 710 + * @name: name of the resource 711 + * 712 + * Returns a pointer to the requested and mapped memory or an ERR_PTR() encoded 713 + * error code on failure. Usage example: 714 + * 715 + * base = of_io_request_and_map(node, 0, "foo"); 716 + * if (IS_ERR(base)) 717 + * return PTR_ERR(base); 718 + */ 719 + void __iomem *of_io_request_and_map(struct device_node *np, int index, 720 + char *name) 721 + { 722 + struct resource res; 723 + void __iomem *mem; 724 + 725 + if (of_address_to_resource(np, index, &res)) 726 + return IOMEM_ERR_PTR(-EINVAL); 727 + 728 + if (!request_mem_region(res.start, resource_size(&res), name)) 729 + return IOMEM_ERR_PTR(-EBUSY); 730 + 731 + mem = ioremap(res.start, resource_size(&res)); 732 + if (!mem) { 733 + release_mem_region(res.start, resource_size(&res)); 734 + return IOMEM_ERR_PTR(-ENOMEM); 735 + } 736 + 737 + return mem; 738 + } 739 + EXPORT_SYMBOL(of_io_request_and_map); 740 + 705 741 /** 706 742 * of_dma_get_range - Get DMA range info 707 743 * @np: device node to get DMA range info
+2
include/linux/io.h
··· 58 58 } 59 59 #endif 60 60 61 + #define IOMEM_ERR_PTR(err) (__force void __iomem *)ERR_PTR(err) 62 + 61 63 void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, 62 64 unsigned long size); 63 65 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
+11
include/linux/of_address.h
··· 109 109 extern int of_address_to_resource(struct device_node *dev, int index, 110 110 struct resource *r); 111 111 void __iomem *of_iomap(struct device_node *node, int index); 112 + void __iomem *of_io_request_and_map(struct device_node *device, 113 + int index, char *name); 112 114 #else 115 + 116 + #include <linux/io.h> 117 + 113 118 static inline int of_address_to_resource(struct device_node *dev, int index, 114 119 struct resource *r) 115 120 { ··· 124 119 static inline void __iomem *of_iomap(struct device_node *device, int index) 125 120 { 126 121 return NULL; 122 + } 123 + 124 + static inline void __iomem *of_io_request_and_map(struct device_node *device, 125 + int index, char *name) 126 + { 127 + return IOMEM_ERR_PTR(-EINVAL); 127 128 } 128 129 #endif 129 130
-2
lib/devres.c
··· 86 86 } 87 87 EXPORT_SYMBOL(devm_iounmap); 88 88 89 - #define IOMEM_ERR_PTR(err) (__force void __iomem *)ERR_PTR(err) 90 - 91 89 /** 92 90 * devm_ioremap_resource() - check, request region, and ioremap resource 93 91 * @dev: generic device to handle the resource for