diff options
author | Joachim Eastwood <joachim.eastwood@jotron.com> | 2012-01-09 20:37:25 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2012-03-03 08:43:37 -0500 |
commit | 80af9e6d7ae633309cc5bca96aee6a45117e7c98 (patch) | |
tree | e46b41733e940d76ecea89384beff60988b95ac9 /drivers/pcmcia/at91_cf.c | |
parent | f24fa8affe020c57a25bbb73ed31a6e4eb5c00c2 (diff) |
pcmcia at91_cf: fix raw gpio number usage
This patches fixes two things:
* Use gpio_valid function to check gpio before usage
This must be done after 63b4c29678500 which uses -EINVAL for unused pin's
* Use gpio_to_irq to convert gpio's to irq
The driver assumed a 1:1 mapping between gpio and irq numbers. This is no
longer true after d0fbda9add3281.
Tested on custom RM9200 board with 8gb CF card.
Signed-off-by: Joachim Eastwood <joachim.eastwood@jotron.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/at91_cf.c')
-rw-r--r-- | drivers/pcmcia/at91_cf.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 4902206f53d9..4127441015db 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -16,13 +16,13 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/gpio.h> | ||
19 | 20 | ||
20 | #include <pcmcia/ss.h> | 21 | #include <pcmcia/ss.h> |
21 | 22 | ||
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
24 | #include <asm/sizes.h> | 25 | #include <asm/sizes.h> |
25 | #include <asm/gpio.h> | ||
26 | 26 | ||
27 | #include <mach/board.h> | 27 | #include <mach/board.h> |
28 | #include <mach/at91rm9200_mc.h> | 28 | #include <mach/at91rm9200_mc.h> |
@@ -69,7 +69,7 @@ static irqreturn_t at91_cf_irq(int irq, void *_cf) | |||
69 | { | 69 | { |
70 | struct at91_cf_socket *cf = _cf; | 70 | struct at91_cf_socket *cf = _cf; |
71 | 71 | ||
72 | if (irq == cf->board->det_pin) { | 72 | if (irq == gpio_to_irq(cf->board->det_pin)) { |
73 | unsigned present = at91_cf_present(cf); | 73 | unsigned present = at91_cf_present(cf); |
74 | 74 | ||
75 | /* kick pccard as needed */ | 75 | /* kick pccard as needed */ |
@@ -95,8 +95,8 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) | |||
95 | 95 | ||
96 | /* NOTE: CF is always 3VCARD */ | 96 | /* NOTE: CF is always 3VCARD */ |
97 | if (at91_cf_present(cf)) { | 97 | if (at91_cf_present(cf)) { |
98 | int rdy = cf->board->irq_pin; /* RDY/nIRQ */ | 98 | int rdy = gpio_is_valid(cf->board->irq_pin); /* RDY/nIRQ */ |
99 | int vcc = cf->board->vcc_pin; | 99 | int vcc = gpio_is_valid(cf->board->vcc_pin); |
100 | 100 | ||
101 | *sp = SS_DETECT | SS_3VCARD; | 101 | *sp = SS_DETECT | SS_3VCARD; |
102 | if (!rdy || gpio_get_value(rdy)) | 102 | if (!rdy || gpio_get_value(rdy)) |
@@ -117,7 +117,7 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) | |||
117 | cf = container_of(sock, struct at91_cf_socket, socket); | 117 | cf = container_of(sock, struct at91_cf_socket, socket); |
118 | 118 | ||
119 | /* switch Vcc if needed and possible */ | 119 | /* switch Vcc if needed and possible */ |
120 | if (cf->board->vcc_pin) { | 120 | if (gpio_is_valid(cf->board->vcc_pin)) { |
121 | switch (s->Vcc) { | 121 | switch (s->Vcc) { |
122 | case 0: | 122 | case 0: |
123 | gpio_set_value(cf->board->vcc_pin, 0); | 123 | gpio_set_value(cf->board->vcc_pin, 0); |
@@ -221,7 +221,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
221 | struct resource *io; | 221 | struct resource *io; |
222 | int status; | 222 | int status; |
223 | 223 | ||
224 | if (!board || !board->det_pin || !board->rst_pin) | 224 | if (!board || !gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin)) |
225 | return -ENODEV; | 225 | return -ENODEV; |
226 | 226 | ||
227 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 227 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -241,7 +241,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
241 | status = gpio_request(board->det_pin, "cf_det"); | 241 | status = gpio_request(board->det_pin, "cf_det"); |
242 | if (status < 0) | 242 | if (status < 0) |
243 | goto fail0; | 243 | goto fail0; |
244 | status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); | 244 | status = request_irq(gpio_to_irq(board->det_pin), at91_cf_irq, 0, driver_name, cf); |
245 | if (status < 0) | 245 | if (status < 0) |
246 | goto fail00; | 246 | goto fail00; |
247 | device_init_wakeup(&pdev->dev, 1); | 247 | device_init_wakeup(&pdev->dev, 1); |
@@ -250,7 +250,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
250 | if (status < 0) | 250 | if (status < 0) |
251 | goto fail0a; | 251 | goto fail0a; |
252 | 252 | ||
253 | if (board->vcc_pin) { | 253 | if (gpio_is_valid(board->vcc_pin)) { |
254 | status = gpio_request(board->vcc_pin, "cf_vcc"); | 254 | status = gpio_request(board->vcc_pin, "cf_vcc"); |
255 | if (status < 0) | 255 | if (status < 0) |
256 | goto fail0b; | 256 | goto fail0b; |
@@ -262,15 +262,15 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
262 | * unless we report that we handle everything (sigh). | 262 | * unless we report that we handle everything (sigh). |
263 | * (Note: DK board doesn't wire the IRQ pin...) | 263 | * (Note: DK board doesn't wire the IRQ pin...) |
264 | */ | 264 | */ |
265 | if (board->irq_pin) { | 265 | if (gpio_is_valid(board->irq_pin)) { |
266 | status = gpio_request(board->irq_pin, "cf_irq"); | 266 | status = gpio_request(board->irq_pin, "cf_irq"); |
267 | if (status < 0) | 267 | if (status < 0) |
268 | goto fail0c; | 268 | goto fail0c; |
269 | status = request_irq(board->irq_pin, at91_cf_irq, | 269 | status = request_irq(gpio_to_irq(board->irq_pin), at91_cf_irq, |
270 | IRQF_SHARED, driver_name, cf); | 270 | IRQF_SHARED, driver_name, cf); |
271 | if (status < 0) | 271 | if (status < 0) |
272 | goto fail0d; | 272 | goto fail0d; |
273 | cf->socket.pci_irq = board->irq_pin; | 273 | cf->socket.pci_irq = gpio_to_irq(board->irq_pin); |
274 | } else | 274 | } else |
275 | cf->socket.pci_irq = nr_irqs + 1; | 275 | cf->socket.pci_irq = nr_irqs + 1; |
276 | 276 | ||
@@ -289,7 +289,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
289 | } | 289 | } |
290 | 290 | ||
291 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, | 291 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, |
292 | board->det_pin, board->irq_pin); | 292 | gpio_to_irq(board->det_pin), gpio_to_irq(board->irq_pin)); |
293 | 293 | ||
294 | cf->socket.owner = THIS_MODULE; | 294 | cf->socket.owner = THIS_MODULE; |
295 | cf->socket.dev.parent = &pdev->dev; | 295 | cf->socket.dev.parent = &pdev->dev; |
@@ -311,19 +311,19 @@ fail2: | |||
311 | fail1: | 311 | fail1: |
312 | if (cf->socket.io_offset) | 312 | if (cf->socket.io_offset) |
313 | iounmap((void __iomem *) cf->socket.io_offset); | 313 | iounmap((void __iomem *) cf->socket.io_offset); |
314 | if (board->irq_pin) { | 314 | if (gpio_is_valid(board->irq_pin)) { |
315 | free_irq(board->irq_pin, cf); | 315 | free_irq(gpio_to_irq(board->irq_pin), cf); |
316 | fail0d: | 316 | fail0d: |
317 | gpio_free(board->irq_pin); | 317 | gpio_free(board->irq_pin); |
318 | } | 318 | } |
319 | fail0c: | 319 | fail0c: |
320 | if (board->vcc_pin) | 320 | if (gpio_is_valid(board->vcc_pin)) |
321 | gpio_free(board->vcc_pin); | 321 | gpio_free(board->vcc_pin); |
322 | fail0b: | 322 | fail0b: |
323 | gpio_free(board->rst_pin); | 323 | gpio_free(board->rst_pin); |
324 | fail0a: | 324 | fail0a: |
325 | device_init_wakeup(&pdev->dev, 0); | 325 | device_init_wakeup(&pdev->dev, 0); |
326 | free_irq(board->det_pin, cf); | 326 | free_irq(gpio_to_irq(board->det_pin), cf); |
327 | fail00: | 327 | fail00: |
328 | gpio_free(board->det_pin); | 328 | gpio_free(board->det_pin); |
329 | fail0: | 329 | fail0: |
@@ -340,15 +340,15 @@ static int __exit at91_cf_remove(struct platform_device *pdev) | |||
340 | pcmcia_unregister_socket(&cf->socket); | 340 | pcmcia_unregister_socket(&cf->socket); |
341 | release_mem_region(io->start, resource_size(io)); | 341 | release_mem_region(io->start, resource_size(io)); |
342 | iounmap((void __iomem *) cf->socket.io_offset); | 342 | iounmap((void __iomem *) cf->socket.io_offset); |
343 | if (board->irq_pin) { | 343 | if (gpio_is_valid(board->irq_pin)) { |
344 | free_irq(board->irq_pin, cf); | 344 | free_irq(gpio_to_irq(board->irq_pin), cf); |
345 | gpio_free(board->irq_pin); | 345 | gpio_free(board->irq_pin); |
346 | } | 346 | } |
347 | if (board->vcc_pin) | 347 | if (gpio_is_valid(board->vcc_pin)) |
348 | gpio_free(board->vcc_pin); | 348 | gpio_free(board->vcc_pin); |
349 | gpio_free(board->rst_pin); | 349 | gpio_free(board->rst_pin); |
350 | device_init_wakeup(&pdev->dev, 0); | 350 | device_init_wakeup(&pdev->dev, 0); |
351 | free_irq(board->det_pin, cf); | 351 | free_irq(gpio_to_irq(board->det_pin), cf); |
352 | gpio_free(board->det_pin); | 352 | gpio_free(board->det_pin); |
353 | kfree(cf); | 353 | kfree(cf); |
354 | return 0; | 354 | return 0; |
@@ -362,9 +362,9 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
362 | struct at91_cf_data *board = cf->board; | 362 | struct at91_cf_data *board = cf->board; |
363 | 363 | ||
364 | if (device_may_wakeup(&pdev->dev)) { | 364 | if (device_may_wakeup(&pdev->dev)) { |
365 | enable_irq_wake(board->det_pin); | 365 | enable_irq_wake(gpio_to_irq(board->det_pin)); |
366 | if (board->irq_pin) | 366 | if (gpio_is_valid(board->irq_pin)) |
367 | enable_irq_wake(board->irq_pin); | 367 | enable_irq_wake(gpio_to_irq(board->irq_pin)); |
368 | } | 368 | } |
369 | return 0; | 369 | return 0; |
370 | } | 370 | } |
@@ -375,9 +375,9 @@ static int at91_cf_resume(struct platform_device *pdev) | |||
375 | struct at91_cf_data *board = cf->board; | 375 | struct at91_cf_data *board = cf->board; |
376 | 376 | ||
377 | if (device_may_wakeup(&pdev->dev)) { | 377 | if (device_may_wakeup(&pdev->dev)) { |
378 | disable_irq_wake(board->det_pin); | 378 | disable_irq_wake(gpio_to_irq(board->det_pin)); |
379 | if (board->irq_pin) | 379 | if (gpio_is_valid(board->irq_pin)) |
380 | disable_irq_wake(board->irq_pin); | 380 | disable_irq_wake(gpio_to_irq(board->irq_pin)); |
381 | } | 381 | } |
382 | 382 | ||
383 | return 0; | 383 | return 0; |