aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2013-01-21 05:08:54 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-22 12:41:43 -0500
commit75096579c3ac39ddc2f8b0d9a8924eba31f4d920 (patch)
tree15d50607ffc22358fdbf98ed61e0962c589779a9 /lib
parent771d394fbd3af266c01813b40a82cec6c80af98d (diff)
lib: devres: Introduce devm_ioremap_resource()
The devm_request_and_ioremap() function is very useful and helps avoid a whole lot of boilerplate. However, one issue that keeps popping up is its lack of a specific error code to determine which of the steps that it performs failed. Furthermore, while the function gives an example and suggests what error code to return on failure, a wide variety of error codes are used throughout the tree. In an attempt to fix these problems, this patch adds a new function that drivers can transition to. The devm_ioremap_resource() returns a pointer to the remapped I/O memory on success or an ERR_PTR() encoded error code on failure. Callers can check for failure using IS_ERR() and determine its cause by extracting the error code using PTR_ERR(). devm_request_and_ioremap() is implemented as a wrapper around the new API and return NULL on failure as before. This ensures that backwards compatibility is maintained until all users have been converted to the new API, at which point the old devm_request_and_ioremap() function should be removed. A semantic patch is included which can be used to convert from the old devm_request_and_ioremap() API to the new devm_ioremap_resource() API. Some non-trivial cases may require manual intervention, though. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Cc: Arnd Bergmann <arnd@arndb.de> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/devres.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/lib/devres.c b/lib/devres.c
index 80b9c76d436a..9c76b3a9cc72 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -86,22 +86,24 @@ void devm_iounmap(struct device *dev, void __iomem *addr)
86EXPORT_SYMBOL(devm_iounmap); 86EXPORT_SYMBOL(devm_iounmap);
87 87
88/** 88/**
89 * devm_request_and_ioremap() - Check, request region, and ioremap resource 89 * devm_ioremap_resource() - check, request region, and ioremap resource
90 * @dev: Generic device to handle the resource for 90 * @dev: generic device to handle the resource for
91 * @res: resource to be handled 91 * @res: resource to be handled
92 * 92 *
93 * Takes all necessary steps to ioremap a mem resource. Uses managed device, so 93 * Checks that a resource is a valid memory region, requests the memory region
94 * everything is undone on driver detach. Checks arguments, so you can feed 94 * and ioremaps it either as cacheable or as non-cacheable memory depending on
95 * it the result from e.g. platform_get_resource() directly. Returns the 95 * the resource's flags. All operations are managed and will be undone on
96 * remapped pointer or NULL on error. Usage example: 96 * driver detach.
97 *
98 * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code
99 * on failure. Usage example:
97 * 100 *
98 * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 101 * res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
99 * base = devm_request_and_ioremap(&pdev->dev, res); 102 * base = devm_ioremap_resource(&pdev->dev, res);
100 * if (!base) 103 * if (IS_ERR(base))
101 * return -EADDRNOTAVAIL; 104 * return PTR_ERR(base);
102 */ 105 */
103void __iomem *devm_request_and_ioremap(struct device *dev, 106void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
104 struct resource *res)
105{ 107{
106 resource_size_t size; 108 resource_size_t size;
107 const char *name; 109 const char *name;
@@ -111,7 +113,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev,
111 113
112 if (!res || resource_type(res) != IORESOURCE_MEM) { 114 if (!res || resource_type(res) != IORESOURCE_MEM) {
113 dev_err(dev, "invalid resource\n"); 115 dev_err(dev, "invalid resource\n");
114 return NULL; 116 return ERR_PTR(-EINVAL);
115 } 117 }
116 118
117 size = resource_size(res); 119 size = resource_size(res);
@@ -119,7 +121,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev,
119 121
120 if (!devm_request_mem_region(dev, res->start, size, name)) { 122 if (!devm_request_mem_region(dev, res->start, size, name)) {
121 dev_err(dev, "can't request region for resource %pR\n", res); 123 dev_err(dev, "can't request region for resource %pR\n", res);
122 return NULL; 124 return ERR_PTR(-EBUSY);
123 } 125 }
124 126
125 if (res->flags & IORESOURCE_CACHEABLE) 127 if (res->flags & IORESOURCE_CACHEABLE)
@@ -130,10 +132,39 @@ void __iomem *devm_request_and_ioremap(struct device *dev,
130 if (!dest_ptr) { 132 if (!dest_ptr) {
131 dev_err(dev, "ioremap failed for resource %pR\n", res); 133 dev_err(dev, "ioremap failed for resource %pR\n", res);
132 devm_release_mem_region(dev, res->start, size); 134 devm_release_mem_region(dev, res->start, size);
135 dest_ptr = ERR_PTR(-ENOMEM);
133 } 136 }
134 137
135 return dest_ptr; 138 return dest_ptr;
136} 139}
140EXPORT_SYMBOL(devm_ioremap_resource);
141
142/**
143 * devm_request_and_ioremap() - Check, request region, and ioremap resource
144 * @dev: Generic device to handle the resource for
145 * @res: resource to be handled
146 *
147 * Takes all necessary steps to ioremap a mem resource. Uses managed device, so
148 * everything is undone on driver detach. Checks arguments, so you can feed
149 * it the result from e.g. platform_get_resource() directly. Returns the
150 * remapped pointer or NULL on error. Usage example:
151 *
152 * res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
153 * base = devm_request_and_ioremap(&pdev->dev, res);
154 * if (!base)
155 * return -EADDRNOTAVAIL;
156 */
157void __iomem *devm_request_and_ioremap(struct device *device,
158 struct resource *res)
159{
160 void __iomem *dest_ptr;
161
162 dest_ptr = devm_ioremap_resource(device, res);
163 if (IS_ERR(dest_ptr))
164 return NULL;
165
166 return dest_ptr;
167}
137EXPORT_SYMBOL(devm_request_and_ioremap); 168EXPORT_SYMBOL(devm_request_and_ioremap);
138 169
139#ifdef CONFIG_HAS_IOPORT 170#ifdef CONFIG_HAS_IOPORT