Blame view

drivers/pcmcia/pxa2xx_base.c 10.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /*======================================================================
  
    Device driver for the PCMCIA control functionality of PXA2xx
    microprocessors.
  
      The contents of this file may be used under the
      terms of the GNU Public License version 2 (the "GPL")
  
      (c) Ian Molton (spyro@f2s.com) 2003
      (c) Stefan Eletzhofer (stefan.eletzhofer@inquant.de) 2003,4
  
      derived from sa11xx_base.c
  
       Portions created by John G. Dorsey are
       Copyright (C) 1999 John G. Dorsey.
  
    ======================================================================*/
  
  #include <linux/module.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
20
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
  #include <linux/cpufreq.h>
  #include <linux/ioport.h>
  #include <linux/kernel.h>
  #include <linux/spinlock.h>
d052d1bef   Russell King   Create platform_d...
26
  #include <linux/platform_device.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27

a09e64fbc   Russell King   [ARM] Move includ...
28
  #include <mach/hardware.h>
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
29
  #include <mach/smemc.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
  #include <asm/io.h>
  #include <asm/irq.h>
a09e64fbc   Russell King   [ARM] Move includ...
32
  #include <mach/pxa2xx-regs.h>
20f18ff32   Marc Zyngier   Add support for t...
33
  #include <asm/mach-types.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  #include <pcmcia/ss.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  #include <pcmcia/cistpl.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
  #include "soc_common.h"
  #include "pxa2xx_base.h"
b393c6965   Eric Miao   [ARM] pxa: move P...
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  /*
   * Personal Computer Memory Card International Association (PCMCIA) sockets
   */
  
  #define PCMCIAPrtSp	0x04000000	/* PCMCIA Partition Space [byte]   */
  #define PCMCIASp	(4*PCMCIAPrtSp)	/* PCMCIA Space [byte]             */
  #define PCMCIAIOSp	PCMCIAPrtSp	/* PCMCIA I/O Space [byte]         */
  #define PCMCIAAttrSp	PCMCIAPrtSp	/* PCMCIA Attribute Space [byte]   */
  #define PCMCIAMemSp	PCMCIAPrtSp	/* PCMCIA Memory Space [byte]      */
  
  #define PCMCIA0Sp	PCMCIASp	/* PCMCIA 0 Space [byte]           */
  #define PCMCIA0IOSp	PCMCIAIOSp	/* PCMCIA 0 I/O Space [byte]       */
  #define PCMCIA0AttrSp	PCMCIAAttrSp	/* PCMCIA 0 Attribute Space [byte] */
  #define PCMCIA0MemSp	PCMCIAMemSp	/* PCMCIA 0 Memory Space [byte]    */
  
  #define PCMCIA1Sp	PCMCIASp	/* PCMCIA 1 Space [byte]           */
  #define PCMCIA1IOSp	PCMCIAIOSp	/* PCMCIA 1 I/O Space [byte]       */
  #define PCMCIA1AttrSp	PCMCIAAttrSp	/* PCMCIA 1 Attribute Space [byte] */
  #define PCMCIA1MemSp	PCMCIAMemSp	/* PCMCIA 1 Memory Space [byte]    */
  
  #define _PCMCIA(Nb)			/* PCMCIA [0..1]                   */ \
  			(0x20000000 + (Nb) * PCMCIASp)
  #define _PCMCIAIO(Nb)	_PCMCIA(Nb)	/* PCMCIA I/O [0..1]               */
  #define _PCMCIAAttr(Nb)			/* PCMCIA Attribute [0..1]         */ \
  			(_PCMCIA(Nb) + 2 * PCMCIAPrtSp)
  #define _PCMCIAMem(Nb)			/* PCMCIA Memory [0..1]            */ \
  			(_PCMCIA(Nb) + 3 * PCMCIAPrtSp)
  
  #define _PCMCIA0	_PCMCIA(0)	/* PCMCIA 0                        */
  #define _PCMCIA0IO	_PCMCIAIO(0)	/* PCMCIA 0 I/O                    */
  #define _PCMCIA0Attr	_PCMCIAAttr(0)	/* PCMCIA 0 Attribute              */
  #define _PCMCIA0Mem	_PCMCIAMem(0)	/* PCMCIA 0 Memory                 */
  
  #define _PCMCIA1	_PCMCIA(1)	/* PCMCIA 1                        */
  #define _PCMCIA1IO	_PCMCIAIO(1)	/* PCMCIA 1 I/O                    */
  #define _PCMCIA1Attr	_PCMCIAAttr(1)	/* PCMCIA 1 Attribute              */
  #define _PCMCIA1Mem	_PCMCIAMem(1)	/* PCMCIA 1 Memory                 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  
  #define MCXX_SETUP_MASK     (0x7f)
  #define MCXX_ASST_MASK      (0x1f)
  #define MCXX_HOLD_MASK      (0x3f)
  #define MCXX_SETUP_SHIFT    (0)
  #define MCXX_ASST_SHIFT     (7)
  #define MCXX_HOLD_SHIFT     (14)
  
  static inline u_int pxa2xx_mcxx_hold(u_int pcmcia_cycle_ns,
  				     u_int mem_clk_10khz)
  {
  	u_int code = pcmcia_cycle_ns * mem_clk_10khz;
  	return (code / 300000) + ((code % 300000) ? 1 : 0) - 1;
  }
  
  static inline u_int pxa2xx_mcxx_asst(u_int pcmcia_cycle_ns,
  				     u_int mem_clk_10khz)
  {
  	u_int code = pcmcia_cycle_ns * mem_clk_10khz;
24d6572b4   Milan Plzik   pxa2xx PCMCIA tim...
95
  	return (code / 300000) + ((code % 300000) ? 1 : 0) + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  }
  
  static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns,
  				      u_int mem_clk_10khz)
  {
  	u_int code = pcmcia_cycle_ns * mem_clk_10khz;
  	return (code / 100000) + ((code % 100000) ? 1 : 0) - 1;
  }
  
  /* This function returns the (approximate) command assertion period, in
   * nanoseconds, for a given CPU clock frequency and MCXX_ASST value:
   */
  static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz,
  					   u_int pcmcia_mcxx_asst)
  {
  	return (300000 * (pcmcia_mcxx_asst + 1) / mem_clk_10khz);
  }
  
  static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock )
  {
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
116
117
118
  	uint32_t val;
  
  	val = ((pxa2xx_mcxx_setup(speed, clock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
123
  		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
  		| ((pxa2xx_mcxx_asst(speed, clock)
  		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
  		| ((pxa2xx_mcxx_hold(speed, clock)
  		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
124
  	__raw_writel(val, MCMEM(sock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
127
128
129
  	return 0;
  }
  
  static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock )
  {
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
130
131
132
  	uint32_t val;
  
  	val = ((pxa2xx_mcxx_setup(speed, clock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
134
135
136
137
  		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
  		| ((pxa2xx_mcxx_asst(speed, clock)
  		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
  		| ((pxa2xx_mcxx_hold(speed, clock)
  		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
138
  	__raw_writel(val, MCIO(sock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
142
143
  	return 0;
  }
  
  static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock )
  {
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
144
145
146
  	uint32_t val;
  
  	val = ((pxa2xx_mcxx_setup(speed, clock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
150
151
  		& MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
  		| ((pxa2xx_mcxx_asst(speed, clock)
  		& MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
  		| ((pxa2xx_mcxx_hold(speed, clock)
  		& MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
152
  	__raw_writel(val, MCATT(sock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  	return 0;
  }
  
  static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int clk)
  {
  	struct soc_pcmcia_timing timing;
  	int sock = skt->nr;
  
  	soc_common_pcmcia_get_timing(skt, &timing);
  
  	pxa2xx_pcmcia_set_mcmem(sock, timing.mem, clk);
  	pxa2xx_pcmcia_set_mcatt(sock, timing.attr, clk);
  	pxa2xx_pcmcia_set_mcio(sock, timing.io, clk);
  
  	return 0;
  }
  
  static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
  {
2a125dd56   Eric Miao   ARM: pxa: remove ...
172
173
  	unsigned long clk = clk_get_rate(skt->clk);
  	return pxa2xx_pcmcia_set_mcxx(skt, clk / 10000);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
178
179
180
181
182
  }
  
  #ifdef CONFIG_CPU_FREQ
  
  static int
  pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
  			       unsigned long val,
  			       struct cpufreq_freqs *freqs)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
187
188
189
190
  	switch (val) {
  	case CPUFREQ_PRECHANGE:
  		if (freqs->new > freqs->old) {
  			debug(skt, 2, "new frequency %u.%uMHz > %u.%uMHz, "
  			       "pre-updating
  ",
  			       freqs->new / 1000, (freqs->new / 100) % 10,
  			       freqs->old / 1000, (freqs->old / 100) % 10);
d344a21a9   Marek Vasut   [ARM] pxa: fix fr...
191
  			pxa2xx_pcmcia_set_timing(skt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
196
197
198
199
200
201
  		}
  		break;
  
  	case CPUFREQ_POSTCHANGE:
  		if (freqs->new < freqs->old) {
  			debug(skt, 2, "new frequency %u.%uMHz < %u.%uMHz, "
  			       "post-updating
  ",
  			       freqs->new / 1000, (freqs->new / 100) % 10,
  			       freqs->old / 1000, (freqs->old / 100) % 10);
d344a21a9   Marek Vasut   [ARM] pxa: fix fr...
202
  			pxa2xx_pcmcia_set_timing(skt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
204
205
206
207
208
  		}
  		break;
  	}
  	return 0;
  }
  #endif
817ed5748   Robert Jarzmik   pcmcia: lubbock: ...
209
  void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops)
20f18ff32   Marc Zyngier   Add support for t...
210
  {
20f18ff32   Marc Zyngier   Add support for t...
211
212
213
214
  	/*
  	 * We have at least one socket, so set MECR:CIT
  	 * (Card Is There)
  	 */
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
215
  	uint32_t mecr = MECR_CIT;
20f18ff32   Marc Zyngier   Add support for t...
216
217
  
  	/* Set MECR:NOS (Number Of Sockets) */
c2de1c382   Marc Zyngier   [ARM] pxa/zeus: m...
218
219
  	if ((ops->first + ops->nr) > 1 ||
  	    machine_is_viper() || machine_is_arcom_zeus())
ad68bb9f7   Marek Vasut   ARM: pxa: Access ...
220
221
222
  		mecr |= MECR_NOS;
  
  	__raw_writel(mecr, MECR);
20f18ff32   Marc Zyngier   Add support for t...
223
  }
d5240dfd3   Russell King   ARM: PXA: fix lub...
224
  EXPORT_SYMBOL(pxa2xx_configure_sockets);
20f18ff32   Marc Zyngier   Add support for t...
225

b393c6965   Eric Miao   [ARM] pxa: move P...
226
227
228
229
230
231
232
  static const char *skt_names[] = {
  	"PCMCIA socket 0",
  	"PCMCIA socket 1",
  };
  
  #define SKT_DEV_INFO_SIZE(n) \
  	(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
701a5dc05   Russell King - ARM Linux   PCMCIA: sa1111: w...
233
  int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
da4f00737   Russell King - ARM Linux   PCMCIA: soc_commo...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  {
  	skt->res_skt.start = _PCMCIA(skt->nr);
  	skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
  	skt->res_skt.name = skt_names[skt->nr];
  	skt->res_skt.flags = IORESOURCE_MEM;
  
  	skt->res_io.start = _PCMCIAIO(skt->nr);
  	skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
  	skt->res_io.name = "io";
  	skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  
  	skt->res_mem.start = _PCMCIAMem(skt->nr);
  	skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
  	skt->res_mem.name = "memory";
  	skt->res_mem.flags = IORESOURCE_MEM;
  
  	skt->res_attr.start = _PCMCIAAttr(skt->nr);
  	skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
  	skt->res_attr.name = "attribute";
  	skt->res_attr.flags = IORESOURCE_MEM;
  
  	return soc_pcmcia_add_one(skt);
  }
d0d26c33b   Russell King   PCMCIA: fix pxa2x...
257
  EXPORT_SYMBOL(pxa2xx_drv_pcmcia_add_one);
da4f00737   Russell King - ARM Linux   PCMCIA: soc_commo...
258

701a5dc05   Russell King - ARM Linux   PCMCIA: sa1111: w...
259
260
261
262
263
264
265
266
  void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
  {
  	/* Provide our PXA2xx specific timing routines. */
  	ops->set_timing  = pxa2xx_pcmcia_set_timing;
  #ifdef CONFIG_CPU_FREQ
  	ops->frequency_change = pxa2xx_pcmcia_frequency_change;
  #endif
  }
d0d26c33b   Russell King   PCMCIA: fix pxa2x...
267
  EXPORT_SYMBOL(pxa2xx_drv_pcmcia_ops);
701a5dc05   Russell King - ARM Linux   PCMCIA: sa1111: w...
268

d0d26c33b   Russell King   PCMCIA: fix pxa2x...
269
  static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  {
701a5dc05   Russell King - ARM Linux   PCMCIA: sa1111: w...
271
  	int i, ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
  	struct pcmcia_low_level *ops;
b393c6965   Eric Miao   [ARM] pxa: move P...
273
274
  	struct skt_dev_info *sinfo;
  	struct soc_pcmcia_socket *skt;
2a125dd56   Eric Miao   ARM: pxa: remove ...
275
  	struct clk *clk;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276

d0d26c33b   Russell King   PCMCIA: fix pxa2x...
277
  	ops = (struct pcmcia_low_level *)dev->dev.platform_data;
a4257af5b   Marek Vasut   ARM: pxa: Add pxa...
278
279
280
281
282
283
284
285
286
287
  	if (!ops) {
  		ret = -ENODEV;
  		goto err0;
  	}
  
  	if (cpu_is_pxa320() && ops->nr > 1) {
  		dev_err(&dev->dev, "pxa320 supports only one pcmcia slot");
  		ret = -EINVAL;
  		goto err0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288

ac92f1517   Russell King   pcmcia: pxa2xx: u...
289
  	clk = devm_clk_get(&dev->dev, NULL);
e09a71649   Wei Yongjun   ARM: pxa: fix ret...
290
  	if (IS_ERR(clk))
2a125dd56   Eric Miao   ARM: pxa: remove ...
291
  		return -ENODEV;
701a5dc05   Russell King - ARM Linux   PCMCIA: sa1111: w...
292
  	pxa2xx_drv_pcmcia_ops(ops);
da4f00737   Russell King - ARM Linux   PCMCIA: soc_commo...
293

8e2caf0d2   Russell King   pcmcia: pxa2xx: c...
294
295
  	sinfo = devm_kzalloc(&dev->dev, SKT_DEV_INFO_SIZE(ops->nr),
  			     GFP_KERNEL);
ac92f1517   Russell King   pcmcia: pxa2xx: u...
296
  	if (!sinfo)
b393c6965   Eric Miao   [ARM] pxa: move P...
297
298
299
300
301
302
303
  		return -ENOMEM;
  
  	sinfo->nskt = ops->nr;
  
  	/* Initialize processor specific parameters */
  	for (i = 0; i < ops->nr; i++) {
  		skt = &sinfo->skt[i];
da4f00737   Russell King - ARM Linux   PCMCIA: soc_commo...
304
  		skt->nr = ops->first + i;
2a125dd56   Eric Miao   ARM: pxa: remove ...
305
  		skt->clk = clk;
e0d21178c   Russell King   PCMCIA: soc_commo...
306
  		soc_pcmcia_init_one(skt, ops, &dev->dev);
b393c6965   Eric Miao   [ARM] pxa: move P...
307

da4f00737   Russell King - ARM Linux   PCMCIA: soc_commo...
308
309
  		ret = pxa2xx_drv_pcmcia_add_one(skt);
  		if (ret)
a4257af5b   Marek Vasut   ARM: pxa: Add pxa...
310
  			goto err1;
b393c6965   Eric Miao   [ARM] pxa: move P...
311
  	}
817ed5748   Robert Jarzmik   pcmcia: lubbock: ...
312
  	pxa2xx_configure_sockets(&dev->dev, ops);
8fb28231a   Axel Lin   ARM: pxa: fix err...
313
  	dev_set_drvdata(&dev->dev, sinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314

a4257af5b   Marek Vasut   ARM: pxa: Add pxa...
315
316
317
318
319
  	return 0;
  
  err1:
  	while (--i >= 0)
  		soc_pcmcia_remove_one(&sinfo->skt[i]);
8e2caf0d2   Russell King   pcmcia: pxa2xx: c...
320

a4257af5b   Marek Vasut   ARM: pxa: Add pxa...
321
  err0:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
  	return ret;
  }
9468613b2   Russell King   [ARM] Fix suspend...
324
325
326
  
  static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
  {
be85458ed   Russell King - ARM Linux   PCMCIA: soc_commo...
327
328
  	struct skt_dev_info *sinfo = platform_get_drvdata(dev);
  	int i;
be85458ed   Russell King - ARM Linux   PCMCIA: soc_commo...
329
330
  	for (i = 0; i < sinfo->nskt; i++)
  		soc_pcmcia_remove_one(&sinfo->skt[i]);
be85458ed   Russell King - ARM Linux   PCMCIA: soc_commo...
331
  	return 0;
9468613b2   Russell King   [ARM] Fix suspend...
332
  }
85c610210   Mike Rapoport   [ARM] pxa: update...
333
  static int pxa2xx_drv_pcmcia_resume(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
  {
817ed5748   Robert Jarzmik   pcmcia: lubbock: ...
335
336
337
  	struct pcmcia_low_level *ops = (struct pcmcia_low_level *)dev->platform_data;
  
  	pxa2xx_configure_sockets(dev, ops);
d7646f763   Dominik Brodowski   pcmcia: use dev_p...
338
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  }
471452104   Alexey Dobriyan   const: constify r...
340
  static const struct dev_pm_ops pxa2xx_drv_pcmcia_pm_ops = {
85c610210   Mike Rapoport   [ARM] pxa: update...
341
342
  	.resume		= pxa2xx_drv_pcmcia_resume,
  };
9468613b2   Russell King   [ARM] Fix suspend...
343
  static struct platform_driver pxa2xx_pcmcia_driver = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
  	.probe		= pxa2xx_drv_pcmcia_probe,
9468613b2   Russell King   [ARM] Fix suspend...
345
  	.remove		= pxa2xx_drv_pcmcia_remove,
9468613b2   Russell King   [ARM] Fix suspend...
346
347
  	.driver		= {
  		.name	= "pxa2xx-pcmcia",
85c610210   Mike Rapoport   [ARM] pxa: update...
348
  		.pm	= &pxa2xx_drv_pcmcia_pm_ops,
9468613b2   Russell King   [ARM] Fix suspend...
349
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
351
352
353
  };
  
  static int __init pxa2xx_pcmcia_init(void)
  {
9468613b2   Russell King   [ARM] Fix suspend...
354
  	return platform_driver_register(&pxa2xx_pcmcia_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
355
356
357
358
  }
  
  static void __exit pxa2xx_pcmcia_exit(void)
  {
9468613b2   Russell King   [ARM] Fix suspend...
359
  	platform_driver_unregister(&pxa2xx_pcmcia_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  }
f36598aec   Richard Purdie   [ARM] 2873/1: PCM...
361
  fs_initcall(pxa2xx_pcmcia_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
364
365
366
  module_exit(pxa2xx_pcmcia_exit);
  
  MODULE_AUTHOR("Stefan Eletzhofer <stefan.eletzhofer@inquant.de> and Ian Molton <spyro@f2s.com>");
  MODULE_DESCRIPTION("Linux PCMCIA Card Services: PXA2xx core socket driver");
  MODULE_LICENSE("GPL");
12c2c019e   Kay Sievers   pcmcia: fix platf...
367
  MODULE_ALIAS("platform:pxa2xx-pcmcia");