diff options
-rw-r--r-- | drivers/of/address.c | 36 | ||||
-rw-r--r-- | include/linux/io.h | 2 | ||||
-rw-r--r-- | include/linux/of_address.h | 11 | ||||
-rw-r--r-- | lib/devres.c | 2 |
4 files changed, 49 insertions, 2 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) | |||
702 | } | 702 | } |
703 | EXPORT_SYMBOL(of_iomap); | 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 | * of_dma_get_range - Get DMA range info | 742 | * of_dma_get_range - Get DMA range info |
707 | * @np: device node to get DMA range info | 743 | * @np: device node to get DMA range info |
diff --git a/include/linux/io.h b/include/linux/io.h index b76e6e545806..d5fc9b8d8b03 100644 --- a/include/linux/io.h +++ b/include/linux/io.h | |||
@@ -58,6 +58,8 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr) | |||
58 | } | 58 | } |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #define IOMEM_ERR_PTR(err) (__force void __iomem *)ERR_PTR(err) | ||
62 | |||
61 | void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, | 63 | void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, |
62 | unsigned long size); | 64 | unsigned long size); |
63 | void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, | 65 | void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, |
diff --git a/include/linux/of_address.h b/include/linux/of_address.h index c13b8782a4eb..fb7b7221e063 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h | |||
@@ -109,7 +109,12 @@ static inline bool of_dma_is_coherent(struct device_node *np) | |||
109 | extern int of_address_to_resource(struct device_node *dev, int index, | 109 | extern int of_address_to_resource(struct device_node *dev, int index, |
110 | struct resource *r); | 110 | struct resource *r); |
111 | void __iomem *of_iomap(struct device_node *node, int index); | 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 | #else | 114 | #else |
115 | |||
116 | #include <linux/io.h> | ||
117 | |||
113 | static inline int of_address_to_resource(struct device_node *dev, int index, | 118 | static inline int of_address_to_resource(struct device_node *dev, int index, |
114 | struct resource *r) | 119 | struct resource *r) |
115 | { | 120 | { |
@@ -120,6 +125,12 @@ static inline void __iomem *of_iomap(struct device_node *device, int index) | |||
120 | { | 125 | { |
121 | return NULL; | 126 | return NULL; |
122 | } | 127 | } |
128 | |||
129 | static inline void __iomem *of_io_request_and_map(struct device_node *device, | ||
130 | int index, char *name) | ||
131 | { | ||
132 | return IOMEM_ERR_PTR(-EINVAL); | ||
133 | } | ||
123 | #endif | 134 | #endif |
124 | 135 | ||
125 | #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI) | 136 | #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI) |
diff --git a/lib/devres.c b/lib/devres.c index f562bf6ff71d..bb632484a860 100644 --- a/lib/devres.c +++ b/lib/devres.c | |||
@@ -86,8 +86,6 @@ void devm_iounmap(struct device *dev, void __iomem *addr) | |||
86 | } | 86 | } |
87 | EXPORT_SYMBOL(devm_iounmap); | 87 | EXPORT_SYMBOL(devm_iounmap); |
88 | 88 | ||
89 | #define IOMEM_ERR_PTR(err) (__force void __iomem *)ERR_PTR(err) | ||
90 | |||
91 | /** | 89 | /** |
92 | * devm_ioremap_resource() - check, request region, and ioremap resource | 90 | * devm_ioremap_resource() - check, request region, and ioremap resource |
93 | * @dev: generic device to handle the resource for | 91 | * @dev: generic device to handle the resource for |