linux/3.8: backport devm_ioremap_resource from 3.9
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.8 / 030-backport-lib-devres-Introduce-devm_ioremap_resource.patch
1 From 75096579c3ac39ddc2f8b0d9a8924eba31f4d920 Mon Sep 17 00:00:00 2001
2 From: Thierry Reding <thierry.reding@avionic-design.de>
3 Date: Mon, 21 Jan 2013 11:08:54 +0100
4 Subject: [PATCH] lib: devres: Introduce devm_ioremap_resource()
5
6 The devm_request_and_ioremap() function is very useful and helps avoid a
7 whole lot of boilerplate. However, one issue that keeps popping up is
8 its lack of a specific error code to determine which of the steps that
9 it performs failed. Furthermore, while the function gives an example and
10 suggests what error code to return on failure, a wide variety of error
11 codes are used throughout the tree.
12
13 In an attempt to fix these problems, this patch adds a new function that
14 drivers can transition to. The devm_ioremap_resource() returns a pointer
15 to the remapped I/O memory on success or an ERR_PTR() encoded error code
16 on failure. Callers can check for failure using IS_ERR() and determine
17 its cause by extracting the error code using PTR_ERR().
18
19 devm_request_and_ioremap() is implemented as a wrapper around the new
20 API and return NULL on failure as before. This ensures that backwards
21 compatibility is maintained until all users have been converted to the
22 new API, at which point the old devm_request_and_ioremap() function
23 should be removed.
24
25 A semantic patch is included which can be used to convert from the old
26 devm_request_and_ioremap() API to the new devm_ioremap_resource() API.
27 Some non-trivial cases may require manual intervention, though.
28
29 Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
30 Cc: Arnd Bergmann <arnd@arndb.de>
31 Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
32 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
33 ---
34 Documentation/driver-model/devres.txt | 3 +-
35 include/linux/device.h | 1 +
36 lib/devres.c | 57 ++++++++++---
37 scripts/coccinelle/api/devm_ioremap_resource.cocci | 90 ++++++++++++++++++++
38 4 files changed, 137 insertions(+), 14 deletions(-)
39 create mode 100644 scripts/coccinelle/api/devm_ioremap_resource.cocci
40
41 --- a/Documentation/driver-model/devres.txt
42 +++ b/Documentation/driver-model/devres.txt
43 @@ -266,7 +266,8 @@ IOMAP
44 devm_ioremap()
45 devm_ioremap_nocache()
46 devm_iounmap()
47 - devm_request_and_ioremap() : checks resource, requests region, ioremaps
48 + devm_ioremap_resource() : checks resource, requests memory region, ioremaps
49 + devm_request_and_ioremap() : obsoleted by devm_ioremap_resource()
50 pcim_iomap()
51 pcim_iounmap()
52 pcim_iomap_table() : array of mapped addresses indexed by BAR
53 --- a/include/linux/device.h
54 +++ b/include/linux/device.h
55 @@ -573,6 +573,7 @@ extern int devres_release_group(struct d
56 extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
57 extern void devm_kfree(struct device *dev, void *p);
58
59 +void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
60 void __iomem *devm_request_and_ioremap(struct device *dev,
61 struct resource *res);
62
63 --- a/lib/devres.c
64 +++ b/lib/devres.c
65 @@ -86,22 +86,24 @@ void devm_iounmap(struct device *dev, vo
66 EXPORT_SYMBOL(devm_iounmap);
67
68 /**
69 - * devm_request_and_ioremap() - Check, request region, and ioremap resource
70 - * @dev: Generic device to handle the resource for
71 + * devm_ioremap_resource() - check, request region, and ioremap resource
72 + * @dev: generic device to handle the resource for
73 * @res: resource to be handled
74 *
75 - * Takes all necessary steps to ioremap a mem resource. Uses managed device, so
76 - * everything is undone on driver detach. Checks arguments, so you can feed
77 - * it the result from e.g. platform_get_resource() directly. Returns the
78 - * remapped pointer or NULL on error. Usage example:
79 + * Checks that a resource is a valid memory region, requests the memory region
80 + * and ioremaps it either as cacheable or as non-cacheable memory depending on
81 + * the resource's flags. All operations are managed and will be undone on
82 + * driver detach.
83 + *
84 + * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code
85 + * on failure. Usage example:
86 *
87 * res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
88 - * base = devm_request_and_ioremap(&pdev->dev, res);
89 - * if (!base)
90 - * return -EADDRNOTAVAIL;
91 + * base = devm_ioremap_resource(&pdev->dev, res);
92 + * if (IS_ERR(base))
93 + * return PTR_ERR(base);
94 */
95 -void __iomem *devm_request_and_ioremap(struct device *dev,
96 - struct resource *res)
97 +void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
98 {
99 resource_size_t size;
100 const char *name;
101 @@ -111,7 +113,7 @@ void __iomem *devm_request_and_ioremap(s
102
103 if (!res || resource_type(res) != IORESOURCE_MEM) {
104 dev_err(dev, "invalid resource\n");
105 - return NULL;
106 + return ERR_PTR(-EINVAL);
107 }
108
109 size = resource_size(res);
110 @@ -119,7 +121,7 @@ void __iomem *devm_request_and_ioremap(s
111
112 if (!devm_request_mem_region(dev, res->start, size, name)) {
113 dev_err(dev, "can't request region for resource %pR\n", res);
114 - return NULL;
115 + return ERR_PTR(-EBUSY);
116 }
117
118 if (res->flags & IORESOURCE_CACHEABLE)
119 @@ -130,10 +132,39 @@ void __iomem *devm_request_and_ioremap(s
120 if (!dest_ptr) {
121 dev_err(dev, "ioremap failed for resource %pR\n", res);
122 devm_release_mem_region(dev, res->start, size);
123 + dest_ptr = ERR_PTR(-ENOMEM);
124 }
125
126 return dest_ptr;
127 }
128 +EXPORT_SYMBOL(devm_ioremap_resource);
129 +
130 +/**
131 + * devm_request_and_ioremap() - Check, request region, and ioremap resource
132 + * @dev: Generic device to handle the resource for
133 + * @res: resource to be handled
134 + *
135 + * Takes all necessary steps to ioremap a mem resource. Uses managed device, so
136 + * everything is undone on driver detach. Checks arguments, so you can feed
137 + * it the result from e.g. platform_get_resource() directly. Returns the
138 + * remapped pointer or NULL on error. Usage example:
139 + *
140 + * res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
141 + * base = devm_request_and_ioremap(&pdev->dev, res);
142 + * if (!base)
143 + * return -EADDRNOTAVAIL;
144 + */
145 +void __iomem *devm_request_and_ioremap(struct device *device,
146 + struct resource *res)
147 +{
148 + void __iomem *dest_ptr;
149 +
150 + dest_ptr = devm_ioremap_resource(device, res);
151 + if (IS_ERR(dest_ptr))
152 + return NULL;
153 +
154 + return dest_ptr;
155 +}
156 EXPORT_SYMBOL(devm_request_and_ioremap);
157
158 #ifdef CONFIG_HAS_IOPORT
159 --- /dev/null
160 +++ b/scripts/coccinelle/api/devm_ioremap_resource.cocci
161 @@ -0,0 +1,90 @@
162 +virtual patch
163 +virtual report
164 +
165 +@depends on patch@
166 +expression base, dev, res;
167 +@@
168 +
169 +-base = devm_request_and_ioremap(dev, res);
170 ++base = devm_ioremap_resource(dev, res);
171 + ...
172 + if (
173 +-base == NULL
174 ++IS_ERR(base)
175 + || ...) {
176 +<...
177 +- return ...;
178 ++ return PTR_ERR(base);
179 +...>
180 + }
181 +
182 +@depends on patch@
183 +expression e, E, ret;
184 +identifier l;
185 +@@
186 +
187 + e = devm_ioremap_resource(...);
188 + ...
189 + if (IS_ERR(e) || ...) {
190 + ... when any
191 +- ret = E;
192 ++ ret = PTR_ERR(e);
193 + ...
194 +(
195 + return ret;
196 +|
197 + goto l;
198 +)
199 + }
200 +
201 +@depends on patch@
202 +expression e;
203 +@@
204 +
205 + e = devm_ioremap_resource(...);
206 + ...
207 + if (IS_ERR(e) || ...) {
208 + ...
209 +- \(dev_dbg\|dev_err\|pr_debug\|pr_err\|DRM_ERROR\)(...);
210 + ...
211 + }
212 +
213 +@depends on patch@
214 +expression e;
215 +identifier l;
216 +@@
217 +
218 + e = devm_ioremap_resource(...);
219 + ...
220 + if (IS_ERR(e) || ...)
221 +-{
222 +(
223 + return ...;
224 +|
225 + goto l;
226 +)
227 +-}
228 +
229 +@r depends on report@
230 +expression e;
231 +identifier l;
232 +position p1;
233 +@@
234 +
235 +*e = devm_request_and_ioremap@p1(...);
236 + ...
237 + if (e == NULL || ...) {
238 + ...
239 +(
240 + return ...;
241 +|
242 + goto l;
243 +)
244 + }
245 +
246 +@script:python depends on r@
247 +p1 << r.p1;
248 +@@
249 +
250 +msg = "ERROR: deprecated devm_request_and_ioremap() API used on line %s" % (p1[0].line)
251 +coccilib.report.print_report(p1[0], msg)