aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig3
-rw-r--r--drivers/pcmcia/Makefile16
-rw-r--r--drivers/pcmcia/at91_cf.c6
-rw-r--r--drivers/pcmcia/ds.c23
-rw-r--r--drivers/pcmcia/omap_cf.c6
-rw-r--r--drivers/pcmcia/pxa2xx_base.c50
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c154
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c16
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x2xx.c49
-rw-r--r--drivers/pcmcia/pxa2xx_lubbock.c6
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c6
-rw-r--r--drivers/pcmcia/pxa2xx_palmld.c151
-rw-r--r--drivers/pcmcia/pxa2xx_palmtx.c53
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c2
-rw-r--r--drivers/pcmcia/pxa2xx_trizeps4.c256
-rw-r--r--drivers/pcmcia/pxa2xx_viper.c179
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c2
-rw-r--r--drivers/pcmcia/sa1100_assabet.c4
-rw-r--r--drivers/pcmcia/sa1100_badge4.c4
-rw-r--r--drivers/pcmcia/sa1100_cerf.c4
-rw-r--r--drivers/pcmcia/sa1100_h3600.c4
-rw-r--r--drivers/pcmcia/sa1100_jornada720.c2
-rw-r--r--drivers/pcmcia/sa1100_neponset.c4
-rw-r--r--drivers/pcmcia/sa1100_shannon.c4
-rw-r--r--drivers/pcmcia/sa1100_simpad.c4
-rw-r--r--drivers/pcmcia/sa1111_generic.c2
-rw-r--r--drivers/pcmcia/sa11xx_base.c2
-rw-r--r--drivers/pcmcia/soc_common.c10
28 files changed, 930 insertions, 92 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index e0f884034c9f..f57eeae3830a 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -220,7 +220,8 @@ config PCMCIA_PXA2XX
220 tristate "PXA2xx support" 220 tristate "PXA2xx support"
221 depends on ARM && ARCH_PXA && PCMCIA 221 depends on ARM && ARCH_PXA && PCMCIA
222 depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \ 222 depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
223 || MACH_ARMCORE || ARCH_PXA_PALM) 223 || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
224 || ARCH_VIPER)
224 help 225 help
225 Say Y here to include support for the PXA2xx PCMCIA controller 226 Say Y here to include support for the PXA2xx PCMCIA controller
226 227
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 2ea5d46a4033..74d1c906c5d6 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
25obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o 25obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
26obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o 26obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
27obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o 27obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
28obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o pxa2xx_cs.o
29obj-$(CONFIG_M32R_PCC) += m32r_pcc.o 28obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
30obj-$(CONFIG_M32R_CFC) += m32r_cfc.o 29obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
31obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o 30obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
@@ -64,9 +63,14 @@ sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
64sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o 63sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
65sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o 64sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
66 65
67pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock.o sa1111_generic.o 66pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o
68pxa2xx_cs-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o 67pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o
69pxa2xx_cs-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o 68pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
70pxa2xx_cs-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x270.o 69pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
71pxa2xx_cs-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o 70pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
71pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
72pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o
73pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
74pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
72 75
76obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 684968558c19..a0ffb8ebfe00 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -18,13 +18,13 @@
18 18
19#include <pcmcia/ss.h> 19#include <pcmcia/ss.h>
20 20
21#include <asm/hardware.h> 21#include <mach/hardware.h>
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/sizes.h> 23#include <asm/sizes.h>
24#include <asm/gpio.h> 24#include <asm/gpio.h>
25 25
26#include <asm/arch/board.h> 26#include <mach/board.h>
27#include <asm/arch/at91rm9200_mc.h> 27#include <mach/at91rm9200_mc.h>
28 28
29 29
30/* 30/*
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 604249a170c5..795660255490 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -394,6 +394,18 @@ static int pcmcia_device_probe(struct device * dev)
394 p_drv = to_pcmcia_drv(dev->driver); 394 p_drv = to_pcmcia_drv(dev->driver);
395 s = p_dev->socket; 395 s = p_dev->socket;
396 396
397 /* The PCMCIA code passes the match data in via dev->driver_data
398 * which is an ugly hack. Once the driver probe is called it may
399 * and often will overwrite the match data so we must save it first
400 *
401 * handle pseudo multifunction devices:
402 * there are at most two pseudo multifunction devices.
403 * if we're matching against the first, schedule a
404 * call which will then check whether there are two
405 * pseudo devices, and if not, add the second one.
406 */
407 did = p_dev->dev.driver_data;
408
397 ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name); 409 ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
398 410
399 if ((!p_drv->probe) || (!p_dev->function_config) || 411 if ((!p_drv->probe) || (!p_dev->function_config) ||
@@ -422,21 +434,14 @@ static int pcmcia_device_probe(struct device * dev)
422 goto put_module; 434 goto put_module;
423 } 435 }
424 436
425 /* handle pseudo multifunction devices:
426 * there are at most two pseudo multifunction devices.
427 * if we're matching against the first, schedule a
428 * call which will then check whether there are two
429 * pseudo devices, and if not, add the second one.
430 */
431 did = p_dev->dev.driver_data;
432 if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && 437 if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
433 (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) 438 (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
434 pcmcia_add_device_later(p_dev->socket, 0); 439 pcmcia_add_device_later(p_dev->socket, 0);
435 440
436 put_module: 441put_module:
437 if (ret) 442 if (ret)
438 module_put(p_drv->owner); 443 module_put(p_drv->owner);
439 put_dev: 444put_dev:
440 if (ret) 445 if (ret)
441 put_device(dev); 446 put_device(dev);
442 return (ret); 447 return (ret);
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 569b746b5731..f3736398900e 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -19,12 +19,12 @@
19 19
20#include <pcmcia/ss.h> 20#include <pcmcia/ss.h>
21 21
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/sizes.h> 24#include <asm/sizes.h>
25 25
26#include <asm/arch/mux.h> 26#include <mach/mux.h>
27#include <asm/arch/tc.h> 27#include <mach/tc.h>
28 28
29 29
30/* NOTE: don't expect this to support many I/O cards. The 16xx chips have 30/* NOTE: don't expect this to support many I/O cards. The 16xx chips have
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 7bdf36357846..bb9ddb9532e3 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -24,12 +24,13 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26 26
27#include <asm/hardware.h> 27#include <mach/hardware.h>
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/irq.h> 29#include <asm/irq.h>
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/arch/pxa-regs.h> 31#include <mach/pxa-regs.h>
32#include <asm/arch/pxa2xx-regs.h> 32#include <mach/pxa2xx-regs.h>
33#include <asm/mach-types.h>
33 34
34#include <pcmcia/cs_types.h> 35#include <pcmcia/cs_types.h>
35#include <pcmcia/ss.h> 36#include <pcmcia/ss.h>
@@ -165,18 +166,32 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
165} 166}
166#endif 167#endif
167 168
169static void pxa2xx_configure_sockets(struct device *dev)
170{
171 struct pcmcia_low_level *ops = dev->platform_data;
172
173 /*
174 * We have at least one socket, so set MECR:CIT
175 * (Card Is There)
176 */
177 MECR |= MECR_CIT;
178
179 /* Set MECR:NOS (Number Of Sockets) */
180 if (ops->nr > 1 || machine_is_viper())
181 MECR |= MECR_NOS;
182 else
183 MECR &= ~MECR_NOS;
184}
185
168int __pxa2xx_drv_pcmcia_probe(struct device *dev) 186int __pxa2xx_drv_pcmcia_probe(struct device *dev)
169{ 187{
170 int ret; 188 int ret;
171 struct pcmcia_low_level *ops; 189 struct pcmcia_low_level *ops;
172 int first, nr;
173 190
174 if (!dev || !dev->platform_data) 191 if (!dev || !dev->platform_data)
175 return -ENODEV; 192 return -ENODEV;
176 193
177 ops = (struct pcmcia_low_level *)dev->platform_data; 194 ops = (struct pcmcia_low_level *)dev->platform_data;
178 first = ops->first;
179 nr = ops->nr;
180 195
181 /* Provide our PXA2xx specific timing routines. */ 196 /* Provide our PXA2xx specific timing routines. */
182 ops->set_timing = pxa2xx_pcmcia_set_timing; 197 ops->set_timing = pxa2xx_pcmcia_set_timing;
@@ -184,21 +199,10 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
184 ops->frequency_change = pxa2xx_pcmcia_frequency_change; 199 ops->frequency_change = pxa2xx_pcmcia_frequency_change;
185#endif 200#endif
186 201
187 ret = soc_common_drv_pcmcia_probe(dev, ops, first, nr); 202 ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
188 203
189 if (ret == 0) { 204 if (!ret)
190 /* 205 pxa2xx_configure_sockets(dev);
191 * We have at least one socket, so set MECR:CIT
192 * (Card Is There)
193 */
194 MECR |= MECR_CIT;
195
196 /* Set MECR:NOS (Number Of Sockets) */
197 if (nr > 1)
198 MECR |= MECR_NOS;
199 else
200 MECR &= ~MECR_NOS;
201 }
202 206
203 return ret; 207 return ret;
204} 208}
@@ -222,11 +226,7 @@ static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t s
222 226
223static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev) 227static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
224{ 228{
225 struct pcmcia_low_level *ops = dev->dev.platform_data; 229 pxa2xx_configure_sockets(&dev->dev);
226 int nr = ops ? ops->nr : 0;
227
228 MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
229
230 return pcmcia_socket_dev_resume(&dev->dev); 230 return pcmcia_socket_dev_resume(&dev->dev);
231} 231}
232 232
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
new file mode 100644
index 000000000000..7c8bcb476622
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -0,0 +1,154 @@
1/*
2 * linux/drivers/pcmcia/pxa/pxa_cm_x255.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Compulab Ltd., 2003, 2007, 2008
9 * Mike Rapoport <mike@compulab.co.il>
10 *
11 */
12
13#include <linux/platform_device.h>
14#include <linux/irq.h>
15#include <linux/delay.h>
16#include <linux/gpio.h>
17
18#include <asm/mach-types.h>
19#include <mach/pxa-regs.h>
20
21#include "soc_common.h"
22
23#define GPIO_PCMCIA_SKTSEL (54)
24#define GPIO_PCMCIA_S0_CD_VALID (16)
25#define GPIO_PCMCIA_S1_CD_VALID (17)
26#define GPIO_PCMCIA_S0_RDYINT (6)
27#define GPIO_PCMCIA_S1_RDYINT (8)
28#define GPIO_PCMCIA_RESET (9)
29
30#define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID)
31#define PCMCIA_S1_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S1_CD_VALID)
32#define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT)
33#define PCMCIA_S1_RDYINT IRQ_GPIO(GPIO_PCMCIA_S1_RDYINT)
34
35
36static struct pcmcia_irqs irqs[] = {
37 { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" },
38 { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" },
39};
40
41static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
42{
43 int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
44 if (ret)
45 return ret;
46 gpio_direction_output(GPIO_PCMCIA_RESET, 0);
47
48 skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
49 ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
50 if (!ret)
51 gpio_free(GPIO_PCMCIA_RESET);
52
53 return ret;
54}
55
56static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
57{
58 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
59 gpio_free(GPIO_PCMCIA_RESET);
60}
61
62
63static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
64 struct pcmcia_state *state)
65{
66 int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
67 int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_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;
74 state->vs_Xv = 0;
75 state->wrprot = 0; /* not available */
76}
77
78
79static int cmx255_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
80 const socket_state_t *state)
81{
82 switch (skt->nr) {
83 case 0:
84 if (state->flags & SS_RESET) {
85 gpio_set_value(GPIO_PCMCIA_SKTSEL, 0);
86 udelay(1);
87 gpio_set_value(GPIO_PCMCIA_RESET, 1);
88 udelay(10);
89 gpio_set_value(GPIO_PCMCIA_RESET, 0);
90 }
91 break;
92 case 1:
93 if (state->flags & SS_RESET) {
94 gpio_set_value(GPIO_PCMCIA_SKTSEL, 1);
95 udelay(1);
96 gpio_set_value(GPIO_PCMCIA_RESET, 1);
97 udelay(10);
98 gpio_set_value(GPIO_PCMCIA_RESET, 0);
99 }
100 break;
101 }
102
103 return 0;
104}
105
106static void cmx255_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
107{
108}
109
110static void cmx255_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
111{
112}
113
114
115static struct pcmcia_low_level cmx255_pcmcia_ops __initdata = {
116 .owner = THIS_MODULE,
117 .hw_init = cmx255_pcmcia_hw_init,
118 .hw_shutdown = cmx255_pcmcia_shutdown,
119 .socket_state = cmx255_pcmcia_socket_state,
120 .configure_socket = cmx255_pcmcia_configure_socket,
121 .socket_init = cmx255_pcmcia_socket_init,
122 .socket_suspend = cmx255_pcmcia_socket_suspend,
123 .nr = 1,
124};
125
126static struct platform_device *cmx255_pcmcia_device;
127
128int __init cmx255_pcmcia_init(void)
129{
130 int ret;
131
132 cmx255_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
133
134 if (!cmx255_pcmcia_device)
135 return -ENOMEM;
136
137 ret = platform_device_add_data(cmx255_pcmcia_device, &cmx255_pcmcia_ops,
138 sizeof(cmx255_pcmcia_ops));
139
140 if (ret == 0) {
141 printk(KERN_INFO "Registering cm-x255 PCMCIA interface.\n");
142 ret = platform_device_add(cmx255_pcmcia_device);
143 }
144
145 if (ret)
146 platform_device_put(cmx255_pcmcia_device);
147
148 return ret;
149}
150
151void __exit cmx255_pcmcia_exit(void)
152{
153 platform_device_unregister(cmx255_pcmcia_device);
154}
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index bb95db7d2b76..6c3aac377126 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -16,7 +16,7 @@
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17 17
18#include <asm/mach-types.h> 18#include <asm/mach-types.h>
19#include <asm/arch/pxa-regs.h> 19#include <mach/pxa-regs.h>
20 20
21#include "soc_common.h" 21#include "soc_common.h"
22 22
@@ -105,13 +105,10 @@ static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = {
105 105
106static struct platform_device *cmx270_pcmcia_device; 106static struct platform_device *cmx270_pcmcia_device;
107 107
108static int __init cmx270_pcmcia_init(void) 108int __init cmx270_pcmcia_init(void)
109{ 109{
110 int ret; 110 int ret;
111 111
112 if (!machine_is_armcore())
113 return -ENODEV;
114
115 cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); 112 cmx270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
116 113
117 if (!cmx270_pcmcia_device) 114 if (!cmx270_pcmcia_device)
@@ -131,14 +128,7 @@ static int __init cmx270_pcmcia_init(void)
131 return ret; 128 return ret;
132} 129}
133 130
134static void __exit cmx270_pcmcia_exit(void) 131void __exit cmx270_pcmcia_exit(void)
135{ 132{
136 platform_device_unregister(cmx270_pcmcia_device); 133 platform_device_unregister(cmx270_pcmcia_device);
137} 134}
138
139module_init(cmx270_pcmcia_init);
140module_exit(cmx270_pcmcia_exit);
141
142MODULE_LICENSE("GPL");
143MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
144MODULE_DESCRIPTION("CM-x270 PCMCIA driver");
diff --git a/drivers/pcmcia/pxa2xx_cm_x2xx.c b/drivers/pcmcia/pxa2xx_cm_x2xx.c
new file mode 100644
index 000000000000..4f09506ad8d4
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_cm_x2xx.c
@@ -0,0 +1,49 @@
1/*
2 * linux/drivers/pcmcia/pxa/pxa_cm_x2xx.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Compulab Ltd., 2003, 2007, 2008
9 * Mike Rapoport <mike@compulab.co.il>
10 *
11 */
12
13#include <linux/module.h>
14
15#include <asm/system.h>
16#include <asm/mach-types.h>
17#include <mach/system.h>
18
19int cmx255_pcmcia_init(void);
20int cmx270_pcmcia_init(void);
21void cmx255_pcmcia_exit(void);
22void cmx270_pcmcia_exit(void);
23
24static int __init cmx2xx_pcmcia_init(void)
25{
26 int ret = -ENODEV;
27
28 if (machine_is_armcore() && cpu_is_pxa25x())
29 ret = cmx255_pcmcia_init();
30 else if (machine_is_armcore() && cpu_is_pxa27x())
31 ret = cmx270_pcmcia_init();
32
33 return ret;
34}
35
36static void __exit cmx2xx_pcmcia_exit(void)
37{
38 if (machine_is_armcore() && cpu_is_pxa25x())
39 cmx255_pcmcia_exit();
40 else if (machine_is_armcore() && cpu_is_pxa27x())
41 cmx270_pcmcia_exit();
42}
43
44module_init(cmx2xx_pcmcia_init);
45module_exit(cmx2xx_pcmcia_exit);
46
47MODULE_LICENSE("GPL");
48MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
49MODULE_DESCRIPTION("CM-x2xx PCMCIA driver");
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index 881ec8a8e389..37ec55df086e 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -21,11 +21,11 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23 23
24#include <asm/hardware.h> 24#include <mach/hardware.h>
25#include <asm/hardware/sa1111.h> 25#include <asm/hardware/sa1111.h>
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27#include <asm/arch/pxa-regs.h> 27#include <mach/pxa-regs.h>
28#include <asm/arch/lubbock.h> 28#include <mach/lubbock.h>
29 29
30#include "sa1111_generic.h" 30#include "sa1111_generic.h"
31 31
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 92d1cc33808c..877001db4916 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -21,12 +21,12 @@
21 21
22#include <pcmcia/ss.h> 22#include <pcmcia/ss.h>
23 23
24#include <asm/hardware.h> 24#include <mach/hardware.h>
25#include <asm/mach-types.h> 25#include <asm/mach-types.h>
26#include <asm/irq.h> 26#include <asm/irq.h>
27 27
28#include <asm/arch/pxa-regs.h> 28#include <mach/pxa-regs.h>
29#include <asm/arch/mainstone.h> 29#include <mach/mainstone.h>
30 30
31#include "soc_common.h" 31#include "soc_common.h"
32 32
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
new file mode 100644
index 000000000000..1736c67e547e
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -0,0 +1,151 @@
1/*
2 * linux/drivers/pcmcia/pxa2xx_palmld.c
3 *
4 * Driver for Palm LifeDrive PCMCIA
5 *
6 * Copyright (C) 2006 Alex Osborne <ato@meshy.org>
7 * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/gpio.h>
18
19#include <asm/mach-types.h>
20#include <mach/palmld.h>
21#include "soc_common.h"
22
23static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
24{
25 int ret;
26
27 ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
28 if (ret)
29 goto err1;
30 ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
31 if (ret)
32 goto err2;
33
34 ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
35 if (ret)
36 goto err2;
37 ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
38 if (ret)
39 goto err3;
40
41 ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
42 if (ret)
43 goto err3;
44 ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
45 if (ret)
46 goto err4;
47
48 skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
49 return 0;
50
51err4:
52 gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
53err3:
54 gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
55err2:
56 gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
57err1:
58 return ret;
59}
60
61static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
62{
63 gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
64 gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
65 gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
66}
67
68static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
69 struct pcmcia_state *state)
70{
71 state->detect = 1; /* always inserted */
72 state->ready = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
73 state->bvd1 = 1;
74 state->bvd2 = 1;
75 state->wrprot = 0;
76 state->vs_3v = 1;
77 state->vs_Xv = 0;
78}
79
80static int palmld_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
81 const socket_state_t *state)
82{
83 gpio_set_value(GPIO_NR_PALMLD_PCMCIA_POWER, 1);
84 gpio_set_value(GPIO_NR_PALMLD_PCMCIA_RESET,
85 !!(state->flags & SS_RESET));
86
87 return 0;
88}
89
90static void palmld_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
91{
92}
93
94static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
95{
96}
97
98static struct pcmcia_low_level palmld_pcmcia_ops = {
99 .owner = THIS_MODULE,
100
101 .first = 0,
102 .nr = 2,
103
104 .hw_init = palmld_pcmcia_hw_init,
105 .hw_shutdown = palmld_pcmcia_hw_shutdown,
106
107 .socket_state = palmld_pcmcia_socket_state,
108 .configure_socket = palmld_pcmcia_configure_socket,
109
110 .socket_init = palmld_pcmcia_socket_init,
111 .socket_suspend = palmld_pcmcia_socket_suspend,
112};
113
114static struct platform_device *palmld_pcmcia_device;
115
116static int __init palmld_pcmcia_init(void)
117{
118 int ret;
119
120 if (!machine_is_palmld())
121 return -ENODEV;
122
123 palmld_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
124 if (!palmld_pcmcia_device)
125 return -ENOMEM;
126
127 ret = platform_device_add_data(palmld_pcmcia_device, &palmld_pcmcia_ops,
128 sizeof(palmld_pcmcia_ops));
129
130 if (!ret)
131 ret = platform_device_add(palmld_pcmcia_device);
132
133 if (ret)
134 platform_device_put(palmld_pcmcia_device);
135
136 return ret;
137}
138
139static void __exit palmld_pcmcia_exit(void)
140{
141 platform_device_unregister(palmld_pcmcia_device);
142}
143
144module_init(palmld_pcmcia_init);
145module_exit(palmld_pcmcia_exit);
146
147MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
148 " Marek Vasut <marek.vasut@gmail.com>");
149MODULE_DESCRIPTION("PCMCIA support for Palm LifeDrive");
150MODULE_ALIAS("platform:pxa2xx-pcmcia");
151MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
index 4abde190c1f5..e07b5c51ec5b 100644
--- a/drivers/pcmcia/pxa2xx_palmtx.c
+++ b/drivers/pcmcia/pxa2xx_palmtx.c
@@ -16,19 +16,64 @@
16 16
17#include <asm/mach-types.h> 17#include <asm/mach-types.h>
18 18
19#include <asm/arch/gpio.h> 19#include <mach/gpio.h>
20#include <asm/arch/palmtx.h> 20#include <mach/palmtx.h>
21 21
22#include "soc_common.h" 22#include "soc_common.h"
23 23
24static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 24static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
25{ 25{
26 skt->irq = IRQ_GPIO(GPIO_NR_PALMTX_PCMCIA_READY); 26 int ret;
27
28 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1");
29 if (ret)
30 goto err1;
31 ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0);
32 if (ret)
33 goto err2;
34
35 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2");
36 if (ret)
37 goto err2;
38 ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0);
39 if (ret)
40 goto err3;
41
42 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST");
43 if (ret)
44 goto err3;
45 ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1);
46 if (ret)
47 goto err4;
48
49 ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY");
50 if (ret)
51 goto err4;
52 ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY);
53 if (ret)
54 goto err5;
55
56 skt->irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
27 return 0; 57 return 0;
58
59err5:
60 gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
61err4:
62 gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
63err3:
64 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
65err2:
66 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
67err1:
68 return ret;
28} 69}
29 70
30static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 71static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
31{ 72{
73 gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
74 gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
75 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
76 gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
32} 77}
33 78
34static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 79static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
@@ -109,7 +154,7 @@ static void __exit palmtx_pcmcia_exit(void)
109 platform_device_unregister(palmtx_pcmcia_device); 154 platform_device_unregister(palmtx_pcmcia_device);
110} 155}
111 156
112fs_initcall(palmtx_pcmcia_init); 157module_init(palmtx_pcmcia_init);
113module_exit(palmtx_pcmcia_exit); 158module_exit(palmtx_pcmcia_exit);
114 159
115MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); 160MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index d71f93d45833..1cd02f5a23a0 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -19,7 +19,7 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20 20
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/hardware.h> 22#include <mach/hardware.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/hardware/scoop.h> 24#include <asm/hardware/scoop.h>
25 25
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
new file mode 100644
index 000000000000..36c7a0b324d2
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -0,0 +1,256 @@
1/*
2 * linux/drivers/pcmcia/pxa2xx_trizeps4.c
3 *
4 * TRIZEPS PCMCIA specific routines.
5 *
6 * Author: Jürgen Schindele
7 * Created: 20 02, 2006
8 * Copyright: Jürgen Schindele
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/gpio.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21
22#include <asm/mach-types.h>
23#include <asm/irq.h>
24
25#include <mach/hardware.h>
26#include <mach/pxa-regs.h>
27#include <mach/trizeps4.h>
28
29#include "soc_common.h"
30
31extern void board_pcmcia_power(int power);
32
33static struct pcmcia_irqs irqs[] = {
34 { 0, IRQ_GPIO(GPIO_PCD), "cs0_cd" }
35 /* on other baseboards we can have more inputs */
36};
37
38static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
39{
40 int ret, i;
41 /* we dont have voltage/card/ready detection
42 * so we dont need interrupts for it
43 */
44 switch (skt->nr) {
45 case 0:
46 if (gpio_request(GPIO_PRDY, "cf_irq") < 0) {
47 pr_err("%s: sock %d unable to request gpio %d\n", __func__,
48 skt->nr, GPIO_PRDY);
49 return -EBUSY;
50 }
51 if (gpio_direction_input(GPIO_PRDY) < 0) {
52 pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
53 skt->nr, GPIO_PRDY);
54 gpio_free(GPIO_PRDY);
55 return -EINVAL;
56 }
57 skt->irq = IRQ_GPIO(GPIO_PRDY);
58 break;
59
60#ifndef CONFIG_MACH_TRIZEPS_CONXS
61 case 1:
62#endif
63 default:
64 break;
65 }
66 /* release the reset of this card */
67 pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
68
69 /* supplementory irqs for the socket */
70 for (i = 0; i < ARRAY_SIZE(irqs); i++) {
71 if (irqs[i].sock != skt->nr)
72 continue;
73 if (gpio_request(IRQ_TO_GPIO(irqs[i].irq), irqs[i].str) < 0) {
74 pr_err("%s: sock %d unable to request gpio %d\n",
75 __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
76 ret = -EBUSY;
77 goto error;
78 }
79 if (gpio_direction_input(IRQ_TO_GPIO(irqs[i].irq)) < 0) {
80 pr_err("%s: sock %d unable to set input gpio %d\n",
81 __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq));
82 ret = -EINVAL;
83 goto error;
84 }
85 }
86 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
87
88error:
89 for (; i >= 0; i--) {
90 gpio_free(IRQ_TO_GPIO(irqs[i].irq));
91 }
92 return (ret);
93}
94
95static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
96{
97 int i;
98 /* free allocated gpio's */
99 gpio_free(GPIO_PRDY);
100 for (i = 0; i < ARRAY_SIZE(irqs); i++)
101 gpio_free(IRQ_TO_GPIO(irqs[i].irq));
102}
103
104static unsigned long trizeps_pcmcia_status[2];
105
106static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
107 struct pcmcia_state *state)
108{
109 unsigned short status = 0, change;
110 status = CFSR_readw();
111 change = (status ^ trizeps_pcmcia_status[skt->nr]) &
112 ConXS_CFSR_BVD_MASK;
113 if (change) {
114 trizeps_pcmcia_status[skt->nr] = status;
115 if (status & ConXS_CFSR_BVD1) {
116 /* enable_irq empty */
117 } else {
118 /* disable_irq empty */
119 }
120 }
121
122 switch (skt->nr) {
123 case 0:
124 /* just fill in fix states */
125 state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
126 state->ready = gpio_get_value(GPIO_PRDY) ? 1 : 0;
127 state->bvd1 = (status & ConXS_CFSR_BVD1) ? 1 : 0;
128 state->bvd2 = (status & ConXS_CFSR_BVD2) ? 1 : 0;
129 state->vs_3v = (status & ConXS_CFSR_VS1) ? 0 : 1;
130 state->vs_Xv = (status & ConXS_CFSR_VS2) ? 0 : 1;
131 state->wrprot = 0; /* not available */
132 break;
133
134#ifndef CONFIG_MACH_TRIZEPS_CONXS
135 /* on ConXS we only have one slot. Second is inactive */
136 case 1:
137 state->detect = 0;
138 state->ready = 0;
139 state->bvd1 = 0;
140 state->bvd2 = 0;
141 state->vs_3v = 0;
142 state->vs_Xv = 0;
143 state->wrprot = 0;
144 break;
145
146#endif
147 }
148}
149
150static int trizeps_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
151 const socket_state_t *state)
152{
153 int ret = 0;
154 unsigned short power = 0;
155
156 /* we do nothing here just check a bit */
157 switch (state->Vcc) {
158 case 0: power &= 0xfc; break;
159 case 33: power |= ConXS_BCR_S0_VCC_3V3; break;
160 case 50:
161 pr_err("%s(): Vcc 5V not supported in socket\n", __func__);
162 break;
163 default:
164 pr_err("%s(): bad Vcc %u\n", __func__, state->Vcc);
165 ret = -1;
166 }
167
168 switch (state->Vpp) {
169 case 0: power &= 0xf3; break;
170 case 33: power |= ConXS_BCR_S0_VPP_3V3; break;
171 case 120:
172 pr_err("%s(): Vpp 12V not supported in socket\n", __func__);
173 break;
174 default:
175 if (state->Vpp != state->Vcc) {
176 pr_err("%s(): bad Vpp %u\n", __func__, state->Vpp);
177 ret = -1;
178 }
179 }
180
181 switch (skt->nr) {
182 case 0: /* we only have 3.3V */
183 board_pcmcia_power(power);
184 break;
185
186#ifndef CONFIG_MACH_TRIZEPS_CONXS
187 /* on ConXS we only have one slot. Second is inactive */
188 case 1:
189#endif
190 default:
191 break;
192 }
193
194 return ret;
195}
196
197static void trizeps_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
198{
199 /* default is on */
200 board_pcmcia_power(0x9);
201}
202
203static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
204{
205 board_pcmcia_power(0x0);
206}
207
208static struct pcmcia_low_level trizeps_pcmcia_ops = {
209 .owner = THIS_MODULE,
210 .hw_init = trizeps_pcmcia_hw_init,
211 .hw_shutdown = trizeps_pcmcia_hw_shutdown,
212 .socket_state = trizeps_pcmcia_socket_state,
213 .configure_socket = trizeps_pcmcia_configure_socket,
214 .socket_init = trizeps_pcmcia_socket_init,
215 .socket_suspend = trizeps_pcmcia_socket_suspend,
216#ifdef CONFIG_MACH_TRIZEPS_CONXS
217 .nr = 1,
218#else
219 .nr = 2,
220#endif
221 .first = 0,
222};
223
224static struct platform_device *trizeps_pcmcia_device;
225
226static int __init trizeps_pcmcia_init(void)
227{
228 int ret;
229
230 trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
231 if (!trizeps_pcmcia_device)
232 return -ENOMEM;
233
234 ret = platform_device_add_data(trizeps_pcmcia_device,
235 &trizeps_pcmcia_ops, sizeof(trizeps_pcmcia_ops));
236
237 if (ret == 0)
238 ret = platform_device_add(trizeps_pcmcia_device);
239
240 if (ret)
241 platform_device_put(trizeps_pcmcia_device);
242
243 return ret;
244}
245
246static void __exit trizeps_pcmcia_exit(void)
247{
248 platform_device_unregister(trizeps_pcmcia_device);
249}
250
251fs_initcall(trizeps_pcmcia_init);
252module_exit(trizeps_pcmcia_exit);
253
254MODULE_LICENSE("GPL");
255MODULE_AUTHOR("Juergen Schindele");
256MODULE_ALIAS("platform:pxa2xx-pcmcia");
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
new file mode 100644
index 000000000000..dd10481be7bf
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -0,0 +1,179 @@
1/*
2 * VIPER PCMCIA support
3 * Copyright 2004 Arcom Control Systems
4 *
5 * Maintained by Marc Zyngier <maz@misterjones.org>
6 * <marc.zyngier@altran.com>
7 *
8 * Based on:
9 * iPAQ h2200 PCMCIA support
10 * Copyright 2004 Koen Kooi <koen@vestingbar.nl>
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file COPYING in the main directory of this archive for
14 * more details.
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/gpio.h>
24
25#include <pcmcia/ss.h>
26
27#include <asm/irq.h>
28
29#include <mach/pxa-regs.h>
30#include <mach/viper.h>
31#include <asm/mach-types.h>
32
33#include "soc_common.h"
34#include "pxa2xx_base.h"
35
36static struct pcmcia_irqs irqs[] = {
37 { 0, gpio_to_irq(VIPER_CF_CD_GPIO), "PCMCIA_CD" }
38};
39
40static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
41{
42 unsigned long flags;
43
44 skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
45
46 if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
47 goto err_request_cd;
48
49 if (gpio_request(VIPER_CF_RDY_GPIO, "CF ready"))
50 goto err_request_rdy;
51
52 if (gpio_request(VIPER_CF_POWER_GPIO, "CF power"))
53 goto err_request_pwr;
54
55 local_irq_save(flags);
56
57 /* GPIO 82 is the CF power enable line. initially off */
58 if (gpio_direction_output(VIPER_CF_POWER_GPIO, 0) ||
59 gpio_direction_input(VIPER_CF_CD_GPIO) ||
60 gpio_direction_input(VIPER_CF_RDY_GPIO)) {
61 local_irq_restore(flags);
62 goto err_dir;
63 }
64
65 local_irq_restore(flags);
66
67 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
68
69err_dir:
70 gpio_free(VIPER_CF_POWER_GPIO);
71err_request_pwr:
72 gpio_free(VIPER_CF_RDY_GPIO);
73err_request_rdy:
74 gpio_free(VIPER_CF_CD_GPIO);
75err_request_cd:
76 printk(KERN_ERR "viper: Failed to setup PCMCIA GPIOs\n");
77 return -1;
78}
79
80/*
81 * Release all resources.
82 */
83static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
84{
85 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
86 gpio_free(VIPER_CF_POWER_GPIO);
87 gpio_free(VIPER_CF_RDY_GPIO);
88 gpio_free(VIPER_CF_CD_GPIO);
89}
90
91static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
92 struct pcmcia_state *state)
93{
94 state->detect = gpio_get_value(VIPER_CF_CD_GPIO) ? 0 : 1;
95 state->ready = gpio_get_value(VIPER_CF_RDY_GPIO) ? 1 : 0;
96 state->bvd1 = 1;
97 state->bvd2 = 1;
98 state->wrprot = 0;
99 state->vs_3v = 1; /* Can only apply 3.3V */
100 state->vs_Xv = 0;
101}
102
103static int viper_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
104 const socket_state_t *state)
105{
106 /* Silently ignore Vpp, output enable, speaker enable. */
107 viper_cf_rst(state->flags & SS_RESET);
108
109 /* Apply socket voltage */
110 switch (state->Vcc) {
111 case 0:
112 gpio_set_value(VIPER_CF_POWER_GPIO, 0);
113 break;
114 case 33:
115 gpio_set_value(VIPER_CF_POWER_GPIO, 1);
116 break;
117 default:
118 printk(KERN_ERR "%s: Unsupported Vcc:%d\n",
119 __func__, state->Vcc);
120 return -1;
121 }
122
123 return 0;
124}
125
126static void viper_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
127{
128}
129
130static void viper_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
131{
132}
133
134static struct pcmcia_low_level viper_pcmcia_ops __initdata = {
135 .owner = THIS_MODULE,
136 .hw_init = viper_pcmcia_hw_init,
137 .hw_shutdown = viper_pcmcia_hw_shutdown,
138 .socket_state = viper_pcmcia_socket_state,
139 .configure_socket = viper_pcmcia_configure_socket,
140 .socket_init = viper_pcmcia_socket_init,
141 .socket_suspend = viper_pcmcia_socket_suspend,
142 .nr = 1,
143};
144
145static struct platform_device *viper_pcmcia_device;
146
147static int __init viper_pcmcia_init(void)
148{
149 int ret;
150
151 if (!machine_is_viper())
152 return -ENODEV;
153
154 viper_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
155 if (!viper_pcmcia_device)
156 return -ENOMEM;
157
158 ret = platform_device_add_data(viper_pcmcia_device,
159 &viper_pcmcia_ops,
160 sizeof(viper_pcmcia_ops));
161
162 if (!ret)
163 ret = platform_device_add(viper_pcmcia_device);
164
165 if (ret)
166 platform_device_put(viper_pcmcia_device);
167
168 return ret;
169}
170
171static void __exit viper_pcmcia_exit(void)
172{
173 platform_device_unregister(viper_pcmcia_device);
174}
175
176module_init(viper_pcmcia_init);
177module_exit(viper_pcmcia_exit);
178
179MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 0e4141bac7b1..17f4ecf1c0c5 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -282,7 +282,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
282 destroy_cis_cache(s); 282 destroy_cis_cache(s);
283 } 283 }
284 s->cis_mem.res = NULL; 284 s->cis_mem.res = NULL;
285 if ((ret != 0) || (count == 0)) 285 if ((ret != 0) || (*count == 0))
286 return 0; 286 return 0;
287 return 1; 287 return 1;
288} 288}
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index ce133ce81c10..f424146a2bc9 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -11,11 +11,11 @@
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/init.h> 12#include <linux/init.h>
13 13
14#include <asm/hardware.h> 14#include <mach/hardware.h>
15#include <asm/mach-types.h> 15#include <asm/mach-types.h>
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/signal.h> 17#include <asm/signal.h>
18#include <asm/arch/assabet.h> 18#include <mach/assabet.h>
19 19
20#include "sa1100_generic.h" 20#include "sa1100_generic.h"
21 21
diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c
index 607c3f326eca..1ca9737ea79e 100644
--- a/drivers/pcmcia/sa1100_badge4.c
+++ b/drivers/pcmcia/sa1100_badge4.c
@@ -18,9 +18,9 @@
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/init.h> 19#include <linux/init.h>
20 20
21#include <asm/hardware.h> 21#include <mach/hardware.h>
22#include <asm/mach-types.h> 22#include <asm/mach-types.h>
23#include <asm/arch/badge4.h> 23#include <mach/badge4.h>
24#include <asm/hardware/sa1111.h> 24#include <asm/hardware/sa1111.h>
25 25
26#include "sa1111_generic.h" 26#include "sa1111_generic.h"
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index 7c3951a2675d..63e6bc431a0d 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -11,10 +11,10 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13 13
14#include <asm/hardware.h> 14#include <mach/hardware.h>
15#include <asm/mach-types.h> 15#include <asm/mach-types.h>
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/arch/cerf.h> 17#include <mach/cerf.h>
18#include "sa1100_generic.h" 18#include "sa1100_generic.h"
19 19
20#define CERF_SOCKET 1 20#define CERF_SOCKET 1
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index e5491879acd9..6de4e1b41d60 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -11,10 +11,10 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13 13
14#include <asm/hardware.h> 14#include <mach/hardware.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include <asm/mach-types.h> 16#include <asm/mach-types.h>
17#include <asm/arch/h3600.h> 17#include <mach/h3600.h>
18 18
19#include "sa1100_generic.h" 19#include "sa1100_generic.h"
20 20
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
index 2167e6714d2d..57ca085473d5 100644
--- a/drivers/pcmcia/sa1100_jornada720.c
+++ b/drivers/pcmcia/sa1100_jornada720.c
@@ -10,7 +10,7 @@
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/init.h> 11#include <linux/init.h>
12 12
13#include <asm/hardware.h> 13#include <mach/hardware.h>
14#include <asm/hardware/sa1111.h> 14#include <asm/hardware/sa1111.h>
15#include <asm/mach-types.h> 15#include <asm/mach-types.h>
16 16
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
index 687492fcd5b4..4c41e86ccff9 100644
--- a/drivers/pcmcia/sa1100_neponset.c
+++ b/drivers/pcmcia/sa1100_neponset.c
@@ -9,9 +9,9 @@
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/init.h> 10#include <linux/init.h>
11 11
12#include <asm/hardware.h> 12#include <mach/hardware.h>
13#include <asm/mach-types.h> 13#include <asm/mach-types.h>
14#include <asm/arch/neponset.h> 14#include <mach/neponset.h>
15#include <asm/hardware/sa1111.h> 15#include <asm/hardware/sa1111.h>
16 16
17#include "sa1111_generic.h" 17#include "sa1111_generic.h"
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 494912fccc0d..46d8c1977c2a 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -9,9 +9,9 @@
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/init.h> 10#include <linux/init.h>
11 11
12#include <asm/hardware.h> 12#include <mach/hardware.h>
13#include <asm/mach-types.h> 13#include <asm/mach-types.h>
14#include <asm/arch/shannon.h> 14#include <mach/shannon.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include "sa1100_generic.h" 16#include "sa1100_generic.h"
17 17
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 42567de894b9..33a08ae09fdf 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -9,10 +9,10 @@
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/init.h> 10#include <linux/init.h>
11 11
12#include <asm/hardware.h> 12#include <mach/hardware.h>
13#include <asm/mach-types.h> 13#include <asm/mach-types.h>
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <asm/arch/simpad.h> 15#include <mach/simpad.h>
16#include "sa1100_generic.h" 16#include "sa1100_generic.h"
17 17
18extern long get_cs3_shadow(void); 18extern long get_cs3_shadow(void);
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 658cddfbcf29..6924d0ea8d32 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -14,7 +14,7 @@
14 14
15#include <pcmcia/ss.h> 15#include <pcmcia/ss.h>
16 16
17#include <asm/hardware.h> 17#include <mach/hardware.h>
18#include <asm/hardware/sa1111.h> 18#include <asm/hardware/sa1111.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/irq.h> 20#include <asm/irq.h>
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 31a7abc55b23..7cb1273202cc 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -37,7 +37,7 @@
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39 39
40#include <asm/hardware.h> 40#include <mach/hardware.h>
41#include <asm/io.h> 41#include <asm/io.h>
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/system.h> 43#include <asm/system.h>
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 89edcbc3bfd2..f49ac6666153 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -43,7 +43,7 @@
43#include <linux/spinlock.h> 43#include <linux/spinlock.h>
44#include <linux/cpufreq.h> 44#include <linux/cpufreq.h>
45 45
46#include <asm/hardware.h> 46#include <mach/hardware.h>
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/system.h> 48#include <asm/system.h>
49 49
@@ -51,7 +51,7 @@
51 51
52/* FIXME: platform dependent resource declaration has to move out of this file */ 52/* FIXME: platform dependent resource declaration has to move out of this file */
53#ifdef CONFIG_ARCH_PXA 53#ifdef CONFIG_ARCH_PXA
54#include <asm/arch/pxa-regs.h> 54#include <mach/pxa-regs.h>
55#endif 55#endif
56 56
57#ifdef CONFIG_PCMCIA_DEBUG 57#ifdef CONFIG_PCMCIA_DEBUG
@@ -748,7 +748,9 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
748 748
749 add_timer(&skt->poll_timer); 749 add_timer(&skt->poll_timer);
750 750
751 device_create_file(&skt->socket.dev, &dev_attr_status); 751 ret = device_create_file(&skt->socket.dev, &dev_attr_status);
752 if (ret)
753 goto out_err_8;
752 } 754 }
753 755
754 dev_set_drvdata(dev, sinfo); 756 dev_set_drvdata(dev, sinfo);
@@ -758,6 +760,8 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
758 do { 760 do {
759 skt = &sinfo->skt[i]; 761 skt = &sinfo->skt[i];
760 762
763 device_remove_file(&skt->socket.dev, &dev_attr_status);
764 out_err_8:
761 del_timer_sync(&skt->poll_timer); 765 del_timer_sync(&skt->poll_timer);
762 pcmcia_unregister_socket(&skt->socket); 766 pcmcia_unregister_socket(&skt->socket);
763 767