aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig8
-rw-r--r--drivers/pcmcia/Makefile14
-rw-r--r--drivers/pcmcia/at91_cf.c5
-rw-r--r--drivers/pcmcia/cardbus.c2
-rw-r--r--drivers/pcmcia/pxa2xx_balloon3.c22
-rw-r--r--drivers/pcmcia/pxa2xx_base.c5
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c39
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c23
-rw-r--r--drivers/pcmcia/pxa2xx_colibri.c21
-rw-r--r--drivers/pcmcia/pxa2xx_e740.c71
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c31
-rw-r--r--drivers/pcmcia/pxa2xx_palmld.c8
-rw-r--r--drivers/pcmcia/pxa2xx_palmtc.c8
-rw-r--r--drivers/pcmcia/pxa2xx_palmtx.c8
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c30
-rw-r--r--drivers/pcmcia/pxa2xx_stargate2.c34
-rw-r--r--drivers/pcmcia/pxa2xx_trizeps4.c62
-rw-r--r--drivers/pcmcia/pxa2xx_viper.c39
-rw-r--r--drivers/pcmcia/pxa2xx_vpac270.c54
-rw-r--r--drivers/pcmcia/sa1100_assabet.c65
-rw-r--r--drivers/pcmcia/sa1100_cerf.c52
-rw-r--r--drivers/pcmcia/sa1100_h3600.c94
-rw-r--r--drivers/pcmcia/sa1100_nanoengine.c132
-rw-r--r--drivers/pcmcia/sa1100_shannon.c56
-rw-r--r--drivers/pcmcia/sa1100_simpad.c27
-rw-r--r--drivers/pcmcia/sa1111_badge4.c (renamed from drivers/pcmcia/sa1100_badge4.c)3
-rw-r--r--drivers/pcmcia/sa1111_generic.c111
-rw-r--r--drivers/pcmcia/sa1111_generic.h1
-rw-r--r--drivers/pcmcia/sa1111_jornada720.c (renamed from drivers/pcmcia/sa1100_jornada720.c)8
-rw-r--r--drivers/pcmcia/sa1111_lubbock.c (renamed from drivers/pcmcia/pxa2xx_lubbock.c)1
-rw-r--r--drivers/pcmcia/sa1111_neponset.c (renamed from drivers/pcmcia/sa1100_neponset.c)18
-rw-r--r--drivers/pcmcia/sa11xx_base.c5
-rw-r--r--drivers/pcmcia/soc_common.c193
-rw-r--r--drivers/pcmcia/soc_common.h23
34 files changed, 401 insertions, 872 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index f9e3fb3a285b..bba3ab2066ee 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -183,10 +183,14 @@ config PCMCIA_BCM63XX
183config PCMCIA_SOC_COMMON 183config PCMCIA_SOC_COMMON
184 tristate 184 tristate
185 185
186config PCMCIA_SA11XX_BASE
187 tristate
188
186config PCMCIA_SA1100 189config PCMCIA_SA1100
187 tristate "SA1100 support" 190 tristate "SA1100 support"
188 depends on ARM && ARCH_SA1100 && PCMCIA 191 depends on ARM && ARCH_SA1100 && PCMCIA
189 select PCMCIA_SOC_COMMON 192 select PCMCIA_SOC_COMMON
193 select PCMCIA_SA11XX_BASE
190 help 194 help
191 Say Y here to include support for SA11x0-based PCMCIA or CF 195 Say Y here to include support for SA11x0-based PCMCIA or CF
192 sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/ 196 sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
@@ -196,8 +200,9 @@ config PCMCIA_SA1100
196 200
197config PCMCIA_SA1111 201config PCMCIA_SA1111
198 tristate "SA1111 support" 202 tristate "SA1111 support"
199 depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA 203 depends on ARM && SA1111 && PCMCIA
200 select PCMCIA_SOC_COMMON 204 select PCMCIA_SOC_COMMON
205 select PCMCIA_SA11XX_BASE if ARCH_SA1100
201 help 206 help
202 Say Y here to include support for SA1111-based PCMCIA or CF 207 Say Y here to include support for SA1111-based PCMCIA or CF
203 sockets, found on the Jornada 720, Graphicsmaster and other 208 sockets, found on the Jornada 720, Graphicsmaster and other
@@ -213,6 +218,7 @@ config PCMCIA_PXA2XX
213 || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \ 218 || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
214 || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ 219 || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
215 || MACH_COLIBRI320) 220 || MACH_COLIBRI320)
221 select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111
216 select PCMCIA_SOC_COMMON 222 select PCMCIA_SOC_COMMON
217 help 223 help
218 Say Y here to include support for the PXA2xx PCMCIA controller 224 Say Y here to include support for the PXA2xx PCMCIA controller
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index ec543a4ff2e4..47525de6a631 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -25,8 +25,9 @@ obj-$(CONFIG_I82092) += i82092.o
25obj-$(CONFIG_TCIC) += tcic.o 25obj-$(CONFIG_TCIC) += tcic.o
26obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o 26obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
27obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o 27obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o
28obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o 28obj-$(CONFIG_PCMCIA_SA11XX_BASE) += sa11xx_base.o
29obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o 29obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
30obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o
30obj-$(CONFIG_M32R_PCC) += m32r_pcc.o 31obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
31obj-$(CONFIG_M32R_CFC) += m32r_cfc.o 32obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
32obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o 33obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o
@@ -39,9 +40,10 @@ obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
39obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o 40obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o
40 41
41sa1111_cs-y += sa1111_generic.o 42sa1111_cs-y += sa1111_generic.o
42sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o 43sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1111_neponset.o
43sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o 44sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1111_badge4.o
44sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o 45sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1111_jornada720.o
46sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o
45 47
46sa1100_cs-y += sa1100_generic.o 48sa1100_cs-y += sa1100_generic.o
47sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o 49sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
@@ -52,9 +54,7 @@ sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o
52sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o 54sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
53sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o 55sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
54 56
55pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o
56pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o 57pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
57pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o
58pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o 58pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
59pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o 59pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
60pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o 60pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 4902206f53d9..1dd68f502634 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -26,6 +26,7 @@
26 26
27#include <mach/board.h> 27#include <mach/board.h>
28#include <mach/at91rm9200_mc.h> 28#include <mach/at91rm9200_mc.h>
29#include <mach/at91_ramc.h>
29 30
30 31
31/* 32/*
@@ -156,7 +157,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
156 /* 157 /*
157 * Use 16 bit accesses unless/until we need 8-bit i/o space. 158 * Use 16 bit accesses unless/until we need 8-bit i/o space.
158 */ 159 */
159 csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; 160 csr = at91_ramc_read(0, AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW;
160 161
161 /* 162 /*
162 * NOTE: this CF controller ignores IOIS16, so we can't really do 163 * NOTE: this CF controller ignores IOIS16, so we can't really do
@@ -175,7 +176,7 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
175 csr |= AT91_SMC_DBW_16; 176 csr |= AT91_SMC_DBW_16;
176 pr_debug("%s: 16bit i/o bus\n", driver_name); 177 pr_debug("%s: 16bit i/o bus\n", driver_name);
177 } 178 }
178 at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr); 179 at91_ramc_write(0, AT91_SMC_CSR(cf->board->chipselect), csr);
179 180
180 io->start = cf->socket.io_offset; 181 io->start = cf->socket.io_offset;
181 io->stop = io->start + SZ_2K - 1; 182 io->stop = io->start + SZ_2K - 1;
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 9a58862f1401..6e75153c5b4f 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -108,5 +108,5 @@ void cb_free(struct pcmcia_socket *s)
108 struct pci_dev *bridge = s->cb_dev; 108 struct pci_dev *bridge = s->cb_dev;
109 109
110 if (bridge) 110 if (bridge)
111 pci_remove_behind_bridge(bridge); 111 pci_stop_and_remove_behind_bridge(bridge);
112} 112}
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c
index 22a75e610f12..2ef576c5b69d 100644
--- a/drivers/pcmcia/pxa2xx_balloon3.c
+++ b/drivers/pcmcia/pxa2xx_balloon3.c
@@ -29,15 +29,6 @@
29 29
30#include "soc_common.h" 30#include "soc_common.h"
31 31
32/*
33 * These are a list of interrupt sources that provokes a polled
34 * check of status
35 */
36static struct pcmcia_irqs irqs[] = {
37 { 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" },
38 { 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" },
39};
40
41static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 32static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
42{ 33{
43 uint16_t ver; 34 uint16_t ver;
@@ -49,12 +40,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
49 ver); 40 ver);
50 41
51 skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ; 42 skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ;
52 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 43 skt->stat[SOC_STAT_CD].gpio = BALLOON3_GPIO_S0_CD;
53} 44 skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
45 skt->stat[SOC_STAT_BVD1].irq = BALLOON3_BP_NSTSCHG_IRQ;
46 skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
54 47
55static void balloon3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 48 return 0;
56{
57 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
58} 49}
59 50
60static unsigned long balloon3_pcmcia_status[2] = { 51static unsigned long balloon3_pcmcia_status[2] = {
@@ -85,13 +76,11 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
85 disable_irq(BALLOON3_BP_NSTSCHG_IRQ); 76 disable_irq(BALLOON3_BP_NSTSCHG_IRQ);
86 } 77 }
87 78
88 state->detect = !gpio_get_value(BALLOON3_GPIO_S0_CD);
89 state->ready = !!(status & BALLOON3_CF_nIRQ); 79 state->ready = !!(status & BALLOON3_CF_nIRQ);
90 state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1); 80 state->bvd1 = !!(status & BALLOON3_CF_nSTSCHG_BVD1);
91 state->bvd2 = 0; /* not available */ 81 state->bvd2 = 0; /* not available */
92 state->vs_3v = 1; /* Always true its a CF card */ 82 state->vs_3v = 1; /* Always true its a CF card */
93 state->vs_Xv = 0; /* not available */ 83 state->vs_Xv = 0; /* not available */
94 state->wrprot = 0; /* not available */
95} 84}
96 85
97static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 86static 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,
106static struct pcmcia_low_level balloon3_pcmcia_ops = { 95static struct pcmcia_low_level balloon3_pcmcia_ops = {
107 .owner = THIS_MODULE, 96 .owner = THIS_MODULE,
108 .hw_init = balloon3_pcmcia_hw_init, 97 .hw_init = balloon3_pcmcia_hw_init,
109 .hw_shutdown = balloon3_pcmcia_hw_shutdown,
110 .socket_state = balloon3_pcmcia_socket_state, 98 .socket_state = balloon3_pcmcia_socket_state,
111 .configure_socket = balloon3_pcmcia_configure_socket, 99 .configure_socket = balloon3_pcmcia_configure_socket,
112 .first = 0, 100 .first = 0,
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 85ac0957dcd0..490bb82b5bdb 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -317,10 +317,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
317 317
318 skt->nr = ops->first + i; 318 skt->nr = ops->first + i;
319 skt->clk = clk; 319 skt->clk = clk;
320 skt->ops = ops; 320 soc_pcmcia_init_one(skt, ops, &dev->dev);
321 skt->socket.owner = ops->owner;
322 skt->socket.dev.parent = &dev->dev;
323 skt->socket.pci_irq = NO_IRQ;
324 321
325 ret = pxa2xx_drv_pcmcia_add_one(skt); 322 ret = pxa2xx_drv_pcmcia_add_one(skt);
326 if (ret) 323 if (ret)
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 31ab6ddf52c9..da40908b29dd 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -25,17 +25,6 @@
25#define GPIO_PCMCIA_S1_RDYINT (8) 25#define GPIO_PCMCIA_S1_RDYINT (8)
26#define GPIO_PCMCIA_RESET (9) 26#define GPIO_PCMCIA_RESET (9)
27 27
28#define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
29#define PCMCIA_S1_CD_VALID gpio_to_irq(GPIO_PCMCIA_S1_CD_VALID)
30#define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
31#define PCMCIA_S1_RDYINT gpio_to_irq(GPIO_PCMCIA_S1_RDYINT)
32
33
34static struct pcmcia_irqs irqs[] = {
35 { .sock = 0, .str = "PCMCIA0 CD" },
36 { .sock = 1, .str = "PCMCIA1 CD" },
37};
38
39static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 28static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
40{ 29{
41 int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); 30 int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
@@ -43,19 +32,23 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
43 return ret; 32 return ret;
44 gpio_direction_output(GPIO_PCMCIA_RESET, 0); 33 gpio_direction_output(GPIO_PCMCIA_RESET, 0);
45 34
46 skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; 35 if (skt->nr == 0) {
47 irqs[0].irq = PCMCIA_S0_CD_VALID; 36 skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
48 irqs[1].irq = PCMCIA_S1_CD_VALID; 37 skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
49 ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 38 skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
50 if (!ret) 39 skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
51 gpio_free(GPIO_PCMCIA_RESET); 40 } else {
41 skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID;
42 skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
43 skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT;
44 skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY";
45 }
52 46
53 return ret; 47 return 0;
54} 48}
55 49
56static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) 50static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
57{ 51{
58 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
59 gpio_free(GPIO_PCMCIA_RESET); 52 gpio_free(GPIO_PCMCIA_RESET);
60} 53}
61 54
@@ -63,16 +56,8 @@ static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
63static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 56static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
64 struct pcmcia_state *state) 57 struct pcmcia_state *state)
65{ 58{
66 int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
67 int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
68
69 state->detect = !gpio_get_value(cd);
70 state->ready = !!gpio_get_value(rdy);
71 state->bvd1 = 1;
72 state->bvd2 = 1;
73 state->vs_3v = 0; 59 state->vs_3v = 0;
74 state->vs_Xv = 0; 60 state->vs_Xv = 0;
75 state->wrprot = 0; /* not available */
76} 61}
77 62
78 63
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index 3dc7621a0767..f59223f2307d 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -22,14 +22,6 @@
22#define GPIO_PCMCIA_S0_RDYINT (82) 22#define GPIO_PCMCIA_S0_RDYINT (82)
23#define GPIO_PCMCIA_RESET (53) 23#define GPIO_PCMCIA_RESET (53)
24 24
25#define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
26#define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
27
28
29static struct pcmcia_irqs irqs[] = {
30 { .sock = 0, .str = "PCMCIA0 CD" },
31};
32
33static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 25static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
34{ 26{
35 int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); 27 int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
@@ -37,18 +29,16 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
37 return ret; 29 return ret;
38 gpio_direction_output(GPIO_PCMCIA_RESET, 0); 30 gpio_direction_output(GPIO_PCMCIA_RESET, 0);
39 31
40 skt->socket.pci_irq = PCMCIA_S0_RDYINT; 32 skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
41 irqs[0].irq = PCMCIA_S0_CD_VALID; 33 skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
42 ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 34 skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
43 if (!ret) 35 skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
44 gpio_free(GPIO_PCMCIA_RESET);
45 36
46 return ret; 37 return ret;
47} 38}
48 39
49static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) 40static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
50{ 41{
51 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
52 gpio_free(GPIO_PCMCIA_RESET); 42 gpio_free(GPIO_PCMCIA_RESET);
53} 43}
54 44
@@ -56,13 +46,8 @@ static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
56static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 46static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
57 struct pcmcia_state *state) 47 struct pcmcia_state *state)
58{ 48{
59 state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0;
60 state->ready = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1;
61 state->bvd1 = 1;
62 state->bvd2 = 1;
63 state->vs_3v = 0; 49 state->vs_3v = 0;
64 state->vs_Xv = 0; 50 state->vs_Xv = 0;
65 state->wrprot = 0; /* not available */
66} 51}
67 52
68 53
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c
index c6dec572a05d..4dee7b2a8032 100644
--- a/drivers/pcmcia/pxa2xx_colibri.c
+++ b/drivers/pcmcia/pxa2xx_colibri.c
@@ -53,13 +53,6 @@ static struct gpio colibri_pcmcia_gpios[] = {
53 { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, 53 { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" },
54}; 54};
55 55
56static struct pcmcia_irqs colibri_irqs[] = {
57 {
58 .sock = 0,
59 .str = "PCMCIA CD"
60 },
61};
62
63static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 56static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
64{ 57{
65 int ret; 58 int ret;
@@ -69,19 +62,10 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
69 if (ret) 62 if (ret)
70 goto err1; 63 goto err1;
71 64
72 colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
73 skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); 65 skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
66 skt->stat[SOC_STAT_CD].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
67 skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
74 68
75 ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
76 ARRAY_SIZE(colibri_irqs));
77 if (ret)
78 goto err2;
79
80 return ret;
81
82err2:
83 gpio_free_array(colibri_pcmcia_gpios,
84 ARRAY_SIZE(colibri_pcmcia_gpios));
85err1: 69err1:
86 return ret; 70 return ret;
87} 71}
@@ -100,7 +84,6 @@ static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
100 state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); 84 state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
101 state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); 85 state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
102 state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); 86 state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
103 state->wrprot = 0;
104 state->vs_3v = 1; 87 state->vs_3v = 1;
105 state->vs_Xv = 0; 88 state->vs_Xv = 0;
106} 89}
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c
index 17cd2ce7428f..8751a323b448 100644
--- a/drivers/pcmcia/pxa2xx_e740.c
+++ b/drivers/pcmcia/pxa2xx_e740.c
@@ -23,53 +23,27 @@
23 23
24#include "soc_common.h" 24#include "soc_common.h"
25 25
26static struct pcmcia_irqs cd_irqs[] = {
27 {
28 .sock = 0,
29 .str = "CF card detect"
30 },
31 {
32 .sock = 1,
33 .str = "Wifi switch"
34 },
35};
36
37static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 26static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
38{ 27{
39 if (skt->nr == 0) 28 if (skt->nr == 0) {
40 skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY0); 29 skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0;
41 else 30 skt->stat[SOC_STAT_CD].name = "CF card detect";
42 skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY1); 31 skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0;
43 32 skt->stat[SOC_STAT_RDY].name = "CF ready";
44 cd_irqs[0].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD0); 33 } else {
45 cd_irqs[1].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD1); 34 skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1;
46 35 skt->stat[SOC_STAT_CD].name = "Wifi switch";
47 return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); 36 skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1;
48} 37 skt->stat[SOC_STAT_RDY].name = "Wifi ready";
38 }
49 39
50/* 40 return 0;
51 * Release all resources.
52 */
53static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
54{
55 soc_pcmcia_free_irqs(skt, &cd_irqs[skt->nr], 1);
56} 41}
57 42
58static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 43static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
59 struct pcmcia_state *state) 44 struct pcmcia_state *state)
60{ 45{
61 if (skt->nr == 0) {
62 state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD0) ? 0 : 1;
63 state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY0) ? 1 : 0;
64 } else {
65 state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD1) ? 0 : 1;
66 state->ready = gpio_get_value(GPIO_E740_PCMCIA_RDY1) ? 1 : 0;
67 }
68
69 state->vs_3v = 1; 46 state->vs_3v = 1;
70 state->bvd1 = 1;
71 state->bvd2 = 1;
72 state->wrprot = 0;
73 state->vs_Xv = 0; 47 state->vs_Xv = 0;
74} 48}
75 49
@@ -109,32 +83,11 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
109 return 0; 83 return 0;
110} 84}
111 85
112/*
113 * Enable card status IRQs on (re-)initialisation. This can
114 * be called at initialisation, power management event, or
115 * pcmcia event.
116 */
117static void e740_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
118{
119 soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
120}
121
122/*
123 * Disable card status IRQs on suspend.
124 */
125static void e740_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
126{
127 soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
128}
129
130static struct pcmcia_low_level e740_pcmcia_ops = { 86static struct pcmcia_low_level e740_pcmcia_ops = {
131 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
132 .hw_init = e740_pcmcia_hw_init, 88 .hw_init = e740_pcmcia_hw_init,
133 .hw_shutdown = e740_pcmcia_hw_shutdown,
134 .socket_state = e740_pcmcia_socket_state, 89 .socket_state = e740_pcmcia_socket_state,
135 .configure_socket = e740_pcmcia_configure_socket, 90 .configure_socket = e740_pcmcia_configure_socket,
136 .socket_init = e740_pcmcia_socket_init,
137 .socket_suspend = e740_pcmcia_socket_suspend,
138 .nr = 2, 91 .nr = 2,
139}; 92};
140 93
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index aded706c0b9f..7e32e25cdcb2 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -30,27 +30,26 @@
30#include "soc_common.h" 30#include "soc_common.h"
31 31
32 32
33static struct pcmcia_irqs irqs[] = {
34 { 0, MAINSTONE_S0_CD_IRQ, "PCMCIA0 CD" },
35 { 1, MAINSTONE_S1_CD_IRQ, "PCMCIA1 CD" },
36 { 0, MAINSTONE_S0_STSCHG_IRQ, "PCMCIA0 STSCHG" },
37 { 1, MAINSTONE_S1_STSCHG_IRQ, "PCMCIA1 STSCHG" },
38};
39
40static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 33static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
41{ 34{
42 /* 35 /*
43 * Setup default state of GPIO outputs 36 * Setup default state of GPIO outputs
44 * before we enable them as outputs. 37 * before we enable them as outputs.
45 */ 38 */
46 39 if (skt->nr == 0) {
47 skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ; 40 skt->socket.pci_irq = MAINSTONE_S0_IRQ;
48 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 41 skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ;
49} 42 skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
50 43 skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ;
51static void mst_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 44 skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
52{ 45 } else {
53 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); 46 skt->socket.pci_irq = MAINSTONE_S1_IRQ;
47 skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ;
48 skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
49 skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ;
50 skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG";
51 }
52 return 0;
54} 53}
55 54
56static unsigned long mst_pcmcia_status[2]; 55static unsigned long mst_pcmcia_status[2];
@@ -84,7 +83,6 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
84 state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0; 83 state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0;
85 state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1; 84 state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1;
86 state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1; 85 state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1;
87 state->wrprot = 0; /* not available */
88} 86}
89 87
90static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 88static 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,
131static struct pcmcia_low_level mst_pcmcia_ops __initdata = { 129static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
132 .owner = THIS_MODULE, 130 .owner = THIS_MODULE,
133 .hw_init = mst_pcmcia_hw_init, 131 .hw_init = mst_pcmcia_hw_init,
134 .hw_shutdown = mst_pcmcia_hw_shutdown,
135 .socket_state = mst_pcmcia_socket_state, 132 .socket_state = mst_pcmcia_socket_state,
136 .configure_socket = mst_pcmcia_configure_socket, 133 .configure_socket = mst_pcmcia_configure_socket,
137 .nr = 2, 134 .nr = 2,
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
index 6a8e011a8c13..ed7d4dbc39fa 100644
--- a/drivers/pcmcia/pxa2xx_palmld.c
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -23,7 +23,6 @@
23static struct gpio palmld_pcmcia_gpios[] = { 23static struct gpio palmld_pcmcia_gpios[] = {
24 { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, 24 { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" },
25 { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, 25 { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
26 { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
27}; 26};
28 27
29static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 28static 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)
33 ret = gpio_request_array(palmld_pcmcia_gpios, 32 ret = gpio_request_array(palmld_pcmcia_gpios,
34 ARRAY_SIZE(palmld_pcmcia_gpios)); 33 ARRAY_SIZE(palmld_pcmcia_gpios));
35 34
36 skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMLD_PCMCIA_READY); 35 skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY;
36 skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
37 37
38 return ret; 38 return ret;
39} 39}
@@ -47,10 +47,6 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
47 struct pcmcia_state *state) 47 struct pcmcia_state *state)
48{ 48{
49 state->detect = 1; /* always inserted */ 49 state->detect = 1; /* always inserted */
50 state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
51 state->bvd1 = 1;
52 state->bvd2 = 1;
53 state->wrprot = 0;
54 state->vs_3v = 1; 50 state->vs_3v = 1;
55 state->vs_Xv = 0; 51 state->vs_Xv = 0;
56} 52}
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c
index 9e38de769ba3..81225a7a8cbb 100644
--- a/drivers/pcmcia/pxa2xx_palmtc.c
+++ b/drivers/pcmcia/pxa2xx_palmtc.c
@@ -26,7 +26,6 @@ static struct gpio palmtc_pcmcia_gpios[] = {
26 { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, 26 { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
27 { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, 27 { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" },
28 { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, 28 { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
29 { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
30 { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, 29 { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" },
31}; 30};
32 31
@@ -37,7 +36,8 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
37 ret = gpio_request_array(palmtc_pcmcia_gpios, 36 ret = gpio_request_array(palmtc_pcmcia_gpios,
38 ARRAY_SIZE(palmtc_pcmcia_gpios)); 37 ARRAY_SIZE(palmtc_pcmcia_gpios));
39 38
40 skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTC_PCMCIA_READY); 39 skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY;
40 skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
41 41
42 return ret; 42 return ret;
43} 43}
@@ -51,10 +51,6 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
51 struct pcmcia_state *state) 51 struct pcmcia_state *state)
52{ 52{
53 state->detect = 1; /* always inserted */ 53 state->detect = 1; /* always inserted */
54 state->ready = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY);
55 state->bvd1 = 1;
56 state->bvd2 = 1;
57 state->wrprot = 0;
58 state->vs_3v = 1; 54 state->vs_3v = 1;
59 state->vs_Xv = 0; 55 state->vs_Xv = 0;
60} 56}
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
index 80645a688ee3..069b6bbcf319 100644
--- a/drivers/pcmcia/pxa2xx_palmtx.c
+++ b/drivers/pcmcia/pxa2xx_palmtx.c
@@ -23,7 +23,6 @@ static struct gpio palmtx_pcmcia_gpios[] = {
23 { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, 23 { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
24 { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, 24 { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
25 { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, 25 { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
26 { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
27}; 26};
28 27
29static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 28static 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)
33 ret = gpio_request_array(palmtx_pcmcia_gpios, 32 ret = gpio_request_array(palmtx_pcmcia_gpios,
34 ARRAY_SIZE(palmtx_pcmcia_gpios)); 33 ARRAY_SIZE(palmtx_pcmcia_gpios));
35 34
36 skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); 35 skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTX_PCMCIA_READY;
36 skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
37 37
38 return ret; 38 return ret;
39} 39}
@@ -47,10 +47,6 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
47 struct pcmcia_state *state) 47 struct pcmcia_state *state)
48{ 48{
49 state->detect = 1; /* always inserted */ 49 state->detect = 1; /* always inserted */
50 state->ready = !!gpio_get_value(GPIO_NR_PALMTX_PCMCIA_READY);
51 state->bvd1 = 1;
52 state->bvd2 = 1;
53 state->wrprot = 0;
54 state->vs_3v = 1; 50 state->vs_3v = 1;
55 state->vs_Xv = 0; 51 state->vs_Xv = 0;
56} 52}
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 69ae2fd22400..b066273b6b4f 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -46,21 +46,9 @@ static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt)
46 46
47static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 47static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
48{ 48{
49 int ret;
50
51 /* Register interrupts */
52 if (SCOOP_DEV[skt->nr].cd_irq >= 0) { 49 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
53 struct pcmcia_irqs cd_irq; 50 skt->stat[SOC_STAT_CD].irq = SCOOP_DEV[skt->nr].cd_irq;
54 51 skt->stat[SOC_STAT_CD].name = SCOOP_DEV[skt->nr].cd_irq_str;
55 cd_irq.sock = skt->nr;
56 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
57 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
58 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
59
60 if (ret) {
61 printk(KERN_ERR "Request for Compact Flash IRQ failed\n");
62 return ret;
63 }
64 } 52 }
65 53
66 skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq; 54 skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
@@ -68,19 +56,6 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
68 return 0; 56 return 0;
69} 57}
70 58
71static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
72{
73 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
74 struct pcmcia_irqs cd_irq;
75
76 cd_irq.sock = skt->nr;
77 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
78 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
79 soc_pcmcia_free_irqs(skt, &cd_irq, 1);
80 }
81}
82
83
84static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 59static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
85 struct pcmcia_state *state) 60 struct pcmcia_state *state)
86{ 61{
@@ -222,7 +197,6 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
222static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { 197static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = {
223 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
224 .hw_init = sharpsl_pcmcia_hw_init, 199 .hw_init = sharpsl_pcmcia_hw_init,
225 .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
226 .socket_state = sharpsl_pcmcia_socket_state, 200 .socket_state = sharpsl_pcmcia_socket_state,
227 .configure_socket = sharpsl_pcmcia_configure_socket, 201 .configure_socket = sharpsl_pcmcia_configure_socket,
228 .socket_init = sharpsl_pcmcia_socket_init, 202 .socket_init = sharpsl_pcmcia_socket_init,
diff --git a/drivers/pcmcia/pxa2xx_stargate2.c b/drivers/pcmcia/pxa2xx_stargate2.c
index 6c2366b74a35..1d73c4401fdd 100644
--- a/drivers/pcmcia/pxa2xx_stargate2.c
+++ b/drivers/pcmcia/pxa2xx_stargate2.c
@@ -33,10 +33,6 @@
33#define SG2_S0_GPIO_DETECT 53 33#define SG2_S0_GPIO_DETECT 53
34#define SG2_S0_GPIO_READY 81 34#define SG2_S0_GPIO_READY 81
35 35
36static struct pcmcia_irqs irqs[] = {
37 {.sock = 0, .str = "PCMCIA0 CD" },
38};
39
40static struct gpio sg2_pcmcia_gpios[] = { 36static struct gpio sg2_pcmcia_gpios[] = {
41 { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" }, 37 { SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },
42 { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" }, 38 { SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" },
@@ -44,27 +40,20 @@ static struct gpio sg2_pcmcia_gpios[] = {
44 40
45static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 41static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
46{ 42{
47 skt->socket.pci_irq = gpio_to_irq(SG2_S0_GPIO_READY); 43 skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT;
48 irqs[0].irq = gpio_to_irq(SG2_S0_GPIO_DETECT); 44 skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
49 45 skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY;
50 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 46 skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
51} 47 return 0;
52
53static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
54{
55 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
56} 48}
57 49
58static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 50static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
59 struct pcmcia_state *state) 51 struct pcmcia_state *state)
60{ 52{
61 state->detect = !gpio_get_value(SG2_S0_GPIO_DETECT);
62 state->ready = !!gpio_get_value(SG2_S0_GPIO_READY);
63 state->bvd1 = 0; /* not available - battery detect on card */ 53 state->bvd1 = 0; /* not available - battery detect on card */
64 state->bvd2 = 0; /* not available */ 54 state->bvd2 = 0; /* not available */
65 state->vs_3v = 1; /* not available - voltage detect for card */ 55 state->vs_3v = 1; /* not available - voltage detect for card */
66 state->vs_Xv = 0; /* not available */ 56 state->vs_Xv = 0; /* not available */
67 state->wrprot = 0; /* not available - write protect */
68} 57}
69 58
70static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 59static 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,
94 return 0; 83 return 0;
95} 84}
96 85
97static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
98{
99 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
100}
101
102static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
103{
104 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
105}
106
107static struct pcmcia_low_level sg2_pcmcia_ops __initdata = { 86static struct pcmcia_low_level sg2_pcmcia_ops __initdata = {
108 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
109 .hw_init = sg2_pcmcia_hw_init, 88 .hw_init = sg2_pcmcia_hw_init,
110 .hw_shutdown = sg2_pcmcia_hw_shutdown,
111 .socket_state = sg2_pcmcia_socket_state, 89 .socket_state = sg2_pcmcia_socket_state,
112 .configure_socket = sg2_pcmcia_configure_socket, 90 .configure_socket = sg2_pcmcia_configure_socket,
113 .socket_init = sg2_pcmcia_socket_init,
114 .socket_suspend = sg2_pcmcia_socket_suspend,
115 .nr = 1, 91 .nr = 1,
116}; 92};
117 93
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
index 7c33f898135a..d326ba1fa1ce 100644
--- a/drivers/pcmcia/pxa2xx_trizeps4.c
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -29,32 +29,17 @@
29 29
30extern void board_pcmcia_power(int power); 30extern void board_pcmcia_power(int power);
31 31
32static struct pcmcia_irqs irqs[] = {
33 { .sock = 0, .str = "cs0_cd" }
34 /* on other baseboards we can have more inputs */
35};
36
37static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 32static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
38{ 33{
39 int ret, i;
40 /* we dont have voltage/card/ready detection 34 /* we dont have voltage/card/ready detection
41 * so we dont need interrupts for it 35 * so we dont need interrupts for it
42 */ 36 */
43 switch (skt->nr) { 37 switch (skt->nr) {
44 case 0: 38 case 0:
45 if (gpio_request(GPIO_PRDY, "cf_irq") < 0) { 39 skt->stat[SOC_STAT_CD].gpio = GPIO_PCD;
46 pr_err("%s: sock %d unable to request gpio %d\n", __func__, 40 skt->stat[SOC_STAT_CD].name = "cs0_cd";
47 skt->nr, GPIO_PRDY); 41 skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY;
48 return -EBUSY; 42 skt->stat[SOC_STAT_RDY].name = "cs0_rdy";
49 }
50 if (gpio_direction_input(GPIO_PRDY) < 0) {
51 pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
52 skt->nr, GPIO_PRDY);
53 gpio_free(GPIO_PRDY);
54 return -EINVAL;
55 }
56 skt->socket.pci_irq = gpio_to_irq(GPIO_PRDY);
57 irqs[0].irq = gpio_to_irq(GPIO_PCD);
58 break; 43 break;
59 default: 44 default:
60 break; 45 break;
@@ -62,39 +47,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
62 /* release the reset of this card */ 47 /* release the reset of this card */
63 pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq); 48 pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
64 49
65 /* supplementory irqs for the socket */ 50 return 0;
66 for (i = 0; i < ARRAY_SIZE(irqs); i++) {
67 if (irqs[i].sock != skt->nr)
68 continue;
69 if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) {
70 pr_err("%s: sock %d unable to request gpio %d\n",
71 __func__, skt->nr, irq_to_gpio(irqs[i].irq));
72 ret = -EBUSY;
73 goto error;
74 }
75 if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) {
76 pr_err("%s: sock %d unable to set input gpio %d\n",
77 __func__, skt->nr, irq_to_gpio(irqs[i].irq));
78 ret = -EINVAL;
79 goto error;
80 }
81 }
82 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
83
84error:
85 for (; i >= 0; i--) {
86 gpio_free(irq_to_gpio(irqs[i].irq));
87 }
88 return (ret);
89}
90
91static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
92{
93 int i;
94 /* free allocated gpio's */
95 gpio_free(GPIO_PRDY);
96 for (i = 0; i < ARRAY_SIZE(irqs); i++)
97 gpio_free(irq_to_gpio(irqs[i].irq));
98} 51}
99 52
100static unsigned long trizeps_pcmcia_status[2]; 53static unsigned long trizeps_pcmcia_status[2];
@@ -118,13 +71,10 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
118 switch (skt->nr) { 71 switch (skt->nr) {
119 case 0: 72 case 0:
120 /* just fill in fix states */ 73 /* just fill in fix states */
121 state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
122 state->ready = gpio_get_value(GPIO_PRDY) ? 1 : 0;
123 state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0; 74 state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0;
124 state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0; 75 state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0;
125 state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1; 76 state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1;
126 state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1; 77 state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1;
127 state->wrprot = 0; /* not available */
128 break; 78 break;
129 79
130#ifndef CONFIG_MACH_TRIZEPS_CONXS 80#ifndef CONFIG_MACH_TRIZEPS_CONXS
@@ -136,7 +86,6 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
136 state->bvd2 = 0; 86 state->bvd2 = 0;
137 state->vs_3v = 0; 87 state->vs_3v = 0;
138 state->vs_Xv = 0; 88 state->vs_Xv = 0;
139 state->wrprot = 0;
140 break; 89 break;
141 90
142#endif 91#endif
@@ -204,7 +153,6 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
204static struct pcmcia_low_level trizeps_pcmcia_ops = { 153static struct pcmcia_low_level trizeps_pcmcia_ops = {
205 .owner = THIS_MODULE, 154 .owner = THIS_MODULE,
206 .hw_init = trizeps_pcmcia_hw_init, 155 .hw_init = trizeps_pcmcia_hw_init,
207 .hw_shutdown = trizeps_pcmcia_hw_shutdown,
208 .socket_state = trizeps_pcmcia_socket_state, 156 .socket_state = trizeps_pcmcia_socket_state,
209 .configure_socket = trizeps_pcmcia_configure_socket, 157 .configure_socket = trizeps_pcmcia_configure_socket,
210 .socket_init = trizeps_pcmcia_socket_init, 158 .socket_init = trizeps_pcmcia_socket_init,
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
index 1064b1c2869d..adfae4987a42 100644
--- a/drivers/pcmcia/pxa2xx_viper.c
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -32,13 +32,6 @@
32 32
33static struct platform_device *arcom_pcmcia_dev; 33static struct platform_device *arcom_pcmcia_dev;
34 34
35static struct pcmcia_irqs irqs[] = {
36 {
37 .sock = 0,
38 .str = "PCMCIA_CD",
39 },
40};
41
42static inline struct arcom_pcmcia_pdata *viper_get_pdata(void) 35static inline struct arcom_pcmcia_pdata *viper_get_pdata(void)
43{ 36{
44 return arcom_pcmcia_dev->dev.platform_data; 37 return arcom_pcmcia_dev->dev.platform_data;
@@ -49,38 +42,28 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
49 struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); 42 struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
50 unsigned long flags; 43 unsigned long flags;
51 44
52 skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio); 45 skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio;
53 irqs[0].irq = gpio_to_irq(pdata->cd_gpio); 46 skt->stat[SOC_STAT_CD].name = "PCMCIA_CD";
54 47 skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio;
55 if (gpio_request(pdata->cd_gpio, "CF detect")) 48 skt->stat[SOC_STAT_RDY].name = "CF ready";
56 goto err_request_cd;
57
58 if (gpio_request(pdata->rdy_gpio, "CF ready"))
59 goto err_request_rdy;
60 49
61 if (gpio_request(pdata->pwr_gpio, "CF power")) 50 if (gpio_request(pdata->pwr_gpio, "CF power"))
62 goto err_request_pwr; 51 goto err_request_pwr;
63 52
64 local_irq_save(flags); 53 local_irq_save(flags);
65 54
66 if (gpio_direction_output(pdata->pwr_gpio, 0) || 55 if (gpio_direction_output(pdata->pwr_gpio, 0)) {
67 gpio_direction_input(pdata->cd_gpio) ||
68 gpio_direction_input(pdata->rdy_gpio)) {
69 local_irq_restore(flags); 56 local_irq_restore(flags);
70 goto err_dir; 57 goto err_dir;
71 } 58 }
72 59
73 local_irq_restore(flags); 60 local_irq_restore(flags);
74 61
75 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 62 return 0;
76 63
77err_dir: 64err_dir:
78 gpio_free(pdata->pwr_gpio); 65 gpio_free(pdata->pwr_gpio);
79err_request_pwr: 66err_request_pwr:
80 gpio_free(pdata->rdy_gpio);
81err_request_rdy:
82 gpio_free(pdata->cd_gpio);
83err_request_cd:
84 dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n"); 67 dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n");
85 return -1; 68 return -1;
86} 69}
@@ -92,22 +75,12 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
92{ 75{
93 struct arcom_pcmcia_pdata *pdata = viper_get_pdata(); 76 struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
94 77
95 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
96 gpio_free(pdata->pwr_gpio); 78 gpio_free(pdata->pwr_gpio);
97 gpio_free(pdata->rdy_gpio);
98 gpio_free(pdata->cd_gpio);
99} 79}
100 80
101static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 81static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
102 struct pcmcia_state *state) 82 struct pcmcia_state *state)
103{ 83{
104 struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
105
106 state->detect = !gpio_get_value(pdata->cd_gpio);
107 state->ready = !!gpio_get_value(pdata->rdy_gpio);
108 state->bvd1 = 1;
109 state->bvd2 = 1;
110 state->wrprot = 0;
111 state->vs_3v = 1; /* Can only apply 3.3V */ 84 state->vs_3v = 1; /* Can only apply 3.3V */
112 state->vs_Xv = 0; 85 state->vs_Xv = 0;
113} 86}
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c
index 61b17d235dbe..a47dcd24a26a 100644
--- a/drivers/pcmcia/pxa2xx_vpac270.c
+++ b/drivers/pcmcia/pxa2xx_vpac270.c
@@ -23,29 +23,14 @@
23#include "soc_common.h" 23#include "soc_common.h"
24 24
25static struct gpio vpac270_pcmcia_gpios[] = { 25static struct gpio vpac270_pcmcia_gpios[] = {
26 { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" },
27 { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" },
28 { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, 26 { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" },
29 { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, 27 { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" },
30}; 28};
31 29
32static struct gpio vpac270_cf_gpios[] = { 30static struct gpio vpac270_cf_gpios[] = {
33 { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" },
34 { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" },
35 { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, 31 { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" },
36}; 32};
37 33
38static struct pcmcia_irqs cd_irqs[] = {
39 {
40 .sock = 0,
41 .str = "PCMCIA CD"
42 },
43 {
44 .sock = 1,
45 .str = "CF CD"
46 },
47};
48
49static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 34static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
50{ 35{
51 int ret; 36 int ret;
@@ -54,20 +39,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
54 ret = gpio_request_array(vpac270_pcmcia_gpios, 39 ret = gpio_request_array(vpac270_pcmcia_gpios,
55 ARRAY_SIZE(vpac270_pcmcia_gpios)); 40 ARRAY_SIZE(vpac270_pcmcia_gpios));
56 41
57 skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); 42 skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD;
58 cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD); 43 skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
59 44 skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY;
60 if (!ret) 45 skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
61 ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
62 } else { 46 } else {
63 ret = gpio_request_array(vpac270_cf_gpios, 47 ret = gpio_request_array(vpac270_cf_gpios,
64 ARRAY_SIZE(vpac270_cf_gpios)); 48 ARRAY_SIZE(vpac270_cf_gpios));
65 49
66 skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); 50 skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD;
67 cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD); 51 skt->stat[SOC_STAT_CD].name = "CF CD";
68 52 skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY;
69 if (!ret) 53 skt->stat[SOC_STAT_RDY].name = "CF Ready";
70 ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
71 } 54 }
72 55
73 return ret; 56 return ret;
@@ -86,16 +69,6 @@ static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
86static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 69static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
87 struct pcmcia_state *state) 70 struct pcmcia_state *state)
88{ 71{
89 if (skt->nr == 0) {
90 state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD);
91 state->ready = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY);
92 } else {
93 state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD);
94 state->ready = !!gpio_get_value(GPIO12_VPAC270_CF_RDY);
95 }
96 state->bvd1 = 1;
97 state->bvd2 = 1;
98 state->wrprot = 0;
99 state->vs_3v = 1; 72 state->vs_3v = 1;
100 state->vs_Xv = 0; 73 state->vs_Xv = 0;
101} 74}
@@ -117,14 +90,6 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
117 return 0; 90 return 0;
118} 91}
119 92
120static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
121{
122}
123
124static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
125{
126}
127
128static struct pcmcia_low_level vpac270_pcmcia_ops = { 93static struct pcmcia_low_level vpac270_pcmcia_ops = {
129 .owner = THIS_MODULE, 94 .owner = THIS_MODULE,
130 95
@@ -136,9 +101,6 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = {
136 101
137 .socket_state = vpac270_pcmcia_socket_state, 102 .socket_state = vpac270_pcmcia_socket_state,
138 .configure_socket = vpac270_pcmcia_configure_socket, 103 .configure_socket = vpac270_pcmcia_configure_socket,
139
140 .socket_init = vpac270_pcmcia_socket_init,
141 .socket_suspend = vpac270_pcmcia_socket_suspend,
142}; 104};
143 105
144static struct platform_device *vpac270_pcmcia_device; 106static struct platform_device *vpac270_pcmcia_device;
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index f1e882272ab0..ba8557eea618 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -10,46 +10,30 @@
10#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/gpio.h>
13 14
14#include <mach/hardware.h>
15#include <asm/mach-types.h> 15#include <asm/mach-types.h>
16#include <asm/irq.h>
17#include <asm/signal.h>
18#include <mach/assabet.h> 16#include <mach/assabet.h>
19 17
20#include "sa1100_generic.h" 18#include "sa1100_generic.h"
21 19
22static struct pcmcia_irqs irqs[] = {
23 { 1, ASSABET_IRQ_GPIO_CF_CD, "CF CD" },
24 { 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" },
25 { 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" },
26};
27
28static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 20static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
29{ 21{
30 skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ; 22 skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD;
31 23 skt->stat[SOC_STAT_CD].name = "CF CD";
32 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 24 skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1;
33} 25 skt->stat[SOC_STAT_BVD1].name = "CF BVD1";
26 skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2;
27 skt->stat[SOC_STAT_BVD2].name = "CF BVD2";
28 skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ;
29 skt->stat[SOC_STAT_RDY].name = "CF RDY";
34 30
35/* 31 return 0;
36 * Release all resources.
37 */
38static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
39{
40 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
41} 32}
42 33
43static void 34static void
44assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 35assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
45{ 36{
46 unsigned long levels = GPLR;
47
48 state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
49 state->ready = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
50 state->bvd1 = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
51 state->bvd2 = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
52 state->wrprot = 0; /* Not available on Assabet. */
53 state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ 37 state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */
54 state->vs_Xv = 0; 38 state->vs_Xv = 0;
55} 39}
@@ -78,38 +62,24 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat
78 return -1; 62 return -1;
79 } 63 }
80 64
81 /* Silently ignore Vpp, output enable, speaker enable. */ 65 /* Silently ignore Vpp, speaker enable. */
82 66
83 if (state->flags & SS_RESET) 67 if (state->flags & SS_RESET)
84 mask |= ASSABET_BCR_CF_RST; 68 mask |= ASSABET_BCR_CF_RST;
69 if (!(state->flags & SS_OUTPUT_ENA))
70 mask |= ASSABET_BCR_CF_BUS_OFF;
85 71
86 ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask); 72 ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
73 ASSABET_BCR_CF_BUS_OFF, mask);
87 74
88 return 0; 75 return 0;
89} 76}
90 77
91/* 78/*
92 * Enable card status IRQs on (re-)initialisation. This can
93 * be called at initialisation, power management event, or
94 * pcmcia event.
95 */
96static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
97{
98 /*
99 * Enable CF bus
100 */
101 ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
102
103 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
104}
105
106/*
107 * Disable card status IRQs on suspend. 79 * Disable card status IRQs on suspend.
108 */ 80 */
109static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 81static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
110{ 82{
111 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
112
113 /* 83 /*
114 * Tristate the CF bus signals. Also assert CF 84 * Tristate the CF bus signals. Also assert CF
115 * reset as per user guide page 4-11. 85 * reset as per user guide page 4-11.
@@ -119,14 +89,9 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
119 89
120static struct pcmcia_low_level assabet_pcmcia_ops = { 90static struct pcmcia_low_level assabet_pcmcia_ops = {
121 .owner = THIS_MODULE, 91 .owner = THIS_MODULE,
122
123 .hw_init = assabet_pcmcia_hw_init, 92 .hw_init = assabet_pcmcia_hw_init,
124 .hw_shutdown = assabet_pcmcia_hw_shutdown,
125
126 .socket_state = assabet_pcmcia_socket_state, 93 .socket_state = assabet_pcmcia_socket_state,
127 .configure_socket = assabet_pcmcia_configure_socket, 94 .configure_socket = assabet_pcmcia_configure_socket,
128
129 .socket_init = assabet_pcmcia_socket_init,
130 .socket_suspend = assabet_pcmcia_socket_suspend, 95 .socket_suspend = assabet_pcmcia_socket_suspend,
131}; 96};
132 97
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index 30560df8c76b..c59c44921a3a 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -10,6 +10,7 @@
10#include <linux/device.h> 10#include <linux/device.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/gpio.h>
13 14
14#include <mach/hardware.h> 15#include <mach/hardware.h>
15#include <asm/mach-types.h> 16#include <asm/mach-types.h>
@@ -19,34 +20,34 @@
19 20
20#define CERF_SOCKET 1 21#define CERF_SOCKET 1
21 22
22static struct pcmcia_irqs irqs[] = {
23 { CERF_SOCKET, CERF_IRQ_GPIO_CF_CD, "CF_CD" },
24 { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" },
25 { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" }
26};
27
28static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 23static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
29{ 24{
30 skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; 25 int ret;
26
27 ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET");
28 if (ret)
29 return ret;
30
31 skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD;
32 skt->stat[SOC_STAT_CD].name = "CF_CD";
33 skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1;
34 skt->stat[SOC_STAT_BVD1].name = "CF_BVD1";
35 skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2;
36 skt->stat[SOC_STAT_BVD2].name = "CF_BVD2";
37 skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ;
38 skt->stat[SOC_STAT_RDY].name = "CF_IRQ";
31 39
32 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 40 return 0;
33} 41}
34 42
35static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 43static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
36{ 44{
37 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); 45 gpio_free(CERF_GPIO_CF_RESET);
38} 46}
39 47
40static void 48static void
41cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 49cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
42{ 50{
43 unsigned long levels = GPLR;
44
45 state->detect = (levels & CERF_GPIO_CF_CD) ?0:1;
46 state->ready = (levels & CERF_GPIO_CF_IRQ) ?1:0;
47 state->bvd1 = (levels & CERF_GPIO_CF_BVD1)?1:0;
48 state->bvd2 = (levels & CERF_GPIO_CF_BVD2)?1:0;
49 state->wrprot = 0;
50 state->vs_3v = 1; 51 state->vs_3v = 1;
51 state->vs_Xv = 0; 52 state->vs_Xv = 0;
52} 53}
@@ -67,34 +68,17 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
67 return -1; 68 return -1;
68 } 69 }
69 70
70 if (state->flags & SS_RESET) { 71 gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET));
71 GPSR = CERF_GPIO_CF_RESET;
72 } else {
73 GPCR = CERF_GPIO_CF_RESET;
74 }
75 72
76 return 0; 73 return 0;
77} 74}
78 75
79static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
80{
81 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
82}
83
84static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
85{
86 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
87}
88
89static struct pcmcia_low_level cerf_pcmcia_ops = { 76static struct pcmcia_low_level cerf_pcmcia_ops = {
90 .owner = THIS_MODULE, 77 .owner = THIS_MODULE,
91 .hw_init = cerf_pcmcia_hw_init, 78 .hw_init = cerf_pcmcia_hw_init,
92 .hw_shutdown = cerf_pcmcia_hw_shutdown, 79 .hw_shutdown = cerf_pcmcia_hw_shutdown,
93 .socket_state = cerf_pcmcia_socket_state, 80 .socket_state = cerf_pcmcia_socket_state,
94 .configure_socket = cerf_pcmcia_configure_socket, 81 .configure_socket = cerf_pcmcia_configure_socket,
95
96 .socket_init = cerf_pcmcia_socket_init,
97 .socket_suspend = cerf_pcmcia_socket_suspend,
98}; 82};
99 83
100int __devinit pcmcia_cerf_init(struct device *dev) 84int __devinit pcmcia_cerf_init(struct device *dev)
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index edf8f0028898..d9c7337b909c 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -19,36 +19,20 @@
19 19
20#include "sa1100_generic.h" 20#include "sa1100_generic.h"
21 21
22static struct pcmcia_irqs irqs[] = {
23 { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
24 { .sock = 1, .str = "PCMCIA CD1" }
25};
26
27static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 22static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
28{ 23{
29 int err; 24 int err;
30 25
31 switch (skt->nr) { 26 switch (skt->nr) {
32 case 0: 27 case 0:
33 err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0"); 28 skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0;
34 if (err) 29 skt->stat[SOC_STAT_CD].name = "PCMCIA CD0";
35 goto err00; 30 skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0;
36 err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0); 31 skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0";
37 if (err)
38 goto err01;
39 skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0);
40
41 err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0");
42 if (err)
43 goto err01;
44 err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0);
45 if (err)
46 goto err02;
47 irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0);
48 32
49 err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON"); 33 err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
50 if (err) 34 if (err)
51 goto err02; 35 goto err01;
52 err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0); 36 err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
53 if (err) 37 if (err)
54 goto err03; 38 goto err03;
@@ -70,30 +54,12 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
70 err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0); 54 err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0);
71 if (err) 55 if (err)
72 goto err06; 56 goto err06;
73 err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
74 if (err)
75 goto err06;
76 break; 57 break;
77 case 1: 58 case 1:
78 err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1"); 59 skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1;
79 if (err) 60 skt->stat[SOC_STAT_CD].name = "PCMCIA CD1";
80 goto err10; 61 skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1;
81 err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1); 62 skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1";
82 if (err)
83 goto err11;
84 skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
85
86 err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
87 if (err)
88 goto err11;
89 err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
90 if (err)
91 goto err12;
92 irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
93
94 err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
95 if (err)
96 goto err12;
97 break; 63 break;
98 } 64 }
99 return 0; 65 return 0;
@@ -102,19 +68,12 @@ err06: gpio_free(H3XXX_EGPIO_CARD_RESET);
102err05: gpio_free(H3XXX_EGPIO_OPT_RESET); 68err05: gpio_free(H3XXX_EGPIO_OPT_RESET);
103err04: gpio_free(H3XXX_EGPIO_OPT_ON); 69err04: gpio_free(H3XXX_EGPIO_OPT_ON);
104err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); 70err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
105err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
106err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); 71err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
107err00: return err; 72 return err;
108
109err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0);
110err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
111err10: return err;
112} 73}
113 74
114static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 75static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
115{ 76{
116 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
117
118 switch (skt->nr) { 77 switch (skt->nr) {
119 case 0: 78 case 0:
120 /* Disable CF bus: */ 79 /* Disable CF bus: */
@@ -126,12 +85,8 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
126 gpio_free(H3XXX_EGPIO_OPT_RESET); 85 gpio_free(H3XXX_EGPIO_OPT_RESET);
127 gpio_free(H3XXX_EGPIO_OPT_ON); 86 gpio_free(H3XXX_EGPIO_OPT_ON);
128 gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); 87 gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
129 gpio_free(H3XXX_GPIO_PCMCIA_CD0);
130 gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
131 break; 88 break;
132 case 1: 89 case 1:
133 gpio_free(H3XXX_GPIO_PCMCIA_CD1);
134 gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
135 break; 90 break;
136 } 91 }
137} 92}
@@ -139,27 +94,10 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
139static void 94static void
140h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 95h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
141{ 96{
142 switch (skt->nr) { 97 state->bvd1 = 0;
143 case 0: 98 state->bvd2 = 0;
144 state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0); 99 state->vs_3v = 0;
145 state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0); 100 state->vs_Xv = 0;
146 state->bvd1 = 0;
147 state->bvd2 = 0;
148 state->wrprot = 0; /* Not available on H3600. */
149 state->vs_3v = 0;
150 state->vs_Xv = 0;
151 break;
152
153 case 1:
154 state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
155 state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
156 state->bvd1 = 0;
157 state->bvd2 = 0;
158 state->wrprot = 0; /* Not available on H3600. */
159 state->vs_3v = 0;
160 state->vs_Xv = 0;
161 break;
162 }
163} 101}
164 102
165static int 103static int
@@ -186,14 +124,10 @@ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
186 gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0); 124 gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);
187 125
188 msleep(10); 126 msleep(10);
189
190 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
191} 127}
192 128
193static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 129static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
194{ 130{
195 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
196
197 /* 131 /*
198 * FIXME: This doesn't fit well. We don't have the mechanism in 132 * FIXME: This doesn't fit well. We don't have the mechanism in
199 * the generic PCMCIA layer to deal with the idea of two sockets 133 * the generic PCMCIA layer to deal with the idea of two sockets
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c
index 93b9c9ba57c3..35c30ff41e81 100644
--- a/drivers/pcmcia/sa1100_nanoengine.c
+++ b/drivers/pcmcia/sa1100_nanoengine.c
@@ -19,6 +19,7 @@
19 */ 19 */
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/gpio.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
23#include <linux/irq.h> 24#include <linux/irq.h>
24#include <linux/init.h> 25#include <linux/init.h>
@@ -34,43 +35,23 @@
34 35
35#include "sa1100_generic.h" 36#include "sa1100_generic.h"
36 37
37static struct pcmcia_irqs irqs_skt0[] = {
38 /* socket, IRQ, name */
39 { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" },
40};
41
42static struct pcmcia_irqs irqs_skt1[] = {
43 /* socket, IRQ, name */
44 { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" },
45};
46
47struct nanoengine_pins { 38struct nanoengine_pins {
48 unsigned input_pins;
49 unsigned output_pins; 39 unsigned output_pins;
50 unsigned clear_outputs; 40 unsigned clear_outputs;
51 unsigned transition_pins; 41 int gpio_rst;
52 unsigned pci_irq; 42 int gpio_cd;
53 struct pcmcia_irqs *pcmcia_irqs; 43 int gpio_rdy;
54 unsigned pcmcia_irqs_size;
55}; 44};
56 45
57static struct nanoengine_pins nano_skts[] = { 46static struct nanoengine_pins nano_skts[] = {
58 { 47 {
59 .input_pins = GPIO_PC_READY0 | GPIO_PC_CD0, 48 .gpio_rst = GPIO_PC_RESET0,
60 .output_pins = GPIO_PC_RESET0, 49 .gpio_cd = GPIO_PC_CD0,
61 .clear_outputs = GPIO_PC_RESET0, 50 .gpio_rdy = GPIO_PC_READY0,
62 .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD0,
63 .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY0,
64 .pcmcia_irqs = irqs_skt0,
65 .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt0)
66 }, { 51 }, {
67 .input_pins = GPIO_PC_READY1 | GPIO_PC_CD1, 52 .gpio_rst = GPIO_PC_RESET1,
68 .output_pins = GPIO_PC_RESET1, 53 .gpio_cd = GPIO_PC_CD1,
69 .clear_outputs = GPIO_PC_RESET1, 54 .gpio_rdy = GPIO_PC_READY1,
70 .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD1,
71 .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY1,
72 .pcmcia_irqs = irqs_skt1,
73 .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt1)
74 } 55 }
75}; 56};
76 57
@@ -79,58 +60,38 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
79static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 60static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
80{ 61{
81 unsigned i = skt->nr; 62 unsigned i = skt->nr;
63 int ret;
82 64
83 if (i >= num_nano_pcmcia_sockets) 65 if (i >= num_nano_pcmcia_sockets)
84 return -ENXIO; 66 return -ENXIO;
85 67
86 GPDR &= ~nano_skts[i].input_pins; 68 ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW,
87 GPDR |= nano_skts[i].output_pins; 69 i ? "PC RST1" : "PC RST0");
88 GPCR = nano_skts[i].clear_outputs; 70 if (ret)
89 irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); 71 return ret;
90 skt->socket.pci_irq = nano_skts[i].pci_irq; 72
73 skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd;
74 skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0";
75 skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy;
76 skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0";
91 77
92 return soc_pcmcia_request_irqs(skt, 78 return 0;
93 nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
94} 79}
95 80
96/*
97 * Release all resources.
98 */
99static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 81static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
100{ 82{
101 unsigned i = skt->nr; 83 gpio_free(nano_skts[skt->nr].gpio_rst);
102
103 if (i >= num_nano_pcmcia_sockets)
104 return;
105
106 soc_pcmcia_free_irqs(skt,
107 nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
108} 84}
109 85
110static int nanoengine_pcmcia_configure_socket( 86static int nanoengine_pcmcia_configure_socket(
111 struct soc_pcmcia_socket *skt, const socket_state_t *state) 87 struct soc_pcmcia_socket *skt, const socket_state_t *state)
112{ 88{
113 unsigned reset;
114 unsigned i = skt->nr; 89 unsigned i = skt->nr;
115 90
116 if (i >= num_nano_pcmcia_sockets) 91 if (i >= num_nano_pcmcia_sockets)
117 return -ENXIO; 92 return -ENXIO;
118 93
119 switch (i) { 94 gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET));
120 case 0:
121 reset = GPIO_PC_RESET0;
122 break;
123 case 1:
124 reset = GPIO_PC_RESET1;
125 break;
126 default:
127 return -ENXIO;
128 }
129
130 if (state->flags & SS_RESET)
131 GPSR = reset;
132 else
133 GPCR = reset;
134 95
135 return 0; 96 return 0;
136} 97}
@@ -138,62 +99,17 @@ static int nanoengine_pcmcia_configure_socket(
138static void nanoengine_pcmcia_socket_state( 99static void nanoengine_pcmcia_socket_state(
139 struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 100 struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
140{ 101{
141 unsigned long levels = GPLR;
142 unsigned i = skt->nr; 102 unsigned i = skt->nr;
143 103
144 if (i >= num_nano_pcmcia_sockets) 104 if (i >= num_nano_pcmcia_sockets)
145 return; 105 return;
146 106
147 memset(state, 0, sizeof(struct pcmcia_state));
148 switch (i) {
149 case 0:
150 state->ready = (levels & GPIO_PC_READY0) ? 1 : 0;
151 state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0;
152 break;
153 case 1:
154 state->ready = (levels & GPIO_PC_READY1) ? 1 : 0;
155 state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0;
156 break;
157 default:
158 return;
159 }
160 state->bvd1 = 1; 107 state->bvd1 = 1;
161 state->bvd2 = 1; 108 state->bvd2 = 1;
162 state->wrprot = 0; /* Not available */
163 state->vs_3v = 1; /* Can only apply 3.3V */ 109 state->vs_3v = 1; /* Can only apply 3.3V */
164 state->vs_Xv = 0; 110 state->vs_Xv = 0;
165} 111}
166 112
167/*
168 * Enable card status IRQs on (re-)initialisation. This can
169 * be called at initialisation, power management event, or
170 * pcmcia event.
171 */
172static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
173{
174 unsigned i = skt->nr;
175
176 if (i >= num_nano_pcmcia_sockets)
177 return;
178
179 soc_pcmcia_enable_irqs(skt,
180 nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
181}
182
183/*
184 * Disable card status IRQs on suspend.
185 */
186static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
187{
188 unsigned i = skt->nr;
189
190 if (i >= num_nano_pcmcia_sockets)
191 return;
192
193 soc_pcmcia_disable_irqs(skt,
194 nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
195}
196
197static struct pcmcia_low_level nanoengine_pcmcia_ops = { 113static struct pcmcia_low_level nanoengine_pcmcia_ops = {
198 .owner = THIS_MODULE, 114 .owner = THIS_MODULE,
199 115
@@ -202,8 +118,6 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = {
202 118
203 .configure_socket = nanoengine_pcmcia_configure_socket, 119 .configure_socket = nanoengine_pcmcia_configure_socket,
204 .socket_state = nanoengine_pcmcia_socket_state, 120 .socket_state = nanoengine_pcmcia_socket_state,
205 .socket_init = nanoengine_pcmcia_socket_init,
206 .socket_suspend = nanoengine_pcmcia_socket_suspend,
207}; 121};
208 122
209int pcmcia_nanoengine_init(struct device *dev) 123int pcmcia_nanoengine_init(struct device *dev)
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 7ff1b43540b8..decb34730bcf 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -15,40 +15,35 @@
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include "sa1100_generic.h" 16#include "sa1100_generic.h"
17 17
18static struct pcmcia_irqs irqs[] = {
19 { 0, SHANNON_IRQ_GPIO_EJECT_0, "PCMCIA_CD_0" },
20 { 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" },
21};
22
23static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 18static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
24{ 19{
25 /* All those are inputs */ 20 /* All those are inputs */
26 GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 21 GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) |
27 SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); 22 GPIO_GPIO(SHANNON_GPIO_EJECT_1) |
28 GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 23 GPIO_GPIO(SHANNON_GPIO_RDY_0) |
29 SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1); 24 GPIO_GPIO(SHANNON_GPIO_RDY_1));
30 25
31 skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0; 26 if (skt->nr == 0) {
32 27 skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0;
33 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 28 skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0";
34} 29 skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0;
30 skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0";
31 } else {
32 skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1;
33 skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1";
34 skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1;
35 skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1";
36 }
35 37
36static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 38 return 0;
37{
38 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
39} 39}
40 40
41static void 41static void
42shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 42shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
43 struct pcmcia_state *state) 43 struct pcmcia_state *state)
44{ 44{
45 unsigned long levels = GPLR;
46
47 switch (skt->nr) { 45 switch (skt->nr) {
48 case 0: 46 case 0:
49 state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
50 state->ready = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
51 state->wrprot = 0; /* Not available on Shannon. */
52 state->bvd1 = 1; 47 state->bvd1 = 1;
53 state->bvd2 = 1; 48 state->bvd2 = 1;
54 state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ 49 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,
56 break; 51 break;
57 52
58 case 1: 53 case 1:
59 state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
60 state->ready = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
61 state->wrprot = 0; /* Not available on Shannon. */
62 state->bvd1 = 1; 54 state->bvd1 = 1;
63 state->bvd2 = 1; 55 state->bvd2 = 1;
64 state->vs_3v = 1; /* FIXME Can only apply 3.3V on Shannon. */ 56 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,
92 return 0; 84 return 0;
93} 85}
94 86
95static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
96{
97 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
98}
99
100static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
101{
102 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
103}
104
105static struct pcmcia_low_level shannon_pcmcia_ops = { 87static struct pcmcia_low_level shannon_pcmcia_ops = {
106 .owner = THIS_MODULE, 88 .owner = THIS_MODULE,
107 .hw_init = shannon_pcmcia_hw_init, 89 .hw_init = shannon_pcmcia_hw_init,
108 .hw_shutdown = shannon_pcmcia_hw_shutdown,
109 .socket_state = shannon_pcmcia_socket_state, 90 .socket_state = shannon_pcmcia_socket_state,
110 .configure_socket = shannon_pcmcia_configure_socket, 91 .configure_socket = shannon_pcmcia_configure_socket,
111
112 .socket_init = shannon_pcmcia_socket_init,
113 .socket_suspend = shannon_pcmcia_socket_suspend,
114}; 92};
115 93
116int __devinit pcmcia_shannon_init(struct device *dev) 94int __devinit pcmcia_shannon_init(struct device *dev)
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 0fac9658b020..8647b17c449e 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -15,24 +15,21 @@
15#include <mach/simpad.h> 15#include <mach/simpad.h>
16#include "sa1100_generic.h" 16#include "sa1100_generic.h"
17 17
18static struct pcmcia_irqs irqs[] = {
19 { 1, IRQ_GPIO_CF_CD, "CF_CD" },
20};
21
22static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 18static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
23{ 19{
24 20
25 simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); 21 simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
26 22
27 skt->socket.pci_irq = IRQ_GPIO_CF_IRQ; 23 skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD;
24 skt->stat[SOC_STAT_CD].name = "CF_CD";
25 skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ;
26 skt->stat[SOC_STAT_RDY].name = "CF_RDY";
28 27
29 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 28 return 0;
30} 29}
31 30
32static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 31static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
33{ 32{
34 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
35
36 /* Disable CF bus: */ 33 /* Disable CF bus: */
37 /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/ 34 /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
38 simpad_clear_cs3_bit(PCMCIA_RESET); 35 simpad_clear_cs3_bit(PCMCIA_RESET);
@@ -42,14 +39,13 @@ static void
42simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 39simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
43 struct pcmcia_state *state) 40 struct pcmcia_state *state)
44{ 41{
45 unsigned long levels = GPLR;
46 long cs3reg = simpad_get_cs3_ro(); 42 long cs3reg = simpad_get_cs3_ro();
47 43
48 state->detect=((levels & GPIO_CF_CD)==0)?1:0; 44 /* the detect signal is inverted - fix that up here */
49 state->ready=(levels & GPIO_CF_IRQ)?1:0; 45 state->detect = !state->detect;
46
50 state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ 47 state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
51 state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ 48 state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
52 state->wrprot=0; /* Not available on Simpad. */
53 49
54 if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) == 50 if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
55 (PCMCIA_VS1|PCMCIA_VS2)) { 51 (PCMCIA_VS1|PCMCIA_VS2)) {
@@ -99,14 +95,8 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
99 return 0; 95 return 0;
100} 96}
101 97
102static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
103{
104 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
105}
106
107static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 98static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
108{ 99{
109 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
110 simpad_set_cs3_bit(PCMCIA_RESET); 100 simpad_set_cs3_bit(PCMCIA_RESET);
111} 101}
112 102
@@ -116,7 +106,6 @@ static struct pcmcia_low_level simpad_pcmcia_ops = {
116 .hw_shutdown = simpad_pcmcia_hw_shutdown, 106 .hw_shutdown = simpad_pcmcia_hw_shutdown,
117 .socket_state = simpad_pcmcia_socket_state, 107 .socket_state = simpad_pcmcia_socket_state,
118 .configure_socket = simpad_pcmcia_configure_socket, 108 .configure_socket = simpad_pcmcia_configure_socket,
119 .socket_init = simpad_pcmcia_socket_init,
120 .socket_suspend = simpad_pcmcia_socket_suspend, 109 .socket_suspend = simpad_pcmcia_socket_suspend,
121}; 110};
122 111
diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1111_badge4.c
index 1ce53f493bef..4d206f4dd67b 100644
--- a/drivers/pcmcia/sa1100_badge4.c
+++ b/drivers/pcmcia/sa1111_badge4.c
@@ -122,13 +122,12 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
122 local_irq_restore(flags); 122 local_irq_restore(flags);
123 } 123 }
124 124
125 return 0; 125 return ret;
126} 126}
127 127
128static struct pcmcia_low_level badge4_pcmcia_ops = { 128static struct pcmcia_low_level badge4_pcmcia_ops = {
129 .owner = THIS_MODULE, 129 .owner = THIS_MODULE,
130 .configure_socket = badge4_pcmcia_configure_socket, 130 .configure_socket = badge4_pcmcia_configure_socket,
131 .socket_init = sa1111_pcmcia_socket_init,
132 .first = 0, 131 .first = 0,
133 .nr = 2, 132 .nr = 2,
134}; 133};
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 27f2fe3b7fb4..70f728ce1856 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -22,6 +22,40 @@
22 22
23#include "sa1111_generic.h" 23#include "sa1111_generic.h"
24 24
25/*
26 * These are offsets from the above base.
27 */
28#define PCCR 0x0000
29#define PCSSR 0x0004
30#define PCSR 0x0008
31
32#define PCSR_S0_READY (1<<0)
33#define PCSR_S1_READY (1<<1)
34#define PCSR_S0_DETECT (1<<2)
35#define PCSR_S1_DETECT (1<<3)
36#define PCSR_S0_VS1 (1<<4)
37#define PCSR_S0_VS2 (1<<5)
38#define PCSR_S1_VS1 (1<<6)
39#define PCSR_S1_VS2 (1<<7)
40#define PCSR_S0_WP (1<<8)
41#define PCSR_S1_WP (1<<9)
42#define PCSR_S0_BVD1 (1<<10)
43#define PCSR_S0_BVD2 (1<<11)
44#define PCSR_S1_BVD1 (1<<12)
45#define PCSR_S1_BVD2 (1<<13)
46
47#define PCCR_S0_RST (1<<0)
48#define PCCR_S1_RST (1<<1)
49#define PCCR_S0_FLT (1<<2)
50#define PCCR_S1_FLT (1<<3)
51#define PCCR_S0_PWAITEN (1<<4)
52#define PCCR_S1_PWAITEN (1<<5)
53#define PCCR_S0_PSE (1<<6)
54#define PCCR_S1_PSE (1<<7)
55
56#define PCSSR_S0_SLEEP (1<<0)
57#define PCSSR_S1_SLEEP (1<<1)
58
25#define IDX_IRQ_S0_READY_NINT (0) 59#define IDX_IRQ_S0_READY_NINT (0)
26#define IDX_IRQ_S0_CD_VALID (1) 60#define IDX_IRQ_S0_CD_VALID (1)
27#define IDX_IRQ_S0_BVD1_STSCHG (2) 61#define IDX_IRQ_S0_BVD1_STSCHG (2)
@@ -29,27 +63,10 @@
29#define IDX_IRQ_S1_CD_VALID (4) 63#define IDX_IRQ_S1_CD_VALID (4)
30#define IDX_IRQ_S1_BVD1_STSCHG (5) 64#define IDX_IRQ_S1_BVD1_STSCHG (5)
31 65
32static struct pcmcia_irqs irqs[] = {
33 { 0, NO_IRQ, "SA1111 PCMCIA card detect" },
34 { 0, NO_IRQ, "SA1111 PCMCIA BVD1" },
35 { 1, NO_IRQ, "SA1111 CF card detect" },
36 { 1, NO_IRQ, "SA1111 CF BVD1" },
37};
38
39static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
40{
41 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
42}
43
44static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
45{
46 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
47}
48
49void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 66void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
50{ 67{
51 struct sa1111_pcmcia_socket *s = to_skt(skt); 68 struct sa1111_pcmcia_socket *s = to_skt(skt);
52 unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR); 69 unsigned long status = sa1111_readl(s->dev->mapbase + PCSR);
53 70
54 switch (skt->nr) { 71 switch (skt->nr) {
55 case 0: 72 case 0:
@@ -105,35 +122,22 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
105 pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; 122 pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
106 123
107 local_irq_save(flags); 124 local_irq_save(flags);
108 val = sa1111_readl(s->dev->mapbase + SA1111_PCCR); 125 val = sa1111_readl(s->dev->mapbase + PCCR);
109 val &= ~pccr_skt_mask; 126 val &= ~pccr_skt_mask;
110 val |= pccr_set_mask & pccr_skt_mask; 127 val |= pccr_set_mask & pccr_skt_mask;
111 sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); 128 sa1111_writel(val, s->dev->mapbase + PCCR);
112 local_irq_restore(flags); 129 local_irq_restore(flags);
113 130
114 return 0; 131 return 0;
115} 132}
116 133
117void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
118{
119 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
120}
121
122static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
123{
124 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
125}
126
127int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, 134int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
128 int (*add)(struct soc_pcmcia_socket *)) 135 int (*add)(struct soc_pcmcia_socket *))
129{ 136{
130 struct sa1111_pcmcia_socket *s; 137 struct sa1111_pcmcia_socket *s;
131 int i, ret = 0; 138 int i, ret = 0;
132 139
133 ops->hw_init = sa1111_pcmcia_hw_init;
134 ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
135 ops->socket_state = sa1111_pcmcia_socket_state; 140 ops->socket_state = sa1111_pcmcia_socket_state;
136 ops->socket_suspend = sa1111_pcmcia_socket_suspend;
137 141
138 for (i = 0; i < ops->nr; i++) { 142 for (i = 0; i < ops->nr; i++) {
139 s = kzalloc(sizeof(*s), GFP_KERNEL); 143 s = kzalloc(sizeof(*s), GFP_KERNEL);
@@ -141,13 +145,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
141 return -ENOMEM; 145 return -ENOMEM;
142 146
143 s->soc.nr = ops->first + i; 147 s->soc.nr = ops->first + i;
144 s->soc.ops = ops; 148 soc_pcmcia_init_one(&s->soc, ops, &dev->dev);
145 s->soc.socket.owner = ops->owner;
146 s->soc.socket.dev.parent = &dev->dev;
147 s->soc.socket.pci_irq = s->soc.nr ?
148 dev->irq[IDX_IRQ_S0_READY_NINT] :
149 dev->irq[IDX_IRQ_S1_READY_NINT];
150 s->dev = dev; 149 s->dev = dev;
150 if (s->soc.nr) {
151 s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT];
152 s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
153 s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect";
154 s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
155 s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1";
156 } else {
157 s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT];
158 s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
159 s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect";
160 s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
161 s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1";
162 }
151 163
152 ret = add(&s->soc); 164 ret = add(&s->soc);
153 if (ret == 0) { 165 if (ret == 0) {
@@ -163,26 +175,26 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
163static int pcmcia_probe(struct sa1111_dev *dev) 175static int pcmcia_probe(struct sa1111_dev *dev)
164{ 176{
165 void __iomem *base; 177 void __iomem *base;
178 int ret;
179
180 ret = sa1111_enable_device(dev);
181 if (ret)
182 return ret;
166 183
167 dev_set_drvdata(&dev->dev, NULL); 184 dev_set_drvdata(&dev->dev, NULL);
168 185
169 if (!request_mem_region(dev->res.start, 512, 186 if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) {
170 SA1111_DRIVER_NAME(dev))) 187 sa1111_disable_device(dev);
171 return -EBUSY; 188 return -EBUSY;
189 }
172 190
173 base = dev->mapbase; 191 base = dev->mapbase;
174 192
175 /* Initialize PCMCIA IRQs */
176 irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
177 irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
178 irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
179 irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
180
181 /* 193 /*
182 * Initialise the suspend state. 194 * Initialise the suspend state.
183 */ 195 */
184 sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR); 196 sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR);
185 sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR); 197 sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR);
186 198
187#ifdef CONFIG_SA1100_BADGE4 199#ifdef CONFIG_SA1100_BADGE4
188 pcmcia_badge4_init(&dev->dev); 200 pcmcia_badge4_init(&dev->dev);
@@ -212,6 +224,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
212 } 224 }
213 225
214 release_mem_region(dev->res.start, 512); 226 release_mem_region(dev->res.start, 512);
227 sa1111_disable_device(dev);
215 return 0; 228 return 0;
216} 229}
217 230
diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h
index 02dc8577cdaf..f6376e34a7e4 100644
--- a/drivers/pcmcia/sa1111_generic.h
+++ b/drivers/pcmcia/sa1111_generic.h
@@ -17,7 +17,6 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
17 17
18extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); 18extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
19extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); 19extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
20extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
21 20
22extern int pcmcia_badge4_init(struct device *); 21extern int pcmcia_badge4_init(struct device *);
23extern int pcmcia_jornada720_init(struct device *); 22extern int pcmcia_jornada720_init(struct device *);
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index 6bcabee6bde4..69428d1f5ae1 100644
--- a/drivers/pcmcia/sa1100_jornada720.c
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -78,13 +78,8 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
78 } 78 }
79 79
80 ret = sa1111_pcmcia_configure_socket(skt, state); 80 ret = sa1111_pcmcia_configure_socket(skt, state);
81 if (ret == 0) { 81 if (ret == 0)
82 unsigned long flags;
83
84 local_irq_save(flags);
85 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); 82 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
86 local_irq_restore(flags);
87 }
88 83
89 return ret; 84 return ret;
90} 85}
@@ -92,7 +87,6 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
92static struct pcmcia_low_level jornada720_pcmcia_ops = { 87static struct pcmcia_low_level jornada720_pcmcia_ops = {
93 .owner = THIS_MODULE, 88 .owner = THIS_MODULE,
94 .configure_socket = jornada720_pcmcia_configure_socket, 89 .configure_socket = jornada720_pcmcia_configure_socket,
95 .socket_init = sa1111_pcmcia_socket_init,
96 .first = 0, 90 .first = 0,
97 .nr = 2, 91 .nr = 2,
98}; 92};
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index c21888eebb58..c5caf5790451 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -202,7 +202,6 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
202static struct pcmcia_low_level lubbock_pcmcia_ops = { 202static struct pcmcia_low_level lubbock_pcmcia_ops = {
203 .owner = THIS_MODULE, 203 .owner = THIS_MODULE,
204 .configure_socket = lubbock_pcmcia_configure_socket, 204 .configure_socket = lubbock_pcmcia_configure_socket,
205 .socket_init = sa1111_pcmcia_socket_init,
206 .first = 0, 205 .first = 0,
207 .nr = 2, 206 .nr = 2,
208}; 207};
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1111_neponset.c
index c95639b5f2a0..1d78739c4c07 100644
--- a/drivers/pcmcia/sa1100_neponset.c
+++ b/drivers/pcmcia/sa1111_neponset.c
@@ -94,30 +94,16 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
94 94
95 ret = sa1111_pcmcia_configure_socket(skt, state); 95 ret = sa1111_pcmcia_configure_socket(skt, state);
96 if (ret == 0) { 96 if (ret == 0) {
97 unsigned long flags; 97 neponset_ncr_frob(ncr_mask, ncr_set);
98
99 local_irq_save(flags);
100 NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
101
102 local_irq_restore(flags);
103 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); 98 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
104 } 99 }
105 100
106 return 0; 101 return ret;
107}
108
109static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
110{
111 if (skt->nr == 0)
112 NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
113
114 sa1111_pcmcia_socket_init(skt);
115} 102}
116 103
117static struct pcmcia_low_level neponset_pcmcia_ops = { 104static struct pcmcia_low_level neponset_pcmcia_ops = {
118 .owner = THIS_MODULE, 105 .owner = THIS_MODULE,
119 .configure_socket = neponset_pcmcia_configure_socket, 106 .configure_socket = neponset_pcmcia_configure_socket,
120 .socket_init = neponset_pcmcia_socket_init,
121 .first = 0, 107 .first = 0,
122 .nr = 2, 108 .nr = 2,
123}; 109};
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 79ecc23643ec..6eecd7cddf57 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -235,10 +235,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
235 skt = &sinfo->skt[i]; 235 skt = &sinfo->skt[i];
236 236
237 skt->nr = first + i; 237 skt->nr = first + i;
238 skt->ops = ops; 238 soc_pcmcia_init_one(skt, ops, dev);
239 skt->socket.owner = ops->owner;
240 skt->socket.dev.parent = dev;
241 skt->socket.pci_irq = NO_IRQ;
242 239
243 ret = sa11xx_drv_pcmcia_add_one(skt); 240 ret = sa11xx_drv_pcmcia_add_one(skt);
244 if (ret) 241 if (ret)
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 5d22c6acb8e2..a2bc6ee1702e 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -32,6 +32,7 @@
32 32
33 33
34#include <linux/cpufreq.h> 34#include <linux/cpufreq.h>
35#include <linux/gpio.h>
35#include <linux/init.h> 36#include <linux/init.h>
36#include <linux/interrupt.h> 37#include <linux/interrupt.h>
37#include <linux/io.h> 38#include <linux/io.h>
@@ -48,6 +49,8 @@
48 49
49#include "soc_common.h" 50#include "soc_common.h"
50 51
52static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev);
53
51#ifdef CONFIG_PCMCIA_DEBUG 54#ifdef CONFIG_PCMCIA_DEBUG
52 55
53static int pc_debug; 56static int pc_debug;
@@ -103,6 +106,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,
103} 106}
104EXPORT_SYMBOL(soc_common_pcmcia_get_timing); 107EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
105 108
109static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
110 unsigned int nr)
111{
112 unsigned int i;
113
114 for (i = 0; i < nr; i++) {
115 if (skt->stat[i].irq)
116 free_irq(skt->stat[i].irq, skt);
117 if (gpio_is_valid(skt->stat[i].gpio))
118 gpio_free(skt->stat[i].gpio);
119 }
120
121 if (skt->ops->hw_shutdown)
122 skt->ops->hw_shutdown(skt);
123}
124
125static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
126{
127 __soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat));
128}
129
130static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
131{
132 int ret = 0, i;
133
134 if (skt->ops->hw_init) {
135 ret = skt->ops->hw_init(skt);
136 if (ret)
137 return ret;
138 }
139
140 for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
141 if (gpio_is_valid(skt->stat[i].gpio)) {
142 int irq;
143
144 ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
145 skt->stat[i].name);
146 if (ret) {
147 __soc_pcmcia_hw_shutdown(skt, i);
148 return ret;
149 }
150
151 irq = gpio_to_irq(skt->stat[i].gpio);
152
153 if (i == SOC_STAT_RDY)
154 skt->socket.pci_irq = irq;
155 else
156 skt->stat[i].irq = irq;
157 }
158
159 if (skt->stat[i].irq) {
160 ret = request_irq(skt->stat[i].irq,
161 soc_common_pcmcia_interrupt,
162 IRQF_TRIGGER_NONE,
163 skt->stat[i].name, skt);
164 if (ret) {
165 if (gpio_is_valid(skt->stat[i].gpio))
166 gpio_free(skt->stat[i].gpio);
167 __soc_pcmcia_hw_shutdown(skt, i);
168 return ret;
169 }
170 }
171 }
172
173 return ret;
174}
175
176static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt)
177{
178 int i;
179
180 for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
181 if (skt->stat[i].irq) {
182 irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING);
183 irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH);
184 }
185}
186
187static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt)
188{
189 int i;
190
191 for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
192 if (skt->stat[i].irq)
193 irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE);
194}
195
106static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) 196static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
107{ 197{
108 struct pcmcia_state state; 198 struct pcmcia_state state;
@@ -110,6 +200,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
110 200
111 memset(&state, 0, sizeof(struct pcmcia_state)); 201 memset(&state, 0, sizeof(struct pcmcia_state));
112 202
203 /* Make battery voltage state report 'good' */
204 state.bvd1 = 1;
205 state.bvd2 = 1;
206
207 /* CD is active low by default */
208 if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio))
209 state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio);
210
211 /* RDY and BVD are active high by default */
212 if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio))
213 state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio);
214 if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio))
215 state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio);
216 if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio))
217 state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio);
218
113 skt->ops->socket_state(skt, &state); 219 skt->ops->socket_state(skt, &state);
114 220
115 stat = state.detect ? SS_DETECT : 0; 221 stat = state.detect ? SS_DETECT : 0;
@@ -187,6 +293,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
187 debug(skt, 2, "initializing socket\n"); 293 debug(skt, 2, "initializing socket\n");
188 if (skt->ops->socket_init) 294 if (skt->ops->socket_init)
189 skt->ops->socket_init(skt); 295 skt->ops->socket_init(skt);
296 soc_pcmcia_hw_enable(skt);
190 return 0; 297 return 0;
191} 298}
192 299
@@ -206,6 +313,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
206 313
207 debug(skt, 2, "suspending socket\n"); 314 debug(skt, 2, "suspending socket\n");
208 315
316 soc_pcmcia_hw_disable(skt);
209 if (skt->ops->socket_suspend) 317 if (skt->ops->socket_suspend)
210 skt->ops->socket_suspend(skt); 318 skt->ops->socket_suspend(skt);
211 319
@@ -525,69 +633,6 @@ static struct pccard_operations soc_common_pcmcia_operations = {
525}; 633};
526 634
527 635
528int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
529 struct pcmcia_irqs *irqs, int nr)
530{
531 int i, res = 0;
532
533 for (i = 0; i < nr; i++) {
534 if (irqs[i].sock != skt->nr)
535 continue;
536 res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
537 IRQF_DISABLED, irqs[i].str, skt);
538 if (res)
539 break;
540 irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
541 }
542
543 if (res) {
544 printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n",
545 irqs[i].irq, res);
546
547 while (i--)
548 if (irqs[i].sock == skt->nr)
549 free_irq(irqs[i].irq, skt);
550 }
551 return res;
552}
553EXPORT_SYMBOL(soc_pcmcia_request_irqs);
554
555void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt,
556 struct pcmcia_irqs *irqs, int nr)
557{
558 int i;
559
560 for (i = 0; i < nr; i++)
561 if (irqs[i].sock == skt->nr)
562 free_irq(irqs[i].irq, skt);
563}
564EXPORT_SYMBOL(soc_pcmcia_free_irqs);
565
566void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
567 struct pcmcia_irqs *irqs, int nr)
568{
569 int i;
570
571 for (i = 0; i < nr; i++)
572 if (irqs[i].sock == skt->nr)
573 irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
574}
575EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
576
577void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
578 struct pcmcia_irqs *irqs, int nr)
579{
580 int i;
581
582 for (i = 0; i < nr; i++)
583 if (irqs[i].sock == skt->nr) {
584 irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
585 irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
586 }
587}
588EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
589
590
591static LIST_HEAD(soc_pcmcia_sockets); 636static LIST_HEAD(soc_pcmcia_sockets);
592static DEFINE_MUTEX(soc_pcmcia_sockets_lock); 637static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
593 638
@@ -634,6 +679,21 @@ module_exit(soc_pcmcia_cpufreq_unregister);
634 679
635#endif 680#endif
636 681
682void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
683 struct pcmcia_low_level *ops, struct device *dev)
684{
685 int i;
686
687 skt->ops = ops;
688 skt->socket.owner = ops->owner;
689 skt->socket.dev.parent = dev;
690 skt->socket.pci_irq = NO_IRQ;
691
692 for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
693 skt->stat[i].gpio = -EINVAL;
694}
695EXPORT_SYMBOL(soc_pcmcia_init_one);
696
637void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) 697void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
638{ 698{
639 mutex_lock(&soc_pcmcia_sockets_lock); 699 mutex_lock(&soc_pcmcia_sockets_lock);
@@ -641,8 +701,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
641 701
642 pcmcia_unregister_socket(&skt->socket); 702 pcmcia_unregister_socket(&skt->socket);
643 703
644 skt->ops->hw_shutdown(skt); 704 soc_pcmcia_hw_shutdown(skt);
645 705
706 /* should not be required; violates some lowlevel drivers */
646 soc_common_pcmcia_config_skt(skt, &dead_socket); 707 soc_common_pcmcia_config_skt(skt, &dead_socket);
647 708
648 list_del(&skt->node); 709 list_del(&skt->node);
@@ -699,7 +760,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
699 */ 760 */
700 skt->ops->set_timing(skt); 761 skt->ops->set_timing(skt);
701 762
702 ret = skt->ops->hw_init(skt); 763 ret = soc_pcmcia_hw_init(skt);
703 if (ret) 764 if (ret)
704 goto out_err_6; 765 goto out_err_6;
705 766
@@ -732,7 +793,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
732 pcmcia_unregister_socket(&skt->socket); 793 pcmcia_unregister_socket(&skt->socket);
733 794
734 out_err_7: 795 out_err_7:
735 skt->ops->hw_shutdown(skt); 796 soc_pcmcia_hw_shutdown(skt);
736 out_err_6: 797 out_err_6:
737 list_del(&skt->node); 798 list_del(&skt->node);
738 mutex_unlock(&soc_pcmcia_sockets_lock); 799 mutex_unlock(&soc_pcmcia_sockets_lock);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 9daa73615c8b..e6fcbea5b682 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -50,6 +50,16 @@ struct soc_pcmcia_socket {
50 struct resource res_attr; 50 struct resource res_attr;
51 void __iomem *virt_io; 51 void __iomem *virt_io;
52 52
53 struct {
54 int gpio;
55 unsigned int irq;
56 const char *name;
57 } stat[4];
58#define SOC_STAT_CD 0 /* Card detect */
59#define SOC_STAT_BVD1 1 /* BATDEAD / IOSTSCHG */
60#define SOC_STAT_BVD2 2 /* BATWARN / IOSPKR */
61#define SOC_STAT_RDY 3 /* Ready / Interrupt */
62
53 unsigned int irq_state; 63 unsigned int irq_state;
54 64
55 struct timer_list poll_timer; 65 struct timer_list poll_timer;
@@ -115,25 +125,16 @@ struct pcmcia_low_level {
115}; 125};
116 126
117 127
118struct pcmcia_irqs {
119 int sock;
120 int irq;
121 const char *str;
122};
123
124struct soc_pcmcia_timing { 128struct soc_pcmcia_timing {
125 unsigned short io; 129 unsigned short io;
126 unsigned short mem; 130 unsigned short mem;
127 unsigned short attr; 131 unsigned short attr;
128}; 132};
129 133
130extern int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
131extern void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
132extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
133extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
134extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); 134extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
135 135
136 136void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
137 struct pcmcia_low_level *ops, struct device *dev);
137void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); 138void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
138int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); 139int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
139 140