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 63b4c29678 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 d0fbda9add.

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>
This commit is contained in:
Joachim Eastwood 2012-01-10 02:37:25 +01:00 committed by Dominik Brodowski
parent f24fa8affe
commit 80af9e6d7a

View file

@ -16,13 +16,13 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/gpio.h>
#include <pcmcia/ss.h> #include <pcmcia/ss.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/sizes.h> #include <asm/sizes.h>
#include <asm/gpio.h>
#include <mach/board.h> #include <mach/board.h>
#include <mach/at91rm9200_mc.h> #include <mach/at91rm9200_mc.h>
@ -69,7 +69,7 @@ static irqreturn_t at91_cf_irq(int irq, void *_cf)
{ {
struct at91_cf_socket *cf = _cf; struct at91_cf_socket *cf = _cf;
if (irq == cf->board->det_pin) { if (irq == gpio_to_irq(cf->board->det_pin)) {
unsigned present = at91_cf_present(cf); unsigned present = at91_cf_present(cf);
/* kick pccard as needed */ /* kick pccard as needed */
@ -95,8 +95,8 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
/* NOTE: CF is always 3VCARD */ /* NOTE: CF is always 3VCARD */
if (at91_cf_present(cf)) { if (at91_cf_present(cf)) {
int rdy = cf->board->irq_pin; /* RDY/nIRQ */ int rdy = gpio_is_valid(cf->board->irq_pin); /* RDY/nIRQ */
int vcc = cf->board->vcc_pin; int vcc = gpio_is_valid(cf->board->vcc_pin);
*sp = SS_DETECT | SS_3VCARD; *sp = SS_DETECT | SS_3VCARD;
if (!rdy || gpio_get_value(rdy)) if (!rdy || gpio_get_value(rdy))
@ -117,7 +117,7 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
cf = container_of(sock, struct at91_cf_socket, socket); cf = container_of(sock, struct at91_cf_socket, socket);
/* switch Vcc if needed and possible */ /* switch Vcc if needed and possible */
if (cf->board->vcc_pin) { if (gpio_is_valid(cf->board->vcc_pin)) {
switch (s->Vcc) { switch (s->Vcc) {
case 0: case 0:
gpio_set_value(cf->board->vcc_pin, 0); gpio_set_value(cf->board->vcc_pin, 0);
@ -221,7 +221,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
struct resource *io; struct resource *io;
int status; int status;
if (!board || !board->det_pin || !board->rst_pin) if (!board || !gpio_is_valid(board->det_pin) || !gpio_is_valid(board->rst_pin))
return -ENODEV; return -ENODEV;
io = platform_get_resource(pdev, IORESOURCE_MEM, 0); io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -241,7 +241,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
status = gpio_request(board->det_pin, "cf_det"); status = gpio_request(board->det_pin, "cf_det");
if (status < 0) if (status < 0)
goto fail0; goto fail0;
status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); status = request_irq(gpio_to_irq(board->det_pin), at91_cf_irq, 0, driver_name, cf);
if (status < 0) if (status < 0)
goto fail00; goto fail00;
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
@ -250,7 +250,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
if (status < 0) if (status < 0)
goto fail0a; goto fail0a;
if (board->vcc_pin) { if (gpio_is_valid(board->vcc_pin)) {
status = gpio_request(board->vcc_pin, "cf_vcc"); status = gpio_request(board->vcc_pin, "cf_vcc");
if (status < 0) if (status < 0)
goto fail0b; goto fail0b;
@ -262,15 +262,15 @@ static int __init at91_cf_probe(struct platform_device *pdev)
* unless we report that we handle everything (sigh). * unless we report that we handle everything (sigh).
* (Note: DK board doesn't wire the IRQ pin...) * (Note: DK board doesn't wire the IRQ pin...)
*/ */
if (board->irq_pin) { if (gpio_is_valid(board->irq_pin)) {
status = gpio_request(board->irq_pin, "cf_irq"); status = gpio_request(board->irq_pin, "cf_irq");
if (status < 0) if (status < 0)
goto fail0c; goto fail0c;
status = request_irq(board->irq_pin, at91_cf_irq, status = request_irq(gpio_to_irq(board->irq_pin), at91_cf_irq,
IRQF_SHARED, driver_name, cf); IRQF_SHARED, driver_name, cf);
if (status < 0) if (status < 0)
goto fail0d; goto fail0d;
cf->socket.pci_irq = board->irq_pin; cf->socket.pci_irq = gpio_to_irq(board->irq_pin);
} else } else
cf->socket.pci_irq = nr_irqs + 1; cf->socket.pci_irq = nr_irqs + 1;
@ -289,7 +289,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
} }
pr_info("%s: irqs det #%d, io #%d\n", driver_name, pr_info("%s: irqs det #%d, io #%d\n", driver_name,
board->det_pin, board->irq_pin); gpio_to_irq(board->det_pin), gpio_to_irq(board->irq_pin));
cf->socket.owner = THIS_MODULE; cf->socket.owner = THIS_MODULE;
cf->socket.dev.parent = &pdev->dev; cf->socket.dev.parent = &pdev->dev;
@ -311,19 +311,19 @@ fail2:
fail1: fail1:
if (cf->socket.io_offset) if (cf->socket.io_offset)
iounmap((void __iomem *) cf->socket.io_offset); iounmap((void __iomem *) cf->socket.io_offset);
if (board->irq_pin) { if (gpio_is_valid(board->irq_pin)) {
free_irq(board->irq_pin, cf); free_irq(gpio_to_irq(board->irq_pin), cf);
fail0d: fail0d:
gpio_free(board->irq_pin); gpio_free(board->irq_pin);
} }
fail0c: fail0c:
if (board->vcc_pin) if (gpio_is_valid(board->vcc_pin))
gpio_free(board->vcc_pin); gpio_free(board->vcc_pin);
fail0b: fail0b:
gpio_free(board->rst_pin); gpio_free(board->rst_pin);
fail0a: fail0a:
device_init_wakeup(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0);
free_irq(board->det_pin, cf); free_irq(gpio_to_irq(board->det_pin), cf);
fail00: fail00:
gpio_free(board->det_pin); gpio_free(board->det_pin);
fail0: fail0:
@ -340,15 +340,15 @@ static int __exit at91_cf_remove(struct platform_device *pdev)
pcmcia_unregister_socket(&cf->socket); pcmcia_unregister_socket(&cf->socket);
release_mem_region(io->start, resource_size(io)); release_mem_region(io->start, resource_size(io));
iounmap((void __iomem *) cf->socket.io_offset); iounmap((void __iomem *) cf->socket.io_offset);
if (board->irq_pin) { if (gpio_is_valid(board->irq_pin)) {
free_irq(board->irq_pin, cf); free_irq(gpio_to_irq(board->irq_pin), cf);
gpio_free(board->irq_pin); gpio_free(board->irq_pin);
} }
if (board->vcc_pin) if (gpio_is_valid(board->vcc_pin))
gpio_free(board->vcc_pin); gpio_free(board->vcc_pin);
gpio_free(board->rst_pin); gpio_free(board->rst_pin);
device_init_wakeup(&pdev->dev, 0); device_init_wakeup(&pdev->dev, 0);
free_irq(board->det_pin, cf); free_irq(gpio_to_irq(board->det_pin), cf);
gpio_free(board->det_pin); gpio_free(board->det_pin);
kfree(cf); kfree(cf);
return 0; return 0;
@ -362,9 +362,9 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
struct at91_cf_data *board = cf->board; struct at91_cf_data *board = cf->board;
if (device_may_wakeup(&pdev->dev)) { if (device_may_wakeup(&pdev->dev)) {
enable_irq_wake(board->det_pin); enable_irq_wake(gpio_to_irq(board->det_pin));
if (board->irq_pin) if (gpio_is_valid(board->irq_pin))
enable_irq_wake(board->irq_pin); enable_irq_wake(gpio_to_irq(board->irq_pin));
} }
return 0; return 0;
} }
@ -375,9 +375,9 @@ static int at91_cf_resume(struct platform_device *pdev)
struct at91_cf_data *board = cf->board; struct at91_cf_data *board = cf->board;
if (device_may_wakeup(&pdev->dev)) { if (device_may_wakeup(&pdev->dev)) {
disable_irq_wake(board->det_pin); disable_irq_wake(gpio_to_irq(board->det_pin));
if (board->irq_pin) if (gpio_is_valid(board->irq_pin))
disable_irq_wake(board->irq_pin); disable_irq_wake(gpio_to_irq(board->irq_pin));
} }
return 0; return 0;