aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig4
-rw-r--r--drivers/pcmcia/Makefile2
-rw-r--r--drivers/pcmcia/at91_cf.c2
-rw-r--r--drivers/pcmcia/au1000_generic.c2
-rw-r--r--drivers/pcmcia/bcm63xx_pcmcia.c536
-rw-r--r--drivers/pcmcia/bcm63xx_pcmcia.h60
-rw-r--r--drivers/pcmcia/bfin_cf_pcmcia.c2
-rw-r--r--drivers/pcmcia/cistpl.c20
-rw-r--r--drivers/pcmcia/cs.c2
-rw-r--r--drivers/pcmcia/cs_internal.h3
-rw-r--r--drivers/pcmcia/ds.c8
-rw-r--r--drivers/pcmcia/i82092.c2
-rw-r--r--drivers/pcmcia/i82365.c6
-rw-r--r--drivers/pcmcia/m32r_cfc.c12
-rw-r--r--drivers/pcmcia/m32r_pcc.c12
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c17
-rw-r--r--drivers/pcmcia/omap_cf.c2
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c2
-rw-r--r--drivers/pcmcia/pd6729.c8
-rw-r--r--drivers/pcmcia/pxa2xx_base.c18
-rw-r--r--drivers/pcmcia/pxa2xx_palmtc.c230
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c3
-rw-r--r--drivers/pcmcia/sa1100_assabet.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c2
-rw-r--r--drivers/pcmcia/sa1100_neponset.c2
-rw-r--r--drivers/pcmcia/sa1111_generic.c2
-rw-r--r--drivers/pcmcia/soc_common.c5
-rw-r--r--drivers/pcmcia/socket_sysfs.c2
-rw-r--r--drivers/pcmcia/tcic.c6
-rw-r--r--drivers/pcmcia/vrc4171_card.c2
-rw-r--r--drivers/pcmcia/yenta_socket.c88
31 files changed, 962 insertions, 102 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index fbf965b31c1..17f38a781d4 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -192,6 +192,10 @@ config PCMCIA_AU1X00
192 tristate "Au1x00 pcmcia support" 192 tristate "Au1x00 pcmcia support"
193 depends on SOC_AU1X00 && PCMCIA 193 depends on SOC_AU1X00 && PCMCIA
194 194
195config PCMCIA_BCM63XX
196 tristate "bcm63xx pcmcia support"
197 depends on BCM63XX && PCMCIA
198
195config PCMCIA_SA1100 199config PCMCIA_SA1100
196 tristate "SA1100 support" 200 tristate "SA1100 support"
197 depends on ARM && ARCH_SA1100 && PCMCIA 201 depends on ARM && ARCH_SA1100 && PCMCIA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 047394d98ac..a03a38acd77 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
27obj-$(CONFIG_M32R_PCC) += m32r_pcc.o 27obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
28obj-$(CONFIG_M32R_CFC) += m32r_cfc.o 28obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
29obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o 29obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
30obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o
30obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o 31obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
31obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o 32obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
32obj-$(CONFIG_OMAP_CF) += omap_cf.o 33obj-$(CONFIG_OMAP_CF) += omap_cf.o
@@ -71,6 +72,7 @@ pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o
71pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o 72pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
72pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps4.o 73pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps4.o
73pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o 74pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
75pxa2xx-obj-$(CONFIG_MACH_PALMTC) += pxa2xx_palmtc.o
74pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o 76pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
75pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o 77pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
76pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o 78pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 9e1140f085f..e1dccedc596 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -363,7 +363,7 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
363 struct at91_cf_socket *cf = platform_get_drvdata(pdev); 363 struct at91_cf_socket *cf = platform_get_drvdata(pdev);
364 struct at91_cf_data *board = cf->board; 364 struct at91_cf_data *board = cf->board;
365 365
366 pcmcia_socket_dev_suspend(&pdev->dev, mesg); 366 pcmcia_socket_dev_suspend(&pdev->dev);
367 if (device_may_wakeup(&pdev->dev)) { 367 if (device_may_wakeup(&pdev->dev)) {
368 enable_irq_wake(board->det_pin); 368 enable_irq_wake(board->det_pin);
369 if (board->irq_pin) 369 if (board->irq_pin)
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 90013341cd5..02088704ac2 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -515,7 +515,7 @@ static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
515static int au1x00_drv_pcmcia_suspend(struct platform_device *dev, 515static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
516 pm_message_t state) 516 pm_message_t state)
517{ 517{
518 return pcmcia_socket_dev_suspend(&dev->dev, state); 518 return pcmcia_socket_dev_suspend(&dev->dev);
519} 519}
520 520
521static int au1x00_drv_pcmcia_resume(struct platform_device *dev) 521static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c
new file mode 100644
index 00000000000..bc88a3b19bb
--- /dev/null
+++ b/drivers/pcmcia/bcm63xx_pcmcia.c
@@ -0,0 +1,536 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 */
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/ioport.h>
12#include <linux/timer.h>
13#include <linux/platform_device.h>
14#include <linux/delay.h>
15#include <linux/pci.h>
16#include <linux/gpio.h>
17
18#include <bcm63xx_regs.h>
19#include <bcm63xx_io.h>
20#include "bcm63xx_pcmcia.h"
21
22#define PFX "bcm63xx_pcmcia: "
23
24#ifdef CONFIG_CARDBUS
25/* if cardbus is used, platform device needs reference to actual pci
26 * device */
27static struct pci_dev *bcm63xx_cb_dev;
28#endif
29
30/*
31 * read/write helper for pcmcia regs
32 */
33static inline u32 pcmcia_readl(struct bcm63xx_pcmcia_socket *skt, u32 off)
34{
35 return bcm_readl(skt->base + off);
36}
37
38static inline void pcmcia_writel(struct bcm63xx_pcmcia_socket *skt,
39 u32 val, u32 off)
40{
41 bcm_writel(val, skt->base + off);
42}
43
44/*
45 * This callback should (re-)initialise the socket, turn on status
46 * interrupts and PCMCIA bus, and wait for power to stabilise so that
47 * the card status signals report correctly.
48 *
49 * Hardware cannot do that.
50 */
51static int bcm63xx_pcmcia_sock_init(struct pcmcia_socket *sock)
52{
53 return 0;
54}
55
56/*
57 * This callback should remove power on the socket, disable IRQs from
58 * the card, turn off status interrupts, and disable the PCMCIA bus.
59 *
60 * Hardware cannot do that.
61 */
62static int bcm63xx_pcmcia_suspend(struct pcmcia_socket *sock)
63{
64 return 0;
65}
66
67/*
68 * Implements the set_socket() operation for the in-kernel PCMCIA
69 * service (formerly SS_SetSocket in Card Services). We more or
70 * less punt all of this work and let the kernel handle the details
71 * of power configuration, reset, &c. We also record the value of
72 * `state' in order to regurgitate it to the PCMCIA core later.
73 */
74static int bcm63xx_pcmcia_set_socket(struct pcmcia_socket *sock,
75 socket_state_t *state)
76{
77 struct bcm63xx_pcmcia_socket *skt;
78 unsigned long flags;
79 u32 val;
80
81 skt = sock->driver_data;
82
83 spin_lock_irqsave(&skt->lock, flags);
84
85 /* note: hardware cannot control socket power, so we will
86 * always report SS_POWERON */
87
88 /* apply socket reset */
89 val = pcmcia_readl(skt, PCMCIA_C1_REG);
90 if (state->flags & SS_RESET)
91 val |= PCMCIA_C1_RESET_MASK;
92 else
93 val &= ~PCMCIA_C1_RESET_MASK;
94
95 /* reverse reset logic for cardbus card */
96 if (skt->card_detected && (skt->card_type & CARD_CARDBUS))
97 val ^= PCMCIA_C1_RESET_MASK;
98
99 pcmcia_writel(skt, val, PCMCIA_C1_REG);
100
101 /* keep requested state for event reporting */
102 skt->requested_state = *state;
103
104 spin_unlock_irqrestore(&skt->lock, flags);
105
106 return 0;
107}
108
109/*
110 * identity cardtype from VS[12] input, CD[12] input while only VS2 is
111 * floating, and CD[12] input while only VS1 is floating
112 */
113enum {
114 IN_VS1 = (1 << 0),
115 IN_VS2 = (1 << 1),
116 IN_CD1_VS2H = (1 << 2),
117 IN_CD2_VS2H = (1 << 3),
118 IN_CD1_VS1H = (1 << 4),
119 IN_CD2_VS1H = (1 << 5),
120};
121
122static const u8 vscd_to_cardtype[] = {
123
124 /* VS1 float, VS2 float */
125 [IN_VS1 | IN_VS2] = (CARD_PCCARD | CARD_5V),
126
127 /* VS1 grounded, VS2 float */
128 [IN_VS2] = (CARD_PCCARD | CARD_5V | CARD_3V),
129
130 /* VS1 grounded, VS2 grounded */
131 [0] = (CARD_PCCARD | CARD_5V | CARD_3V | CARD_XV),
132
133 /* VS1 tied to CD1, VS2 float */
134 [IN_VS1 | IN_VS2 | IN_CD1_VS1H] = (CARD_CARDBUS | CARD_3V),
135
136 /* VS1 grounded, VS2 tied to CD2 */
137 [IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V | CARD_XV),
138
139 /* VS1 tied to CD2, VS2 grounded */
140 [IN_VS1 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_3V | CARD_XV | CARD_YV),
141
142 /* VS1 float, VS2 grounded */
143 [IN_VS1] = (CARD_PCCARD | CARD_XV),
144
145 /* VS1 float, VS2 tied to CD2 */
146 [IN_VS1 | IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V),
147
148 /* VS1 float, VS2 tied to CD1 */
149 [IN_VS1 | IN_VS2 | IN_CD1_VS2H] = (CARD_CARDBUS | CARD_XV | CARD_YV),
150
151 /* VS1 tied to CD2, VS2 float */
152 [IN_VS1 | IN_VS2 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_YV),
153
154 /* VS2 grounded, VS1 is tied to CD1, CD2 is grounded */
155 [IN_VS1 | IN_CD1_VS1H] = 0, /* ignore cardbay */
156};
157
158/*
159 * poll hardware to check card insertion status
160 */
161static unsigned int __get_socket_status(struct bcm63xx_pcmcia_socket *skt)
162{
163 unsigned int stat;
164 u32 val;
165
166 stat = 0;
167
168 /* check CD for card presence */
169 val = pcmcia_readl(skt, PCMCIA_C1_REG);
170
171 if (!(val & PCMCIA_C1_CD1_MASK) && !(val & PCMCIA_C1_CD2_MASK))
172 stat |= SS_DETECT;
173
174 /* if new insertion, detect cardtype */
175 if ((stat & SS_DETECT) && !skt->card_detected) {
176 unsigned int stat = 0;
177
178 /* float VS1, float VS2 */
179 val |= PCMCIA_C1_VS1OE_MASK;
180 val |= PCMCIA_C1_VS2OE_MASK;
181 pcmcia_writel(skt, val, PCMCIA_C1_REG);
182
183 /* wait for output to stabilize and read VS[12] */
184 udelay(10);
185 val = pcmcia_readl(skt, PCMCIA_C1_REG);
186 stat |= (val & PCMCIA_C1_VS1_MASK) ? IN_VS1 : 0;
187 stat |= (val & PCMCIA_C1_VS2_MASK) ? IN_VS2 : 0;
188
189 /* drive VS1 low, float VS2 */
190 val &= ~PCMCIA_C1_VS1OE_MASK;
191 val |= PCMCIA_C1_VS2OE_MASK;
192 pcmcia_writel(skt, val, PCMCIA_C1_REG);
193
194 /* wait for output to stabilize and read CD[12] */
195 udelay(10);
196 val = pcmcia_readl(skt, PCMCIA_C1_REG);
197 stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS2H : 0;
198 stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS2H : 0;
199
200 /* float VS1, drive VS2 low */
201 val |= PCMCIA_C1_VS1OE_MASK;
202 val &= ~PCMCIA_C1_VS2OE_MASK;
203 pcmcia_writel(skt, val, PCMCIA_C1_REG);
204
205 /* wait for output to stabilize and read CD[12] */
206 udelay(10);
207 val = pcmcia_readl(skt, PCMCIA_C1_REG);
208 stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS1H : 0;
209 stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS1H : 0;
210
211 /* guess cardtype from all this */
212 skt->card_type = vscd_to_cardtype[stat];
213 if (!skt->card_type)
214 dev_err(&skt->socket.dev, "unsupported card type\n");
215
216 /* drive both VS pin to 0 again */
217 val &= ~(PCMCIA_C1_VS1OE_MASK | PCMCIA_C1_VS2OE_MASK);
218
219 /* enable correct logic */
220 val &= ~(PCMCIA_C1_EN_PCMCIA_MASK | PCMCIA_C1_EN_CARDBUS_MASK);
221 if (skt->card_type & CARD_PCCARD)
222 val |= PCMCIA_C1_EN_PCMCIA_MASK;
223 else
224 val |= PCMCIA_C1_EN_CARDBUS_MASK;
225
226 pcmcia_writel(skt, val, PCMCIA_C1_REG);
227 }
228 skt->card_detected = (stat & SS_DETECT) ? 1 : 0;
229
230 /* report card type/voltage */
231 if (skt->card_type & CARD_CARDBUS)
232 stat |= SS_CARDBUS;
233 if (skt->card_type & CARD_3V)
234 stat |= SS_3VCARD;
235 if (skt->card_type & CARD_XV)
236 stat |= SS_XVCARD;
237 stat |= SS_POWERON;
238
239 if (gpio_get_value(skt->pd->ready_gpio))
240 stat |= SS_READY;
241
242 return stat;
243}
244
245/*
246 * core request to get current socket status
247 */
248static int bcm63xx_pcmcia_get_status(struct pcmcia_socket *sock,
249 unsigned int *status)
250{
251 struct bcm63xx_pcmcia_socket *skt;
252
253 skt = sock->driver_data;
254
255 spin_lock_bh(&skt->lock);
256 *status = __get_socket_status(skt);
257 spin_unlock_bh(&skt->lock);
258
259 return 0;
260}
261
262/*
263 * socket polling timer callback
264 */
265static void bcm63xx_pcmcia_poll(unsigned long data)
266{
267 struct bcm63xx_pcmcia_socket *skt;
268 unsigned int stat, events;
269
270 skt = (struct bcm63xx_pcmcia_socket *)data;
271
272 spin_lock_bh(&skt->lock);
273
274 stat = __get_socket_status(skt);
275
276 /* keep only changed bits, and mask with required one from the
277 * core */
278 events = (stat ^ skt->old_status) & skt->requested_state.csc_mask;
279 skt->old_status = stat;
280 spin_unlock_bh(&skt->lock);
281
282 if (events)
283 pcmcia_parse_events(&skt->socket, events);
284
285 mod_timer(&skt->timer,
286 jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
287}
288
289static int bcm63xx_pcmcia_set_io_map(struct pcmcia_socket *sock,
290 struct pccard_io_map *map)
291{
292 /* this doesn't seem to be called by pcmcia layer if static
293 * mapping is used */
294 return 0;
295}
296
297static int bcm63xx_pcmcia_set_mem_map(struct pcmcia_socket *sock,
298 struct pccard_mem_map *map)
299{
300 struct bcm63xx_pcmcia_socket *skt;
301 struct resource *res;
302
303 skt = sock->driver_data;
304 if (map->flags & MAP_ATTRIB)
305 res = skt->attr_res;
306 else
307 res = skt->common_res;
308
309 map->static_start = res->start + map->card_start;
310 return 0;
311}
312
313static struct pccard_operations bcm63xx_pcmcia_operations = {
314 .init = bcm63xx_pcmcia_sock_init,
315 .suspend = bcm63xx_pcmcia_suspend,
316 .get_status = bcm63xx_pcmcia_get_status,
317 .set_socket = bcm63xx_pcmcia_set_socket,
318 .set_io_map = bcm63xx_pcmcia_set_io_map,
319 .set_mem_map = bcm63xx_pcmcia_set_mem_map,
320};
321
322/*
323 * register pcmcia socket to core
324 */
325static int __devinit bcm63xx_drv_pcmcia_probe(struct platform_device *pdev)
326{
327 struct bcm63xx_pcmcia_socket *skt;
328 struct pcmcia_socket *sock;
329 struct resource *res, *irq_res;
330 unsigned int regmem_size = 0, iomem_size = 0;
331 u32 val;
332 int ret;
333
334 skt = kzalloc(sizeof(*skt), GFP_KERNEL);
335 if (!skt)
336 return -ENOMEM;
337 spin_lock_init(&skt->lock);
338 sock = &skt->socket;
339 sock->driver_data = skt;
340
341 /* make sure we have all resources we need */
342 skt->common_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
343 skt->attr_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
344 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
345 skt->pd = pdev->dev.platform_data;
346 if (!skt->common_res || !skt->attr_res || !irq_res || !skt->pd) {
347 ret = -EINVAL;
348 goto err;
349 }
350
351 /* remap pcmcia registers */
352 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
353 regmem_size = resource_size(res);
354 if (!request_mem_region(res->start, regmem_size, "bcm63xx_pcmcia")) {
355 ret = -EINVAL;
356 goto err;
357 }
358 skt->reg_res = res;
359
360 skt->base = ioremap(res->start, regmem_size);
361 if (!skt->base) {
362 ret = -ENOMEM;
363 goto err;
364 }
365
366 /* remap io registers */
367 res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
368 iomem_size = resource_size(res);
369 skt->io_base = ioremap(res->start, iomem_size);
370 if (!skt->io_base) {
371 ret = -ENOMEM;
372 goto err;
373 }
374
375 /* resources are static */
376 sock->resource_ops = &pccard_static_ops;
377 sock->ops = &bcm63xx_pcmcia_operations;
378 sock->owner = THIS_MODULE;
379 sock->dev.parent = &pdev->dev;
380 sock->features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
381 sock->io_offset = (unsigned long)skt->io_base;
382 sock->pci_irq = irq_res->start;
383
384#ifdef CONFIG_CARDBUS
385 sock->cb_dev = bcm63xx_cb_dev;
386 if (bcm63xx_cb_dev)
387 sock->features |= SS_CAP_CARDBUS;
388#endif
389
390 /* assume common & attribute memory have the same size */
391 sock->map_size = resource_size(skt->common_res);
392
393 /* initialize polling timer */
394 setup_timer(&skt->timer, bcm63xx_pcmcia_poll, (unsigned long)skt);
395
396 /* initialize pcmcia control register, drive VS[12] to 0,
397 * leave CB IDSEL to the old value since it is set by the PCI
398 * layer */
399 val = pcmcia_readl(skt, PCMCIA_C1_REG);
400 val &= PCMCIA_C1_CBIDSEL_MASK;
401 val |= PCMCIA_C1_EN_PCMCIA_GPIO_MASK;
402 pcmcia_writel(skt, val, PCMCIA_C1_REG);
403
404 /*
405 * Hardware has only one set of timings registers, not one for
406 * each memory access type, so we configure them for the
407 * slowest one: attribute memory.
408 */
409 val = PCMCIA_C2_DATA16_MASK;
410 val |= 10 << PCMCIA_C2_RWCOUNT_SHIFT;
411 val |= 6 << PCMCIA_C2_INACTIVE_SHIFT;
412 val |= 3 << PCMCIA_C2_SETUP_SHIFT;
413 val |= 3 << PCMCIA_C2_HOLD_SHIFT;
414 pcmcia_writel(skt, val, PCMCIA_C2_REG);
415
416 ret = pcmcia_register_socket(sock);
417 if (ret)
418 goto err;
419
420 /* start polling socket */
421 mod_timer(&skt->timer,
422 jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
423
424 platform_set_drvdata(pdev, skt);
425 return 0;
426
427err:
428 if (skt->io_base)
429 iounmap(skt->io_base);
430 if (skt->base)
431 iounmap(skt->base);
432 if (skt->reg_res)
433 release_mem_region(skt->reg_res->start, regmem_size);
434 kfree(skt);
435 return ret;
436}
437
438static int __devexit bcm63xx_drv_pcmcia_remove(struct platform_device *pdev)
439{
440 struct bcm63xx_pcmcia_socket *skt;
441 struct resource *res;
442
443 skt = platform_get_drvdata(pdev);
444 del_timer_sync(&skt->timer);
445 iounmap(skt->base);
446 iounmap(skt->io_base);
447 res = skt->reg_res;
448 release_mem_region(res->start, resource_size(res));
449 kfree(skt);
450 return 0;
451}
452
453struct platform_driver bcm63xx_pcmcia_driver = {
454 .probe = bcm63xx_drv_pcmcia_probe,
455 .remove = __devexit_p(bcm63xx_drv_pcmcia_remove),
456 .driver = {
457 .name = "bcm63xx_pcmcia",
458 .owner = THIS_MODULE,
459 },
460};
461
462#ifdef CONFIG_CARDBUS
463static int __devinit bcm63xx_cb_probe(struct pci_dev *dev,
464 const struct pci_device_id *id)
465{
466 /* keep pci device */
467 bcm63xx_cb_dev = dev;
468 return platform_driver_register(&bcm63xx_pcmcia_driver);
469}
470
471static void __devexit bcm63xx_cb_exit(struct pci_dev *dev)
472{
473 platform_driver_unregister(&bcm63xx_pcmcia_driver);
474 bcm63xx_cb_dev = NULL;
475}
476
477static struct pci_device_id bcm63xx_cb_table[] = {
478 {
479 .vendor = PCI_VENDOR_ID_BROADCOM,
480 .device = BCM6348_CPU_ID,
481 .subvendor = PCI_VENDOR_ID_BROADCOM,
482 .subdevice = PCI_ANY_ID,
483 .class = PCI_CLASS_BRIDGE_CARDBUS << 8,
484 .class_mask = ~0,
485 },
486
487 {
488 .vendor = PCI_VENDOR_ID_BROADCOM,
489 .device = BCM6358_CPU_ID,
490 .subvendor = PCI_VENDOR_ID_BROADCOM,
491 .subdevice = PCI_ANY_ID,
492 .class = PCI_CLASS_BRIDGE_CARDBUS << 8,
493 .class_mask = ~0,
494 },
495
496 { },
497};
498
499MODULE_DEVICE_TABLE(pci, bcm63xx_cb_table);
500
501static struct pci_driver bcm63xx_cardbus_driver = {
502 .name = "bcm63xx_cardbus",
503 .id_table = bcm63xx_cb_table,
504 .probe = bcm63xx_cb_probe,
505 .remove = __devexit_p(bcm63xx_cb_exit),
506};
507#endif
508
509/*
510 * if cardbus support is enabled, register our platform device after
511 * our fake cardbus bridge has been registered
512 */
513static int __init bcm63xx_pcmcia_init(void)
514{
515#ifdef CONFIG_CARDBUS
516 return pci_register_driver(&bcm63xx_cardbus_driver);
517#else
518 return platform_driver_register(&bcm63xx_pcmcia_driver);
519#endif
520}
521
522static void __exit bcm63xx_pcmcia_exit(void)
523{
524#ifdef CONFIG_CARDBUS
525 return pci_unregister_driver(&bcm63xx_cardbus_driver);
526#else
527 platform_driver_unregister(&bcm63xx_pcmcia_driver);
528#endif
529}
530
531module_init(bcm63xx_pcmcia_init);
532module_exit(bcm63xx_pcmcia_exit);
533
534MODULE_LICENSE("GPL");
535MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
536MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm63xx Socket Controller");
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.h b/drivers/pcmcia/bcm63xx_pcmcia.h
new file mode 100644
index 00000000000..ed957399d86
--- /dev/null
+++ b/drivers/pcmcia/bcm63xx_pcmcia.h
@@ -0,0 +1,60 @@
1#ifndef BCM63XX_PCMCIA_H_
2#define BCM63XX_PCMCIA_H_
3
4#include <linux/types.h>
5#include <linux/timer.h>
6#include <pcmcia/ss.h>
7#include <bcm63xx_dev_pcmcia.h>
8
9/* socket polling rate in ms */
10#define BCM63XX_PCMCIA_POLL_RATE 500
11
12enum {
13 CARD_CARDBUS = (1 << 0),
14 CARD_PCCARD = (1 << 1),
15 CARD_5V = (1 << 2),
16 CARD_3V = (1 << 3),
17 CARD_XV = (1 << 4),
18 CARD_YV = (1 << 5),
19};
20
21struct bcm63xx_pcmcia_socket {
22 struct pcmcia_socket socket;
23
24 /* platform specific data */
25 struct bcm63xx_pcmcia_platform_data *pd;
26
27 /* all regs access are protected by this spinlock */
28 spinlock_t lock;
29
30 /* pcmcia registers resource */
31 struct resource *reg_res;
32
33 /* base remapped address of registers */
34 void __iomem *base;
35
36 /* whether a card is detected at the moment */
37 int card_detected;
38
39 /* type of detected card (mask of above enum) */
40 u8 card_type;
41
42 /* keep last socket status to implement event reporting */
43 unsigned int old_status;
44
45 /* backup of requested socket state */
46 socket_state_t requested_state;
47
48 /* timer used for socket status polling */
49 struct timer_list timer;
50
51 /* attribute/common memory resources */
52 struct resource *attr_res;
53 struct resource *common_res;
54 struct resource *io_res;
55
56 /* base address of io memory */
57 void __iomem *io_base;
58};
59
60#endif /* BCM63XX_PCMCIA_H_ */
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c
index b59d4115d20..300b368605c 100644
--- a/drivers/pcmcia/bfin_cf_pcmcia.c
+++ b/drivers/pcmcia/bfin_cf_pcmcia.c
@@ -302,7 +302,7 @@ static int __devexit bfin_cf_remove(struct platform_device *pdev)
302 302
303static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg) 303static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
304{ 304{
305 return pcmcia_socket_dev_suspend(&pdev->dev, mesg); 305 return pcmcia_socket_dev_suspend(&pdev->dev);
306} 306}
307 307
308static int bfin_cf_resume(struct platform_device *pdev) 308static int bfin_cf_resume(struct platform_device *pdev)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 4a110b7b267..6c4a4fc8363 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -1463,7 +1463,9 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t
1463 return -ENOMEM; 1463 return -ENOMEM;
1464 } 1464 }
1465 tuple.DesiredTuple = code; 1465 tuple.DesiredTuple = code;
1466 tuple.Attributes = TUPLE_RETURN_COMMON; 1466 tuple.Attributes = 0;
1467 if (function == BIND_FN_ALL)
1468 tuple.Attributes = TUPLE_RETURN_COMMON;
1467 ret = pccard_get_first_tuple(s, function, &tuple); 1469 ret = pccard_get_first_tuple(s, function, &tuple);
1468 if (ret != 0) 1470 if (ret != 0)
1469 goto done; 1471 goto done;
@@ -1490,7 +1492,7 @@ EXPORT_SYMBOL(pccard_read_tuple);
1490 1492
1491======================================================================*/ 1493======================================================================*/
1492 1494
1493int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *info) 1495int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
1494{ 1496{
1495 tuple_t *tuple; 1497 tuple_t *tuple;
1496 cisparse_t *p; 1498 cisparse_t *p;
@@ -1515,30 +1517,30 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned
1515 count = reserved = 0; 1517 count = reserved = 0;
1516 tuple->DesiredTuple = RETURN_FIRST_TUPLE; 1518 tuple->DesiredTuple = RETURN_FIRST_TUPLE;
1517 tuple->Attributes = TUPLE_RETURN_COMMON; 1519 tuple->Attributes = TUPLE_RETURN_COMMON;
1518 ret = pccard_get_first_tuple(s, function, tuple); 1520 ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
1519 if (ret != 0) 1521 if (ret != 0)
1520 goto done; 1522 goto done;
1521 1523
1522 /* First tuple should be DEVICE; we should really have either that 1524 /* First tuple should be DEVICE; we should really have either that
1523 or a CFTABLE_ENTRY of some sort */ 1525 or a CFTABLE_ENTRY of some sort */
1524 if ((tuple->TupleCode == CISTPL_DEVICE) || 1526 if ((tuple->TupleCode == CISTPL_DEVICE) ||
1525 (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) || 1527 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p) == 0) ||
1526 (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0)) 1528 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
1527 dev_ok++; 1529 dev_ok++;
1528 1530
1529 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2 1531 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
1530 tuple, for card identification. Certain old D-Link and Linksys 1532 tuple, for card identification. Certain old D-Link and Linksys
1531 cards have only a broken VERS_2 tuple; hence the bogus test. */ 1533 cards have only a broken VERS_2 tuple; hence the bogus test. */
1532 if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) || 1534 if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
1533 (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) || 1535 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
1534 (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC)) 1536 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
1535 ident_ok++; 1537 ident_ok++;
1536 1538
1537 if (!dev_ok && !ident_ok) 1539 if (!dev_ok && !ident_ok)
1538 goto done; 1540 goto done;
1539 1541
1540 for (count = 1; count < MAX_TUPLES; count++) { 1542 for (count = 1; count < MAX_TUPLES; count++) {
1541 ret = pccard_get_next_tuple(s, function, tuple); 1543 ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
1542 if (ret != 0) 1544 if (ret != 0)
1543 break; 1545 break;
1544 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || 1546 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 0660ad18258..934d4bee39a 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -101,7 +101,7 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
101static int socket_resume(struct pcmcia_socket *skt); 101static int socket_resume(struct pcmcia_socket *skt);
102static int socket_suspend(struct pcmcia_socket *skt); 102static int socket_suspend(struct pcmcia_socket *skt);
103 103
104int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state) 104int pcmcia_socket_dev_suspend(struct device *dev)
105{ 105{
106 struct pcmcia_socket *socket; 106 struct pcmcia_socket *socket;
107 107
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 79615e6d540..1f4098f1354 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -197,8 +197,7 @@ int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
197 cisdata_t code, void *parse); 197 cisdata_t code, void *parse);
198int pcmcia_replace_cis(struct pcmcia_socket *s, 198int pcmcia_replace_cis(struct pcmcia_socket *s,
199 const u8 *data, const size_t len); 199 const u8 *data, const size_t len);
200int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, 200int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
201 unsigned int *count);
202 201
203/* rsrc_mgr.c */ 202/* rsrc_mgr.c */
204int pcmcia_validate_mem(struct pcmcia_socket *s); 203int pcmcia_validate_mem(struct pcmcia_socket *s);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 9f300d3cb12..f5b7079f13d 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -547,7 +547,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
547 if (!vers1) 547 if (!vers1)
548 return -ENOMEM; 548 return -ENOMEM;
549 549
550 if (!pccard_read_tuple(p_dev->socket, p_dev->func, 550 if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL,
551 CISTPL_MANFID, &manf_id)) { 551 CISTPL_MANFID, &manf_id)) {
552 p_dev->manf_id = manf_id.manf; 552 p_dev->manf_id = manf_id.manf;
553 p_dev->card_id = manf_id.card; 553 p_dev->card_id = manf_id.card;
@@ -581,9 +581,9 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
581 kfree(devgeo); 581 kfree(devgeo);
582 } 582 }
583 583
584 if (!pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_VERS_1, 584 if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1,
585 vers1)) { 585 vers1)) {
586 for (i=0; i < vers1->ns; i++) { 586 for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) {
587 char *tmp; 587 char *tmp;
588 unsigned int length; 588 unsigned int length;
589 589
@@ -733,7 +733,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
733 return -EAGAIN; /* try again, but later... */ 733 return -EAGAIN; /* try again, but later... */
734 } 734 }
735 735
736 ret = pccard_validate_cis(s, BIND_FN_ALL, &no_chains); 736 ret = pccard_validate_cis(s, &no_chains);
737 if (ret || !no_chains) { 737 if (ret || !no_chains) {
738 ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n"); 738 ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
739 return -ENODEV; 739 return -ENODEV;
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 46561face12..a04f21c8170 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -42,7 +42,7 @@ MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
42#ifdef CONFIG_PM 42#ifdef CONFIG_PM
43static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state) 43static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
44{ 44{
45 return pcmcia_socket_dev_suspend(&dev->dev, state); 45 return pcmcia_socket_dev_suspend(&dev->dev);
46} 46}
47 47
48static int i82092aa_socket_resume (struct pci_dev *dev) 48static int i82092aa_socket_resume (struct pci_dev *dev)
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 40d4953e4b1..a4aacb830b8 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1053,8 +1053,8 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
1053 u_char map, ioctl; 1053 u_char map, ioctl;
1054 1054
1055 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, " 1055 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
1056 "%#x-%#x)\n", sock, io->map, io->flags, 1056 "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
1057 io->speed, io->start, io->stop); 1057 (unsigned long long)io->start, (unsigned long long)io->stop);
1058 map = io->map; 1058 map = io->map;
1059 if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) || 1059 if ((map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
1060 (io->stop < io->start)) return -EINVAL; 1060 (io->stop < io->start)) return -EINVAL;
@@ -1241,7 +1241,7 @@ static int pcic_init(struct pcmcia_socket *s)
1241static int i82365_drv_pcmcia_suspend(struct platform_device *dev, 1241static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
1242 pm_message_t state) 1242 pm_message_t state)
1243{ 1243{
1244 return pcmcia_socket_dev_suspend(&dev->dev, state); 1244 return pcmcia_socket_dev_suspend(&dev->dev);
1245} 1245}
1246 1246
1247static int i82365_drv_pcmcia_resume(struct platform_device *dev) 1247static int i82365_drv_pcmcia_resume(struct platform_device *dev)
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 62b4ecc97c4..7dfbee1dcd7 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -537,8 +537,9 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
537 u_char map; 537 u_char map;
538 538
539 debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, " 539 debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
540 "%#lx-%#lx)\n", sock, io->map, io->flags, 540 "%#llx-%#llx)\n", sock, io->map, io->flags,
541 io->speed, io->start, io->stop); 541 io->speed, (unsigned long long)io->start,
542 (unsigned long long)io->stop);
542 map = io->map; 543 map = io->map;
543 544
544 return 0; 545 return 0;
@@ -554,8 +555,9 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
554 pcc_socket_t *t = &socket[sock]; 555 pcc_socket_t *t = &socket[sock];
555 556
556 debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, " 557 debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
557 "%#lx, %#x)\n", sock, map, mem->flags, 558 "%#llx, %#x)\n", sock, map, mem->flags,
558 mem->speed, mem->static_start, mem->card_start); 559 mem->speed, (unsigned long long)mem->static_start,
560 mem->card_start);
559 561
560 /* 562 /*
561 * sanity check 563 * sanity check
@@ -699,7 +701,7 @@ static struct pccard_operations pcc_operations = {
699static int cfc_drv_pcmcia_suspend(struct platform_device *dev, 701static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
700 pm_message_t state) 702 pm_message_t state)
701{ 703{
702 return pcmcia_socket_dev_suspend(&dev->dev, state); 704 return pcmcia_socket_dev_suspend(&dev->dev);
703} 705}
704 706
705static int cfc_drv_pcmcia_resume(struct platform_device *dev) 707static int cfc_drv_pcmcia_resume(struct platform_device *dev)
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 12034b41d19..c6524f99ccc 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -492,8 +492,9 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
492 u_char map; 492 u_char map;
493 493
494 debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, " 494 debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
495 "%#x-%#x)\n", sock, io->map, io->flags, 495 "%#llx-%#llx)\n", sock, io->map, io->flags,
496 io->speed, io->start, io->stop); 496 io->speed, (unsigned long long)io->start,
497 (unsigned long long)io->stop);
497 map = io->map; 498 map = io->map;
498 499
499 return 0; 500 return 0;
@@ -515,8 +516,9 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
515#endif 516#endif
516 517
517 debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, " 518 debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
518 "%#lx, %#x)\n", sock, map, mem->flags, 519 "%#llx, %#x)\n", sock, map, mem->flags,
519 mem->speed, mem->static_start, mem->card_start); 520 mem->speed, (unsigned long long)mem->static_start,
521 mem->card_start);
520 522
521 /* 523 /*
522 * sanity check 524 * sanity check
@@ -675,7 +677,7 @@ static struct pccard_operations pcc_operations = {
675static int pcc_drv_pcmcia_suspend(struct platform_device *dev, 677static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
676 pm_message_t state) 678 pm_message_t state)
677{ 679{
678 return pcmcia_socket_dev_suspend(&dev->dev, state); 680 return pcmcia_socket_dev_suspend(&dev->dev);
679} 681}
680 682
681static int pcc_drv_pcmcia_resume(struct platform_device *dev) 683static int pcc_drv_pcmcia_resume(struct platform_device *dev)
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index d1ad0966392..403559ba49d 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -975,8 +975,9 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
975#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start) 975#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
976 976
977 dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, " 977 dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, "
978 "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags, 978 "%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
979 io->speed, io->start, io->stop); 979 io->speed, (unsigned long long)io->start,
980 (unsigned long long)io->stop);
980 981
981 if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff) 982 if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
982 || (io->stop > 0xffff) || (io->stop < io->start)) 983 || (io->stop > 0xffff) || (io->stop < io->start))
@@ -1055,8 +1056,9 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
1055 pcmconf8xx_t *pcmcia = s->pcmcia; 1056 pcmconf8xx_t *pcmcia = s->pcmcia;
1056 1057
1057 dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, " 1058 dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
1058 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, 1059 "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
1059 mem->speed, mem->static_start, mem->card_start); 1060 mem->speed, (unsigned long long)mem->static_start,
1061 mem->card_start);
1060 1062
1061 if ((mem->map >= PCMCIA_MEM_WIN_NO) 1063 if ((mem->map >= PCMCIA_MEM_WIN_NO)
1062// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE) 1064// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
@@ -1107,8 +1109,9 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
1107 } 1109 }
1108 1110
1109 dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, " 1111 dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
1110 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, 1112 "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
1111 mem->speed, mem->static_start, mem->card_start); 1113 mem->speed, (unsigned long long)mem->static_start,
1114 mem->card_start);
1112 1115
1113 /* copy the struct and modify the copy */ 1116 /* copy the struct and modify the copy */
1114 1117
@@ -1296,7 +1299,7 @@ static int m8xx_remove(struct of_device *ofdev)
1296#ifdef CONFIG_PM 1299#ifdef CONFIG_PM
1297static int m8xx_suspend(struct platform_device *pdev, pm_message_t state) 1300static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
1298{ 1301{
1299 return pcmcia_socket_dev_suspend(&pdev->dev, state); 1302 return pcmcia_socket_dev_suspend(&pdev->dev);
1300} 1303}
1301 1304
1302static int m8xx_resume(struct platform_device *pdev) 1305static int m8xx_resume(struct platform_device *pdev)
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index f3736398900..68570bc3ac8 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -334,7 +334,7 @@ static int __exit omap_cf_remove(struct platform_device *pdev)
334 334
335static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg) 335static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
336{ 336{
337 return pcmcia_socket_dev_suspend(&pdev->dev, mesg); 337 return pcmcia_socket_dev_suspend(&pdev->dev);
338} 338}
339 339
340static int omap_cf_resume(struct platform_device *pdev) 340static int omap_cf_resume(struct platform_device *pdev)
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 32c44040c1e..30cf71d2ee2 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -881,7 +881,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
881 mutex_lock(&s->skt_mutex); 881 mutex_lock(&s->skt_mutex);
882 pcmcia_validate_mem(s); 882 pcmcia_validate_mem(s);
883 mutex_unlock(&s->skt_mutex); 883 mutex_unlock(&s->skt_mutex);
884 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains); 884 ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
885 break; 885 break;
886 case DS_SUSPEND_CARD: 886 case DS_SUSPEND_CARD:
887 ret = pcmcia_suspend_card(s); 887 ret = pcmcia_suspend_card(s);
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 8bed1dab903..70a33468bcd 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -641,6 +641,12 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
641 if ((ret = pci_enable_device(dev))) 641 if ((ret = pci_enable_device(dev)))
642 goto err_out_free_mem; 642 goto err_out_free_mem;
643 643
644 if (!pci_resource_start(dev, 0)) {
645 printk(KERN_INFO "pd6729: refusing to load the driver "
646 "as the io_base is 0.\n");
647 goto err_out_free_mem;
648 }
649
644 printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge " 650 printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge "
645 "at 0x%llx on irq %d\n", 651 "at 0x%llx on irq %d\n",
646 (unsigned long long)pci_resource_start(dev, 0), dev->irq); 652 (unsigned long long)pci_resource_start(dev, 0), dev->irq);
@@ -758,7 +764,7 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev)
758#ifdef CONFIG_PM 764#ifdef CONFIG_PM
759static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state) 765static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
760{ 766{
761 return pcmcia_socket_dev_suspend(&dev->dev, state); 767 return pcmcia_socket_dev_suspend(&dev->dev);
762} 768}
763 769
764static int pd6729_socket_resume(struct pci_dev *dev) 770static int pd6729_socket_resume(struct pci_dev *dev)
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index c49a7269f6d..0e35acb1366 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -300,25 +300,29 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
300 return soc_common_drv_pcmcia_remove(&dev->dev); 300 return soc_common_drv_pcmcia_remove(&dev->dev);
301} 301}
302 302
303static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state) 303static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
304{ 304{
305 return pcmcia_socket_dev_suspend(&dev->dev, state); 305 return pcmcia_socket_dev_suspend(dev);
306} 306}
307 307
308static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev) 308static int pxa2xx_drv_pcmcia_resume(struct device *dev)
309{ 309{
310 pxa2xx_configure_sockets(&dev->dev); 310 pxa2xx_configure_sockets(dev);
311 return pcmcia_socket_dev_resume(&dev->dev); 311 return pcmcia_socket_dev_resume(dev);
312} 312}
313 313
314static struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = {
315 .suspend = pxa2xx_drv_pcmcia_suspend,
316 .resume = pxa2xx_drv_pcmcia_resume,
317};
318
314static struct platform_driver pxa2xx_pcmcia_driver = { 319static struct platform_driver pxa2xx_pcmcia_driver = {
315 .probe = pxa2xx_drv_pcmcia_probe, 320 .probe = pxa2xx_drv_pcmcia_probe,
316 .remove = pxa2xx_drv_pcmcia_remove, 321 .remove = pxa2xx_drv_pcmcia_remove,
317 .suspend = pxa2xx_drv_pcmcia_suspend,
318 .resume = pxa2xx_drv_pcmcia_resume,
319 .driver = { 322 .driver = {
320 .name = "pxa2xx-pcmcia", 323 .name = "pxa2xx-pcmcia",
321 .owner = THIS_MODULE, 324 .owner = THIS_MODULE,
325 .pm = &pxa2xx_drv_pcmcia_pm_ops,
322 }, 326 },
323}; 327};
324 328
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c
new file mode 100644
index 00000000000..3a8993ed562
--- /dev/null
+++ b/drivers/pcmcia/pxa2xx_palmtc.c
@@ -0,0 +1,230 @@
1/*
2 * linux/drivers/pcmcia/pxa2xx_palmtc.c
3 *
4 * Driver for Palm Tungsten|C PCMCIA
5 *
6 * Copyright (C) 2008 Alex Osborne <ato@meshy.org>
7 * Copyright (C) 2009 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#include <linux/delay.h>
19
20#include <asm/mach-types.h>
21#include <mach/palmtc.h>
22#include "soc_common.h"
23
24static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
25{
26 int ret;
27
28 ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1");
29 if (ret)
30 goto err1;
31 ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
32 if (ret)
33 goto err2;
34
35 ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2");
36 if (ret)
37 goto err2;
38 ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
39 if (ret)
40 goto err3;
41
42 ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3");
43 if (ret)
44 goto err3;
45 ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
46 if (ret)
47 goto err4;
48
49 ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST");
50 if (ret)
51 goto err4;
52 ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
53 if (ret)
54 goto err5;
55
56 ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY");
57 if (ret)
58 goto err5;
59 ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY);
60 if (ret)
61 goto err6;
62
63 ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY");
64 if (ret)
65 goto err6;
66 ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
67 if (ret)
68 goto err7;
69
70 skt->irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
71 return 0;
72
73err7:
74 gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
75err6:
76 gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
77err5:
78 gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
79err4:
80 gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
81err3:
82 gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
83err2:
84 gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
85err1:
86 return ret;
87}
88
89static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
90{
91 gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
92 gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
93 gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
94 gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
95 gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
96 gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
97}
98
99static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
100 struct pcmcia_state *state)
101{
102 state->detect = 1; /* always inserted */
103 state->ready = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY);
104 state->bvd1 = 1;
105 state->bvd2 = 1;
106 state->wrprot = 0;
107 state->vs_3v = 1;
108 state->vs_Xv = 0;
109}
110
111static int palmtc_wifi_powerdown(void)
112{
113 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
114 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
115 mdelay(40);
116 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
117 return 0;
118}
119
120static int palmtc_wifi_powerup(void)
121{
122 int timeout = 50;
123
124 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 1);
125 mdelay(50);
126
127 /* Power up the card, 1.8V first, after a while 3.3V */
128 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER1, 1);
129 mdelay(100);
130 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER2, 1);
131
132 /* Wait till the card is ready */
133 while (!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_PWRREADY) &&
134 timeout) {
135 mdelay(1);
136 timeout--;
137 }
138
139 /* Power down the WiFi in case of error */
140 if (!timeout) {
141 palmtc_wifi_powerdown();
142 return 1;
143 }
144
145 /* Reset the card */
146 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
147 mdelay(20);
148 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_RESET, 0);
149 mdelay(25);
150
151 gpio_set_value(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
152
153 return 0;
154}
155
156static int palmtc_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
157 const socket_state_t *state)
158{
159 int ret = 1;
160
161 if (state->Vcc == 0)
162 ret = palmtc_wifi_powerdown();
163 else if (state->Vcc == 33)
164 ret = palmtc_wifi_powerup();
165
166 return ret;
167}
168
169static void palmtc_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
170{
171}
172
173static void palmtc_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
174{
175}
176
177static struct pcmcia_low_level palmtc_pcmcia_ops = {
178 .owner = THIS_MODULE,
179
180 .first = 0,
181 .nr = 1,
182
183 .hw_init = palmtc_pcmcia_hw_init,
184 .hw_shutdown = palmtc_pcmcia_hw_shutdown,
185
186 .socket_state = palmtc_pcmcia_socket_state,
187 .configure_socket = palmtc_pcmcia_configure_socket,
188
189 .socket_init = palmtc_pcmcia_socket_init,
190 .socket_suspend = palmtc_pcmcia_socket_suspend,
191};
192
193static struct platform_device *palmtc_pcmcia_device;
194
195static int __init palmtc_pcmcia_init(void)
196{
197 int ret;
198
199 if (!machine_is_palmtc())
200 return -ENODEV;
201
202 palmtc_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
203 if (!palmtc_pcmcia_device)
204 return -ENOMEM;
205
206 ret = platform_device_add_data(palmtc_pcmcia_device, &palmtc_pcmcia_ops,
207 sizeof(palmtc_pcmcia_ops));
208
209 if (!ret)
210 ret = platform_device_add(palmtc_pcmcia_device);
211
212 if (ret)
213 platform_device_put(palmtc_pcmcia_device);
214
215 return ret;
216}
217
218static void __exit palmtc_pcmcia_exit(void)
219{
220 platform_device_unregister(palmtc_pcmcia_device);
221}
222
223module_init(palmtc_pcmcia_init);
224module_exit(palmtc_pcmcia_exit);
225
226MODULE_AUTHOR("Alex Osborne <ato@meshy.org>,"
227 " Marek Vasut <marek.vasut@gmail.com>");
228MODULE_DESCRIPTION("PCMCIA support for Palm Tungsten|C");
229MODULE_ALIAS("platform:pxa2xx-pcmcia");
230MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 9ca22c7aafb..7039f3cf5b7 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -206,6 +206,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
206 /* First, what does a floating port look like? */ 206 /* First, what does a floating port look like? */
207 b = kzalloc(256, GFP_KERNEL); 207 b = kzalloc(256, GFP_KERNEL);
208 if (!b) { 208 if (!b) {
209 printk("\n");
209 dev_printk(KERN_ERR, &s->dev, 210 dev_printk(KERN_ERR, &s->dev,
210 "do_io_probe: unable to kmalloc 256 bytes"); 211 "do_io_probe: unable to kmalloc 256 bytes");
211 return; 212 return;
@@ -275,7 +276,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
275 s->cis_mem.res = res; 276 s->cis_mem.res = res;
276 s->cis_virt = ioremap(res->start, s->map_size); 277 s->cis_virt = ioremap(res->start, s->map_size);
277 if (s->cis_virt) { 278 if (s->cis_virt) {
278 ret = pccard_validate_cis(s, BIND_FN_ALL, count); 279 ret = pccard_validate_cis(s, count);
279 /* invalidate mapping and CIS cache */ 280 /* invalidate mapping and CIS cache */
280 iounmap(s->cis_virt); 281 iounmap(s->cis_virt);
281 s->cis_virt = NULL; 282 s->cis_virt = NULL;
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index f424146a2bc..ac8aa09ba0d 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -130,7 +130,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = {
130 .socket_suspend = assabet_pcmcia_socket_suspend, 130 .socket_suspend = assabet_pcmcia_socket_suspend,
131}; 131};
132 132
133int __init pcmcia_assabet_init(struct device *dev) 133int pcmcia_assabet_init(struct device *dev)
134{ 134{
135 int ret = -ENODEV; 135 int ret = -ENODEV;
136 136
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index d8da5ac844e..2d0e9975153 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -89,7 +89,7 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
89static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev, 89static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
90 pm_message_t state) 90 pm_message_t state)
91{ 91{
92 return pcmcia_socket_dev_suspend(&dev->dev, state); 92 return pcmcia_socket_dev_suspend(&dev->dev);
93} 93}
94 94
95static int sa11x0_drv_pcmcia_resume(struct platform_device *dev) 95static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
index 4c41e86ccff..0c76d337815 100644
--- a/drivers/pcmcia/sa1100_neponset.c
+++ b/drivers/pcmcia/sa1100_neponset.c
@@ -123,7 +123,7 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
123 .socket_suspend = sa1111_pcmcia_socket_suspend, 123 .socket_suspend = sa1111_pcmcia_socket_suspend,
124}; 124};
125 125
126int __init pcmcia_neponset_init(struct sa1111_dev *sadev) 126int pcmcia_neponset_init(struct sa1111_dev *sadev)
127{ 127{
128 int ret = -ENODEV; 128 int ret = -ENODEV;
129 129
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 401052a21ce..4be4e172ffa 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -159,7 +159,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
159 159
160static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state) 160static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state)
161{ 161{
162 return pcmcia_socket_dev_suspend(&dev->dev, state); 162 return pcmcia_socket_dev_suspend(&dev->dev);
163} 163}
164 164
165static int pcmcia_resume(struct sa1111_dev *dev) 165static int pcmcia_resume(struct sa1111_dev *dev)
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 163cf98e238..ef7e9e58782 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -336,8 +336,9 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
336 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); 336 struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
337 unsigned short speed = map->speed; 337 unsigned short speed = map->speed;
338 338
339 debug(skt, 2, "map %u speed %u start 0x%08x stop 0x%08x\n", 339 debug(skt, 2, "map %u speed %u start 0x%08llx stop 0x%08llx\n",
340 map->map, map->speed, map->start, map->stop); 340 map->map, map->speed, (unsigned long long)map->start,
341 (unsigned long long)map->stop);
341 debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", 342 debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
342 (map->flags==0)?"<NONE>":"", 343 (map->flags==0)?"<NONE>":"",
343 (map->flags&MAP_ACTIVE)?"ACTIVE ":"", 344 (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index ff9a3bb3c88..78d5aab542f 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -300,7 +300,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
300 300
301 if (!(s->state & SOCKET_PRESENT)) 301 if (!(s->state & SOCKET_PRESENT))
302 return -ENODEV; 302 return -ENODEV;
303 if (pccard_validate_cis(s, BIND_FN_ALL, &chains)) 303 if (pccard_validate_cis(s, &chains))
304 return -EIO; 304 return -EIO;
305 if (!chains) 305 if (!chains)
306 return -ENODATA; 306 return -ENODATA;
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 8eb04230fec..6918849d511 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -366,7 +366,7 @@ static int __init get_tcic_id(void)
366static int tcic_drv_pcmcia_suspend(struct platform_device *dev, 366static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
367 pm_message_t state) 367 pm_message_t state)
368{ 368{
369 return pcmcia_socket_dev_suspend(&dev->dev, state); 369 return pcmcia_socket_dev_suspend(&dev->dev);
370} 370}
371 371
372static int tcic_drv_pcmcia_resume(struct platform_device *dev) 372static int tcic_drv_pcmcia_resume(struct platform_device *dev)
@@ -732,8 +732,8 @@ static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
732 u_short base, len, ioctl; 732 u_short base, len, ioctl;
733 733
734 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, " 734 debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
735 "%#x-%#x)\n", psock, io->map, io->flags, 735 "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
736 io->speed, io->start, io->stop); 736 (unsigned long long)io->start, (unsigned long long)io->stop);
737 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) || 737 if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
738 (io->stop < io->start)) return -EINVAL; 738 (io->stop < io->start)) return -EINVAL;
739 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT)); 739 tcic_setw(TCIC_ADDR+2, TCIC_ADR2_INDREG | (psock << TCIC_SS_SHFT));
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index d4ad50d737b..c9fcbdc164e 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -707,7 +707,7 @@ __setup("vrc4171_card=", vrc4171_card_setup);
707static int vrc4171_card_suspend(struct platform_device *dev, 707static int vrc4171_card_suspend(struct platform_device *dev,
708 pm_message_t state) 708 pm_message_t state)
709{ 709{
710 return pcmcia_socket_dev_suspend(&dev->dev, state); 710 return pcmcia_socket_dev_suspend(&dev->dev);
711} 711}
712 712
713static int vrc4171_card_resume(struct platform_device *dev) 713static int vrc4171_card_resume(struct platform_device *dev)
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index b459e87a30a..abe0e44c6e9 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1225,60 +1225,71 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
1225} 1225}
1226 1226
1227#ifdef CONFIG_PM 1227#ifdef CONFIG_PM
1228static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) 1228static int yenta_dev_suspend_noirq(struct device *dev)
1229{ 1229{
1230 struct yenta_socket *socket = pci_get_drvdata(dev); 1230 struct pci_dev *pdev = to_pci_dev(dev);
1231 struct yenta_socket *socket = pci_get_drvdata(pdev);
1231 int ret; 1232 int ret;
1232 1233
1233 ret = pcmcia_socket_dev_suspend(&dev->dev, state); 1234 ret = pcmcia_socket_dev_suspend(dev);
1234 1235
1235 if (socket) { 1236 if (!socket)
1236 if (socket->type && socket->type->save_state) 1237 return ret;
1237 socket->type->save_state(socket);
1238 1238
1239 /* FIXME: pci_save_state needs to have a better interface */ 1239 if (socket->type && socket->type->save_state)
1240 pci_save_state(dev); 1240 socket->type->save_state(socket);
1241 pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
1242 pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
1243 pci_disable_device(dev);
1244 1241
1245 /* 1242 pci_save_state(pdev);
1246 * Some laptops (IBM T22) do not like us putting the Cardbus 1243 pci_read_config_dword(pdev, 16*4, &socket->saved_state[0]);
1247 * bridge into D3. At a guess, some other laptop will 1244 pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]);
1248 * probably require this, so leave it commented out for now. 1245 pci_disable_device(pdev);
1249 */ 1246
1250 /* pci_set_power_state(dev, 3); */ 1247 /*
1251 } 1248 * Some laptops (IBM T22) do not like us putting the Cardbus
1249 * bridge into D3. At a guess, some other laptop will
1250 * probably require this, so leave it commented out for now.
1251 */
1252 /* pci_set_power_state(dev, 3); */
1252 1253
1253 return ret; 1254 return ret;
1254} 1255}
1255 1256
1256 1257static int yenta_dev_resume_noirq(struct device *dev)
1257static int yenta_dev_resume (struct pci_dev *dev)
1258{ 1258{
1259 struct yenta_socket *socket = pci_get_drvdata(dev); 1259 struct pci_dev *pdev = to_pci_dev(dev);
1260 struct yenta_socket *socket = pci_get_drvdata(pdev);
1261 int ret;
1260 1262
1261 if (socket) { 1263 if (!socket)
1262 int rc; 1264 return 0;
1263 1265
1264 pci_set_power_state(dev, 0); 1266 pci_write_config_dword(pdev, 16*4, socket->saved_state[0]);
1265 /* FIXME: pci_restore_state needs to have a better interface */ 1267 pci_write_config_dword(pdev, 17*4, socket->saved_state[1]);
1266 pci_restore_state(dev);
1267 pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
1268 pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
1269 1268
1270 rc = pci_enable_device(dev); 1269 ret = pci_enable_device(pdev);
1271 if (rc) 1270 if (ret)
1272 return rc; 1271 return ret;
1273 1272
1274 pci_set_master(dev); 1273 pci_set_master(pdev);
1275 1274
1276 if (socket->type && socket->type->restore_state) 1275 if (socket->type && socket->type->restore_state)
1277 socket->type->restore_state(socket); 1276 socket->type->restore_state(socket);
1278 }
1279 1277
1280 return pcmcia_socket_dev_resume(&dev->dev); 1278 return pcmcia_socket_dev_resume(dev);
1281} 1279}
1280
1281static struct dev_pm_ops yenta_pm_ops = {
1282 .suspend_noirq = yenta_dev_suspend_noirq,
1283 .resume_noirq = yenta_dev_resume_noirq,
1284 .freeze_noirq = yenta_dev_suspend_noirq,
1285 .thaw_noirq = yenta_dev_resume_noirq,
1286 .poweroff_noirq = yenta_dev_suspend_noirq,
1287 .restore_noirq = yenta_dev_resume_noirq,
1288};
1289
1290#define YENTA_PM_OPS (&yenta_pm_ops)
1291#else
1292#define YENTA_PM_OPS NULL
1282#endif 1293#endif
1283 1294
1284#define CB_ID(vend,dev,type) \ 1295#define CB_ID(vend,dev,type) \
@@ -1376,10 +1387,7 @@ static struct pci_driver yenta_cardbus_driver = {
1376 .id_table = yenta_table, 1387 .id_table = yenta_table,
1377 .probe = yenta_probe, 1388 .probe = yenta_probe,
1378 .remove = __devexit_p(yenta_close), 1389 .remove = __devexit_p(yenta_close),
1379#ifdef CONFIG_PM 1390 .driver.pm = YENTA_PM_OPS,
1380 .suspend = yenta_dev_suspend,
1381 .resume = yenta_dev_resume,
1382#endif
1383}; 1391};
1384 1392
1385 1393