aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-05-03 22:30:14 -0400
committerShawn Guo <shawn.guo@linaro.org>2012-05-12 01:32:18 -0400
commit940a4f7b51f7ad600821e389e80d216baf9e1df8 (patch)
tree91455b31186a949a76a2bfb85ca96621d2469b6c /drivers/gpio
parent84f3570a96c4632cb2d3958ff7542f66b49c33cd (diff)
gpio/mxs: use devm_* helpers to make error handling simple
It uses devm_* helpers to make the error handling of probe clean and simple. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-mxs.c52
1 files changed, 13 insertions, 39 deletions
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 385c58e8405b..95a11dba285c 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -186,44 +186,29 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
186 struct resource *iores = NULL; 186 struct resource *iores = NULL;
187 int err; 187 int err;
188 188
189 port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL); 189 port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
190 if (!port) 190 if (!port)
191 return -ENOMEM; 191 return -ENOMEM;
192 192
193 port->id = pdev->id; 193 port->id = pdev->id;
194 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; 194 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
195 195
196 port->irq = platform_get_irq(pdev, 0);
197 if (port->irq < 0)
198 return port->irq;
199
196 /* 200 /*
197 * map memory region only once, as all the gpio ports 201 * map memory region only once, as all the gpio ports
198 * share the same one 202 * share the same one
199 */ 203 */
200 if (!base) { 204 if (!base) {
201 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 205 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
202 if (!iores) { 206 base = devm_request_and_ioremap(&pdev->dev, iores);
203 err = -ENODEV; 207 if (!base)
204 goto out_kfree; 208 return -EADDRNOTAVAIL;
205 }
206
207 if (!request_mem_region(iores->start, resource_size(iores),
208 pdev->name)) {
209 err = -EBUSY;
210 goto out_kfree;
211 }
212
213 base = ioremap(iores->start, resource_size(iores));
214 if (!base) {
215 err = -ENOMEM;
216 goto out_release_mem;
217 }
218 } 209 }
219 port->base = base; 210 port->base = base;
220 211
221 port->irq = platform_get_irq(pdev, 0);
222 if (port->irq < 0) {
223 err = -EINVAL;
224 goto out_iounmap;
225 }
226
227 /* 212 /*
228 * select the pin interrupt functionality but initially 213 * select the pin interrupt functionality but initially
229 * disable the interrupts 214 * disable the interrupts
@@ -246,29 +231,18 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
246 port->base + PINCTRL_DOUT(port->id), NULL, 231 port->base + PINCTRL_DOUT(port->id), NULL,
247 port->base + PINCTRL_DOE(port->id), NULL, false); 232 port->base + PINCTRL_DOE(port->id), NULL, false);
248 if (err) 233 if (err)
249 goto out_iounmap; 234 return err;
250 235
251 port->bgc.gc.to_irq = mxs_gpio_to_irq; 236 port->bgc.gc.to_irq = mxs_gpio_to_irq;
252 port->bgc.gc.base = port->id * 32; 237 port->bgc.gc.base = port->id * 32;
253 238
254 err = gpiochip_add(&port->bgc.gc); 239 err = gpiochip_add(&port->bgc.gc);
255 if (err) 240 if (err) {
256 goto out_bgpio_remove; 241 bgpio_remove(&port->bgc);
242 return err;
243 }
257 244
258 return 0; 245 return 0;
259
260out_bgpio_remove:
261 bgpio_remove(&port->bgc);
262out_iounmap:
263 if (iores)
264 iounmap(port->base);
265out_release_mem:
266 if (iores)
267 release_mem_region(iores->start, resource_size(iores));
268out_kfree:
269 kfree(port);
270 dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
271 return err;
272} 246}
273 247
274static struct platform_driver mxs_gpio_driver = { 248static struct platform_driver mxs_gpio_driver = {