const: struct nla_policy
[safe/jmp/linux-2.6] / drivers / pcmcia / sa1100_h3600.c
index 6de4e1b..56329ad 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
-#include <mach/h3600.h>
+#include <mach/h3xxx.h>
 
 #include "sa1100_generic.h"
 
 static struct pcmcia_irqs irqs[] = {
-       { 0, IRQ_GPIO_H3600_PCMCIA_CD0, "PCMCIA CD0" },
-       { 1, IRQ_GPIO_H3600_PCMCIA_CD1, "PCMCIA CD1" }
+       { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
+       { .sock = 1, .str = "PCMCIA CD1" }
 };
 
 static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
-                          : IRQ_GPIO_H3600_PCMCIA_IRQ0;
+       int err;
 
+       switch (skt->nr) {
+       case 0:
+               err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0");
+               if (err)
+                       goto err00;
+               err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0);
+               if (err)
+                       goto err01;
+               skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0);
+
+               err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0");
+               if (err)
+                       goto err01;
+               err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0);
+               if (err)
+                       goto err02;
+               irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0);
+
+               err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
+               if (err)
+                       goto err02;
+               err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
+               if (err)
+                       goto err03;
+               err = gpio_request(H3XXX_EGPIO_OPT_ON, "OPT ON");
+               if (err)
+                       goto err03;
+               err = gpio_direction_output(H3XXX_EGPIO_OPT_ON, 0);
+               if (err)
+                       goto err04;
+               err = gpio_request(H3XXX_EGPIO_OPT_RESET, "OPT RESET");
+               if (err)
+                       goto err04;
+               err = gpio_direction_output(H3XXX_EGPIO_OPT_RESET, 0);
+               if (err)
+                       goto err05;
+               err = gpio_request(H3XXX_EGPIO_CARD_RESET, "PCMCIA CARD RESET");
+               if (err)
+                       goto err05;
+               err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0);
+               if (err)
+                       goto err06;
+               err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+               if (err)
+                       goto err06;
+               break;
+       case 1:
+               err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1");
+               if (err)
+                       goto err10;
+               err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1);
+               if (err)
+                       goto err11;
+               skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
+
+               err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
+               if (err)
+                       goto err11;
+               err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
+               if (err)
+                       goto err12;
+               irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
+
+               err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+               if (err)
+                       goto err12;
+               break;
+       }
+       return 0;
 
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+err06: gpio_free(H3XXX_EGPIO_CARD_RESET);
+err05: gpio_free(H3XXX_EGPIO_OPT_RESET);
+err04: gpio_free(H3XXX_EGPIO_OPT_ON);
+err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
+err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+err00: return err;
+
+err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+err10: return err;
 }
 
 static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
        soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
   
-       /* Disable CF bus: */
-       clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
-       clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
-       set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+       switch (skt->nr) {
+       case 0:
+               /* Disable CF bus: */
+               gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
+               gpio_set_value(H3XXX_EGPIO_OPT_ON, 0);
+               gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1);
+
+               gpio_free(H3XXX_EGPIO_CARD_RESET);
+               gpio_free(H3XXX_EGPIO_OPT_RESET);
+               gpio_free(H3XXX_EGPIO_OPT_ON);
+               gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
+               gpio_free(H3XXX_GPIO_PCMCIA_CD0);
+               gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
+               break;
+       case 1:
+               gpio_free(H3XXX_GPIO_PCMCIA_CD1);
+               gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
+               break;
+       }
 }
 
 static void
 h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-       unsigned long levels = GPLR;
-
        switch (skt->nr) {
        case 0:
-               state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
-               state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
+               state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0);
+               state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0);
                state->bvd1 = 0;
                state->bvd2 = 0;
                state->wrprot = 0; /* Not available on H3600. */
@@ -59,8 +151,8 @@ h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *st
                break;
 
        case 1:
-               state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
-               state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
+               state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
+               state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
                state->bvd1 = 0;
                state->bvd2 = 0;
                state->wrprot = 0; /* Not available on H3600. */
@@ -79,10 +171,7 @@ h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_
                return -1;
        }
 
-       if (state->flags & SS_RESET)
-               set_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
-       else
-               clr_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
+       gpio_set_value(H3XXX_EGPIO_CARD_RESET, !!(state->flags & SS_RESET));
 
        /* Silently ignore Vpp, output enable, speaker enable. */
 
@@ -92,9 +181,9 @@ h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_
 static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 {
        /* Enable CF bus: */
-       set_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
-       set_h3600_egpio(IPAQ_EGPIO_OPT_ON);
-       clr_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+       gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 1);
+       gpio_set_value(H3XXX_EGPIO_OPT_ON, 1);
+       gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);
 
        msleep(10);
 
@@ -112,10 +201,10 @@ static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
         * socket 0 then socket 1.
         */
        if (skt->nr == 1) {
-               clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
-               clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
+               gpio_set_value(H3XXX_EGPIO_OPT_ON, 0);
+               gpio_set_value(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
                /* hmm, does this suck power? */
-               set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+               gpio_set_value(H3XXX_EGPIO_OPT_RESET, 1);
        }
 }
 
@@ -134,7 +223,7 @@ int __init pcmcia_h3600_init(struct device *dev)
 {
        int ret = -ENODEV;
 
-       if (machine_is_h3600())
+       if (machine_is_h3600() || machine_is_h3100())
                ret = sa11xx_drv_pcmcia_probe(dev, &h3600_pcmcia_ops, 0, 2);
 
        return ret;