at91_cf: use generic gpio calls
authorDavid Brownell <dbrownell@users.sourceforge.net>
Tue, 5 Feb 2008 06:27:42 +0000 (22:27 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 5 Feb 2008 17:44:09 +0000 (09:44 -0800)
Update the AT91 CF driver to use the generic GPIO calls instead of the
AT91-specific ones; and request exclusive use of those signals.

Minor tweaks to cleanup code paths: always in reverse order of how the
resources were allocated, with remove() matching the fault paths of
probe().

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/pcmcia/at91_cf.c

index eb6abd3..385e145 100644 (file)
@@ -21,9 +21,9 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/sizes.h>
+#include <asm/gpio.h>
 
 #include <asm/arch/board.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/at91rm9200_mc.h>
 
 
@@ -56,7 +56,7 @@ struct at91_cf_socket {
 
 static inline int at91_cf_present(struct at91_cf_socket *cf)
 {
-       return !at91_get_gpio_value(cf->board->det_pin);
+       return !gpio_get_value(cf->board->det_pin);
 }
 
 /*--------------------------------------------------------------------------*/
@@ -100,9 +100,9 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
                int vcc = cf->board->vcc_pin;
 
                *sp = SS_DETECT | SS_3VCARD;
-               if (!rdy || at91_get_gpio_value(rdy))
+               if (!rdy || gpio_get_value(rdy))
                        *sp |= SS_READY;
-               if (!vcc || at91_get_gpio_value(vcc))
+               if (!vcc || gpio_get_value(vcc))
                        *sp |= SS_POWERON;
        } else
                *sp = 0;
@@ -121,10 +121,10 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
        if (cf->board->vcc_pin) {
                switch (s->Vcc) {
                        case 0:
-                               at91_set_gpio_value(cf->board->vcc_pin, 0);
+                               gpio_set_value(cf->board->vcc_pin, 0);
                                break;
                        case 33:
-                               at91_set_gpio_value(cf->board->vcc_pin, 1);
+                               gpio_set_value(cf->board->vcc_pin, 1);
                                break;
                        default:
                                return -EINVAL;
@@ -132,7 +132,7 @@ at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
        }
 
        /* toggle reset if needed */
-       at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET);
+       gpio_set_value(cf->board->rst_pin, s->flags & SS_RESET);
 
        pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
                driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
@@ -239,11 +239,24 @@ static int __init at91_cf_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, cf);
 
        /* must be a GPIO; ergo must trigger on both edges */
-       status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf);
+       status = gpio_request(board->det_pin, "cf_det");
        if (status < 0)
                goto fail0;
+       status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf);
+       if (status < 0)
+               goto fail00;
        device_init_wakeup(&pdev->dev, 1);
 
+       status = gpio_request(board->rst_pin, "cf_rst");
+       if (status < 0)
+               goto fail0a;
+
+       if (board->vcc_pin) {
+               status = gpio_request(board->vcc_pin, "cf_vcc");
+               if (status < 0)
+                       goto fail0b;
+       }
+
        /*
         * The card driver will request this irq later as needed.
         * but it causes lots of "irqNN: nobody cared" messages
@@ -251,16 +264,20 @@ static int __init at91_cf_probe(struct platform_device *pdev)
         * (Note:  DK board doesn't wire the IRQ pin...)
         */
        if (board->irq_pin) {
+               status = gpio_request(board->irq_pin, "cf_irq");
+               if (status < 0)
+                       goto fail0c;
                status = request_irq(board->irq_pin, at91_cf_irq,
                                IRQF_SHARED, driver_name, cf);
                if (status < 0)
-                       goto fail0a;
+                       goto fail0d;
                cf->socket.pci_irq = board->irq_pin;
        } else
                cf->socket.pci_irq = NR_IRQS + 1;
 
        /* pcmcia layer only remaps "real" memory not iospace */
-       cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
+       cf->socket.io_offset = (unsigned long)
+                       ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K);
        if (!cf->socket.io_offset) {
                status = -ENXIO;
                goto fail1;
@@ -296,11 +313,21 @@ fail2:
 fail1:
        if (cf->socket.io_offset)
                iounmap((void __iomem *) cf->socket.io_offset);
-       if (board->irq_pin)
+       if (board->irq_pin) {
                free_irq(board->irq_pin, cf);
+fail0d:
+               gpio_free(board->irq_pin);
+       }
+fail0c:
+       if (board->vcc_pin)
+               gpio_free(board->vcc_pin);
+fail0b:
+       gpio_free(board->rst_pin);
 fail0a:
        device_init_wakeup(&pdev->dev, 0);
        free_irq(board->det_pin, cf);
+fail00:
+       gpio_free(board->det_pin);
 fail0:
        kfree(cf);
        return status;
@@ -313,13 +340,18 @@ static int __exit at91_cf_remove(struct platform_device *pdev)
        struct resource         *io = cf->socket.io[0].res;
 
        pcmcia_unregister_socket(&cf->socket);
-       if (board->irq_pin)
+       release_mem_region(io->start, io->end + 1 - io->start);
+       iounmap((void __iomem *) cf->socket.io_offset);
+       if (board->irq_pin) {
                free_irq(board->irq_pin, cf);
+               gpio_free(board->irq_pin);
+       }
+       if (board->vcc_pin)
+               gpio_free(board->vcc_pin);
+       gpio_free(board->rst_pin);
        device_init_wakeup(&pdev->dev, 0);
        free_irq(board->det_pin, cf);
-       iounmap((void __iomem *) cf->socket.io_offset);
-       release_mem_region(io->start, io->end + 1 - io->start);
-
+       gpio_free(board->det_pin);
        kfree(cf);
        return 0;
 }