ソースを参照

Merge branch 'pcmcia' of git://git.linaro.org/people/rmk/linux-arm

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
Linus Torvalds 13 年 前
コミット
24613ff927
38 ファイル変更371 行追加894 行削除
  1. 0 1
      arch/arm/mach-pxa/include/mach/balloon3.h
  2. 6 9
      arch/arm/mach-sa1100/include/mach/assabet.h
  3. 5 10
      arch/arm/mach-sa1100/include/mach/cerf.h
  4. 6 6
      arch/arm/mach-sa1100/include/mach/nanoengine.h
  5. 4 8
      arch/arm/mach-sa1100/include/mach/shannon.h
  6. 2 4
      arch/arm/mach-sa1100/include/mach/simpad.h
  7. 7 1
      drivers/pcmcia/Kconfig
  8. 7 7
      drivers/pcmcia/Makefile
  9. 5 17
      drivers/pcmcia/pxa2xx_balloon3.c
  10. 1 4
      drivers/pcmcia/pxa2xx_base.c
  11. 12 27
      drivers/pcmcia/pxa2xx_cm_x255.c
  12. 4 19
      drivers/pcmcia/pxa2xx_cm_x270.c
  13. 2 19
      drivers/pcmcia/pxa2xx_colibri.c
  14. 12 59
      drivers/pcmcia/pxa2xx_e740.c
  15. 14 17
      drivers/pcmcia/pxa2xx_mainstone.c
  16. 2 6
      drivers/pcmcia/pxa2xx_palmld.c
  17. 2 6
      drivers/pcmcia/pxa2xx_palmtc.c
  18. 2 6
      drivers/pcmcia/pxa2xx_palmtx.c
  19. 2 28
      drivers/pcmcia/pxa2xx_sharpsl.c
  20. 5 29
      drivers/pcmcia/pxa2xx_stargate2.c
  21. 5 57
      drivers/pcmcia/pxa2xx_trizeps4.c
  22. 6 33
      drivers/pcmcia/pxa2xx_viper.c
  23. 8 46
      drivers/pcmcia/pxa2xx_vpac270.c
  24. 15 50
      drivers/pcmcia/sa1100_assabet.c
  25. 18 34
      drivers/pcmcia/sa1100_cerf.c
  26. 14 80
      drivers/pcmcia/sa1100_h3600.c
  27. 23 109
      drivers/pcmcia/sa1100_nanoengine.c
  28. 17 39
      drivers/pcmcia/sa1100_shannon.c
  29. 8 19
      drivers/pcmcia/sa1100_simpad.c
  30. 1 2
      drivers/pcmcia/sa1111_badge4.c
  31. 14 42
      drivers/pcmcia/sa1111_generic.c
  32. 0 1
      drivers/pcmcia/sa1111_generic.h
  33. 1 7
      drivers/pcmcia/sa1111_jornada720.c
  34. 0 1
      drivers/pcmcia/sa1111_lubbock.c
  35. 1 10
      drivers/pcmcia/sa1111_neponset.c
  36. 1 4
      drivers/pcmcia/sa11xx_base.c
  37. 127 66
      drivers/pcmcia/soc_common.c
  38. 12 11
      drivers/pcmcia/soc_common.h

+ 0 - 1
arch/arm/mach-pxa/include/mach/balloon3.h

@@ -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)
 

+ 6 - 9
arch/arm/mach-sa1100/include/mach/assabet.h

@@ -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

+ 5 - 10
arch/arm/mach-sa1100/include/mach/cerf.h

@@ -14,15 +14,10 @@
 #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_

+ 6 - 6
arch/arm/mach-sa1100/include/mach/nanoengine.h

@@ -16,12 +16,12 @@
 
 #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

+ 4 - 8
arch/arm/mach-sa1100/include/mach/shannon.h

@@ -23,14 +23,10 @@
 #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... */
 

+ 2 - 4
arch/arm/mach-sa1100/include/mach/simpad.h

@@ -39,10 +39,8 @@
 
 
 /*---  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

+ 7 - 1
drivers/pcmcia/Kconfig

@@ -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

+ 7 - 7
drivers/pcmcia/Makefile

@@ -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

+ 5 - 17
drivers/pcmcia/pxa2xx_balloon3.c

@@ -29,15 +29,6 @@
 
 #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,

+ 1 - 4
drivers/pcmcia/pxa2xx_base.c

@@ -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)

+ 12 - 27
drivers/pcmcia/pxa2xx_cm_x255.c

@@ -25,17 +25,6 @@
 #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 */
 }
 
 

+ 4 - 19
drivers/pcmcia/pxa2xx_cm_x270.c

@@ -22,14 +22,6 @@
 #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 */
 }
 
 

+ 2 - 19
drivers/pcmcia/pxa2xx_colibri.c

@@ -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;
 }

+ 12 - 59
drivers/pcmcia/pxa2xx_e740.c

@@ -23,53 +23,27 @@
 
 #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,
 };
 

+ 14 - 17
drivers/pcmcia/pxa2xx_mainstone.c

@@ -30,27 +30,26 @@
 #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,

+ 2 - 6
drivers/pcmcia/pxa2xx_palmld.c

@@ -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;
 }

+ 2 - 6
drivers/pcmcia/pxa2xx_palmtc.c

@@ -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;
 }

+ 2 - 6
drivers/pcmcia/pxa2xx_palmtx.c

@@ -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;
 }

+ 2 - 28
drivers/pcmcia/pxa2xx_sharpsl.c

@@ -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,

+ 5 - 29
drivers/pcmcia/pxa2xx_stargate2.c

@@ -33,10 +33,6 @@
 #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,
 };
 

+ 5 - 57
drivers/pcmcia/pxa2xx_trizeps4.c

@@ -29,32 +29,17 @@
 
 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,

+ 6 - 33
drivers/pcmcia/pxa2xx_viper.c

@@ -32,13 +32,6 @@
 
 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;
 }

+ 8 - 46
drivers/pcmcia/pxa2xx_vpac270.c

@@ -23,29 +23,14 @@
 #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;

+ 15 - 50
drivers/pcmcia/sa1100_assabet.c

@@ -10,46 +10,30 @@
 #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,
 };
 

+ 18 - 34
drivers/pcmcia/sa1100_cerf.c

@@ -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>
@@ -19,34 +20,34 @@
 
 #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)

+ 14 - 80
drivers/pcmcia/sa1100_h3600.c

@@ -19,36 +19,20 @@
 
 #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

+ 23 - 109
drivers/pcmcia/sa1100_nanoengine.c

@@ -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>
@@ -34,43 +35,23 @@
 
 #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)

+ 17 - 39
drivers/pcmcia/sa1100_shannon.c

@@ -15,40 +15,35 @@
 #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)

+ 8 - 19
drivers/pcmcia/sa1100_simpad.c

@@ -15,24 +15,21 @@
 #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,
 };
 

+ 1 - 2
drivers/pcmcia/sa1100_badge4.c → drivers/pcmcia/sa1111_badge4.c

@@ -122,13 +122,12 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
 		local_irq_restore(flags);
 	}
 
-	return 0;
+	return ret;
 }
 
 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,
 };

+ 14 - 42
drivers/pcmcia/sa1111_generic.c

@@ -29,23 +29,6 @@
 #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.
 	 */

+ 0 - 1
drivers/pcmcia/sa1111_generic.h

@@ -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 *);

+ 1 - 7
drivers/pcmcia/sa1100_jornada720.c → drivers/pcmcia/sa1111_jornada720.c

@@ -78,13 +78,8 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 	}
 
 	ret = sa1111_pcmcia_configure_socket(skt, state);
-	if (ret == 0) {
-		unsigned long flags;
-
-		local_irq_save(flags);
+	if (ret == 0)
 		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-		local_irq_restore(flags);
-	}
 
 	return ret;
 }
@@ -92,7 +87,6 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 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,
 };

+ 0 - 1
drivers/pcmcia/pxa2xx_lubbock.c → drivers/pcmcia/sa1111_lubbock.c

@@ -202,7 +202,6 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 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,
 };

+ 1 - 10
drivers/pcmcia/sa1100_neponset.c → drivers/pcmcia/sa1111_neponset.c

@@ -103,21 +103,12 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
 		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);
+	return ret;
 }
 
 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,
 };

+ 1 - 4
drivers/pcmcia/sa11xx_base.c

@@ -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)

+ 127 - 66
drivers/pcmcia/soc_common.c

@@ -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);

+ 12 - 11
drivers/pcmcia/soc_common.h

@@ -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);