diff options
Diffstat (limited to 'drivers/pcmcia')
32 files changed, 348 insertions, 856 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 | |||
183 | config PCMCIA_SOC_COMMON | 183 | config PCMCIA_SOC_COMMON |
184 | tristate | 184 | tristate |
185 | 185 | ||
186 | config PCMCIA_SA11XX_BASE | ||
187 | tristate | ||
188 | |||
186 | config PCMCIA_SA1100 | 189 | config 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 | ||
197 | config PCMCIA_SA1111 | 201 | config 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 | |||
25 | obj-$(CONFIG_TCIC) += tcic.o | 25 | obj-$(CONFIG_TCIC) += tcic.o |
26 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o | 26 | obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o |
27 | obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o | 27 | obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o |
28 | obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o | 28 | obj-$(CONFIG_PCMCIA_SA11XX_BASE) += sa11xx_base.o |
29 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o | 29 | obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o |
30 | obj-$(CONFIG_PCMCIA_SA1111) += sa1111_cs.o | ||
30 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o | 31 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o |
31 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o | 32 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o |
32 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o | 33 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o |
@@ -39,9 +40,10 @@ obj-$(CONFIG_ELECTRA_CF) += electra_cf.o | |||
39 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o | 40 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o |
40 | 41 | ||
41 | sa1111_cs-y += sa1111_generic.o | 42 | sa1111_cs-y += sa1111_generic.o |
42 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o | 43 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1111_neponset.o |
43 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o | 44 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1111_badge4.o |
44 | sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o | 45 | sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1111_jornada720.o |
46 | sa1111_cs-$(CONFIG_ARCH_LUBBOCK) += sa1111_lubbock.o | ||
45 | 47 | ||
46 | sa1100_cs-y += sa1100_generic.o | 48 | sa1100_cs-y += sa1100_generic.o |
47 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o | 49 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o |
@@ -52,9 +54,7 @@ sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o | |||
52 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o | 54 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o |
53 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o | 55 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o |
54 | 56 | ||
55 | pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o | ||
56 | pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o | 57 | pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o |
57 | pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o | ||
58 | pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o | 58 | pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o |
59 | pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o | 59 | pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o |
60 | pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o | 60 | pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o |
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 | */ | ||
36 | static struct pcmcia_irqs irqs[] = { | ||
37 | { 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" }, | ||
38 | { 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" }, | ||
39 | }; | ||
40 | |||
41 | static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 32 | static 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 | ||
55 | static 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 | ||
60 | static unsigned long balloon3_pcmcia_status[2] = { | 51 | static 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 | ||
97 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 86 | static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
@@ -106,7 +95,6 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
106 | static struct pcmcia_low_level balloon3_pcmcia_ops = { | 95 | static 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 64d433ec4fc6..66a54222bbf4 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
318 | 318 | ||
319 | skt->nr = ops->first + i; | 319 | skt->nr = ops->first + i; |
320 | skt->clk = clk; | 320 | skt->clk = clk; |
321 | skt->ops = ops; | 321 | soc_pcmcia_init_one(skt, ops, &dev->dev); |
322 | skt->socket.owner = ops->owner; | ||
323 | skt->socket.dev.parent = &dev->dev; | ||
324 | skt->socket.pci_irq = NO_IRQ; | ||
325 | 322 | ||
326 | ret = pxa2xx_drv_pcmcia_add_one(skt); | 323 | ret = pxa2xx_drv_pcmcia_add_one(skt); |
327 | if (ret) | 324 | 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 | |||
34 | static struct pcmcia_irqs irqs[] = { | ||
35 | { .sock = 0, .str = "PCMCIA0 CD" }, | ||
36 | { .sock = 1, .str = "PCMCIA1 CD" }, | ||
37 | }; | ||
38 | |||
39 | static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static 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 | ||
56 | static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt) | 50 | static 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) | |||
63 | static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 56 | static 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 | |||
29 | static struct pcmcia_irqs irqs[] = { | ||
30 | { .sock = 0, .str = "PCMCIA0 CD" }, | ||
31 | }; | ||
32 | |||
33 | static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 25 | static 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 | ||
49 | static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) | 40 | static 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) | |||
56 | static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 46 | static 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 | ||
56 | static struct pcmcia_irqs colibri_irqs[] = { | ||
57 | { | ||
58 | .sock = 0, | ||
59 | .str = "PCMCIA CD" | ||
60 | }, | ||
61 | }; | ||
62 | |||
63 | static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 56 | static 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 | |||
82 | err2: | ||
83 | gpio_free_array(colibri_pcmcia_gpios, | ||
84 | ARRAY_SIZE(colibri_pcmcia_gpios)); | ||
85 | err1: | 69 | err1: |
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 | ||
26 | static 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 | |||
37 | static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 26 | static 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 | */ | ||
53 | static 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 | ||
58 | static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 43 | static 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 | */ | ||
117 | static 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 | */ | ||
125 | static 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 | |||
130 | static struct pcmcia_low_level e740_pcmcia_ops = { | 86 | static 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 | ||
33 | static 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 | |||
40 | static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 33 | static 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; | |
51 | static 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 | ||
56 | static unsigned long mst_pcmcia_status[2]; | 55 | static 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 | ||
90 | static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 88 | static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
@@ -131,7 +129,6 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
131 | static struct pcmcia_low_level mst_pcmcia_ops __initdata = { | 129 | static 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 @@ | |||
23 | static struct gpio palmld_pcmcia_gpios[] = { | 23 | static 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 | ||
29 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
@@ -33,7 +32,8 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
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 | ||
29 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 28 | static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
@@ -33,7 +32,8 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
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 | ||
47 | static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 47 | static 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 | ||
71 | static 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 | |||
84 | static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 59 | static 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) | |||
222 | static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = { | 197 | static 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 | ||
36 | static struct pcmcia_irqs irqs[] = { | ||
37 | {.sock = 0, .str = "PCMCIA0 CD" }, | ||
38 | }; | ||
39 | |||
40 | static struct gpio sg2_pcmcia_gpios[] = { | 36 | static 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 | ||
45 | static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 41 | static 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 | |||
53 | static 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 | ||
58 | static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 50 | static 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 | ||
70 | static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | 59 | static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, |
@@ -94,24 +83,11 @@ static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, | |||
94 | return 0; | 83 | return 0; |
95 | } | 84 | } |
96 | 85 | ||
97 | static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
98 | { | ||
99 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
100 | } | ||
101 | |||
102 | static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
103 | { | ||
104 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
105 | } | ||
106 | |||
107 | static struct pcmcia_low_level sg2_pcmcia_ops __initdata = { | 86 | static 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 | ||
30 | extern void board_pcmcia_power(int power); | 30 | extern void board_pcmcia_power(int power); |
31 | 31 | ||
32 | static struct pcmcia_irqs irqs[] = { | ||
33 | { .sock = 0, .str = "cs0_cd" } | ||
34 | /* on other baseboards we can have more inputs */ | ||
35 | }; | ||
36 | |||
37 | static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 32 | static 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 | |||
84 | error: | ||
85 | for (; i >= 0; i--) { | ||
86 | gpio_free(irq_to_gpio(irqs[i].irq)); | ||
87 | } | ||
88 | return (ret); | ||
89 | } | ||
90 | |||
91 | static 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 | ||
100 | static unsigned long trizeps_pcmcia_status[2]; | 53 | static 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) | |||
204 | static struct pcmcia_low_level trizeps_pcmcia_ops = { | 153 | static 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 | ||
33 | static struct platform_device *arcom_pcmcia_dev; | 33 | static struct platform_device *arcom_pcmcia_dev; |
34 | 34 | ||
35 | static struct pcmcia_irqs irqs[] = { | ||
36 | { | ||
37 | .sock = 0, | ||
38 | .str = "PCMCIA_CD", | ||
39 | }, | ||
40 | }; | ||
41 | |||
42 | static inline struct arcom_pcmcia_pdata *viper_get_pdata(void) | 35 | static 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 | ||
77 | err_dir: | 64 | err_dir: |
78 | gpio_free(pdata->pwr_gpio); | 65 | gpio_free(pdata->pwr_gpio); |
79 | err_request_pwr: | 66 | err_request_pwr: |
80 | gpio_free(pdata->rdy_gpio); | ||
81 | err_request_rdy: | ||
82 | gpio_free(pdata->cd_gpio); | ||
83 | err_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 | ||
101 | static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 81 | static 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 | ||
25 | static struct gpio vpac270_pcmcia_gpios[] = { | 25 | static 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 | ||
32 | static struct gpio vpac270_cf_gpios[] = { | 30 | static 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 | ||
38 | static 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 | |||
49 | static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 34 | static 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) | |||
86 | static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 69 | static 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 | ||
120 | static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
121 | { | ||
122 | } | ||
123 | |||
124 | static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
125 | { | ||
126 | } | ||
127 | |||
128 | static struct pcmcia_low_level vpac270_pcmcia_ops = { | 93 | static 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 | ||
144 | static struct platform_device *vpac270_pcmcia_device; | 106 | static 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 | ||
22 | static 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 | |||
28 | static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 20 | static 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 | */ | ||
38 | static 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 | ||
43 | static void | 34 | static void |
44 | assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 35 | assabet_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 | */ | ||
96 | static 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 | */ |
109 | static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 81 | static 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 | ||
120 | static struct pcmcia_low_level assabet_pcmcia_ops = { | 90 | static 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 | ||
22 | static 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 | |||
28 | static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 23 | static 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 | ||
35 | static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 43 | static 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 | ||
40 | static void | 48 | static void |
41 | cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 49 | cerf_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 | ||
79 | static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
80 | { | ||
81 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
82 | } | ||
83 | |||
84 | static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
85 | { | ||
86 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
87 | } | ||
88 | |||
89 | static struct pcmcia_low_level cerf_pcmcia_ops = { | 76 | static 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 | ||
100 | int __devinit pcmcia_cerf_init(struct device *dev) | 84 | int __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 | ||
22 | static struct pcmcia_irqs irqs[] = { | ||
23 | { .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */ | ||
24 | { .sock = 1, .str = "PCMCIA CD1" } | ||
25 | }; | ||
26 | |||
27 | static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 22 | static 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); | |||
102 | err05: gpio_free(H3XXX_EGPIO_OPT_RESET); | 68 | err05: gpio_free(H3XXX_EGPIO_OPT_RESET); |
103 | err04: gpio_free(H3XXX_EGPIO_OPT_ON); | 69 | err04: gpio_free(H3XXX_EGPIO_OPT_ON); |
104 | err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); | 70 | err03: gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON); |
105 | err02: gpio_free(H3XXX_GPIO_PCMCIA_CD0); | ||
106 | err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | 71 | err01: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); |
107 | err00: return err; | 72 | return err; |
108 | |||
109 | err12: gpio_free(H3XXX_GPIO_PCMCIA_CD0); | ||
110 | err11: gpio_free(H3XXX_GPIO_PCMCIA_IRQ0); | ||
111 | err10: return err; | ||
112 | } | 73 | } |
113 | 74 | ||
114 | static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 75 | static 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) | |||
139 | static void | 94 | static void |
140 | h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 95 | h3600_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 | ||
165 | static int | 103 | static 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 | ||
193 | static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 129 | static 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 | ||
37 | static struct pcmcia_irqs irqs_skt0[] = { | ||
38 | /* socket, IRQ, name */ | ||
39 | { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" }, | ||
40 | }; | ||
41 | |||
42 | static struct pcmcia_irqs irqs_skt1[] = { | ||
43 | /* socket, IRQ, name */ | ||
44 | { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" }, | ||
45 | }; | ||
46 | |||
47 | struct nanoengine_pins { | 38 | struct 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 | ||
57 | static struct nanoengine_pins nano_skts[] = { | 46 | static 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); | |||
79 | static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 60 | static 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 | */ | ||
99 | static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 81 | static 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 | ||
110 | static int nanoengine_pcmcia_configure_socket( | 86 | static 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( | |||
138 | static void nanoengine_pcmcia_socket_state( | 99 | static 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 | */ | ||
172 | static 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 | */ | ||
186 | static 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 | |||
197 | static struct pcmcia_low_level nanoengine_pcmcia_ops = { | 113 | static 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 | ||
209 | int pcmcia_nanoengine_init(struct device *dev) | 123 | int 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 | ||
18 | static 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 | |||
23 | static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 18 | static 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 | ||
36 | static 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 | ||
41 | static void | 41 | static void |
42 | shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 42 | shannon_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 | ||
95 | static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
96 | { | ||
97 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
98 | } | ||
99 | |||
100 | static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
101 | { | ||
102 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
103 | } | ||
104 | |||
105 | static struct pcmcia_low_level shannon_pcmcia_ops = { | 87 | static 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 | ||
116 | int __devinit pcmcia_shannon_init(struct device *dev) | 94 | int __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 | ||
18 | static struct pcmcia_irqs irqs[] = { | ||
19 | { 1, IRQ_GPIO_CF_CD, "CF_CD" }, | ||
20 | }; | ||
21 | |||
22 | static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 18 | static 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 | ||
32 | static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 31 | static 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 | |||
42 | simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, | 39 | simpad_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 | ||
102 | static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
103 | { | ||
104 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
105 | } | ||
106 | |||
107 | static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | 98 | static 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 | ||
128 | static struct pcmcia_low_level badge4_pcmcia_ops = { | 128 | static 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..ef5848f65241 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c | |||
@@ -29,23 +29,6 @@ | |||
29 | #define IDX_IRQ_S1_CD_VALID (4) | 29 | #define IDX_IRQ_S1_CD_VALID (4) |
30 | #define IDX_IRQ_S1_BVD1_STSCHG (5) | 30 | #define IDX_IRQ_S1_BVD1_STSCHG (5) |
31 | 31 | ||
32 | static 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 | |||
39 | static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
40 | { | ||
41 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
42 | } | ||
43 | |||
44 | static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
45 | { | ||
46 | soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
47 | } | ||
48 | |||
49 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | 32 | void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) |
50 | { | 33 | { |
51 | struct sa1111_pcmcia_socket *s = to_skt(skt); | 34 | struct sa1111_pcmcia_socket *s = to_skt(skt); |
@@ -114,26 +97,13 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s | |||
114 | return 0; | 97 | return 0; |
115 | } | 98 | } |
116 | 99 | ||
117 | void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | ||
118 | { | ||
119 | soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
120 | } | ||
121 | |||
122 | static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | ||
123 | { | ||
124 | soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); | ||
125 | } | ||
126 | |||
127 | int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | 100 | int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, |
128 | int (*add)(struct soc_pcmcia_socket *)) | 101 | int (*add)(struct soc_pcmcia_socket *)) |
129 | { | 102 | { |
130 | struct sa1111_pcmcia_socket *s; | 103 | struct sa1111_pcmcia_socket *s; |
131 | int i, ret = 0; | 104 | int i, ret = 0; |
132 | 105 | ||
133 | ops->hw_init = sa1111_pcmcia_hw_init; | ||
134 | ops->hw_shutdown = sa1111_pcmcia_hw_shutdown; | ||
135 | ops->socket_state = sa1111_pcmcia_socket_state; | 106 | ops->socket_state = sa1111_pcmcia_socket_state; |
136 | ops->socket_suspend = sa1111_pcmcia_socket_suspend; | ||
137 | 107 | ||
138 | for (i = 0; i < ops->nr; i++) { | 108 | for (i = 0; i < ops->nr; i++) { |
139 | s = kzalloc(sizeof(*s), GFP_KERNEL); | 109 | s = kzalloc(sizeof(*s), GFP_KERNEL); |
@@ -141,13 +111,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, | |||
141 | return -ENOMEM; | 111 | return -ENOMEM; |
142 | 112 | ||
143 | s->soc.nr = ops->first + i; | 113 | s->soc.nr = ops->first + i; |
144 | s->soc.ops = ops; | 114 | 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; | 115 | s->dev = dev; |
116 | if (s->soc.nr) { | ||
117 | s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT]; | ||
118 | s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID]; | ||
119 | s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect"; | ||
120 | s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG]; | ||
121 | s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1"; | ||
122 | } else { | ||
123 | s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT]; | ||
124 | s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID]; | ||
125 | s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect"; | ||
126 | s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG]; | ||
127 | s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1"; | ||
128 | } | ||
151 | 129 | ||
152 | ret = add(&s->soc); | 130 | ret = add(&s->soc); |
153 | if (ret == 0) { | 131 | if (ret == 0) { |
@@ -172,12 +150,6 @@ static int pcmcia_probe(struct sa1111_dev *dev) | |||
172 | 150 | ||
173 | base = dev->mapbase; | 151 | base = dev->mapbase; |
174 | 152 | ||
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 | /* | 153 | /* |
182 | * Initialise the suspend state. | 154 | * Initialise the suspend state. |
183 | */ | 155 | */ |
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 | ||
18 | extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); | 18 | extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *); |
19 | extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); | 19 | extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *); |
20 | extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *); | ||
21 | 20 | ||
22 | extern int pcmcia_badge4_init(struct device *); | 21 | extern int pcmcia_badge4_init(struct device *); |
23 | extern int pcmcia_jornada720_init(struct device *); | 22 | extern 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 | |||
92 | static struct pcmcia_low_level jornada720_pcmcia_ops = { | 87 | static 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, | |||
202 | static struct pcmcia_low_level lubbock_pcmcia_ops = { | 202 | static 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..50f297d850e7 100644 --- a/drivers/pcmcia/sa1100_neponset.c +++ b/drivers/pcmcia/sa1111_neponset.c | |||
@@ -103,21 +103,12 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta | |||
103 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); | 103 | sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); |
104 | } | 104 | } |
105 | 105 | ||
106 | return 0; | 106 | return ret; |
107 | } | ||
108 | |||
109 | static 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 | } | 107 | } |
116 | 108 | ||
117 | static struct pcmcia_low_level neponset_pcmcia_ops = { | 109 | static struct pcmcia_low_level neponset_pcmcia_ops = { |
118 | .owner = THIS_MODULE, | 110 | .owner = THIS_MODULE, |
119 | .configure_socket = neponset_pcmcia_configure_socket, | 111 | .configure_socket = neponset_pcmcia_configure_socket, |
120 | .socket_init = neponset_pcmcia_socket_init, | ||
121 | .first = 0, | 112 | .first = 0, |
122 | .nr = 2, | 113 | .nr = 2, |
123 | }; | 114 | }; |
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 0c62fe31a40e..a3ee89a6dd0e 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c | |||
@@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
236 | skt = &sinfo->skt[i]; | 236 | skt = &sinfo->skt[i]; |
237 | 237 | ||
238 | skt->nr = first + i; | 238 | skt->nr = first + i; |
239 | skt->ops = ops; | 239 | soc_pcmcia_init_one(skt, ops, dev); |
240 | skt->socket.owner = ops->owner; | ||
241 | skt->socket.dev.parent = dev; | ||
242 | skt->socket.pci_irq = NO_IRQ; | ||
243 | 240 | ||
244 | ret = sa11xx_drv_pcmcia_add_one(skt); | 241 | ret = sa11xx_drv_pcmcia_add_one(skt); |
245 | if (ret) | 242 | if (ret) |
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index a0a9c2aa8d78..e0433f571962 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> |
@@ -49,6 +50,8 @@ | |||
49 | 50 | ||
50 | #include "soc_common.h" | 51 | #include "soc_common.h" |
51 | 52 | ||
53 | static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev); | ||
54 | |||
52 | #ifdef CONFIG_PCMCIA_DEBUG | 55 | #ifdef CONFIG_PCMCIA_DEBUG |
53 | 56 | ||
54 | static int pc_debug; | 57 | static int pc_debug; |
@@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, | |||
104 | } | 107 | } |
105 | EXPORT_SYMBOL(soc_common_pcmcia_get_timing); | 108 | EXPORT_SYMBOL(soc_common_pcmcia_get_timing); |
106 | 109 | ||
110 | static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt, | ||
111 | unsigned int nr) | ||
112 | { | ||
113 | unsigned int i; | ||
114 | |||
115 | for (i = 0; i < nr; i++) { | ||
116 | if (skt->stat[i].irq) | ||
117 | free_irq(skt->stat[i].irq, skt); | ||
118 | if (gpio_is_valid(skt->stat[i].gpio)) | ||
119 | gpio_free(skt->stat[i].gpio); | ||
120 | } | ||
121 | |||
122 | if (skt->ops->hw_shutdown) | ||
123 | skt->ops->hw_shutdown(skt); | ||
124 | } | ||
125 | |||
126 | static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | ||
127 | { | ||
128 | __soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat)); | ||
129 | } | ||
130 | |||
131 | static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | ||
132 | { | ||
133 | int ret = 0, i; | ||
134 | |||
135 | if (skt->ops->hw_init) { | ||
136 | ret = skt->ops->hw_init(skt); | ||
137 | if (ret) | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) { | ||
142 | if (gpio_is_valid(skt->stat[i].gpio)) { | ||
143 | int irq; | ||
144 | |||
145 | ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN, | ||
146 | skt->stat[i].name); | ||
147 | if (ret) { | ||
148 | __soc_pcmcia_hw_shutdown(skt, i); | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | irq = gpio_to_irq(skt->stat[i].gpio); | ||
153 | |||
154 | if (i == SOC_STAT_RDY) | ||
155 | skt->socket.pci_irq = irq; | ||
156 | else | ||
157 | skt->stat[i].irq = irq; | ||
158 | } | ||
159 | |||
160 | if (skt->stat[i].irq) { | ||
161 | ret = request_irq(skt->stat[i].irq, | ||
162 | soc_common_pcmcia_interrupt, | ||
163 | IRQF_TRIGGER_NONE, | ||
164 | skt->stat[i].name, skt); | ||
165 | if (ret) { | ||
166 | if (gpio_is_valid(skt->stat[i].gpio)) | ||
167 | gpio_free(skt->stat[i].gpio); | ||
168 | __soc_pcmcia_hw_shutdown(skt, i); | ||
169 | return ret; | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt) | ||
178 | { | ||
179 | int i; | ||
180 | |||
181 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) | ||
182 | if (skt->stat[i].irq) { | ||
183 | irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING); | ||
184 | irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt) | ||
189 | { | ||
190 | int i; | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) | ||
193 | if (skt->stat[i].irq) | ||
194 | irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE); | ||
195 | } | ||
196 | |||
107 | static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) | 197 | static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) |
108 | { | 198 | { |
109 | struct pcmcia_state state; | 199 | struct pcmcia_state state; |
@@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) | |||
111 | 201 | ||
112 | memset(&state, 0, sizeof(struct pcmcia_state)); | 202 | memset(&state, 0, sizeof(struct pcmcia_state)); |
113 | 203 | ||
204 | /* Make battery voltage state report 'good' */ | ||
205 | state.bvd1 = 1; | ||
206 | state.bvd2 = 1; | ||
207 | |||
208 | /* CD is active low by default */ | ||
209 | if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio)) | ||
210 | state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio); | ||
211 | |||
212 | /* RDY and BVD are active high by default */ | ||
213 | if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio)) | ||
214 | state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio); | ||
215 | if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio)) | ||
216 | state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio); | ||
217 | if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio)) | ||
218 | state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio); | ||
219 | |||
114 | skt->ops->socket_state(skt, &state); | 220 | skt->ops->socket_state(skt, &state); |
115 | 221 | ||
116 | stat = state.detect ? SS_DETECT : 0; | 222 | stat = state.detect ? SS_DETECT : 0; |
@@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock) | |||
188 | debug(skt, 2, "initializing socket\n"); | 294 | debug(skt, 2, "initializing socket\n"); |
189 | if (skt->ops->socket_init) | 295 | if (skt->ops->socket_init) |
190 | skt->ops->socket_init(skt); | 296 | skt->ops->socket_init(skt); |
297 | soc_pcmcia_hw_enable(skt); | ||
191 | return 0; | 298 | return 0; |
192 | } | 299 | } |
193 | 300 | ||
@@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock) | |||
207 | 314 | ||
208 | debug(skt, 2, "suspending socket\n"); | 315 | debug(skt, 2, "suspending socket\n"); |
209 | 316 | ||
317 | soc_pcmcia_hw_disable(skt); | ||
210 | if (skt->ops->socket_suspend) | 318 | if (skt->ops->socket_suspend) |
211 | skt->ops->socket_suspend(skt); | 319 | skt->ops->socket_suspend(skt); |
212 | 320 | ||
@@ -526,69 +634,6 @@ static struct pccard_operations soc_common_pcmcia_operations = { | |||
526 | }; | 634 | }; |
527 | 635 | ||
528 | 636 | ||
529 | int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, | ||
530 | struct pcmcia_irqs *irqs, int nr) | ||
531 | { | ||
532 | int i, res = 0; | ||
533 | |||
534 | for (i = 0; i < nr; i++) { | ||
535 | if (irqs[i].sock != skt->nr) | ||
536 | continue; | ||
537 | res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt, | ||
538 | IRQF_DISABLED, irqs[i].str, skt); | ||
539 | if (res) | ||
540 | break; | ||
541 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); | ||
542 | } | ||
543 | |||
544 | if (res) { | ||
545 | printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n", | ||
546 | irqs[i].irq, res); | ||
547 | |||
548 | while (i--) | ||
549 | if (irqs[i].sock == skt->nr) | ||
550 | free_irq(irqs[i].irq, skt); | ||
551 | } | ||
552 | return res; | ||
553 | } | ||
554 | EXPORT_SYMBOL(soc_pcmcia_request_irqs); | ||
555 | |||
556 | void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, | ||
557 | struct pcmcia_irqs *irqs, int nr) | ||
558 | { | ||
559 | int i; | ||
560 | |||
561 | for (i = 0; i < nr; i++) | ||
562 | if (irqs[i].sock == skt->nr) | ||
563 | free_irq(irqs[i].irq, skt); | ||
564 | } | ||
565 | EXPORT_SYMBOL(soc_pcmcia_free_irqs); | ||
566 | |||
567 | void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, | ||
568 | struct pcmcia_irqs *irqs, int nr) | ||
569 | { | ||
570 | int i; | ||
571 | |||
572 | for (i = 0; i < nr; i++) | ||
573 | if (irqs[i].sock == skt->nr) | ||
574 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE); | ||
575 | } | ||
576 | EXPORT_SYMBOL(soc_pcmcia_disable_irqs); | ||
577 | |||
578 | void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, | ||
579 | struct pcmcia_irqs *irqs, int nr) | ||
580 | { | ||
581 | int i; | ||
582 | |||
583 | for (i = 0; i < nr; i++) | ||
584 | if (irqs[i].sock == skt->nr) { | ||
585 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING); | ||
586 | irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH); | ||
587 | } | ||
588 | } | ||
589 | EXPORT_SYMBOL(soc_pcmcia_enable_irqs); | ||
590 | |||
591 | |||
592 | static LIST_HEAD(soc_pcmcia_sockets); | 637 | static LIST_HEAD(soc_pcmcia_sockets); |
593 | static DEFINE_MUTEX(soc_pcmcia_sockets_lock); | 638 | static DEFINE_MUTEX(soc_pcmcia_sockets_lock); |
594 | 639 | ||
@@ -635,6 +680,21 @@ module_exit(soc_pcmcia_cpufreq_unregister); | |||
635 | 680 | ||
636 | #endif | 681 | #endif |
637 | 682 | ||
683 | void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, | ||
684 | struct pcmcia_low_level *ops, struct device *dev) | ||
685 | { | ||
686 | int i; | ||
687 | |||
688 | skt->ops = ops; | ||
689 | skt->socket.owner = ops->owner; | ||
690 | skt->socket.dev.parent = dev; | ||
691 | skt->socket.pci_irq = NO_IRQ; | ||
692 | |||
693 | for (i = 0; i < ARRAY_SIZE(skt->stat); i++) | ||
694 | skt->stat[i].gpio = -EINVAL; | ||
695 | } | ||
696 | EXPORT_SYMBOL(soc_pcmcia_init_one); | ||
697 | |||
638 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) | 698 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) |
639 | { | 699 | { |
640 | mutex_lock(&soc_pcmcia_sockets_lock); | 700 | mutex_lock(&soc_pcmcia_sockets_lock); |
@@ -642,8 +702,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) | |||
642 | 702 | ||
643 | pcmcia_unregister_socket(&skt->socket); | 703 | pcmcia_unregister_socket(&skt->socket); |
644 | 704 | ||
645 | skt->ops->hw_shutdown(skt); | 705 | soc_pcmcia_hw_shutdown(skt); |
646 | 706 | ||
707 | /* should not be required; violates some lowlevel drivers */ | ||
647 | soc_common_pcmcia_config_skt(skt, &dead_socket); | 708 | soc_common_pcmcia_config_skt(skt, &dead_socket); |
648 | 709 | ||
649 | list_del(&skt->node); | 710 | list_del(&skt->node); |
@@ -700,7 +761,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) | |||
700 | */ | 761 | */ |
701 | skt->ops->set_timing(skt); | 762 | skt->ops->set_timing(skt); |
702 | 763 | ||
703 | ret = skt->ops->hw_init(skt); | 764 | ret = soc_pcmcia_hw_init(skt); |
704 | if (ret) | 765 | if (ret) |
705 | goto out_err_6; | 766 | goto out_err_6; |
706 | 767 | ||
@@ -733,7 +794,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) | |||
733 | pcmcia_unregister_socket(&skt->socket); | 794 | pcmcia_unregister_socket(&skt->socket); |
734 | 795 | ||
735 | out_err_7: | 796 | out_err_7: |
736 | skt->ops->hw_shutdown(skt); | 797 | soc_pcmcia_hw_shutdown(skt); |
737 | out_err_6: | 798 | out_err_6: |
738 | list_del(&skt->node); | 799 | list_del(&skt->node); |
739 | mutex_unlock(&soc_pcmcia_sockets_lock); | 800 | 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 | ||
118 | struct pcmcia_irqs { | ||
119 | int sock; | ||
120 | int irq; | ||
121 | const char *str; | ||
122 | }; | ||
123 | |||
124 | struct soc_pcmcia_timing { | 128 | struct 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 | ||
130 | extern int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
131 | extern void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
132 | extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
133 | extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); | ||
134 | extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); | 134 | extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); |
135 | 135 | ||
136 | 136 | void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, | |
137 | struct pcmcia_low_level *ops, struct device *dev); | ||
137 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); | 138 | void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); |
138 | int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); | 139 | int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); |
139 | 140 | ||