Merge branch 'pcmcia' of git://git.linaro.org/people/rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 24 Mar 2012 00:37:40 +0000 (17:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 24 Mar 2012 00:37:40 +0000 (17:37 -0700)
Pull #3 ARM updates from Russell King:
 "This adds gpio support to soc_common, allowing an amount of code to be
  deleted from each PCMCIA socket driver for the PXA/SA11x0 SoCs."

* 'pcmcia' of git://git.linaro.org/people/rmk/linux-arm:
  PCMCIA: sa1111: rename sa1111 socket drivers to have sa1111_ prefix.
  PCMCIA: make lubbock socket driver part of sa1111_cs
  PCMCIA: add Kconfig control for building sa11xx_base.c
  PCMCIA: sa1111: jornada720: no need to disable IRQs around sa1111_set_io
  PCMCIA: sa1111: pass along sa1111_pcmcia_configure_socket() failure code
  PCMCIA: soc_common: remove explicit wrprot initialization in socket drivers
  PCMCIA: soc_common: remove soc_pcmcia_*_irqs functions
  PCMCIA: sa11x0: h3600: convert to use new irq/gpio management
  PCMCIA: sa11x0: simpad: convert to use new irq/gpio management
  PCMCIA: sa11x0: shannon: convert to use new irq/gpio management
  PCMCIA: sa11x0: nanoengine: convert reset handling to use GPIO subsystem
  PCMCIA: sa11x0: nanoengine: convert to use new irq/gpio management
  PCMCIA: sa11x0: cerf: convert reset handling to use GPIO subsystem
  PCMCIA: sa11x0: cerf: convert to use new irq/gpio management
  PCMCIA: sa11x0: assabet: convert to use new irq/gpio management
  PCMCIA: sa1111: use new per-socket irq/gpio infrastructure
  PCMCIA: pxa: convert PXA socket drivers to use new irq/gpio management
  PCMCIA: soc_common: add GPIO support for card status signals
  PCMCIA: soc_common: move common initialization into soc_common

42 files changed:
arch/arm/mach-pxa/include/mach/balloon3.h
arch/arm/mach-sa1100/include/mach/assabet.h
arch/arm/mach-sa1100/include/mach/cerf.h
arch/arm/mach-sa1100/include/mach/nanoengine.h
arch/arm/mach-sa1100/include/mach/shannon.h
arch/arm/mach-sa1100/include/mach/simpad.h
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/pxa2xx_balloon3.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/pxa2xx_cm_x255.c
drivers/pcmcia/pxa2xx_cm_x270.c
drivers/pcmcia/pxa2xx_colibri.c
drivers/pcmcia/pxa2xx_e740.c
drivers/pcmcia/pxa2xx_lubbock.c [deleted file]
drivers/pcmcia/pxa2xx_mainstone.c
drivers/pcmcia/pxa2xx_palmld.c
drivers/pcmcia/pxa2xx_palmtc.c
drivers/pcmcia/pxa2xx_palmtx.c
drivers/pcmcia/pxa2xx_sharpsl.c
drivers/pcmcia/pxa2xx_stargate2.c
drivers/pcmcia/pxa2xx_trizeps4.c
drivers/pcmcia/pxa2xx_viper.c
drivers/pcmcia/pxa2xx_vpac270.c
drivers/pcmcia/sa1100_assabet.c
drivers/pcmcia/sa1100_badge4.c [deleted file]
drivers/pcmcia/sa1100_cerf.c
drivers/pcmcia/sa1100_h3600.c
drivers/pcmcia/sa1100_jornada720.c [deleted file]
drivers/pcmcia/sa1100_nanoengine.c
drivers/pcmcia/sa1100_neponset.c [deleted file]
drivers/pcmcia/sa1100_shannon.c
drivers/pcmcia/sa1100_simpad.c
drivers/pcmcia/sa1111_badge4.c [new file with mode: 0644]
drivers/pcmcia/sa1111_generic.c
drivers/pcmcia/sa1111_generic.h
drivers/pcmcia/sa1111_jornada720.c [new file with mode: 0644]
drivers/pcmcia/sa1111_lubbock.c [new file with mode: 0644]
drivers/pcmcia/sa1111_neponset.c [new file with mode: 0644]
drivers/pcmcia/sa11xx_base.c
drivers/pcmcia/soc_common.c
drivers/pcmcia/soc_common.h

index f02fa1e6ba8619d995773d831bdd04bb7ad34802..954641e6c8b1cec4f1b0f29ea8fae26f0cbfcdf3 100644 (file)
@@ -174,7 +174,6 @@ enum balloon3_features {
 
 #define BALLOON3_AUX_NIRQ      PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ)
 #define BALLOON3_CODEC_IRQ     PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ)
-#define BALLOON3_S0_CD_IRQ     PXA_GPIO_TO_IRQ(BALLOON3_GPIO_S0_CD)
 
 #define BALLOON3_NR_IRQS       (IRQ_BOARD_START + 16)
 
index 28c2cf50c259e9275e605ce8c578bc133fa49429..307391488c22607c617d7931ed7867c3bdcd185d 100644 (file)
@@ -85,21 +85,18 @@ extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set);
 #define ASSABET_BSR_RAD_RI     (1 << 31)
 
 
-/* GPIOs for which the generic definition doesn't say much */
+/* GPIOs (bitmasks) for which the generic definition doesn't say much */
 #define ASSABET_GPIO_RADIO_IRQ         GPIO_GPIO (14)  /* Radio interrupt request  */
 #define ASSABET_GPIO_PS_MODE_SYNC      GPIO_GPIO (16)  /* Power supply mode/sync   */
 #define ASSABET_GPIO_STEREO_64FS_CLK   GPIO_GPIO (19)  /* SSP UDA1341 clock input  */
-#define ASSABET_GPIO_CF_IRQ            GPIO_GPIO (21)  /* CF IRQ   */
-#define ASSABET_GPIO_CF_CD             GPIO_GPIO (22)  /* CF CD */
-#define ASSABET_GPIO_CF_BVD2           GPIO_GPIO (24)  /* CF BVD */
 #define ASSABET_GPIO_GFX_IRQ           GPIO_GPIO (24)  /* Graphics IRQ */
-#define ASSABET_GPIO_CF_BVD1           GPIO_GPIO (25)  /* CF BVD */
 #define ASSABET_GPIO_BATT_LOW          GPIO_GPIO (26)  /* Low battery */
 #define ASSABET_GPIO_RCLK              GPIO_GPIO (26)  /* CCLK/2  */
 
-#define ASSABET_IRQ_GPIO_CF_IRQ                IRQ_GPIO21
-#define ASSABET_IRQ_GPIO_CF_CD         IRQ_GPIO22
-#define ASSABET_IRQ_GPIO_CF_BVD2       IRQ_GPIO24
-#define ASSABET_IRQ_GPIO_CF_BVD1       IRQ_GPIO25
+/* These are gpiolib GPIO numbers, not bitmasks */
+#define ASSABET_GPIO_CF_IRQ            21      /* CF IRQ */
+#define ASSABET_GPIO_CF_CD             22      /* CF CD  */
+#define ASSABET_GPIO_CF_BVD2           24      /* CF BVD / IOSPKR */
+#define ASSABET_GPIO_CF_BVD1           25      /* CF BVD / IOSTSCHG */
 
 #endif
index c3ac3d0f946594f69372d1b0f285d72031a74e17..88fd9c006ce0af71a35e3a0bfc96822790dce799 100644 (file)
 #define CERF_ETH_IO                    0xf0000000
 #define CERF_ETH_IRQ IRQ_GPIO26
 
-#define CERF_GPIO_CF_BVD2              GPIO_GPIO (19)
-#define CERF_GPIO_CF_BVD1              GPIO_GPIO (20)
-#define CERF_GPIO_CF_RESET             GPIO_GPIO (21)
-#define CERF_GPIO_CF_IRQ               GPIO_GPIO (22)
-#define CERF_GPIO_CF_CD                        GPIO_GPIO (23)
-
-#define CERF_IRQ_GPIO_CF_BVD2          IRQ_GPIO19
-#define CERF_IRQ_GPIO_CF_BVD1          IRQ_GPIO20
-#define CERF_IRQ_GPIO_CF_IRQ           IRQ_GPIO22
-#define CERF_IRQ_GPIO_CF_CD            IRQ_GPIO23
+#define CERF_GPIO_CF_BVD2              19
+#define CERF_GPIO_CF_BVD1              20
+#define CERF_GPIO_CF_RESET             21
+#define CERF_GPIO_CF_IRQ               22
+#define CERF_GPIO_CF_CD                        23
 
 #endif // _INCLUDE_CERF_H_
index 14f8382d06659a1ad0914a8d8029cb9ae6a9238d..5ebd469a31f236a892908e2af5858970aa5d4556 100644 (file)
 
 #include <mach/irqs.h>
 
-#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/
-#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */
-#define GPIO_PC_CD0    GPIO_GPIO(13) /* detect for socket 0 (active low) */
-#define GPIO_PC_CD1    GPIO_GPIO(14) /* detect for socket 1 (active low) */
-#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */
-#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */
+#define GPIO_PC_READY0 11 /* ready for socket 0 (active high)*/
+#define GPIO_PC_READY1 12 /* ready for socket 1 (active high) */
+#define GPIO_PC_CD0    13 /* detect for socket 0 (active low) */
+#define GPIO_PC_CD1    14 /* detect for socket 1 (active low) */
+#define GPIO_PC_RESET0 15 /* reset socket 0 */
+#define GPIO_PC_RESET1 16 /* reset socket 1 */
 
 #define NANOENGINE_IRQ_GPIO_PCI                IRQ_GPIO0
 #define NANOENGINE_IRQ_GPIO_PC_READY0  IRQ_GPIO11
index ec27d6e121404e3aa781a8fd49499635ddf19cc1..019f857a79384a49222bc115c7d651108967d889 100644 (file)
 #define SHANNON_GPIO_SENSE_12V         GPIO_GPIO (21)  /* Input, 12v flash unprotect detected */
 #define SHANNON_GPIO_DISP_EN           GPIO_GPIO (22)  /* out */
 /* XXX GPIO 23 unaccounted for */
-#define SHANNON_GPIO_EJECT_0           GPIO_GPIO (24)  /* in */
-#define SHANNON_IRQ_GPIO_EJECT_0       IRQ_GPIO24
-#define SHANNON_GPIO_EJECT_1           GPIO_GPIO (25)  /* in */
-#define SHANNON_IRQ_GPIO_EJECT_1       IRQ_GPIO25
-#define SHANNON_GPIO_RDY_0             GPIO_GPIO (26)  /* in */
-#define SHANNON_IRQ_GPIO_RDY_0         IRQ_GPIO26
-#define SHANNON_GPIO_RDY_1             GPIO_GPIO (27)  /* in */
-#define SHANNON_IRQ_GPIO_RDY_1         IRQ_GPIO27
+#define SHANNON_GPIO_EJECT_0           24              /* in */
+#define SHANNON_GPIO_EJECT_1           25              /* in */
+#define SHANNON_GPIO_RDY_0             26              /* in */
+#define SHANNON_GPIO_RDY_1             27              /* in */
 
 /* MCP UCB codec GPIO pins... */
 
index db28118103ebd3e0e8ef9c599abf87fdcc40095f..cdea671e8931ef618f5c8b6b28710bbb25b77048 100644 (file)
 
 
 /*---  PCMCIA  ---*/
-#define GPIO_CF_CD              GPIO_GPIO24
-#define GPIO_CF_IRQ             GPIO_GPIO1
-#define IRQ_GPIO_CF_IRQ         IRQ_GPIO1
-#define IRQ_GPIO_CF_CD          IRQ_GPIO24
+#define GPIO_CF_CD              24
+#define GPIO_CF_IRQ             1
 
 /*--- SmartCard ---*/
 #define GPIO_SMART_CARD                GPIO_GPIO10
index f9e3fb3a285b2ab06460542b0d5753e27d2a5dfa..bba3ab2066eefafbc580630f17beda79717d915a 100644 (file)
@@ -183,10 +183,14 @@ config PCMCIA_BCM63XX
 config PCMCIA_SOC_COMMON
        tristate
 
+config PCMCIA_SA11XX_BASE
+       tristate
+
 config PCMCIA_SA1100
        tristate "SA1100 support"
        depends on ARM && ARCH_SA1100 && PCMCIA
        select PCMCIA_SOC_COMMON
+       select PCMCIA_SA11XX_BASE
        help
          Say Y here to include support for SA11x0-based PCMCIA or CF
          sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
@@ -196,8 +200,9 @@ config PCMCIA_SA1100
 
 config PCMCIA_SA1111
        tristate "SA1111 support"
-       depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
+       depends on ARM && SA1111 && PCMCIA
        select PCMCIA_SOC_COMMON
+       select PCMCIA_SA11XX_BASE if ARCH_SA1100
        help
          Say Y  here to include support for SA1111-based PCMCIA or CF
          sockets, found on the Jornada 720, Graphicsmaster and other
@@ -213,6 +218,7 @@ config PCMCIA_PXA2XX
                    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
                    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
                    || MACH_COLIBRI320)
+       select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111
        select PCMCIA_SOC_COMMON
        help
          Say Y here to include support for the PXA2xx PCMCIA controller
index ec543a4ff2e4a5db60113814d4c1fe0d111919d2..47525de6a631f13fd36ffdaf06413258bb51c64d 100644 (file)
@@ -25,8 +25,9 @@ obj-$(CONFIG_I82092)                          += i82092.o
 obj-$(CONFIG_TCIC)                             += tcic.o
 obj-$(CONFIG_PCMCIA_M8XX)                      += m8xx_pcmcia.o
 obj-$(CONFIG_PCMCIA_SOC_COMMON)                        += soc_common.o
-obj-$(CONFIG_PCMCIA_SA1100)                    += sa11xx_base.o sa1100_cs.o
-obj-$(CONFIG_PCMCIA_SA1111)                    += sa11xx_base.o sa1111_cs.o
+obj-$(CONFIG_PCMCIA_SA11XX_BASE)               += sa11xx_base.o
+obj-$(CONFIG_PCMCIA_SA1100)                    += sa1100_cs.o
+obj-$(CONFIG_PCMCIA_SA1111)                    += sa1111_cs.o
 obj-$(CONFIG_M32R_PCC)                         += m32r_pcc.o
 obj-$(CONFIG_M32R_CFC)                         += m32r_cfc.o
 obj-$(CONFIG_PCMCIA_BCM63XX)                   += bcm63xx_pcmcia.o
@@ -39,9 +40,10 @@ obj-$(CONFIG_ELECTRA_CF)                     += electra_cf.o
 obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)          += db1xxx_ss.o
 
 sa1111_cs-y                                    += sa1111_generic.o
-sa1111_cs-$(CONFIG_ASSABET_NEPONSET)           += sa1100_neponset.o
-sa1111_cs-$(CONFIG_SA1100_BADGE4)              += sa1100_badge4.o
-sa1111_cs-$(CONFIG_SA1100_JORNADA720)          += sa1100_jornada720.o
+sa1111_cs-$(CONFIG_ASSABET_NEPONSET)           += sa1111_neponset.o
+sa1111_cs-$(CONFIG_SA1100_BADGE4)              += sa1111_badge4.o
+sa1111_cs-$(CONFIG_SA1100_JORNADA720)          += sa1111_jornada720.o
+sa1111_cs-$(CONFIG_ARCH_LUBBOCK)               += sa1111_lubbock.o
 
 sa1100_cs-y                                    += sa1100_generic.o
 sa1100_cs-$(CONFIG_SA1100_ASSABET)             += sa1100_assabet.o
@@ -52,9 +54,7 @@ sa1100_cs-$(CONFIG_SA1100_NANOENGINE)         += sa1100_nanoengine.o
 sa1100_cs-$(CONFIG_SA1100_SHANNON)             += sa1100_shannon.o
 sa1100_cs-$(CONFIG_SA1100_SIMPAD)              += sa1100_simpad.o
 
-pxa2xx_lubbock_cs-y                            += pxa2xx_lubbock.o sa1111_generic.o
 pxa2xx_cm_x2xx_cs-y                            += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
-pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK)              += pxa2xx_lubbock_cs.o
 pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)            += pxa2xx_mainstone.o
 pxa2xx-obj-$(CONFIG_PXA_SHARPSL)               += pxa2xx_sharpsl.o
 pxa2xx-obj-$(CONFIG_MACH_ARMCORE)              += pxa2xx_cm_x2xx_cs.o
index 22a75e610f122d15961847d01fd8d90c818208cc..2ef576c5b69d06a28808f7d17e48c1ff0334ab73 100644 (file)
 
 #include "soc_common.h"
 
-/*
- * These are a list of interrupt sources that provokes a polled
- * check of status
- */
-static struct pcmcia_irqs irqs[] = {
-       { 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" },
-       { 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" },
-};
-
 static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        uint16_t ver;
@@ -49,12 +40,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                        ver);
 
        skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ;
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
+       skt->stat[SOC_STAT_CD].gpio = BALLOON3_GPIO_S0_CD;
+       skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+       skt->stat[SOC_STAT_BVD1].irq = BALLOON3_BP_NSTSCHG_IRQ;
+       skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
 
-static void balloon3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       return 0;
 }
 
 static unsigned long balloon3_pcmcia_status[2] = {
@@ -85,13 +76,11 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                        disable_irq(BALLOON3_BP_NSTSCHG_IRQ);
        }
 
-       state->detect   = !gpio_get_value(BALLOON3_GPIO_S0_CD);
        state->ready    = !!(status & BALLOON3_CF_nIRQ);
        state->bvd1     = !!(status & BALLOON3_CF_nSTSCHG_BVD1);
        state->bvd2     = 0;    /* not available */
        state->vs_3v    = 1;    /* Always true its a CF card */
        state->vs_Xv    = 0;    /* not available */
-       state->wrprot   = 0;    /* not available */
 }
 
 static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
@@ -106,7 +95,6 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 static struct pcmcia_low_level balloon3_pcmcia_ops = {
        .owner                  = THIS_MODULE,
        .hw_init                = balloon3_pcmcia_hw_init,
-       .hw_shutdown            = balloon3_pcmcia_hw_shutdown,
        .socket_state           = balloon3_pcmcia_socket_state,
        .configure_socket       = balloon3_pcmcia_configure_socket,
        .first                  = 0,
index 64d433ec4fc6f78fb7350fe333831e4e8e35371a..66a54222bbf4d83a9ce45c0cf6dfac359cd1c230 100644 (file)
@@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
 
                skt->nr = ops->first + i;
                skt->clk = clk;
-               skt->ops = ops;
-               skt->socket.owner = ops->owner;
-               skt->socket.dev.parent = &dev->dev;
-               skt->socket.pci_irq = NO_IRQ;
+               soc_pcmcia_init_one(skt, ops, &dev->dev);
 
                ret = pxa2xx_drv_pcmcia_add_one(skt);
                if (ret)
index 31ab6ddf52c932c1791e87a874a2c6ace211e073..da40908b29dde1efa49cd4240d914b869bade9b8 100644 (file)
 #define GPIO_PCMCIA_S1_RDYINT  (8)
 #define GPIO_PCMCIA_RESET      (9)
 
-#define PCMCIA_S0_CD_VALID     gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
-#define PCMCIA_S1_CD_VALID     gpio_to_irq(GPIO_PCMCIA_S1_CD_VALID)
-#define PCMCIA_S0_RDYINT       gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
-#define PCMCIA_S1_RDYINT       gpio_to_irq(GPIO_PCMCIA_S1_RDYINT)
-
-
-static struct pcmcia_irqs irqs[] = {
-       { .sock = 0, .str = "PCMCIA0 CD" },
-       { .sock = 1, .str = "PCMCIA1 CD" },
-};
-
 static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
@@ -43,19 +32,23 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                return ret;
        gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-       skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
-       irqs[0].irq = PCMCIA_S0_CD_VALID;
-       irqs[1].irq = PCMCIA_S1_CD_VALID;
-       ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-       if (!ret)
-               gpio_free(GPIO_PCMCIA_RESET);
+       if (skt->nr == 0) {
+               skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+               skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
+               skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
+       } else {
+               skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
+               skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT;
+               skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY";
+       }
 
-       return ret;
+       return 0;
 }
 
 static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
        gpio_free(GPIO_PCMCIA_RESET);
 }
 
@@ -63,16 +56,8 @@ static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                       struct pcmcia_state *state)
 {
-       int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
-       int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
-
-       state->detect = !gpio_get_value(cd);
-       state->ready  = !!gpio_get_value(rdy);
-       state->bvd1   = 1;
-       state->bvd2   = 1;
        state->vs_3v  = 0;
        state->vs_Xv  = 0;
-       state->wrprot = 0;  /* not available */
 }
 
 
index 3dc7621a076701a843fe0722d0340db703830fa8..f59223f2307d0878bca779465f9c1ce56ffaf2f7 100644 (file)
 #define GPIO_PCMCIA_S0_RDYINT  (82)
 #define GPIO_PCMCIA_RESET      (53)
 
-#define PCMCIA_S0_CD_VALID     gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
-#define PCMCIA_S0_RDYINT       gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
-
-
-static struct pcmcia_irqs irqs[] = {
-       { .sock = 0, .str = "PCMCIA0 CD" },
-};
-
 static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
@@ -37,18 +29,16 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                return ret;
        gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-       skt->socket.pci_irq = PCMCIA_S0_RDYINT;
-       irqs[0].irq = PCMCIA_S0_CD_VALID;
-       ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-       if (!ret)
-               gpio_free(GPIO_PCMCIA_RESET);
+       skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
+       skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+       skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
+       skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
 
        return ret;
 }
 
 static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
        gpio_free(GPIO_PCMCIA_RESET);
 }
 
@@ -56,13 +46,8 @@ static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                       struct pcmcia_state *state)
 {
-       state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0;
-       state->ready  = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1;
-       state->bvd1   = 1;
-       state->bvd2   = 1;
        state->vs_3v  = 0;
        state->vs_Xv  = 0;
-       state->wrprot = 0;  /* not available */
 }
 
 
index c6dec572a05da6593bac0bce1777042393f66e03..4dee7b2a8032918ff6216134c23c8955ae5e6061 100644 (file)
@@ -53,13 +53,6 @@ static struct gpio colibri_pcmcia_gpios[] = {
        { 0,    GPIOF_INIT_HIGH,"PCMCIA Reset" },
 };
 
-static struct pcmcia_irqs colibri_irqs[] = {
-       {
-               .sock = 0,
-               .str  = "PCMCIA CD"
-       },
-};
-
 static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret;
@@ -69,19 +62,10 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        if (ret)
                goto err1;
 
-       colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
        skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
+       skt->stat[SOC_STAT_CD].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
+       skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
 
-       ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
-                                       ARRAY_SIZE(colibri_irqs));
-       if (ret)
-               goto err2;
-
-       return ret;
-
-err2:
-       gpio_free_array(colibri_pcmcia_gpios,
-                       ARRAY_SIZE(colibri_pcmcia_gpios));
 err1:
        return ret;
 }
@@ -100,7 +84,6 @@ static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
        state->ready  = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
        state->bvd1   = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
        state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
-       state->wrprot = 0;
        state->vs_3v  = 1;
        state->vs_Xv  = 0;
 }
index 17cd2ce7428f76881c3e20b6fca1eebbb5f246a6..8751a323b448e1069227a2d4d2399facea4949af 100644 (file)
 
 #include "soc_common.h"
 
-static struct pcmcia_irqs cd_irqs[] = {
-       {
-               .sock = 0,
-               .str  = "CF card detect"
-       },
-       {
-               .sock = 1,
-               .str  = "Wifi switch"
-       },
-};
-
 static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       if (skt->nr == 0)
-               skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY0);
-       else
-               skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY1);
-
-       cd_irqs[0].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD0);
-       cd_irqs[1].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD1);
-
-       return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1);
-}
+       if (skt->nr == 0) {
+               skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0;
+               skt->stat[SOC_STAT_CD].name = "CF card detect";
+               skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0;
+               skt->stat[SOC_STAT_RDY].name = "CF ready";
+       } else {
+               skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1;
+               skt->stat[SOC_STAT_CD].name = "Wifi switch";
+               skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1;
+               skt->stat[SOC_STAT_RDY].name = "Wifi ready";
+       }
 
-/*
- * Release all resources.
- */
-static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_free_irqs(skt, &cd_irqs[skt->nr], 1);
+       return 0;
 }
 
 static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                        struct pcmcia_state *state)
 {
-       if (skt->nr == 0) {
-               state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD0) ? 0 : 1;
-               state->ready  = gpio_get_value(GPIO_E740_PCMCIA_RDY0) ? 1 : 0;
-       } else {
-               state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD1) ? 0 : 1;
-               state->ready  = gpio_get_value(GPIO_E740_PCMCIA_RDY1) ? 1 : 0;
-       }
-
        state->vs_3v  = 1;
-       state->bvd1   = 1;
-       state->bvd2   = 1;
-       state->wrprot = 0;
        state->vs_Xv  = 0;
 }
 
@@ -109,32 +83,11 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-/*
- * Enable card status IRQs on (re-)initialisation.  This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-static void e740_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
-}
-
-/*
- * Disable card status IRQs on suspend.
- */
-static void e740_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
-}
-
 static struct pcmcia_low_level e740_pcmcia_ops = {
        .owner            = THIS_MODULE,
        .hw_init          = e740_pcmcia_hw_init,
-       .hw_shutdown      = e740_pcmcia_hw_shutdown,
        .socket_state     = e740_pcmcia_socket_state,
        .configure_socket = e740_pcmcia_configure_socket,
-       .socket_init      = e740_pcmcia_socket_init,
-       .socket_suspend   = e740_pcmcia_socket_suspend,
        .nr               = 2,
 };
 
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
deleted file mode 100644 (file)
index c21888e..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * linux/drivers/pcmcia/pxa2xx_lubbock.c
- *
- * Author:     George Davis
- * Created:    Jan 10, 2002
- * Copyright:  MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
- *
- * Lubbock PCMCIA specific routines.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
-#include <asm/mach-types.h>
-#include <mach/lubbock.h>
-
-#include "sa1111_generic.h"
-
-static int
-lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
-                               const socket_state_t *state)
-{
-       struct sa1111_pcmcia_socket *s = to_skt(skt);
-       unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
-       int ret = 0;
-
-       pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
-
-       /* Lubbock uses the Maxim MAX1602, with the following connections:
-        *
-        * Socket 0 (PCMCIA):
-        *      MAX1602 Lubbock         Register
-        *      Pin     Signal
-        *      -----   -------         ----------------------
-        *      A0VPP   S0_PWR0         SA-1111 GPIO A<0>
-        *      A1VPP   S0_PWR1         SA-1111 GPIO A<1>
-        *      A0VCC   S0_PWR2         SA-1111 GPIO A<2>
-        *      A1VCC   S0_PWR3         SA-1111 GPIO A<3>
-        *      VX      VCC
-        *      VY      +3.3V
-        *      12IN    +12V
-        *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
-        *
-        * Socket 1 (CF):
-        *      MAX1602 Lubbock         Register
-        *      Pin     Signal
-        *      -----   -------         ----------------------
-        *      A0VPP   GND             VPP is not connected
-        *      A1VPP   GND             VPP is not connected
-        *      A0VCC   S1_PWR0         MISC_WR<14>
-        *      A1VCC   S1_PWR1         MISC_WR<15>
-        *      VX      VCC
-        *      VY      +3.3V
-        *      12IN    GND             VPP is not connected
-        *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
-        *
-        */
-
- again:
-       switch (skt->nr) {
-       case 0:
-               pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-               switch (state->Vcc) {
-               case 0: /* Hi-Z */
-                       break;
-
-               case 33: /* VY */
-                       pa_dwr_set |= GPIO_A3;
-                       break;
-
-               case 50: /* VX */
-                       pa_dwr_set |= GPIO_A2;
-                       break;
-
-               default:
-                       printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                              __func__, state->Vcc);
-                       ret = -1;
-               }
-
-               switch (state->Vpp) {
-               case 0: /* Hi-Z */
-                       break;
-
-               case 120: /* 12IN */
-                       pa_dwr_set |= GPIO_A1;
-                       break;
-
-               default: /* VCC */
-                       if (state->Vpp == state->Vcc)
-                               pa_dwr_set |= GPIO_A0;
-                       else {
-                               printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-                                      __func__, state->Vpp);
-                               ret = -1;
-                               break;
-                       }
-               }
-               break;
-
-       case 1:
-               misc_mask = (1 << 15) | (1 << 14);
-
-               switch (state->Vcc) {
-               case 0: /* Hi-Z */
-                       break;
-
-               case 33: /* VY */
-                       misc_set |= 1 << 15;
-                       break;
-
-               case 50: /* VX */
-                       misc_set |= 1 << 14;
-                       break;
-
-               default:
-                       printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-                              __func__, state->Vcc);
-                       ret = -1;
-                       break;
-               }
-
-               if (state->Vpp != state->Vcc && state->Vpp != 0) {
-                       printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-                              __func__, state->Vpp);
-                       ret = -1;
-                       break;
-               }
-               break;
-
-       default:
-               ret = -1;
-       }
-
-       if (ret == 0)
-               ret = sa1111_pcmcia_configure_socket(skt, state);
-
-       if (ret == 0) {
-               lubbock_set_misc_wr(misc_mask, misc_set);
-               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-       }
-
-#if 1
-       if (ret == 0 && state->Vcc == 33) {
-               struct pcmcia_state new_state;
-
-               /*
-                * HACK ALERT:
-                * We can't sense the voltage properly on Lubbock before
-                * actually applying some power to the socket (catch 22).
-                * Resense the socket Voltage Sense pins after applying
-                * socket power.
-                *
-                * Note: It takes about 2.5ms for the MAX1602 VCC output
-                * to rise.
-                */
-               mdelay(3);
-
-               sa1111_pcmcia_socket_state(skt, &new_state);
-
-               if (!new_state.vs_3v && !new_state.vs_Xv) {
-                       /*
-                        * Switch to 5V,  Configure socket with 5V voltage
-                        */
-                       lubbock_set_misc_wr(misc_mask, 0);
-                       sa1111_set_io(s->dev, pa_dwr_mask, 0);
-
-                       /*
-                        * It takes about 100ms to turn off Vcc.
-                        */
-                       mdelay(100);
-
-                       /*
-                        * We need to hack around the const qualifier as
-                        * well to keep this ugly workaround localized and
-                        * not force it to the rest of the code. Barf bags
-                        * available in the seat pocket in front of you!
-                        */
-                       ((socket_state_t *)state)->Vcc = 50;
-                       ((socket_state_t *)state)->Vpp = 50;
-                       goto again;
-               }
-       }
-#endif
-
-       return ret;
-}
-
-static struct pcmcia_low_level lubbock_pcmcia_ops = {
-       .owner                  = THIS_MODULE,
-       .configure_socket       = lubbock_pcmcia_configure_socket,
-       .socket_init            = sa1111_pcmcia_socket_init,
-       .first                  = 0,
-       .nr                     = 2,
-};
-
-#include "pxa2xx_base.h"
-
-int pcmcia_lubbock_init(struct sa1111_dev *sadev)
-{
-       int ret = -ENODEV;
-
-       if (machine_is_lubbock()) {
-               /*
-                * Set GPIO_A<3:0> to be outputs for the MAX1600,
-                * and switch to standby mode.
-                */
-               sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-               sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-               sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-
-               /* Set CF Socket 1 power to standby mode. */
-               lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
-
-               pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
-               pxa2xx_configure_sockets(&sadev->dev);
-               ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
-                               pxa2xx_drv_pcmcia_add_one);
-       }
-
-       return ret;
-}
-
-MODULE_LICENSE("GPL");
index aded706c0b9fa941a98a94ff84a3881f38a1da42..7e32e25cdcb29d20965d2e7843bf0a8d3b8bf8a2 100644 (file)
 #include "soc_common.h"
 
 
-static struct pcmcia_irqs irqs[] = {
-       { 0, MAINSTONE_S0_CD_IRQ, "PCMCIA0 CD" },
-       { 1, MAINSTONE_S1_CD_IRQ, "PCMCIA1 CD" },
-       { 0, MAINSTONE_S0_STSCHG_IRQ, "PCMCIA0 STSCHG" },
-       { 1, MAINSTONE_S1_STSCHG_IRQ, "PCMCIA1 STSCHG" },
-};
-
 static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        /*
         * Setup default state of GPIO outputs
         * before we enable them as outputs.
         */
-
-       skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void mst_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       if (skt->nr == 0) {
+               skt->socket.pci_irq = MAINSTONE_S0_IRQ;
+               skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+               skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ;
+               skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
+       } else {
+               skt->socket.pci_irq = MAINSTONE_S1_IRQ;
+               skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
+               skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ;
+               skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG";
+       }
+       return 0;
 }
 
 static unsigned long mst_pcmcia_status[2];
@@ -84,7 +83,6 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
        state->bvd2   = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0;
        state->vs_3v  = (status & MST_PCMCIA_nVS1) ? 0 : 1;
        state->vs_Xv  = (status & MST_PCMCIA_nVS2) ? 0 : 1;
-       state->wrprot = 0;  /* not available */
 }
 
 static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
@@ -131,7 +129,6 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
        .owner                  = THIS_MODULE,
        .hw_init                = mst_pcmcia_hw_init,
-       .hw_shutdown            = mst_pcmcia_hw_shutdown,
        .socket_state           = mst_pcmcia_socket_state,
        .configure_socket       = mst_pcmcia_configure_socket,
        .nr                     = 2,
index 6a8e011a8c130b0e2a3df3d832bf896ab867ccb0..ed7d4dbc39faf69a050d104acd79eb9b2472603a 100644 (file)
@@ -23,7 +23,6 @@
 static struct gpio palmld_pcmcia_gpios[] = {
        { GPIO_NR_PALMLD_PCMCIA_POWER,  GPIOF_INIT_LOW, "PCMCIA Power" },
        { GPIO_NR_PALMLD_PCMCIA_RESET,  GPIOF_INIT_HIGH,"PCMCIA Reset" },
-       { GPIO_NR_PALMLD_PCMCIA_READY,  GPIOF_IN,       "PCMCIA Ready" },
 };
 
 static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
@@ -33,7 +32,8 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        ret = gpio_request_array(palmld_pcmcia_gpios,
                                ARRAY_SIZE(palmld_pcmcia_gpios));
 
-       skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMLD_PCMCIA_READY);
+       skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY;
+       skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 
        return ret;
 }
@@ -47,10 +47,6 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                        struct pcmcia_state *state)
 {
        state->detect = 1; /* always inserted */
-       state->ready  = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
-       state->bvd1   = 1;
-       state->bvd2   = 1;
-       state->wrprot = 0;
        state->vs_3v  = 1;
        state->vs_Xv  = 0;
 }
index 9e38de769ba3b30cbcd3d8f067783f1f314ab488..81225a7a8cbbdb893bb2b3b163b4d5d8c90683f0 100644 (file)
@@ -26,7 +26,6 @@ static struct gpio palmtc_pcmcia_gpios[] = {
        { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
        { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" },
        { GPIO_NR_PALMTC_PCMCIA_RESET,  GPIOF_INIT_HIGH,"PCMCIA Reset" },
-       { GPIO_NR_PALMTC_PCMCIA_READY,  GPIOF_IN,       "PCMCIA Ready" },
        { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN,     "PCMCIA Power Ready" },
 };
 
@@ -37,7 +36,8 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        ret = gpio_request_array(palmtc_pcmcia_gpios,
                                ARRAY_SIZE(palmtc_pcmcia_gpios));
 
-       skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTC_PCMCIA_READY);
+       skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY;
+       skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 
        return ret;
 }
@@ -51,10 +51,6 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                        struct pcmcia_state *state)
 {
        state->detect = 1; /* always inserted */
-       state->ready  = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY);
-       state->bvd1   = 1;
-       state->bvd2   = 1;
-       state->wrprot = 0;
        state->vs_3v  = 1;
        state->vs_Xv  = 0;
 }
index 80645a688ee3cf7b2fc3ddc1e55ddda02058e842..069b6bbcf319ec8022a7474c463947ebc9581397 100644 (file)
@@ -23,7 +23,6 @@ static struct gpio palmtx_pcmcia_gpios[] = {
        { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
        { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
        { GPIO_NR_PALMTX_PCMCIA_RESET,  GPIOF_INIT_HIGH,"PCMCIA Reset" },
-       { GPIO_NR_PALMTX_PCMCIA_READY,  GPIOF_IN,       "PCMCIA Ready" },
 };
 
 static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
@@ -33,7 +32,8 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        ret = gpio_request_array(palmtx_pcmcia_gpios,
                                ARRAY_SIZE(palmtx_pcmcia_gpios));
 
-       skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
+       skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTX_PCMCIA_READY;
+       skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 
        return ret;
 }
@@ -47,10 +47,6 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                        struct pcmcia_state *state)
 {
        state->detect = 1; /* always inserted */
-       state->ready  = !!gpio_get_value(GPIO_NR_PALMTX_PCMCIA_READY);
-       state->bvd1   = 1;
-       state->bvd2   = 1;
-       state->wrprot = 0;
        state->vs_3v  = 1;
        state->vs_Xv  = 0;
 }
index 69ae2fd22400a7b9db6f59420f90b9c29dfd5ade..b066273b6b4f4dc5a87ee9c37ee589938f8b0d39 100644 (file)
@@ -46,21 +46,9 @@ static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt)
 
 static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       int ret;
-
-       /* Register interrupts */
        if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
-               struct pcmcia_irqs cd_irq;
-
-               cd_irq.sock = skt->nr;
-               cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq;
-               cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str;
-               ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
-
-               if (ret) {
-                       printk(KERN_ERR "Request for Compact Flash IRQ failed\n");
-                       return ret;
-               }
+               skt->stat[SOC_STAT_CD].irq = SCOOP_DEV[skt->nr].cd_irq;
+               skt->stat[SOC_STAT_CD].name = SCOOP_DEV[skt->nr].cd_irq_str;
        }
 
        skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
@@ -68,19 +56,6 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        return 0;
 }
 
-static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
-               struct pcmcia_irqs cd_irq;
-
-               cd_irq.sock = skt->nr;
-               cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq;
-               cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str;
-               soc_pcmcia_free_irqs(skt, &cd_irq, 1);
-       }
-}
-
-
 static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                    struct pcmcia_state *state)
 {
@@ -222,7 +197,6 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = {
        .owner                  = THIS_MODULE,
        .hw_init                = sharpsl_pcmcia_hw_init,
-       .hw_shutdown            = sharpsl_pcmcia_hw_shutdown,
        .socket_state           = sharpsl_pcmcia_socket_state,
        .configure_socket       = sharpsl_pcmcia_configure_socket,
        .socket_init            = sharpsl_pcmcia_socket_init,
index 6c2366b74a35957af5c471ce10f2f2e10b9ccb12..1d73c4401fdd6ecc1a3a8c171bd11379dcc322c8 100644 (file)
 #define SG2_S0_GPIO_DETECT     53
 #define SG2_S0_GPIO_READY      81
 
-static struct pcmcia_irqs irqs[] = {
-       {.sock = 0, .str = "PCMCIA0 CD" },
-};
-
 static struct gpio sg2_pcmcia_gpios[] = {
        { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },
        { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" },
@@ -44,27 +40,20 @@ static struct gpio sg2_pcmcia_gpios[] = {
 
 static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->socket.pci_irq = gpio_to_irq(SG2_S0_GPIO_READY);
-       irqs[0].irq = gpio_to_irq(SG2_S0_GPIO_DETECT);
-
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT;
+       skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+       skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY;
+       skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
+       return 0;
 }
 
 static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                    struct pcmcia_state *state)
 {
-       state->detect = !gpio_get_value(SG2_S0_GPIO_DETECT);
-       state->ready  = !!gpio_get_value(SG2_S0_GPIO_READY);
        state->bvd1   = 0; /* not available - battery detect on card */
        state->bvd2   = 0; /* not available */
        state->vs_3v  = 1; /* not available - voltage detect for card */
        state->vs_Xv  = 0; /* not available */
-       state->wrprot = 0; /* not available - write protect */
 }
 
 static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
@@ -94,24 +83,11 @@ static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static struct pcmcia_low_level sg2_pcmcia_ops __initdata = {
        .owner                  = THIS_MODULE,
        .hw_init                = sg2_pcmcia_hw_init,
-       .hw_shutdown            = sg2_pcmcia_hw_shutdown,
        .socket_state           = sg2_pcmcia_socket_state,
        .configure_socket       = sg2_pcmcia_configure_socket,
-       .socket_init            = sg2_pcmcia_socket_init,
-       .socket_suspend         = sg2_pcmcia_socket_suspend,
        .nr                     = 1,
 };
 
index 7c33f898135ab165bf876d3267f072ef40ad282b..d326ba1fa1ce10cbd95fd198c6968d1bea6236b3 100644 (file)
 
 extern void board_pcmcia_power(int power);
 
-static struct pcmcia_irqs irqs[] = {
-       { .sock = 0, .str = "cs0_cd" }
-       /* on other baseboards we can have more inputs */
-};
-
 static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       int ret, i;
        /* we dont have voltage/card/ready detection
         * so we dont need interrupts for it
         */
        switch (skt->nr) {
        case 0:
-               if (gpio_request(GPIO_PRDY, "cf_irq") < 0) {
-                       pr_err("%s: sock %d unable to request gpio %d\n", __func__,
-                               skt->nr, GPIO_PRDY);
-                       return -EBUSY;
-               }
-               if (gpio_direction_input(GPIO_PRDY) < 0) {
-                       pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
-                               skt->nr, GPIO_PRDY);
-                       gpio_free(GPIO_PRDY);
-                       return -EINVAL;
-               }
-               skt->socket.pci_irq = gpio_to_irq(GPIO_PRDY);
-               irqs[0].irq = gpio_to_irq(GPIO_PCD);
+               skt->stat[SOC_STAT_CD].gpio = GPIO_PCD;
+               skt->stat[SOC_STAT_CD].name = "cs0_cd";
+               skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY;
+               skt->stat[SOC_STAT_RDY].name = "cs0_rdy";
                break;
        default:
                break;
@@ -62,39 +47,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        /* release the reset of this card */
        pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
 
-       /* supplementory irqs for the socket */
-       for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-               if (irqs[i].sock != skt->nr)
-                       continue;
-               if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) {
-                       pr_err("%s: sock %d unable to request gpio %d\n",
-                               __func__, skt->nr, irq_to_gpio(irqs[i].irq));
-                       ret = -EBUSY;
-                       goto error;
-               }
-               if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) {
-                       pr_err("%s: sock %d unable to set input gpio %d\n",
-                               __func__, skt->nr, irq_to_gpio(irqs[i].irq));
-                       ret = -EINVAL;
-                       goto error;
-               }
-       }
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
-error:
-       for (; i >= 0; i--) {
-               gpio_free(irq_to_gpio(irqs[i].irq));
-       }
-       return (ret);
-}
-
-static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       int i;
-       /* free allocated gpio's */
-       gpio_free(GPIO_PRDY);
-       for (i = 0; i < ARRAY_SIZE(irqs); i++)
-               gpio_free(irq_to_gpio(irqs[i].irq));
+       return 0;
 }
 
 static unsigned long trizeps_pcmcia_status[2];
@@ -118,13 +71,10 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
        switch (skt->nr) {
        case 0:
                /* just fill in fix states */
-               state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
-               state->ready  = gpio_get_value(GPIO_PRDY) ? 1 : 0;
                state->bvd1   = (status & ConXS_CFSR_BVD1) ? 1 : 0;
                state->bvd2   = (status & ConXS_CFSR_BVD2) ? 1 : 0;
                state->vs_3v  = (status & ConXS_CFSR_VS1) ? 0 : 1;
                state->vs_Xv  = (status & ConXS_CFSR_VS2) ? 0 : 1;
-               state->wrprot = 0;      /* not available */
                break;
 
 #ifndef CONFIG_MACH_TRIZEPS_CONXS
@@ -136,7 +86,6 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                state->bvd2   = 0;
                state->vs_3v  = 0;
                state->vs_Xv  = 0;
-               state->wrprot = 0;
                break;
 
 #endif
@@ -204,7 +153,6 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 static struct pcmcia_low_level trizeps_pcmcia_ops = {
        .owner                  = THIS_MODULE,
        .hw_init                = trizeps_pcmcia_hw_init,
-       .hw_shutdown            = trizeps_pcmcia_hw_shutdown,
        .socket_state           = trizeps_pcmcia_socket_state,
        .configure_socket       = trizeps_pcmcia_configure_socket,
        .socket_init            = trizeps_pcmcia_socket_init,
index 1064b1c2869d002634b92dfbd7ffa5709825b8bc..adfae4987a42a7077242ccceedcc9af1df6b2d2d 100644 (file)
 
 static struct platform_device *arcom_pcmcia_dev;
 
-static struct pcmcia_irqs irqs[] = {
-       {
-               .sock   = 0,
-               .str    = "PCMCIA_CD",
-       },
-};
-
 static inline struct arcom_pcmcia_pdata *viper_get_pdata(void)
 {
        return arcom_pcmcia_dev->dev.platform_data;
@@ -49,38 +42,28 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
        unsigned long flags;
 
-       skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio);
-       irqs[0].irq = gpio_to_irq(pdata->cd_gpio);
-
-       if (gpio_request(pdata->cd_gpio, "CF detect"))
-               goto err_request_cd;
-
-       if (gpio_request(pdata->rdy_gpio, "CF ready"))
-               goto err_request_rdy;
+       skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio;
+       skt->stat[SOC_STAT_CD].name = "PCMCIA_CD";
+       skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio;
+       skt->stat[SOC_STAT_RDY].name = "CF ready";
 
        if (gpio_request(pdata->pwr_gpio, "CF power"))
                goto err_request_pwr;
 
        local_irq_save(flags);
 
-       if (gpio_direction_output(pdata->pwr_gpio, 0) ||
-           gpio_direction_input(pdata->cd_gpio) ||
-           gpio_direction_input(pdata->rdy_gpio)) {
+       if (gpio_direction_output(pdata->pwr_gpio, 0)) {
                local_irq_restore(flags);
                goto err_dir;
        }
 
        local_irq_restore(flags);
 
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       return 0;
 
 err_dir:
        gpio_free(pdata->pwr_gpio);
 err_request_pwr:
-       gpio_free(pdata->rdy_gpio);
-err_request_rdy:
-       gpio_free(pdata->cd_gpio);
-err_request_cd:
        dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n");
        return -1;
 }
@@ -92,22 +75,12 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
        struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
 
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
        gpio_free(pdata->pwr_gpio);
-       gpio_free(pdata->rdy_gpio);
-       gpio_free(pdata->cd_gpio);
 }
 
 static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                      struct pcmcia_state *state)
 {
-       struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
-
-       state->detect = !gpio_get_value(pdata->cd_gpio);
-       state->ready  = !!gpio_get_value(pdata->rdy_gpio);
-       state->bvd1   = 1;
-       state->bvd2   = 1;
-       state->wrprot = 0;
        state->vs_3v  = 1; /* Can only apply 3.3V */
        state->vs_Xv  = 0;
 }
index 61b17d235dbe9ee12d7d584f9fbf9943644f7f23..a47dcd24a26a3eab642cc7a9671e5128f581d7a1 100644 (file)
 #include "soc_common.h"
 
 static struct gpio vpac270_pcmcia_gpios[] = {
-       { GPIO84_VPAC270_PCMCIA_CD,     GPIOF_IN,       "PCMCIA Card Detect" },
-       { GPIO35_VPAC270_PCMCIA_RDY,    GPIOF_IN,       "PCMCIA Ready" },
        { GPIO107_VPAC270_PCMCIA_PPEN,  GPIOF_INIT_LOW, "PCMCIA PPEN" },
        { GPIO11_VPAC270_PCMCIA_RESET,  GPIOF_INIT_LOW, "PCMCIA Reset" },
 };
 
 static struct gpio vpac270_cf_gpios[] = {
-       { GPIO17_VPAC270_CF_CD,         GPIOF_IN,       "CF Card Detect" },
-       { GPIO12_VPAC270_CF_RDY,        GPIOF_IN,       "CF Ready" },
        { GPIO16_VPAC270_CF_RESET,      GPIOF_INIT_LOW, "CF Reset" },
 };
 
-static struct pcmcia_irqs cd_irqs[] = {
-       {
-               .sock = 0,
-               .str  = "PCMCIA CD"
-       },
-       {
-               .sock = 1,
-               .str  = "CF CD"
-       },
-};
-
 static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        int ret;
@@ -54,20 +39,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                ret = gpio_request_array(vpac270_pcmcia_gpios,
                                ARRAY_SIZE(vpac270_pcmcia_gpios));
 
-               skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
-               cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD);
-
-               if (!ret)
-                       ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
+               skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
+               skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY;
+               skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
        } else {
                ret = gpio_request_array(vpac270_cf_gpios,
                                ARRAY_SIZE(vpac270_cf_gpios));
 
-               skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
-               cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD);
-
-               if (!ret)
-                       ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
+               skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD;
+               skt->stat[SOC_STAT_CD].name = "CF CD";
+               skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY;
+               skt->stat[SOC_STAT_RDY].name = "CF Ready";
        }
 
        return ret;
@@ -86,16 +69,6 @@ static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                                        struct pcmcia_state *state)
 {
-       if (skt->nr == 0) {
-               state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD);
-               state->ready  = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY);
-       } else {
-               state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD);
-               state->ready  = !!gpio_get_value(GPIO12_VPAC270_CF_RDY);
-       }
-       state->bvd1   = 1;
-       state->bvd2   = 1;
-       state->wrprot = 0;
        state->vs_3v  = 1;
        state->vs_Xv  = 0;
 }
@@ -117,14 +90,6 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level vpac270_pcmcia_ops = {
        .owner                  = THIS_MODULE,
 
@@ -136,9 +101,6 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = {
 
        .socket_state           = vpac270_pcmcia_socket_state,
        .configure_socket       = vpac270_pcmcia_configure_socket,
-
-       .socket_init            = vpac270_pcmcia_socket_init,
-       .socket_suspend         = vpac270_pcmcia_socket_suspend,
 };
 
 static struct platform_device *vpac270_pcmcia_device;
index f1e882272ab0e7f2c2c83dce6e271ce04f12c911..ba8557eea6183d0356aaf92eceeff97dd067401b 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
-#include <asm/signal.h>
 #include <mach/assabet.h>
 
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs[] = {
-       { 1, ASSABET_IRQ_GPIO_CF_CD,   "CF CD"   },
-       { 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" },
-       { 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" },
-};
-
 static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ;
-
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
+       skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD;
+       skt->stat[SOC_STAT_CD].name = "CF CD";
+       skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1;
+       skt->stat[SOC_STAT_BVD1].name = "CF BVD1";
+       skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2;
+       skt->stat[SOC_STAT_BVD2].name = "CF BVD2";
+       skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ;
+       skt->stat[SOC_STAT_RDY].name = "CF RDY";
 
-/*
- * Release all resources.
- */
-static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       return 0;
 }
 
 static void
 assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-       unsigned long levels = GPLR;
-
-       state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
-       state->ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
-       state->bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
-       state->bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
-       state->wrprot = 0; /* Not available on Assabet. */
        state->vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
        state->vs_Xv  = 0;
 }
@@ -78,38 +62,24 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat
                return -1;
        }
 
-       /* Silently ignore Vpp, output enable, speaker enable. */
+       /* Silently ignore Vpp, speaker enable. */
 
        if (state->flags & SS_RESET)
                mask |= ASSABET_BCR_CF_RST;
+       if (!(state->flags & SS_OUTPUT_ENA))
+               mask |= ASSABET_BCR_CF_BUS_OFF;
 
-       ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask);
+       ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
+                       ASSABET_BCR_CF_BUS_OFF, mask);
 
        return 0;
 }
 
-/*
- * Enable card status IRQs on (re-)initialisation.  This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       /*
-        * Enable CF bus
-        */
-       ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
-
-       soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 /*
  * Disable card status IRQs on suspend.
  */
 static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
        /*
         * Tristate the CF bus signals.  Also assert CF
         * reset as per user guide page 4-11.
@@ -119,14 +89,9 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 
 static struct pcmcia_low_level assabet_pcmcia_ops = { 
        .owner                  = THIS_MODULE,
-
        .hw_init                = assabet_pcmcia_hw_init,
-       .hw_shutdown            = assabet_pcmcia_hw_shutdown,
-
        .socket_state           = assabet_pcmcia_socket_state,
        .configure_socket       = assabet_pcmcia_configure_socket,
-
-       .socket_init            = assabet_pcmcia_socket_init,
        .socket_suspend         = assabet_pcmcia_socket_suspend,
 };
 
diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c
deleted file mode 100644 (file)
index 1ce53f4..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * linux/drivers/pcmcia/sa1100_badge4.c
- *
- * BadgePAD 4 PCMCIA specific routines
- *
- *   Christopher Hoover <ch@hpl.hp.com>
- *
- * Copyright (C) 2002 Hewlett-Packard Company
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <mach/badge4.h>
-#include <asm/hardware/sa1111.h>
-
-#include "sa1111_generic.h"
-
-/*
- * BadgePAD 4 Details
- *
- * PCM Vcc:
- *
- *  PCM Vcc on BadgePAD 4 can be jumpered for 3v3 (short pins 1 and 3
- *  on JP6) or 5v0 (short pins 3 and 5 on JP6).
- *
- * PCM Vpp:
- *
- *  PCM Vpp on BadgePAD 4 can be jumpered for 12v0 (short pins 4 and 6
- *  on JP6) or tied to PCM Vcc (short pins 2 and 4 on JP6).  N.B.,
- *  12v0 operation requires that the power supply actually supply 12v0
- *  via pin 7 of JP7.
- *
- * CF Vcc:
- *
- *  CF Vcc on BadgePAD 4 can be jumpered either for 3v3 (short pins 1
- *  and 2 on JP10) or 5v0 (short pins 2 and 3 on JP10).
- *
- * Unfortunately there's no way programmatically to determine how a
- * given board is jumpered.  This code assumes a default jumpering
- * as described below.
- *
- * If the defaults aren't correct, you may override them with a pcmv
- * setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf vcc>.  The units are
- * tenths of volts; e.g. pcmv=33,120,50 indicates 3v3 PCM Vcc, 12v0
- * PCM Vpp, and 5v0 CF Vcc.
- *
- */
-
-static int badge4_pcmvcc = 50;  /* pins 3 and 5 jumpered on JP6 */
-static int badge4_pcmvpp = 50;  /* pins 2 and 4 jumpered on JP6 */
-static int badge4_cfvcc = 33;   /* pins 1 and 2 jumpered on JP10 */
-
-static void complain_about_jumpering(const char *whom,
-                                    const char *supply,
-                                    int given, int wanted)
-{
-       printk(KERN_ERR
-        "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
-        "; re-jumper the board and/or use pcmv=xx,xx,xx\n",
-              whom, supply,
-              wanted / 10, wanted % 10,
-              supply,
-              given / 10, given % 10);
-}
-
-static int
-badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-       int ret;
-
-       switch (skt->nr) {
-       case 0:
-               if ((state->Vcc != 0) &&
-                   (state->Vcc != badge4_pcmvcc)) {
-                       complain_about_jumpering(__func__, "pcmvcc",
-                                                badge4_pcmvcc, state->Vcc);
-                       // Apply power regardless of the jumpering.
-                       // return -1;
-               }
-               if ((state->Vpp != 0) &&
-                   (state->Vpp != badge4_pcmvpp)) {
-                       complain_about_jumpering(__func__, "pcmvpp",
-                                                badge4_pcmvpp, state->Vpp);
-                       return -1;
-               }
-               break;
-
-       case 1:
-               if ((state->Vcc != 0) &&
-                   (state->Vcc != badge4_cfvcc)) {
-                       complain_about_jumpering(__func__, "cfvcc",
-                                                badge4_cfvcc, state->Vcc);
-                       return -1;
-               }
-               break;
-
-       default:
-               return -1;
-       }
-
-       ret = sa1111_pcmcia_configure_socket(skt, state);
-       if (ret == 0) {
-               unsigned long flags;
-               int need5V;
-
-               local_irq_save(flags);
-
-               need5V = ((state->Vcc == 50) || (state->Vpp == 50));
-
-               badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V);
-
-               local_irq_restore(flags);
-       }
-
-       return 0;
-}
-
-static struct pcmcia_low_level badge4_pcmcia_ops = {
-       .owner                  = THIS_MODULE,
-       .configure_socket       = badge4_pcmcia_configure_socket,
-       .socket_init            = sa1111_pcmcia_socket_init,
-       .first                  = 0,
-       .nr                     = 2,
-};
-
-int pcmcia_badge4_init(struct device *dev)
-{
-       int ret = -ENODEV;
-
-       if (machine_is_badge4()) {
-               printk(KERN_INFO
-                      "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n",
-                      __func__,
-                      badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
-
-               sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
-               ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
-                               sa11xx_drv_pcmcia_add_one);
-       }
-
-       return ret;
-}
-
-static int __init pcmv_setup(char *s)
-{
-       int v[4];
-
-       s = get_options(s, ARRAY_SIZE(v), v);
-
-       if (v[0] >= 1) badge4_pcmvcc = v[1];
-       if (v[0] >= 2) badge4_pcmvpp = v[2];
-       if (v[0] >= 3) badge4_cfvcc = v[3];
-
-       return 1;
-}
-
-__setup("pcmv=", pcmv_setup);
index 30560df8c76b6893151ae1f22654492177bdb78f..c59c44921a3a94f7093850660fd644c8b465a826 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 
 #define CERF_SOCKET    1
 
-static struct pcmcia_irqs irqs[] = {
-       { CERF_SOCKET, CERF_IRQ_GPIO_CF_CD,   "CF_CD"   },
-       { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" },
-       { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" }
-};
-
 static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ;
+       int ret;
+
+       ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET");
+       if (ret)
+               return ret;
+
+       skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD;
+       skt->stat[SOC_STAT_CD].name = "CF_CD";
+       skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1;
+       skt->stat[SOC_STAT_BVD1].name = "CF_BVD1";
+       skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2;
+       skt->stat[SOC_STAT_BVD2].name = "CF_BVD2";
+       skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ;
+       skt->stat[SOC_STAT_RDY].name = "CF_IRQ";
 
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       return 0;
 }
 
 static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       gpio_free(CERF_GPIO_CF_RESET);
 }
 
 static void
 cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-       unsigned long levels = GPLR;
-
-       state->detect   = (levels & CERF_GPIO_CF_CD)  ?0:1;
-       state->ready    = (levels & CERF_GPIO_CF_IRQ) ?1:0;
-       state->bvd1     = (levels & CERF_GPIO_CF_BVD1)?1:0;
-       state->bvd2     = (levels & CERF_GPIO_CF_BVD2)?1:0;
-       state->wrprot   = 0;
        state->vs_3v    = 1;
        state->vs_Xv    = 0;
 }
@@ -67,34 +68,17 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                return -1;
        }
 
-       if (state->flags & SS_RESET) {
-               GPSR = CERF_GPIO_CF_RESET;
-       } else {
-               GPCR = CERF_GPIO_CF_RESET;
-       }
+       gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET));
 
        return 0;
 }
 
-static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static struct pcmcia_low_level cerf_pcmcia_ops = { 
        .owner                  = THIS_MODULE,
        .hw_init                = cerf_pcmcia_hw_init,
        .hw_shutdown            = cerf_pcmcia_hw_shutdown,
        .socket_state           = cerf_pcmcia_socket_state,
        .configure_socket       = cerf_pcmcia_configure_socket,
-
-       .socket_init            = cerf_pcmcia_socket_init,
-       .socket_suspend         = cerf_pcmcia_socket_suspend,
 };
 
 int __devinit pcmcia_cerf_init(struct device *dev)
index edf8f00288987c539595ed5fa5522f8e0d196953..d9c7337b909ce3fb06b0609aa4eef81bf2cf5e28 100644 (file)
 
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs[] = {
-       { .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)
 {
        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);
+               skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA CD0";
+               skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0;
+               skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0";
 
                err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
                if (err)
-                       goto err02;
+                       goto err01;
                err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
                if (err)
                        goto err03;
@@ -68,32 +52,14 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                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;
+               skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA CD1";
+               skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1;
+               skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1";
                break;
        }
        return 0;
@@ -102,19 +68,12 @@ 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;
+       return err;
 }
 
 static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-  
        switch (skt->nr) {
        case 0:
                /* Disable CF bus: */
@@ -126,12 +85,8 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
                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;
        }
 }
@@ -139,27 +94,10 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void
 h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-       switch (skt->nr) {
-       case 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. */
-               state->vs_3v = 0;
-               state->vs_Xv = 0;
-               break;
-
-       case 1:
-               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. */
-               state->vs_3v = 0;
-               state->vs_Xv = 0;
-               break;
-       }
+       state->bvd1 = 0;
+       state->bvd2 = 0;
+       state->vs_3v = 0;
+       state->vs_Xv = 0;
 }
 
 static int
@@ -186,14 +124,10 @@ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
        gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);
 
        msleep(10);
-
-       soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
 static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
        /*
         * FIXME:  This doesn't fit well.  We don't have the mechanism in
         * the generic PCMCIA layer to deal with the idea of two sockets
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
deleted file mode 100644 (file)
index 6bcabee..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_jornada720.c
- *
- * Jornada720 PCMCIA specific routines
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
-#include <asm/mach-types.h>
-
-#include "sa1111_generic.h"
-
-/* Does SOCKET1_3V actually do anything? */
-#define SOCKET0_POWER  GPIO_GPIO0
-#define SOCKET0_3V     GPIO_GPIO2
-#define SOCKET1_POWER  (GPIO_GPIO1 | GPIO_GPIO3)
-#define SOCKET1_3V     GPIO_GPIO3
-
-static int
-jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-       struct sa1111_pcmcia_socket *s = to_skt(skt);
-       unsigned int pa_dwr_mask, pa_dwr_set;
-       int ret;
-
-       printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
-               skt->nr, state->Vcc, state->Vpp);
-
-       switch (skt->nr) {
-       case 0:
-               pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
-
-               switch (state->Vcc) {
-               default:
-               case  0:
-                       pa_dwr_set = 0;
-                       break;
-               case 33:
-                       pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
-                       break;
-               case 50:
-                       pa_dwr_set = SOCKET0_POWER;
-                       break;
-               }
-               break;
-
-       case 1:
-               pa_dwr_mask = SOCKET1_POWER;
-
-               switch (state->Vcc) {
-               default:
-               case 0:
-                       pa_dwr_set = 0;
-                       break;
-               case 33:
-                       pa_dwr_set = SOCKET1_POWER;
-                       break;
-               case 50:
-                       pa_dwr_set = SOCKET1_POWER;
-                       break;
-               }
-               break;
-
-       default:
-               return -1;
-       }
-
-       if (state->Vpp != state->Vcc && state->Vpp != 0) {
-               printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
-                       __func__, state->Vpp);
-               return -EPERM;
-       }
-
-       ret = sa1111_pcmcia_configure_socket(skt, state);
-       if (ret == 0) {
-               unsigned long flags;
-
-               local_irq_save(flags);
-               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-               local_irq_restore(flags);
-       }
-
-       return ret;
-}
-
-static struct pcmcia_low_level jornada720_pcmcia_ops = {
-       .owner                  = THIS_MODULE,
-       .configure_socket       = jornada720_pcmcia_configure_socket,
-       .socket_init            = sa1111_pcmcia_socket_init,
-       .first                  = 0,
-       .nr                     = 2,
-};
-
-int __devinit pcmcia_jornada720_init(struct device *dev)
-{
-       int ret = -ENODEV;
-
-       if (machine_is_jornada720()) {
-               unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-               GRER |= 0x00000002;
-
-               /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-               sa1111_set_io_dir(dev, pin, 0, 0);
-               sa1111_set_io(dev, pin, 0);
-               sa1111_set_sleep_io(dev, pin, 0);
-
-               sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
-               ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
-                               sa11xx_drv_pcmcia_add_one);
-       }
-
-       return ret;
-}
index 93b9c9ba57c3a9cbe716038b8b9d473106151e3d..35c30ff41e817cf5d92dc2d84a2f6efacfadad4c 100644 (file)
@@ -19,6 +19,7 @@
  */
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/init.h>
 
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs_skt0[] = {
-       /* socket, IRQ, name */
-       { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" },
-};
-
-static struct pcmcia_irqs irqs_skt1[] = {
-       /* socket, IRQ, name */
-       { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" },
-};
-
 struct nanoengine_pins {
-       unsigned input_pins;
        unsigned output_pins;
        unsigned clear_outputs;
-       unsigned transition_pins;
-       unsigned pci_irq;
-       struct pcmcia_irqs *pcmcia_irqs;
-       unsigned pcmcia_irqs_size;
+       int gpio_rst;
+       int gpio_cd;
+       int gpio_rdy;
 };
 
 static struct nanoengine_pins nano_skts[] = {
        {
-               .input_pins             = GPIO_PC_READY0 | GPIO_PC_CD0,
-               .output_pins            = GPIO_PC_RESET0,
-               .clear_outputs          = GPIO_PC_RESET0,
-               .transition_pins        = NANOENGINE_IRQ_GPIO_PC_CD0,
-               .pci_irq                = NANOENGINE_IRQ_GPIO_PC_READY0,
-               .pcmcia_irqs            = irqs_skt0,
-               .pcmcia_irqs_size       = ARRAY_SIZE(irqs_skt0)
+               .gpio_rst               = GPIO_PC_RESET0,
+               .gpio_cd                = GPIO_PC_CD0,
+               .gpio_rdy               = GPIO_PC_READY0,
        }, {
-               .input_pins             = GPIO_PC_READY1 | GPIO_PC_CD1,
-               .output_pins            = GPIO_PC_RESET1,
-               .clear_outputs          = GPIO_PC_RESET1,
-               .transition_pins        = NANOENGINE_IRQ_GPIO_PC_CD1,
-               .pci_irq                = NANOENGINE_IRQ_GPIO_PC_READY1,
-               .pcmcia_irqs            = irqs_skt1,
-               .pcmcia_irqs_size       = ARRAY_SIZE(irqs_skt1)
+               .gpio_rst               = GPIO_PC_RESET1,
+               .gpio_cd                = GPIO_PC_CD1,
+               .gpio_rdy               = GPIO_PC_READY1,
        }
 };
 
@@ -79,58 +60,38 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
 static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        unsigned i = skt->nr;
+       int ret;
 
        if (i >= num_nano_pcmcia_sockets)
                return -ENXIO;
 
-       GPDR &= ~nano_skts[i].input_pins;
-       GPDR |= nano_skts[i].output_pins;
-       GPCR = nano_skts[i].clear_outputs;
-       irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH);
-       skt->socket.pci_irq = nano_skts[i].pci_irq;
+       ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW,
+               i ? "PC RST1" : "PC RST0");
+       if (ret)
+               return ret;
+
+       skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd;
+       skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0";
+       skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy;
+       skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0";
 
-       return soc_pcmcia_request_irqs(skt,
-               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+       return 0;
 }
 
-/*
- * Release all resources.
- */
 static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       unsigned i = skt->nr;
-
-       if (i >= num_nano_pcmcia_sockets)
-               return;
-
-       soc_pcmcia_free_irqs(skt,
-               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+       gpio_free(nano_skts[skt->nr].gpio_rst);
 }
 
 static int nanoengine_pcmcia_configure_socket(
        struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
-       unsigned reset;
        unsigned i = skt->nr;
 
        if (i >= num_nano_pcmcia_sockets)
                return -ENXIO;
 
-       switch (i) {
-       case 0:
-               reset = GPIO_PC_RESET0;
-               break;
-       case 1:
-               reset = GPIO_PC_RESET1;
-               break;
-       default:
-               return -ENXIO;
-       }
-
-       if (state->flags & SS_RESET)
-               GPSR = reset;
-       else
-               GPCR = reset;
+       gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET));
 
        return 0;
 }
@@ -138,62 +99,17 @@ static int nanoengine_pcmcia_configure_socket(
 static void nanoengine_pcmcia_socket_state(
        struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-       unsigned long levels = GPLR;
        unsigned i = skt->nr;
 
        if (i >= num_nano_pcmcia_sockets)
                return;
 
-       memset(state, 0, sizeof(struct pcmcia_state));
-       switch (i) {
-       case 0:
-               state->ready = (levels & GPIO_PC_READY0) ? 1 : 0;
-               state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0;
-               break;
-       case 1:
-               state->ready = (levels & GPIO_PC_READY1) ? 1 : 0;
-               state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0;
-               break;
-       default:
-               return;
-       }
        state->bvd1 = 1;
        state->bvd2 = 1;
-       state->wrprot = 0; /* Not available */
        state->vs_3v = 1; /* Can only apply 3.3V */
        state->vs_Xv = 0;
 }
 
-/*
- * Enable card status IRQs on (re-)initialisation.  This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       unsigned i = skt->nr;
-
-       if (i >= num_nano_pcmcia_sockets)
-               return;
-
-       soc_pcmcia_enable_irqs(skt,
-               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
-}
-
-/*
- * Disable card status IRQs on suspend.
- */
-static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-       unsigned i = skt->nr;
-
-       if (i >= num_nano_pcmcia_sockets)
-               return;
-
-       soc_pcmcia_disable_irqs(skt,
-               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
-}
-
 static struct pcmcia_low_level nanoengine_pcmcia_ops = {
        .owner                  = THIS_MODULE,
 
@@ -202,8 +118,6 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = {
 
        .configure_socket       = nanoengine_pcmcia_configure_socket,
        .socket_state           = nanoengine_pcmcia_socket_state,
-       .socket_init            = nanoengine_pcmcia_socket_init,
-       .socket_suspend         = nanoengine_pcmcia_socket_suspend,
 };
 
 int pcmcia_nanoengine_init(struct device *dev)
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
deleted file mode 100644 (file)
index c95639b..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * linux/drivers/pcmcia/sa1100_neponset.c
- *
- * Neponset PCMCIA specific routines
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <mach/neponset.h>
-#include <asm/hardware/sa1111.h>
-
-#include "sa1111_generic.h"
-
-/*
- * Neponset uses the Maxim MAX1600, with the following connections:
- *
- *   MAX1600      Neponset
- *
- *    A0VCC        SA-1111 GPIO A<1>
- *    A1VCC        SA-1111 GPIO A<0>
- *    A0VPP        CPLD NCR A0VPP
- *    A1VPP        CPLD NCR A1VPP
- *    B0VCC        SA-1111 GPIO A<2>
- *    B1VCC        SA-1111 GPIO A<3>
- *    B0VPP        ground (slot B is CF)
- *    B1VPP        ground (slot B is CF)
- *
- *     VX          VCC (5V)
- *     VY          VCC3_3 (3.3V)
- *     12INA       12V
- *     12INB       ground (slot B is CF)
- *
- * The MAX1600 CODE pin is tied to ground, placing the device in 
- * "Standard Intel code" mode. Refer to the Maxim data sheet for
- * the corresponding truth table.
- */
-
-static int
-neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-       struct sa1111_pcmcia_socket *s = to_skt(skt);
-       unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
-       int ret;
-
-       switch (skt->nr) {
-       case 0:
-               pa_dwr_mask = GPIO_A0 | GPIO_A1;
-               ncr_mask = NCR_A0VPP | NCR_A1VPP;
-
-               if (state->Vpp == 0)
-                       ncr_set = 0;
-               else if (state->Vpp == 120)
-                       ncr_set = NCR_A1VPP;
-               else if (state->Vpp == state->Vcc)
-                       ncr_set = NCR_A0VPP;
-               else {
-                       printk(KERN_ERR "%s(): unrecognized VPP %u\n",
-                              __func__, state->Vpp);
-                       return -1;
-               }
-               break;
-
-       case 1:
-               pa_dwr_mask = GPIO_A2 | GPIO_A3;
-               ncr_mask = 0;
-               ncr_set = 0;
-
-               if (state->Vpp != state->Vcc && state->Vpp != 0) {
-                       printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-                              __func__, state->Vpp);
-                       return -1;
-               }
-               break;
-
-       default:
-               return -1;
-       }
-
-       /*
-        * pa_dwr_set is the mask for selecting Vcc on both sockets.
-        * pa_dwr_mask selects which bits (and therefore socket) we change.
-        */
-       switch (state->Vcc) {
-       default:
-       case 0:  pa_dwr_set = 0;                break;
-       case 33: pa_dwr_set = GPIO_A1|GPIO_A2;  break;
-       case 50: pa_dwr_set = GPIO_A0|GPIO_A3;  break;
-       }
-
-       ret = sa1111_pcmcia_configure_socket(skt, state);
-       if (ret == 0) {
-               unsigned long flags;
-
-               local_irq_save(flags);
-               NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
-
-               local_irq_restore(flags);
-               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-       }
-
-       return 0;
-}
-
-static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       if (skt->nr == 0)
-               NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
-
-       sa1111_pcmcia_socket_init(skt);
-}
-
-static struct pcmcia_low_level neponset_pcmcia_ops = {
-       .owner                  = THIS_MODULE,
-       .configure_socket       = neponset_pcmcia_configure_socket,
-       .socket_init            = neponset_pcmcia_socket_init,
-       .first                  = 0,
-       .nr                     = 2,
-};
-
-int pcmcia_neponset_init(struct sa1111_dev *sadev)
-{
-       int ret = -ENODEV;
-
-       if (machine_is_assabet()) {
-               /*
-                * Set GPIO_A<3:0> to be outputs for the MAX1600,
-                * and switch to standby mode.
-                */
-               sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-               sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-               sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-               sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
-               ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
-                               sa11xx_drv_pcmcia_add_one);
-       }
-
-       return ret;
-}
index 7ff1b43540b809b2a970638bdbf45dff292d0af3..decb34730bcf436b8aa097b086b1723f8e6b21af 100644 (file)
 #include <asm/irq.h>
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs[] = {
-       { 0, SHANNON_IRQ_GPIO_EJECT_0, "PCMCIA_CD_0" },
-       { 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" },
-};
-
 static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        /* All those are inputs */
-       GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
-                 SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
-       GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
-                 SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
-
-       skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
-
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
+       GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) |
+                 GPIO_GPIO(SHANNON_GPIO_EJECT_1) |
+                 GPIO_GPIO(SHANNON_GPIO_RDY_0) |
+                 GPIO_GPIO(SHANNON_GPIO_RDY_1));
+
+       if (skt->nr == 0) {
+               skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0";
+               skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0;
+               skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0";
+       } else {
+               skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1;
+               skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1";
+               skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1;
+               skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1";
+       }
 
-static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       return 0;
 }
 
 static void
 shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                            struct pcmcia_state *state)
 {
-       unsigned long levels = GPLR;
-
        switch (skt->nr) {
        case 0:
-               state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
-               state->ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
-               state->wrprot = 0; /* Not available on Shannon. */
                state->bvd1   = 1; 
                state->bvd2   = 1; 
                state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
@@ -56,9 +51,6 @@ shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                break;
 
        case 1:
-               state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
-               state->ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
-               state->wrprot = 0; /* Not available on Shannon. */
                state->bvd1   = 1; 
                state->bvd2   = 1; 
                state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
@@ -92,25 +84,11 @@ shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static struct pcmcia_low_level shannon_pcmcia_ops = {
        .owner                  = THIS_MODULE,
        .hw_init                = shannon_pcmcia_hw_init,
-       .hw_shutdown            = shannon_pcmcia_hw_shutdown,
        .socket_state           = shannon_pcmcia_socket_state,
        .configure_socket       = shannon_pcmcia_configure_socket,
-
-       .socket_init            = shannon_pcmcia_socket_init,
-       .socket_suspend         = shannon_pcmcia_socket_suspend,
 };
 
 int __devinit pcmcia_shannon_init(struct device *dev)
index 0fac9658b020194825388330d953de1744a0f49a..8647b17c449ef79183a3d42f73a045f42e26e965 100644 (file)
 #include <mach/simpad.h>
 #include "sa1100_generic.h"
  
-static struct pcmcia_irqs irqs[] = {
-       { 1, IRQ_GPIO_CF_CD, "CF_CD" },
-};
-
 static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 
        simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-       skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
+       skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD;
+       skt->stat[SOC_STAT_CD].name = "CF_CD";
+       skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ;
+       skt->stat[SOC_STAT_RDY].name = "CF_RDY";
 
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+       return 0;
 }
 
 static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
        /* Disable CF bus: */
        /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
        simpad_clear_cs3_bit(PCMCIA_RESET);
@@ -42,14 +39,13 @@ static void
 simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
                           struct pcmcia_state *state)
 {
-       unsigned long levels = GPLR;
        long cs3reg = simpad_get_cs3_ro();
 
-       state->detect=((levels & GPIO_CF_CD)==0)?1:0;
-       state->ready=(levels & GPIO_CF_IRQ)?1:0;
+       /* the detect signal is inverted - fix that up here */
+       state->detect = !state->detect;
+
        state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
        state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
-       state->wrprot=0; /* Not available on Simpad. */
 
        if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
                        (PCMCIA_VS1|PCMCIA_VS2)) {
@@ -99,14 +95,8 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
        return 0;
 }
 
-static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
-       soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
        simpad_set_cs3_bit(PCMCIA_RESET);
 }
 
@@ -116,7 +106,6 @@ static struct pcmcia_low_level simpad_pcmcia_ops = {
        .hw_shutdown            = simpad_pcmcia_hw_shutdown,
        .socket_state           = simpad_pcmcia_socket_state,
        .configure_socket       = simpad_pcmcia_configure_socket,
-       .socket_init            = simpad_pcmcia_socket_init,
        .socket_suspend         = simpad_pcmcia_socket_suspend,
 };
 
diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c
new file mode 100644 (file)
index 0000000..4d206f4
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * linux/drivers/pcmcia/sa1100_badge4.c
+ *
+ * BadgePAD 4 PCMCIA specific routines
+ *
+ *   Christopher Hoover <ch@hpl.hp.com>
+ *
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <mach/badge4.h>
+#include <asm/hardware/sa1111.h>
+
+#include "sa1111_generic.h"
+
+/*
+ * BadgePAD 4 Details
+ *
+ * PCM Vcc:
+ *
+ *  PCM Vcc on BadgePAD 4 can be jumpered for 3v3 (short pins 1 and 3
+ *  on JP6) or 5v0 (short pins 3 and 5 on JP6).
+ *
+ * PCM Vpp:
+ *
+ *  PCM Vpp on BadgePAD 4 can be jumpered for 12v0 (short pins 4 and 6
+ *  on JP6) or tied to PCM Vcc (short pins 2 and 4 on JP6).  N.B.,
+ *  12v0 operation requires that the power supply actually supply 12v0
+ *  via pin 7 of JP7.
+ *
+ * CF Vcc:
+ *
+ *  CF Vcc on BadgePAD 4 can be jumpered either for 3v3 (short pins 1
+ *  and 2 on JP10) or 5v0 (short pins 2 and 3 on JP10).
+ *
+ * Unfortunately there's no way programmatically to determine how a
+ * given board is jumpered.  This code assumes a default jumpering
+ * as described below.
+ *
+ * If the defaults aren't correct, you may override them with a pcmv
+ * setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf vcc>.  The units are
+ * tenths of volts; e.g. pcmv=33,120,50 indicates 3v3 PCM Vcc, 12v0
+ * PCM Vpp, and 5v0 CF Vcc.
+ *
+ */
+
+static int badge4_pcmvcc = 50;  /* pins 3 and 5 jumpered on JP6 */
+static int badge4_pcmvpp = 50;  /* pins 2 and 4 jumpered on JP6 */
+static int badge4_cfvcc = 33;   /* pins 1 and 2 jumpered on JP10 */
+
+static void complain_about_jumpering(const char *whom,
+                                    const char *supply,
+                                    int given, int wanted)
+{
+       printk(KERN_ERR
+        "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
+        "; re-jumper the board and/or use pcmv=xx,xx,xx\n",
+              whom, supply,
+              wanted / 10, wanted % 10,
+              supply,
+              given / 10, given % 10);
+}
+
+static int
+badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+       int ret;
+
+       switch (skt->nr) {
+       case 0:
+               if ((state->Vcc != 0) &&
+                   (state->Vcc != badge4_pcmvcc)) {
+                       complain_about_jumpering(__func__, "pcmvcc",
+                                                badge4_pcmvcc, state->Vcc);
+                       // Apply power regardless of the jumpering.
+                       // return -1;
+               }
+               if ((state->Vpp != 0) &&
+                   (state->Vpp != badge4_pcmvpp)) {
+                       complain_about_jumpering(__func__, "pcmvpp",
+                                                badge4_pcmvpp, state->Vpp);
+                       return -1;
+               }
+               break;
+
+       case 1:
+               if ((state->Vcc != 0) &&
+                   (state->Vcc != badge4_cfvcc)) {
+                       complain_about_jumpering(__func__, "cfvcc",
+                                                badge4_cfvcc, state->Vcc);
+                       return -1;
+               }
+               break;
+
+       default:
+               return -1;
+       }
+
+       ret = sa1111_pcmcia_configure_socket(skt, state);
+       if (ret == 0) {
+               unsigned long flags;
+               int need5V;
+
+               local_irq_save(flags);
+
+               need5V = ((state->Vcc == 50) || (state->Vpp == 50));
+
+               badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V);
+
+               local_irq_restore(flags);
+       }
+
+       return ret;
+}
+
+static struct pcmcia_low_level badge4_pcmcia_ops = {
+       .owner                  = THIS_MODULE,
+       .configure_socket       = badge4_pcmcia_configure_socket,
+       .first                  = 0,
+       .nr                     = 2,
+};
+
+int pcmcia_badge4_init(struct device *dev)
+{
+       int ret = -ENODEV;
+
+       if (machine_is_badge4()) {
+               printk(KERN_INFO
+                      "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n",
+                      __func__,
+                      badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
+
+               sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
+               ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
+                               sa11xx_drv_pcmcia_add_one);
+       }
+
+       return ret;
+}
+
+static int __init pcmv_setup(char *s)
+{
+       int v[4];
+
+       s = get_options(s, ARRAY_SIZE(v), v);
+
+       if (v[0] >= 1) badge4_pcmvcc = v[1];
+       if (v[0] >= 2) badge4_pcmvpp = v[2];
+       if (v[0] >= 3) badge4_cfvcc = v[3];
+
+       return 1;
+}
+
+__setup("pcmv=", pcmv_setup);
index 27f2fe3b7fb4a5e41a44a03fa75e2becce0d63d7..ef5848f65241fbb27cea4223b775b2a529ea1630 100644 (file)
 #define IDX_IRQ_S1_CD_VALID    (4)
 #define IDX_IRQ_S1_BVD1_STSCHG (5)
 
-static struct pcmcia_irqs irqs[] = {
-       { 0, NO_IRQ, "SA1111 PCMCIA card detect" },
-       { 0, NO_IRQ, "SA1111 PCMCIA BVD1"        },
-       { 1, NO_IRQ, "SA1111 CF card detect"     },
-       { 1, NO_IRQ, "SA1111 CF BVD1"            },
-};
-
-static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-       return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
        struct sa1111_pcmcia_socket *s = to_skt(skt);
@@ -114,26 +97,13 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
        return 0;
 }
 
-void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-       soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
        int (*add)(struct soc_pcmcia_socket *))
 {
        struct sa1111_pcmcia_socket *s;
        int i, ret = 0;
 
-       ops->hw_init = sa1111_pcmcia_hw_init;
-       ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
        ops->socket_state = sa1111_pcmcia_socket_state;
-       ops->socket_suspend = sa1111_pcmcia_socket_suspend;
 
        for (i = 0; i < ops->nr; i++) {
                s = kzalloc(sizeof(*s), GFP_KERNEL);
@@ -141,13 +111,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
                        return -ENOMEM;
 
                s->soc.nr = ops->first + i;
-               s->soc.ops = ops;
-               s->soc.socket.owner = ops->owner;
-               s->soc.socket.dev.parent = &dev->dev;
-               s->soc.socket.pci_irq = s->soc.nr ?
-                               dev->irq[IDX_IRQ_S0_READY_NINT] :
-                               dev->irq[IDX_IRQ_S1_READY_NINT];
+               soc_pcmcia_init_one(&s->soc, ops, &dev->dev);
                s->dev = dev;
+               if (s->soc.nr) {
+                       s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT];
+                       s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
+                       s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect";
+                       s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
+                       s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1";
+               } else {
+                       s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT];
+                       s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
+                       s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect";
+                       s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
+                       s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1";
+               }
 
                ret = add(&s->soc);
                if (ret == 0) {
@@ -172,12 +150,6 @@ static int pcmcia_probe(struct sa1111_dev *dev)
 
        base = dev->mapbase;
 
-       /* Initialize PCMCIA IRQs */
-       irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
-       irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
-       irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
-       irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
-
        /*
         * Initialise the suspend state.
         */
index 02dc8577cdafcaa9f5b9dd09a6fd5948d60e35a1..f6376e34a7e4393e6521cf12eef1803feb863e14 100644 (file)
@@ -17,7 +17,6 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
 
 extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
 extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
-extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
 
 extern int pcmcia_badge4_init(struct device *);
 extern int pcmcia_jornada720_init(struct device *);
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
new file mode 100644 (file)
index 0000000..69428d1
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * drivers/pcmcia/sa1100_jornada720.c
+ *
+ * Jornada720 PCMCIA specific routines
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/mach-types.h>
+
+#include "sa1111_generic.h"
+
+/* Does SOCKET1_3V actually do anything? */
+#define SOCKET0_POWER  GPIO_GPIO0
+#define SOCKET0_3V     GPIO_GPIO2
+#define SOCKET1_POWER  (GPIO_GPIO1 | GPIO_GPIO3)
+#define SOCKET1_3V     GPIO_GPIO3
+
+static int
+jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
+       unsigned int pa_dwr_mask, pa_dwr_set;
+       int ret;
+
+       printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
+               skt->nr, state->Vcc, state->Vpp);
+
+       switch (skt->nr) {
+       case 0:
+               pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
+
+               switch (state->Vcc) {
+               default:
+               case  0:
+                       pa_dwr_set = 0;
+                       break;
+               case 33:
+                       pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
+                       break;
+               case 50:
+                       pa_dwr_set = SOCKET0_POWER;
+                       break;
+               }
+               break;
+
+       case 1:
+               pa_dwr_mask = SOCKET1_POWER;
+
+               switch (state->Vcc) {
+               default:
+               case 0:
+                       pa_dwr_set = 0;
+                       break;
+               case 33:
+                       pa_dwr_set = SOCKET1_POWER;
+                       break;
+               case 50:
+                       pa_dwr_set = SOCKET1_POWER;
+                       break;
+               }
+               break;
+
+       default:
+               return -1;
+       }
+
+       if (state->Vpp != state->Vcc && state->Vpp != 0) {
+               printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
+                       __func__, state->Vpp);
+               return -EPERM;
+       }
+
+       ret = sa1111_pcmcia_configure_socket(skt, state);
+       if (ret == 0)
+               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+
+       return ret;
+}
+
+static struct pcmcia_low_level jornada720_pcmcia_ops = {
+       .owner                  = THIS_MODULE,
+       .configure_socket       = jornada720_pcmcia_configure_socket,
+       .first                  = 0,
+       .nr                     = 2,
+};
+
+int __devinit pcmcia_jornada720_init(struct device *dev)
+{
+       int ret = -ENODEV;
+
+       if (machine_is_jornada720()) {
+               unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+               GRER |= 0x00000002;
+
+               /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+               sa1111_set_io_dir(dev, pin, 0, 0);
+               sa1111_set_io(dev, pin, 0);
+               sa1111_set_sleep_io(dev, pin, 0);
+
+               sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
+               ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
+                               sa11xx_drv_pcmcia_add_one);
+       }
+
+       return ret;
+}
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
new file mode 100644 (file)
index 0000000..c5caf57
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_lubbock.c
+ *
+ * Author:     George Davis
+ * Created:    Jan 10, 2002
+ * Copyright:  MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
+ *
+ * Lubbock PCMCIA specific routines.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/mach-types.h>
+#include <mach/lubbock.h>
+
+#include "sa1111_generic.h"
+
+static int
+lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+                               const socket_state_t *state)
+{
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
+       unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
+       int ret = 0;
+
+       pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
+
+       /* Lubbock uses the Maxim MAX1602, with the following connections:
+        *
+        * Socket 0 (PCMCIA):
+        *      MAX1602 Lubbock         Register
+        *      Pin     Signal
+        *      -----   -------         ----------------------
+        *      A0VPP   S0_PWR0         SA-1111 GPIO A<0>
+        *      A1VPP   S0_PWR1         SA-1111 GPIO A<1>
+        *      A0VCC   S0_PWR2         SA-1111 GPIO A<2>
+        *      A1VCC   S0_PWR3         SA-1111 GPIO A<3>
+        *      VX      VCC
+        *      VY      +3.3V
+        *      12IN    +12V
+        *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
+        *
+        * Socket 1 (CF):
+        *      MAX1602 Lubbock         Register
+        *      Pin     Signal
+        *      -----   -------         ----------------------
+        *      A0VPP   GND             VPP is not connected
+        *      A1VPP   GND             VPP is not connected
+        *      A0VCC   S1_PWR0         MISC_WR<14>
+        *      A1VCC   S1_PWR1         MISC_WR<15>
+        *      VX      VCC
+        *      VY      +3.3V
+        *      12IN    GND             VPP is not connected
+        *      CODE    +3.3V           Cirrus  Code, CODE = High (VY)
+        *
+        */
+
+ again:
+       switch (skt->nr) {
+       case 0:
+               pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+               switch (state->Vcc) {
+               case 0: /* Hi-Z */
+                       break;
+
+               case 33: /* VY */
+                       pa_dwr_set |= GPIO_A3;
+                       break;
+
+               case 50: /* VX */
+                       pa_dwr_set |= GPIO_A2;
+                       break;
+
+               default:
+                       printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
+                              __func__, state->Vcc);
+                       ret = -1;
+               }
+
+               switch (state->Vpp) {
+               case 0: /* Hi-Z */
+                       break;
+
+               case 120: /* 12IN */
+                       pa_dwr_set |= GPIO_A1;
+                       break;
+
+               default: /* VCC */
+                       if (state->Vpp == state->Vcc)
+                               pa_dwr_set |= GPIO_A0;
+                       else {
+                               printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
+                                      __func__, state->Vpp);
+                               ret = -1;
+                               break;
+                       }
+               }
+               break;
+
+       case 1:
+               misc_mask = (1 << 15) | (1 << 14);
+
+               switch (state->Vcc) {
+               case 0: /* Hi-Z */
+                       break;
+
+               case 33: /* VY */
+                       misc_set |= 1 << 15;
+                       break;
+
+               case 50: /* VX */
+                       misc_set |= 1 << 14;
+                       break;
+
+               default:
+                       printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
+                              __func__, state->Vcc);
+                       ret = -1;
+                       break;
+               }
+
+               if (state->Vpp != state->Vcc && state->Vpp != 0) {
+                       printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
+                              __func__, state->Vpp);
+                       ret = -1;
+                       break;
+               }
+               break;
+
+       default:
+               ret = -1;
+       }
+
+       if (ret == 0)
+               ret = sa1111_pcmcia_configure_socket(skt, state);
+
+       if (ret == 0) {
+               lubbock_set_misc_wr(misc_mask, misc_set);
+               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+       }
+
+#if 1
+       if (ret == 0 && state->Vcc == 33) {
+               struct pcmcia_state new_state;
+
+               /*
+                * HACK ALERT:
+                * We can't sense the voltage properly on Lubbock before
+                * actually applying some power to the socket (catch 22).
+                * Resense the socket Voltage Sense pins after applying
+                * socket power.
+                *
+                * Note: It takes about 2.5ms for the MAX1602 VCC output
+                * to rise.
+                */
+               mdelay(3);
+
+               sa1111_pcmcia_socket_state(skt, &new_state);
+
+               if (!new_state.vs_3v && !new_state.vs_Xv) {
+                       /*
+                        * Switch to 5V,  Configure socket with 5V voltage
+                        */
+                       lubbock_set_misc_wr(misc_mask, 0);
+                       sa1111_set_io(s->dev, pa_dwr_mask, 0);
+
+                       /*
+                        * It takes about 100ms to turn off Vcc.
+                        */
+                       mdelay(100);
+
+                       /*
+                        * We need to hack around the const qualifier as
+                        * well to keep this ugly workaround localized and
+                        * not force it to the rest of the code. Barf bags
+                        * available in the seat pocket in front of you!
+                        */
+                       ((socket_state_t *)state)->Vcc = 50;
+                       ((socket_state_t *)state)->Vpp = 50;
+                       goto again;
+               }
+       }
+#endif
+
+       return ret;
+}
+
+static struct pcmcia_low_level lubbock_pcmcia_ops = {
+       .owner                  = THIS_MODULE,
+       .configure_socket       = lubbock_pcmcia_configure_socket,
+       .first                  = 0,
+       .nr                     = 2,
+};
+
+#include "pxa2xx_base.h"
+
+int pcmcia_lubbock_init(struct sa1111_dev *sadev)
+{
+       int ret = -ENODEV;
+
+       if (machine_is_lubbock()) {
+               /*
+                * Set GPIO_A<3:0> to be outputs for the MAX1600,
+                * and switch to standby mode.
+                */
+               sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
+               sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+               sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+
+               /* Set CF Socket 1 power to standby mode. */
+               lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
+
+               pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
+               pxa2xx_configure_sockets(&sadev->dev);
+               ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
+                               pxa2xx_drv_pcmcia_add_one);
+       }
+
+       return ret;
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
new file mode 100644 (file)
index 0000000..50f297d
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * linux/drivers/pcmcia/sa1100_neponset.c
+ *
+ * Neponset PCMCIA specific routines
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <mach/neponset.h>
+#include <asm/hardware/sa1111.h>
+
+#include "sa1111_generic.h"
+
+/*
+ * Neponset uses the Maxim MAX1600, with the following connections:
+ *
+ *   MAX1600      Neponset
+ *
+ *    A0VCC        SA-1111 GPIO A<1>
+ *    A1VCC        SA-1111 GPIO A<0>
+ *    A0VPP        CPLD NCR A0VPP
+ *    A1VPP        CPLD NCR A1VPP
+ *    B0VCC        SA-1111 GPIO A<2>
+ *    B1VCC        SA-1111 GPIO A<3>
+ *    B0VPP        ground (slot B is CF)
+ *    B1VPP        ground (slot B is CF)
+ *
+ *     VX          VCC (5V)
+ *     VY          VCC3_3 (3.3V)
+ *     12INA       12V
+ *     12INB       ground (slot B is CF)
+ *
+ * The MAX1600 CODE pin is tied to ground, placing the device in 
+ * "Standard Intel code" mode. Refer to the Maxim data sheet for
+ * the corresponding truth table.
+ */
+
+static int
+neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
+       unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
+       int ret;
+
+       switch (skt->nr) {
+       case 0:
+               pa_dwr_mask = GPIO_A0 | GPIO_A1;
+               ncr_mask = NCR_A0VPP | NCR_A1VPP;
+
+               if (state->Vpp == 0)
+                       ncr_set = 0;
+               else if (state->Vpp == 120)
+                       ncr_set = NCR_A1VPP;
+               else if (state->Vpp == state->Vcc)
+                       ncr_set = NCR_A0VPP;
+               else {
+                       printk(KERN_ERR "%s(): unrecognized VPP %u\n",
+                              __func__, state->Vpp);
+                       return -1;
+               }
+               break;
+
+       case 1:
+               pa_dwr_mask = GPIO_A2 | GPIO_A3;
+               ncr_mask = 0;
+               ncr_set = 0;
+
+               if (state->Vpp != state->Vcc && state->Vpp != 0) {
+                       printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
+                              __func__, state->Vpp);
+                       return -1;
+               }
+               break;
+
+       default:
+               return -1;
+       }
+
+       /*
+        * pa_dwr_set is the mask for selecting Vcc on both sockets.
+        * pa_dwr_mask selects which bits (and therefore socket) we change.
+        */
+       switch (state->Vcc) {
+       default:
+       case 0:  pa_dwr_set = 0;                break;
+       case 33: pa_dwr_set = GPIO_A1|GPIO_A2;  break;
+       case 50: pa_dwr_set = GPIO_A0|GPIO_A3;  break;
+       }
+
+       ret = sa1111_pcmcia_configure_socket(skt, state);
+       if (ret == 0) {
+               unsigned long flags;
+
+               local_irq_save(flags);
+               NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
+
+               local_irq_restore(flags);
+               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+       }
+
+       return ret;
+}
+
+static struct pcmcia_low_level neponset_pcmcia_ops = {
+       .owner                  = THIS_MODULE,
+       .configure_socket       = neponset_pcmcia_configure_socket,
+       .first                  = 0,
+       .nr                     = 2,
+};
+
+int pcmcia_neponset_init(struct sa1111_dev *sadev)
+{
+       int ret = -ENODEV;
+
+       if (machine_is_assabet()) {
+               /*
+                * Set GPIO_A<3:0> to be outputs for the MAX1600,
+                * and switch to standby mode.
+                */
+               sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
+               sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+               sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+               sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
+               ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
+                               sa11xx_drv_pcmcia_add_one);
+       }
+
+       return ret;
+}
index 0c62fe31a40e20ead5c0709757f177c738376574..a3ee89a6dd0e04c27b7881bf020ff30f03e6868d 100644 (file)
@@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
                skt = &sinfo->skt[i];
 
                skt->nr = first + i;
-               skt->ops = ops;
-               skt->socket.owner = ops->owner;
-               skt->socket.dev.parent = dev;
-               skt->socket.pci_irq = NO_IRQ;
+               soc_pcmcia_init_one(skt, ops, dev);
 
                ret = sa11xx_drv_pcmcia_add_one(skt);
                if (ret)
index a0a9c2aa8d78a5a02aae23065b6e2a51ccec7621..e0433f571962743d1191fd47f53253f2a65f04de 100644 (file)
@@ -32,6 +32,7 @@
 
 
 #include <linux/cpufreq.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -49,6 +50,8 @@
 
 #include "soc_common.h"
 
+static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev);
+
 #ifdef CONFIG_PCMCIA_DEBUG
 
 static int pc_debug;
@@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,
 }
 EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
 
+static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
+       unsigned int nr)
+{
+       unsigned int i;
+
+       for (i = 0; i < nr; i++) {
+               if (skt->stat[i].irq)
+                       free_irq(skt->stat[i].irq, skt);
+               if (gpio_is_valid(skt->stat[i].gpio))
+                       gpio_free(skt->stat[i].gpio);
+       }
+
+       if (skt->ops->hw_shutdown)
+               skt->ops->hw_shutdown(skt);
+}
+
+static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+       __soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat));
+}
+
+static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+       int ret = 0, i;
+
+       if (skt->ops->hw_init) {
+               ret = skt->ops->hw_init(skt);
+               if (ret)
+                       return ret;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
+               if (gpio_is_valid(skt->stat[i].gpio)) {
+                       int irq;
+
+                       ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
+                                              skt->stat[i].name);
+                       if (ret) {
+                               __soc_pcmcia_hw_shutdown(skt, i);
+                               return ret;
+                       }
+
+                       irq = gpio_to_irq(skt->stat[i].gpio);
+
+                       if (i == SOC_STAT_RDY)
+                               skt->socket.pci_irq = irq;
+                       else
+                               skt->stat[i].irq = irq;
+               }
+
+               if (skt->stat[i].irq) {
+                       ret = request_irq(skt->stat[i].irq,
+                                         soc_common_pcmcia_interrupt,
+                                         IRQF_TRIGGER_NONE,
+                                         skt->stat[i].name, skt);
+                       if (ret) {
+                               if (gpio_is_valid(skt->stat[i].gpio))
+                                       gpio_free(skt->stat[i].gpio);
+                               __soc_pcmcia_hw_shutdown(skt, i);
+                               return ret;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
+               if (skt->stat[i].irq) {
+                       irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING);
+                       irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH);
+               }
+}
+
+static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
+               if (skt->stat[i].irq)
+                       irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE);
+}
+
 static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 {
        struct pcmcia_state state;
@@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 
        memset(&state, 0, sizeof(struct pcmcia_state));
 
+       /* Make battery voltage state report 'good' */
+       state.bvd1 = 1;
+       state.bvd2 = 1;
+
+       /* CD is active low by default */
+       if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio))
+               state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio);
+
+       /* RDY and BVD are active high by default */
+       if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio))
+               state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio);
+       if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio))
+               state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio);
+       if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio))
+               state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio);
+
        skt->ops->socket_state(skt, &state);
 
        stat = state.detect  ? SS_DETECT : 0;
@@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
        debug(skt, 2, "initializing socket\n");
        if (skt->ops->socket_init)
                skt->ops->socket_init(skt);
+       soc_pcmcia_hw_enable(skt);
        return 0;
 }
 
@@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
 
        debug(skt, 2, "suspending socket\n");
 
+       soc_pcmcia_hw_disable(skt);
        if (skt->ops->socket_suspend)
                skt->ops->socket_suspend(skt);
 
@@ -526,69 +634,6 @@ static struct pccard_operations soc_common_pcmcia_operations = {
 };
 
 
-int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
-                           struct pcmcia_irqs *irqs, int nr)
-{
-       int i, res = 0;
-
-       for (i = 0; i < nr; i++) {
-               if (irqs[i].sock != skt->nr)
-                       continue;
-               res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
-                                 IRQF_DISABLED, irqs[i].str, skt);
-               if (res)
-                       break;
-               irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
-       }
-
-       if (res) {
-               printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n",
-                       irqs[i].irq, res);
-
-               while (i--)
-                       if (irqs[i].sock == skt->nr)
-                               free_irq(irqs[i].irq, skt);
-       }
-       return res;
-}
-EXPORT_SYMBOL(soc_pcmcia_request_irqs);
-
-void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt,
-                         struct pcmcia_irqs *irqs, int nr)
-{
-       int i;
-
-       for (i = 0; i < nr; i++)
-               if (irqs[i].sock == skt->nr)
-                       free_irq(irqs[i].irq, skt);
-}
-EXPORT_SYMBOL(soc_pcmcia_free_irqs);
-
-void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
-                            struct pcmcia_irqs *irqs, int nr)
-{
-       int i;
-
-       for (i = 0; i < nr; i++)
-               if (irqs[i].sock == skt->nr)
-                       irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
-}
-EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
-
-void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
-                           struct pcmcia_irqs *irqs, int nr)
-{
-       int i;
-
-       for (i = 0; i < nr; i++)
-               if (irqs[i].sock == skt->nr) {
-                       irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
-                       irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
-               }
-}
-EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
-
-
 static LIST_HEAD(soc_pcmcia_sockets);
 static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
 
@@ -635,6 +680,21 @@ module_exit(soc_pcmcia_cpufreq_unregister);
 
 #endif
 
+void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
+       struct pcmcia_low_level *ops, struct device *dev)
+{
+       int i;
+
+       skt->ops = ops;
+       skt->socket.owner = ops->owner;
+       skt->socket.dev.parent = dev;
+       skt->socket.pci_irq = NO_IRQ;
+
+       for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
+               skt->stat[i].gpio = -EINVAL;
+}
+EXPORT_SYMBOL(soc_pcmcia_init_one);
+
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 {
        mutex_lock(&soc_pcmcia_sockets_lock);
@@ -642,8 +702,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 
        pcmcia_unregister_socket(&skt->socket);
 
-       skt->ops->hw_shutdown(skt);
+       soc_pcmcia_hw_shutdown(skt);
 
+       /* should not be required; violates some lowlevel drivers */
        soc_common_pcmcia_config_skt(skt, &dead_socket);
 
        list_del(&skt->node);
@@ -700,7 +761,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
         */
        skt->ops->set_timing(skt);
 
-       ret = skt->ops->hw_init(skt);
+       ret = soc_pcmcia_hw_init(skt);
        if (ret)
                goto out_err_6;
 
@@ -733,7 +794,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
        pcmcia_unregister_socket(&skt->socket);
 
  out_err_7:
-       skt->ops->hw_shutdown(skt);
+       soc_pcmcia_hw_shutdown(skt);
  out_err_6:
        list_del(&skt->node);
        mutex_unlock(&soc_pcmcia_sockets_lock);
index 9daa73615c8bba3914f1a2fbf44fbfaa09e33b47..e6fcbea5b682e8574cf392dbadc8bd3f7df6e6b4 100644 (file)
@@ -50,6 +50,16 @@ struct soc_pcmcia_socket {
        struct resource         res_attr;
        void __iomem            *virt_io;
 
+       struct {
+               int             gpio;
+               unsigned int    irq;
+               const char      *name;
+       } stat[4];
+#define SOC_STAT_CD            0       /* Card detect */
+#define SOC_STAT_BVD1          1       /* BATDEAD / IOSTSCHG */
+#define SOC_STAT_BVD2          2       /* BATWARN / IOSPKR */
+#define SOC_STAT_RDY           3       /* Ready / Interrupt */
+
        unsigned int            irq_state;
 
        struct timer_list       poll_timer;
@@ -115,25 +125,16 @@ struct pcmcia_low_level {
 };
 
 
-struct pcmcia_irqs {
-       int sock;
-       int irq;
-       const char *str;
-};
-
 struct soc_pcmcia_timing {
        unsigned short io;
        unsigned short mem;
        unsigned short attr;
 };
 
-extern int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
-extern void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
-extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
-extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
 extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
 
-
+void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
+       struct pcmcia_low_level *ops, struct device *dev);
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);