Blame view

drivers/pcmcia/m8xx_pcmcia.c 31.8 KB
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1
2
3
  /*
   * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
   *
cbba0de2f   Magnus Damm   pcmcia: Update em...
4
   * (C) 1999-2000 Magnus Damm <damm@opensource.se>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
5
6
7
8
9
10
11
   * (C) 2001-2002 Montavista Software, Inc.
   *     <mlocke@mvista.com>
   *
   * Support for two slots by Cyclades Corporation
   *     <oliver.kurth@cyclades.de>
   * Further fixes, v2.6 kernel port
   *     <marcelo.tosatti@cyclades.com>
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
12
   * 
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
13
   * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
14
   *     <vbordug@ru.mvista.com>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
   *
   * "The ExCA standard specifies that socket controllers should provide
   * two IO and five memory windows per socket, which can be independently
   * configured and positioned in the host address space and mapped to
   * arbitrary segments of card address space. " - David A Hinds. 1999
   *
   * This controller does _not_ meet the ExCA standard.
   *
   * m8xx pcmcia controller brief info:
   * + 8 windows (attrib, mem, i/o)
   * + up to two slots (SLOT_A and SLOT_B)
   * + inputpins, outputpins, event and mask registers.
   * - no offset register. sigh.
   *
   * Because of the lacking offset register we must map the whole card.
   * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
   * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
   * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
   * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
   * They are maximum 64KByte each...
   */
  
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/types.h>
  #include <linux/fcntl.h>
  #include <linux/string.h>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
42
43
  #include <linux/kernel.h>
  #include <linux/errno.h>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
44
45
46
47
  #include <linux/timer.h>
  #include <linux/ioport.h>
  #include <linux/delay.h>
  #include <linux/interrupt.h>
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
48
  #include <linux/fsl_devices.h>
1977f0327   Jiri Slaby   remove asm/bitops...
49
  #include <linux/bitops.h>
ad19dbdb4   Stephen Rothwell   pcmcia: Use linux...
50
51
  #include <linux/of_device.h>
  #include <linux/of_platform.h>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
52

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
53
  #include <asm/io.h>
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
54
55
  #include <asm/system.h>
  #include <asm/time.h>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
56
57
58
  #include <asm/mpc8xx.h>
  #include <asm/8xx_immap.h>
  #include <asm/irq.h>
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
59
  #include <asm/fs_pd.h>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
60

de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
61
  #include <pcmcia/ss.h>
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  #define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
  #define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
  
  static const char *version = "Version 0.06, Aug 2005";
  MODULE_LICENSE("Dual MPL/GPL");
  
  #if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
  
  /* The RPX series use SLOT_B */
  #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
  #define CONFIG_PCMCIA_SLOT_B
  #define CONFIG_BD_IS_MHZ
  #endif
  
  /* The ADS board use SLOT_A */
  #ifdef CONFIG_ADS
  #define CONFIG_PCMCIA_SLOT_A
  #define CONFIG_BD_IS_MHZ
  #endif
  
  /* The FADS series are a mess */
  #ifdef CONFIG_FADS
  #if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
  #define CONFIG_PCMCIA_SLOT_A
  #else
  #define CONFIG_PCMCIA_SLOT_B
  #endif
  #endif
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
90
91
92
93
  #if defined(CONFIG_MPC885ADS)
  #define CONFIG_PCMCIA_SLOT_A
  #define PCMCIA_GLITCHY_CD
  #endif
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
94
95
96
97
98
  /* Cyclades ACS uses both slots */
  #ifdef CONFIG_PRxK
  #define CONFIG_PCMCIA_SLOT_A
  #define CONFIG_PCMCIA_SLOT_B
  #endif
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
99
  #endif				/* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  
  #if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
  
  #define PCMCIA_SOCKETS_NO 2
  /* We have only 8 windows, dualsocket support will be limited. */
  #define PCMCIA_MEM_WIN_NO 2
  #define PCMCIA_IO_WIN_NO  2
  #define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B"
  
  #elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B)
  
  #define PCMCIA_SOCKETS_NO 1
  /* full support for one slot */
  #define PCMCIA_MEM_WIN_NO 5
  #define PCMCIA_IO_WIN_NO  2
  
  /* define _slot_ to be able to optimize macros */
  
  #ifdef CONFIG_PCMCIA_SLOT_A
  #define _slot_ 0
  #define PCMCIA_SLOT_MSG "SLOT_A"
  #else
  #define _slot_ 1
  #define PCMCIA_SLOT_MSG "SLOT_B"
  #endif
  
  #else
  #error m8xx_pcmcia: Bad configuration!
  #endif
  
  /* ------------------------------------------------------------------------- */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
131
132
133
  #define PCMCIA_MEM_WIN_BASE 0xe0000000	/* base address for memory window 0   */
  #define PCMCIA_MEM_WIN_SIZE 0x04000000	/* each memory window is 64 MByte     */
  #define PCMCIA_IO_WIN_BASE  _IO_BASE	/* base address for io window 0       */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
134
  /* ------------------------------------------------------------------------- */
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
135
  static int pcmcia_schlvl;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
136

34af946a2   Ingo Molnar   [PATCH] spin/rwlo...
137
  static DEFINE_SPINLOCK(events_lock);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
138

de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
139
140
141
142
  #define PCMCIA_SOCKET_KEY_5V 1
  #define PCMCIA_SOCKET_KEY_LV 2
  
  /* look up table for pgcrx registers */
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
143
  static u32 *m8xx_pgcrx[2];
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
144
145
146
147
148
149
150
151
152
  
  /*
   * This structure is used to address each window in the PCMCIA controller.
   *
   * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly
   * after pcmcia_win[n]...
   */
  
  struct pcmcia_win {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
153
154
  	u32 br;
  	u32 or;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  };
  
  /*
   * For some reason the hardware guys decided to make both slots share
   * some registers.
   *
   * Could someone invent object oriented hardware ?
   *
   * The macros are used to get the right bit from the registers.
   * SLOT_A : slot = 0
   * SLOT_B : slot = 1
   */
  
  #define M8XX_PCMCIA_VS1(slot)      (0x80000000 >> (slot << 4))
  #define M8XX_PCMCIA_VS2(slot)      (0x40000000 >> (slot << 4))
  #define M8XX_PCMCIA_VS_MASK(slot)  (0xc0000000 >> (slot << 4))
  #define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
  
  #define M8XX_PCMCIA_WP(slot)       (0x20000000 >> (slot << 4))
  #define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
  #define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
  #define M8XX_PCMCIA_BVD2(slot)     (0x04000000 >> (slot << 4))
  #define M8XX_PCMCIA_BVD1(slot)     (0x02000000 >> (slot << 4))
  #define M8XX_PCMCIA_RDY(slot)      (0x01000000 >> (slot << 4))
  #define M8XX_PCMCIA_RDY_L(slot)    (0x00800000 >> (slot << 4))
  #define M8XX_PCMCIA_RDY_H(slot)    (0x00400000 >> (slot << 4))
  #define M8XX_PCMCIA_RDY_R(slot)    (0x00200000 >> (slot << 4))
  #define M8XX_PCMCIA_RDY_F(slot)    (0x00100000 >> (slot << 4))
  #define M8XX_PCMCIA_MASK(slot)     (0xFFFF0000 >> (slot << 4))
  
  #define M8XX_PCMCIA_POR_VALID    0x00000001
  #define M8XX_PCMCIA_POR_WRPROT   0x00000002
  #define M8XX_PCMCIA_POR_ATTRMEM  0x00000010
  #define M8XX_PCMCIA_POR_IO       0x00000018
  #define M8XX_PCMCIA_POR_16BIT    0x00000040
  
  #define M8XX_PGCRX(slot)  m8xx_pgcrx[slot]
  
  #define M8XX_PGCRX_CXOE    0x00000080
  #define M8XX_PGCRX_CXRESET 0x00000040
  
  /* we keep one lookup table per socket to check flags */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
197
  #define PCMCIA_EVENTS_MAX 5	/* 4 max at a time + termination */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
198
199
200
201
202
  
  struct event_table {
  	u32 regbit;
  	u32 eventbit;
  };
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
203
  static const char driver_name[] = "m8xx-pcmcia";
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
204
  struct socket_info {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
205
206
  	void (*handler) (void *info, u32 events);
  	void *info;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
207
208
  
  	u32 slot;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
209
210
211
  	pcmconf8xx_t *pcmcia;
  	u32 bus_freq;
  	int hwirq;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
212
213
214
  
  	socket_state_t state;
  	struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
215
  	struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
216
217
218
219
220
221
222
223
224
225
226
227
  	struct event_table events[PCMCIA_EVENTS_MAX];
  	struct pcmcia_socket socket;
  };
  
  static struct socket_info socket[PCMCIA_SOCKETS_NO];
  
  /*
   * Search this table to see if the windowsize is
   * supported...
   */
  
  #define M8XX_SIZES_NO 32
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
228
  static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] = {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
229
230
231
232
233
234
235
236
237
238
239
240
  	0x00000001, 0x00000002, 0x00000008, 0x00000004,
  	0x00000080, 0x00000040, 0x00000010, 0x00000020,
  	0x00008000, 0x00004000, 0x00001000, 0x00002000,
  	0x00000100, 0x00000200, 0x00000800, 0x00000400,
  
  	0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
  	0x01000000, 0x02000000, 0xffffffff, 0x04000000,
  	0x00010000, 0x00020000, 0x00080000, 0x00040000,
  	0x00800000, 0x00400000, 0x00100000, 0x00200000
  };
  
  /* ------------------------------------------------------------------------- */
7d12e780e   David Howells   IRQ: Maintain reg...
241
  static irqreturn_t m8xx_interrupt(int irq, void *dev);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
242

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
243
  #define PCMCIA_BMT_LIMIT (15*4)	/* Bus Monitor Timeout value */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  
  /* ------------------------------------------------------------------------- */
  /* board specific stuff:                                                     */
  /* voltage_set(), hardware_enable() and hardware_disable()                   */
  /* ------------------------------------------------------------------------- */
  /* RPX Boards from Embedded Planet                                           */
  
  #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
  
  /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
   * SYPCR is write once only, therefore must the slowest memory be faster
   * than the bus monitor or we will get a machine check due to the bus timeout.
   */
  
  #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
  
  #undef PCMCIA_BMT_LIMIT
  #define PCMCIA_BMT_LIMIT (6*8)
  
  static int voltage_set(int slot, int vcc, int vpp)
  {
  	u32 reg = 0;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
266
267
268
  	switch (vcc) {
  	case 0:
  		break;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
269
270
271
272
273
274
275
276
277
  	case 33:
  		reg |= BCSR1_PCVCTL4;
  		break;
  	case 50:
  		reg |= BCSR1_PCVCTL5;
  		break;
  	default:
  		return 1;
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
278
279
280
  	switch (vpp) {
  	case 0:
  		break;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
281
282
  	case 33:
  	case 50:
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
283
  		if (vcc == vpp)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
284
285
286
287
288
289
290
291
292
  			reg |= BCSR1_PCVCTL6;
  		else
  			return 1;
  		break;
  	case 120:
  		reg |= BCSR1_PCVCTL7;
  	default:
  		return 1;
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
293
  	if (!((vcc == 50) || (vcc == 0)))
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
294
295
296
  		return 1;
  
  	/* first, turn off all power */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
297
298
299
300
301
  	out_be32(((u32 *) RPX_CSR_ADDR),
  		 in_be32(((u32 *) RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 |
  						     BCSR1_PCVCTL5 |
  						     BCSR1_PCVCTL6 |
  						     BCSR1_PCVCTL7));
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
302
303
  
  	/* enable new powersettings */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
304
  	out_be32(((u32 *) RPX_CSR_ADDR), in_be32(((u32 *) RPX_CSR_ADDR)) | reg);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
305
306
307
308
309
  
  	return 0;
  }
  
  #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
310
311
  #define hardware_enable(_slot_)	/* No hardware to enable */
  #define hardware_disable(_slot_)	/* No hardware to disable */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
312

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
313
  #endif				/* CONFIG_RPXCLASSIC */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
314
315
316
317
318
319
320
321
322
323
  
  /* FADS Boards from Motorola                                               */
  
  #if defined(CONFIG_FADS)
  
  #define PCMCIA_BOARD_MSG "FADS"
  
  static int voltage_set(int slot, int vcc, int vpp)
  {
  	u32 reg = 0;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
324
325
326
327
328
329
330
331
332
333
334
  	switch (vcc) {
  	case 0:
  		break;
  	case 33:
  		reg |= BCSR1_PCCVCC0;
  		break;
  	case 50:
  		reg |= BCSR1_PCCVCC1;
  		break;
  	default:
  		return 1;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
335
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
336
337
338
339
340
341
342
343
  	switch (vpp) {
  	case 0:
  		break;
  	case 33:
  	case 50:
  		if (vcc == vpp)
  			reg |= BCSR1_PCCVPP1;
  		else
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
344
  			return 1;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
345
346
347
348
349
350
351
352
  		break;
  	case 120:
  		if ((vcc == 33) || (vcc == 50))
  			reg |= BCSR1_PCCVPP0;
  		else
  			return 1;
  	default:
  		return 1;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
353
354
355
  	}
  
  	/* first, turn off all power */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
356
357
358
  	out_be32((u32 *) BCSR1,
  		 in_be32((u32 *) BCSR1) & ~(BCSR1_PCCVCC_MASK |
  					    BCSR1_PCCVPP_MASK));
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
359
360
  
  	/* enable new powersettings */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
361
  	out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | reg);
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
362
363
364
365
366
367
368
369
  
  	return 0;
  }
  
  #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
  
  static void hardware_enable(int slot)
  {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
370
  	out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) & ~BCSR1_PCCEN);
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
371
372
373
374
  }
  
  static void hardware_disable(int slot)
  {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
375
  	out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | BCSR1_PCCEN);
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
376
377
378
379
380
381
382
383
384
  }
  
  #endif
  
  /* MPC885ADS Boards */
  
  #if defined(CONFIG_MPC885ADS)
  
  #define PCMCIA_BOARD_MSG "MPC885ADS"
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
385
  #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
386

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
387
  static inline void hardware_enable(int slot)
1371d3be0   Vitaly Bordug   [PATCH] 8xx PCMCI...
388
  {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
389
  	m8xx_pcmcia_ops.hw_ctrl(slot, 1);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
390
  }
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
391
  static inline void hardware_disable(int slot)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
392
  {
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
393
  	m8xx_pcmcia_ops.hw_ctrl(slot, 0);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
394
  }
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
395
  static inline int voltage_set(int slot, int vcc, int vpp)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
396
  {
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
397
  	return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
  }
  
  #endif
  
  /* ------------------------------------------------------------------------- */
  /* Motorola MBX860                                                           */
  
  #if defined(CONFIG_MBX)
  
  #define PCMCIA_BOARD_MSG "MBX"
  
  static int voltage_set(int slot, int vcc, int vpp)
  {
  	u8 reg = 0;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
412
413
414
415
416
417
418
419
420
421
422
  	switch (vcc) {
  	case 0:
  		break;
  	case 33:
  		reg |= CSR2_VCC_33;
  		break;
  	case 50:
  		reg |= CSR2_VCC_50;
  		break;
  	default:
  		return 1;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
423
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
  	switch (vpp) {
  	case 0:
  		break;
  	case 33:
  	case 50:
  		if (vcc == vpp)
  			reg |= CSR2_VPP_VCC;
  		else
  			return 1;
  		break;
  	case 120:
  		if ((vcc == 33) || (vcc == 50))
  			reg |= CSR2_VPP_12;
  		else
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
438
  			return 1;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
439
440
  	default:
  		return 1;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
441
442
443
  	}
  
  	/* first, turn off all power */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
444
445
  	out_8((u8 *) MBX_CSR2_ADDR,
  	      in_8((u8 *) MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
446
447
  
  	/* enable new powersettings */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
448
  	out_8((u8 *) MBX_CSR2_ADDR, in_8((u8 *) MBX_CSR2_ADDR) | reg);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
449
450
451
452
453
  
  	return 0;
  }
  
  #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
454
455
  #define hardware_enable(_slot_)	/* No hardware to enable */
  #define hardware_disable(_slot_)	/* No hardware to disable */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
456

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
457
  #endif				/* CONFIG_MBX */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
458
459
460
461
462
463
464
465
466
467
468
469
  
  #if defined(CONFIG_PRxK)
  #include <asm/cpld.h>
  extern volatile fpga_pc_regs *fpga_pc;
  
  #define PCMCIA_BOARD_MSG "MPC855T"
  
  static int voltage_set(int slot, int vcc, int vpp)
  {
  	u8 reg = 0;
  	u8 regread;
  	cpld_regs *ccpld = get_cpld();
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
470
471
472
473
474
475
476
477
478
479
480
  	switch (vcc) {
  	case 0:
  		break;
  	case 33:
  		reg |= PCMCIA_VCC_33;
  		break;
  	case 50:
  		reg |= PCMCIA_VCC_50;
  		break;
  	default:
  		return 1;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
481
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
482
483
484
485
486
487
488
489
  	switch (vpp) {
  	case 0:
  		break;
  	case 33:
  	case 50:
  		if (vcc == vpp)
  			reg |= PCMCIA_VPP_VCC;
  		else
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
490
  			return 1;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
491
492
493
494
495
496
497
498
  		break;
  	case 120:
  		if ((vcc == 33) || (vcc == 50))
  			reg |= PCMCIA_VPP_12;
  		else
  			return 1;
  	default:
  		return 1;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
499
500
501
502
  	}
  
  	reg = reg >> (slot << 2);
  	regread = in_8(&ccpld->fpga_pc_ctl);
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
503
504
  	if (reg !=
  	    (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
505
  		/* enable new powersettings */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
506
507
508
  		regread =
  		    regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >>
  				(slot << 2));
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
509
510
511
512
513
514
515
516
  		out_8(&ccpld->fpga_pc_ctl, reg | regread);
  		msleep(100);
  	}
  
  	return 0;
  }
  
  #define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
517
518
  #define hardware_enable(_slot_)	/* No hardware to enable */
  #define hardware_disable(_slot_)	/* No hardware to disable */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
519

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
520
  #endif				/* CONFIG_PRxK */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
521

de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
522
  static u32 pending_events[PCMCIA_SOCKETS_NO];
34af946a2   Ingo Molnar   [PATCH] spin/rwlo...
523
  static DEFINE_SPINLOCK(pending_event_lock);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
524

7d12e780e   David Howells   IRQ: Maintain reg...
525
  static irqreturn_t m8xx_interrupt(int irq, void *dev)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
526
527
528
529
  {
  	struct socket_info *s;
  	struct event_table *e;
  	unsigned int i, events, pscr, pipr, per;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
530
  	pcmconf8xx_t *pcmcia = socket[0].pcmcia;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
531

c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
532
533
  	pr_debug("m8xx_pcmcia: Interrupt!
  ");
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
534
  	/* get interrupt sources */
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
535
536
537
  	pscr = in_be32(&pcmcia->pcmc_pscr);
  	pipr = in_be32(&pcmcia->pcmc_pipr);
  	per = in_be32(&pcmcia->pcmc_per);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
538

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
539
  	for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
540
541
542
  		s = &socket[i];
  		e = &s->events[0];
  		events = 0;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
543
544
  		while (e->regbit) {
  			if (pscr & e->regbit)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
545
  				events |= e->eventbit;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
546
  			e++;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
547
548
549
550
551
552
553
  		}
  
  		/*
  		 * report only if both card detect signals are the same
  		 * not too nice done,
  		 * we depend on that CD2 is the bit to the left of CD1...
  		 */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
554
555
556
  		if (events & SS_DETECT)
  			if (((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
  			    (pipr & M8XX_PCMCIA_CD1(i))) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
557
558
  				events &= ~SS_DETECT;
  			}
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
559
560
561
562
563
564
  #ifdef PCMCIA_GLITCHY_CD
  		/*
  		 * I've experienced CD problems with my ADS board.
  		 * We make an extra check to see if there was a
  		 * real change of Card detection.
  		 */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
565
566
567
568
  		if ((events & SS_DETECT) &&
  		    ((pipr &
  		      (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
  		    (s->state.Vcc | s->state.Vpp)) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
569
570
571
  			events &= ~SS_DETECT;
  			/*printk( "CD glitch workaround - CD = 0x%08x!
  ",
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
572
573
  			   (pipr & (M8XX_PCMCIA_CD2(i)
  			   | M8XX_PCMCIA_CD1(i)))); */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
574
575
576
577
  		}
  #endif
  
  		/* call the handler */
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
578
  		pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, "
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
579
580
  			"pipr = 0x%08x
  ", i, events, pscr, pipr);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
581

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
582
  		if (events) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
583
584
585
586
587
588
589
590
591
592
593
594
  			spin_lock(&pending_event_lock);
  			pending_events[i] |= events;
  			spin_unlock(&pending_event_lock);
  			/*
  			 * Turn off RDY_L bits in the PER mask on
  			 * CD interrupt receival.
  			 *
  			 * They can generate bad interrupts on the
  			 * ACS4,8,16,32.   - marcelo
  			 */
  			per &= ~M8XX_PCMCIA_RDY_L(0);
  			per &= ~M8XX_PCMCIA_RDY_L(1);
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
595
  			out_be32(&pcmcia->pcmc_per, per);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
596
597
598
599
600
601
602
  
  			if (events)
  				pcmcia_parse_events(&socket[i].socket, events);
  		}
  	}
  
  	/* clear the interrupt sources */
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
603
  	out_be32(&pcmcia->pcmc_pscr, pscr);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
604

c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
605
606
  	pr_debug("m8xx_pcmcia: Interrupt done.
  ");
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
607
608
609
610
611
612
613
  
  	return IRQ_HANDLED;
  }
  
  static u32 m8xx_get_graycode(u32 size)
  {
  	u32 k;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
614
615
  	for (k = 0; k < M8XX_SIZES_NO; k++)
  		if (m8xx_size_to_gray[k] == size)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
616
  			break;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
617
  	if ((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
618
619
620
621
  		k = -1;
  
  	return k;
  }
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
622
  static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
623
624
  {
  	u32 reg, clocks, psst, psl, psht;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
625
  	if (!ns) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
626
627
628
629
630
631
  
  		/*
  		 * We get called with IO maps setup to 0ns
  		 * if not specified by the user.
  		 * They should be 255ns.
  		 */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
632
  		if (is_io)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
633
634
  			ns = 255;
  		else
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
635
  			ns = 100;	/* fast memory if 0 */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
636
637
638
639
640
641
642
643
644
  	}
  
  	/*
  	 * In PSST, PSL, PSHT fields we tell the controller
  	 * timing parameters in CLKOUT clock cycles.
  	 * CLKOUT is the same as GCLK2_50.
  	 */
  
  /* how we want to adjust the timing - in percent */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
645
  #define ADJ 180			/* 80 % longer accesstime - to be sure */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
646

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
647
  	clocks = ((bus_freq / 1000) * ns) / 1000;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
648
649
650
651
652
  	clocks = (clocks * ADJ) / (100 * 1000);
  	if (clocks >= PCMCIA_BMT_LIMIT) {
  		printk("Max access time limit reached
  ");
  		clocks = PCMCIA_BMT_LIMIT - 1;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
653
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
654
655
656
  	psst = clocks / 7;	/* setup time */
  	psht = clocks / 7;	/* hold time */
  	psl = (clocks * 5) / 7;	/* strobe length */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
657
658
  
  	psst += clocks - (psst + psht + psl);
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
659
660
  	reg = psst << 12;
  	reg |= psl << 7;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
661
662
663
664
665
666
667
668
669
670
  	reg |= psht << 16;
  
  	return reg;
  }
  
  static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
  {
  	int lsock = container_of(sock, struct socket_info, socket)->slot;
  	struct socket_info *s = &socket[lsock];
  	unsigned int pipr, reg;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
671
  	pcmconf8xx_t *pcmcia = s->pcmcia;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
672

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
673
  	pipr = in_be32(&pcmcia->pcmc_pipr);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
674

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
675
676
  	*value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
  			   | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
  	*value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
  
  	if (s->state.flags & SS_IOCARD)
  		*value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0;
  	else {
  		*value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0;
  		*value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0;
  		*value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0;
  	}
  
  	if (s->state.Vcc | s->state.Vpp)
  		*value |= SS_POWERON;
  
  	/*
  	 * Voltage detection:
  	 * This driver only supports 16-Bit pc-cards.
  	 * Cardbus is not handled here.
  	 *
  	 * To determine what voltage to use we must read the VS1 and VS2 pin.
  	 * Depending on what socket type is present,
  	 * different combinations mean different things.
  	 *
  	 * Card Key  Socket Key   VS1   VS2   Card         Vcc for CIS parse
  	 *
  	 * 5V        5V, LV*      NC    NC    5V only       5V (if available)
  	 *
  	 * 5V        5V, LV*      GND   NC    5 or 3.3V     as low as possible
  	 *
  	 * 5V        5V, LV*      GND   GND   5, 3.3, x.xV  as low as possible
  	 *
  	 * LV*       5V            -     -    shall not fit into socket
  	 *
  	 * LV*       LV*          GND   NC    3.3V only     3.3V
  	 *
  	 * LV*       LV*          NC    GND   x.xV          x.xV (if avail.)
  	 *
  	 * LV*       LV*          GND   GND   3.3 or x.xV   as low as possible
  	 *
  	 * *LV means Low Voltage
  	 *
  	 *
  	 * That gives us the following table:
  	 *
  	 * Socket    VS1  VS2   Voltage
  	 *
  	 * 5V        NC   NC    5V
  	 * 5V        NC   GND   none (should not be possible)
  	 * 5V        GND  NC    >= 3.3V
  	 * 5V        GND  GND   >= x.xV
  	 *
  	 * LV        NC   NC    5V   (if available)
  	 * LV        NC   GND   x.xV (if available)
  	 * LV        GND  NC    3.3V
  	 * LV        GND  GND   >= x.xV
  	 *
  	 * So, how do I determine if I have a 5V or a LV
  	 * socket on my board?  Look at the socket!
  	 *
  	 *
  	 * Socket with 5V key:
  	 * ++--------------------------------------------+
  	 * ||                                            |
  	 * ||                                           ||
  	 * ||                                           ||
  	 * |                                             |
  	 * +---------------------------------------------+
  	 *
  	 * Socket with LV key:
  	 * ++--------------------------------------------+
  	 * ||                                            |
  	 * |                                            ||
  	 * |                                            ||
  	 * |                                             |
  	 * +---------------------------------------------+
  	 *
  	 *
  	 * With other words - LV only cards does not fit
  	 * into the 5V socket!
  	 */
  
  	/* read out VS1 and VS2 */
  
  	reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
760
  	    >> M8XX_PCMCIA_VS_SHIFT(lsock);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
761

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
762
763
  	if (socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
  		switch (reg) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
764
765
  		case 1:
  			*value |= SS_3VCARD;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
766
  			break;	/* GND, NC - 3.3V only */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
767
768
  		case 2:
  			*value |= SS_XVCARD;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
769
  			break;	/* NC. GND - x.xV only */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
770
771
  		};
  	}
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
772
773
  	pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x
  ", lsock, *value);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
774
775
  	return 0;
  }
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
776
  static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
777
778
779
780
781
782
  {
  	int lsock = container_of(sock, struct socket_info, socket)->slot;
  	struct socket_info *s = &socket[lsock];
  	struct event_table *e;
  	unsigned int reg;
  	unsigned long flags;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
783
  	pcmconf8xx_t *pcmcia = socket[0].pcmcia;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
784

c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
785
  	pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
786
787
788
  		"io_irq %d, csc_mask %#2.2x)
  ", lsock, state->flags,
  		state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
789
790
  
  	/* First, set voltage - bail out if invalid */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
791
  	if (voltage_set(lsock, state->Vcc, state->Vpp))
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
792
793
794
  		return -EINVAL;
  
  	/* Take care of reset... */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
795
796
  	if (state->flags & SS_RESET)
  		out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET);	/* active high */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
797
  	else
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
798
799
  		out_be32(M8XX_PGCRX(lsock),
  			 in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
800
801
802
803
804
805
806
807
  
  	/* ... and output enable. */
  
  	/* The CxOE signal is connected to a 74541 on the ADS.
  	   I guess most other boards used the ADS as a reference.
  	   I tried to control the CxOE signal with SS_OUTPUT_ENA,
  	   but the reset signal seems connected via the 541.
  	   If the CxOE is left high are some signals tristated and
f26fc4e08   Joe Perches   drivers/pcmcia/: ...
808
  	   no pullups are present -> the cards act weird.
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
809
  	   So right now the buffers are enabled if the power is on. */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
810
811
  	if (state->Vcc || state->Vpp)
  		out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE);	/* active low */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
812
  	else
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
813
814
  		out_be32(M8XX_PGCRX(lsock),
  			 in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
  
  	/*
  	 * We'd better turn off interrupts before
  	 * we mess with the events-table..
  	 */
  
  	spin_lock_irqsave(&events_lock, flags);
  
  	/*
  	 * Play around with the interrupt mask to be able to
  	 * give the events the generic pcmcia driver wants us to.
  	 */
  
  	e = &s->events[0];
  	reg = 0;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
830
  	if (state->csc_mask & SS_DETECT) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
831
832
833
834
835
  		e->eventbit = SS_DETECT;
  		reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
  				    | M8XX_PCMCIA_CD1(lsock));
  		e++;
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
836
  	if (state->flags & SS_IOCARD) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
837
838
839
  		/*
  		 * I/O card
  		 */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
840
  		if (state->csc_mask & SS_STSCHG) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
841
842
843
844
845
846
847
  			e->eventbit = SS_STSCHG;
  			reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
  			e++;
  		}
  		/*
  		 * If io_irq is non-zero we should enable irq.
  		 */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
848
  		if (state->io_irq) {
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
849
  			out_be32(M8XX_PGCRX(lsock),
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
850
851
  				 in_be32(M8XX_PGCRX(lsock)) |
  				 mk_int_int_mask(s->hwirq) << 24);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
852
853
854
855
856
857
858
859
860
861
  			/*
  			 * Strange thing here:
  			 * The manual does not tell us which interrupt
  			 * the sources generate.
  			 * Anyhow, I found out that RDY_L generates IREQLVL.
  			 *
  			 * We use level triggerd interrupts, and they don't
  			 * have to be cleared in PSCR in the interrupt handler.
  			 */
  			reg |= M8XX_PCMCIA_RDY_L(lsock);
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
862
863
864
865
  		} else
  			out_be32(M8XX_PGCRX(lsock),
  				 in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
  	} else {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
866
867
868
  		/*
  		 * Memory card
  		 */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
869
  		if (state->csc_mask & SS_BATDEAD) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
870
871
872
873
  			e->eventbit = SS_BATDEAD;
  			reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
  			e++;
  		}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
874
  		if (state->csc_mask & SS_BATWARN) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
875
876
877
878
879
  			e->eventbit = SS_BATWARN;
  			reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
  			e++;
  		}
  		/* What should I trigger on - low/high,raise,fall? */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
880
  		if (state->csc_mask & SS_READY) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
881
  			e->eventbit = SS_READY;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
882
  			reg |= e->regbit = 0;	//??
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
883
884
885
  			e++;
  		}
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
886
  	e->regbit = 0;		/* terminate list */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
887
888
889
890
891
892
  
  	/*
  	 * Clear the status changed .
  	 * Port A and Port B share the same port.
  	 * Writing ones will clear the bits.
  	 */
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
893
  	out_be32(&pcmcia->pcmc_pscr, reg);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
894
895
896
897
898
899
900
  
  	/*
  	 * Write the mask.
  	 * Port A and Port B share the same port.
  	 * Need for read-modify-write.
  	 * Ones will enable the interrupt.
  	 */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
901
902
903
  	reg |=
  	    in_be32(&pcmcia->
  		    pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
904
  	out_be32(&pcmcia->pcmc_per, reg);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
  
  	spin_unlock_irqrestore(&events_lock, flags);
  
  	/* copy the struct and modify the copy */
  
  	s->state = *state;
  
  	return 0;
  }
  
  static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
  {
  	int lsock = container_of(sock, struct socket_info, socket)->slot;
  
  	struct socket_info *s = &socket[lsock];
  	struct pcmcia_win *w;
  	unsigned int reg, winnr;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
922
  	pcmconf8xx_t *pcmcia = s->pcmcia;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
923
924
  #define M8XX_SIZE (io->stop - io->start + 1)
  #define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
925
  	pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, "
5f784336d   Wolfram Sang   pcmcia: Fix possi...
926
927
928
929
  		"%#4.4llx-%#4.4llx)
  ", lsock, io->map, io->flags,
  		io->speed, (unsigned long long)io->start,
  		(unsigned long long)io->stop);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
930
931
932
933
  
  	if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
  	    || (io->stop > 0xffff) || (io->stop < io->start))
  		return -EINVAL;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
934
  	if ((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
935
  		return -EINVAL;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
936
  	if (io->flags & MAP_ACTIVE) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
937

c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
938
939
  		pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE
  ");
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
940
941
  
  		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
942
  		    + (lsock * PCMCIA_IO_WIN_NO) + io->map;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
943
944
  
  		/* setup registers */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
945
  		w = (void *)&pcmcia->pcmc_pbr0;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
946
  		w += winnr;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
947
  		out_be32(&w->or, 0);	/* turn off window first */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
948
949
950
  		out_be32(&w->br, M8XX_BASE);
  
  		reg <<= 27;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
951
  		reg |= M8XX_PCMCIA_POR_IO | (lsock << 2);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
952

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
953
  		reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
954

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
955
  		if (io->flags & MAP_WRPROT)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
956
  			reg |= M8XX_PCMCIA_POR_WRPROT;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
957
958
  		/*if(io->flags & (MAP_16BIT | MAP_AUTOSZ)) */
  		if (io->flags & MAP_16BIT)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
959
  			reg |= M8XX_PCMCIA_POR_16BIT;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
960
  		if (io->flags & MAP_ACTIVE)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
961
962
963
  			reg |= M8XX_PCMCIA_POR_VALID;
  
  		out_be32(&w->or, reg);
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
964
965
966
  		pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at "
  			"%#8.8x, OR = %#8.8x.
  ", lsock, io->map, w->br, w->or);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
967
968
969
  	} else {
  		/* shutdown IO window */
  		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
970
  		    + (lsock * PCMCIA_IO_WIN_NO) + io->map;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
971
972
  
  		/* setup registers */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
973
  		w = (void *)&pcmcia->pcmc_pbr0;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
974
  		w += winnr;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
975
976
  		out_be32(&w->or, 0);	/* turn off window */
  		out_be32(&w->br, 0);	/* turn off base address */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
977

c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
978
979
980
  		pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at "
  			"%#8.8x, OR = %#8.8x.
  ", lsock, io->map, w->br, w->or);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
981
982
983
984
  	}
  
  	/* copy the struct and modify the copy */
  	s->io_win[io->map] = *io;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
985
  	s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
986
987
  	pr_debug("m8xx_pcmcia: SetIOMap exit
  ");
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
988
989
990
  
  	return 0;
  }
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
991
992
  static int m8xx_set_mem_map(struct pcmcia_socket *sock,
  			    struct pccard_mem_map *mem)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
993
994
995
996
997
998
  {
  	int lsock = container_of(sock, struct socket_info, socket)->slot;
  	struct socket_info *s = &socket[lsock];
  	struct pcmcia_win *w;
  	struct pccard_mem_map *old;
  	unsigned int reg, winnr;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
999
  	pcmconf8xx_t *pcmcia = s->pcmcia;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1000

c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
1001
  	pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
5f784336d   Wolfram Sang   pcmcia: Fix possi...
1002
1003
1004
1005
  		"%#5.5llx, %#5.5x)
  ", lsock, mem->map, mem->flags,
  		mem->speed, (unsigned long long)mem->static_start,
  		mem->card_start);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1006
1007
  
  	if ((mem->map >= PCMCIA_MEM_WIN_NO)
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1008
  //          || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1009
  	    || (mem->card_start >= 0x04000000)
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1010
1011
  	    || (mem->static_start & 0xfff)	/* 4KByte resolution */
  	    ||(mem->card_start & 0xfff))
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1012
  		return -EINVAL;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1013
1014
1015
  	if ((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
  		printk("Cannot set size to 0x%08x.
  ", PCMCIA_MEM_WIN_SIZE);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1016
1017
1018
1019
1020
1021
1022
  		return -EINVAL;
  	}
  	reg <<= 27;
  
  	winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
  
  	/* Setup the window in the pcmcia controller */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1023
  	w = (void *)&pcmcia->pcmc_pbr0;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1024
1025
1026
  	w += winnr;
  
  	reg |= lsock << 2;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1027
  	reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1028

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1029
1030
  	if (mem->flags & MAP_ATTRIB)
  		reg |= M8XX_PCMCIA_POR_ATTRMEM;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1031

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1032
  	if (mem->flags & MAP_WRPROT)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1033
  		reg |= M8XX_PCMCIA_POR_WRPROT;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1034
  	if (mem->flags & MAP_16BIT)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1035
  		reg |= M8XX_PCMCIA_POR_16BIT;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1036
  	if (mem->flags & MAP_ACTIVE)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1037
1038
1039
  		reg |= M8XX_PCMCIA_POR_VALID;
  
  	out_be32(&w->or, reg);
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
1040
  	pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, "
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1041
1042
  		"OR = %#8.8x.
  ", lsock, mem->map, w->br, w->or);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1043

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1044
  	if (mem->flags & MAP_ACTIVE) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1045
1046
  		/* get the new base address */
  		mem->static_start = PCMCIA_MEM_WIN_BASE +
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1047
1048
  		    (PCMCIA_MEM_WIN_SIZE * winnr)
  		    + mem->card_start;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1049
  	}
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
1050
  	pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
5f784336d   Wolfram Sang   pcmcia: Fix possi...
1051
1052
1053
1054
  		"%#5.5llx, %#5.5x)
  ", lsock, mem->map, mem->flags,
  		mem->speed, (unsigned long long)mem->static_start,
  		mem->card_start);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1055
1056
1057
1058
1059
1060
  
  	/* copy the struct and modify the copy */
  
  	old = &s->mem_win[mem->map];
  
  	*old = *mem;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1061
  	old->flags &= (MAP_ATTRIB | MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1062
1063
1064
1065
1066
1067
1068
1069
1070
  
  	return 0;
  }
  
  static int m8xx_sock_init(struct pcmcia_socket *sock)
  {
  	int i;
  	pccard_io_map io = { 0, 0, 0, 0, 1 };
  	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
c9f50dddd   Dominik Brodowski   pcmcia: use dynam...
1071
1072
  	pr_debug("m8xx_pcmcia: sock_init(%d)
  ", s);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
  
  	m8xx_set_socket(sock, &dead_socket);
  	for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
  		io.map = i;
  		m8xx_set_io_map(sock, &io);
  	}
  	for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
  		mem.map = i;
  		m8xx_set_mem_map(sock, &mem);
  	}
  
  	return 0;
  
  }
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1087
  static int m8xx_sock_suspend(struct pcmcia_socket *sock)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1088
1089
1090
1091
1092
  {
  	return m8xx_set_socket(sock, &dead_socket);
  }
  
  static struct pccard_operations m8xx_services = {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1093
  	.init = m8xx_sock_init,
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1094
  	.suspend = m8xx_sock_suspend,
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1095
  	.get_status = m8xx_get_status,
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1096
1097
1098
1099
  	.set_socket = m8xx_set_socket,
  	.set_io_map = m8xx_set_io_map,
  	.set_mem_map = m8xx_set_mem_map,
  };
1c48a5c93   Grant Likely   dt: Eliminate of_...
1100
  static int __init m8xx_probe(struct platform_device *ofdev)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1101
1102
  {
  	struct pcmcia_win *w;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1103
1104
1105
  	unsigned int i, m, hwirq;
  	pcmconf8xx_t *pcmcia;
  	int status;
2005ce352   Anatolij Gustschin   of/pcmcia: m8xx_p...
1106
  	struct device_node *np = ofdev->dev.of_node;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1107
1108
1109
  
  	pcmcia_info("%s
  ", version);
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1110
  	pcmcia = of_iomap(np, 0);
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1111
  	if (pcmcia == NULL)
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1112
1113
1114
  		return -EINVAL;
  
  	pcmcia_schlvl = irq_of_parse_and_map(np, 0);
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1115
  	hwirq = irq_map[pcmcia_schlvl].hwirq;
5a1c3e1aa   Julia Lawall   drivers/pcmcia: A...
1116
1117
  	if (pcmcia_schlvl < 0) {
  		iounmap(pcmcia);
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1118
  		return -EINVAL;
5a1c3e1aa   Julia Lawall   drivers/pcmcia: A...
1119
  	}
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1120
1121
1122
  
  	m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
  	m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1123
  	pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1124
1125
  		    " with IRQ %u  (%d). 
  ", pcmcia_schlvl, hwirq);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1126
1127
  
  	/* Configure Status change interrupt */
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1128
1129
  	if (request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
  			driver_name, socket)) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1130
1131
1132
  		pcmcia_error("Cannot allocate IRQ %u for SCHLVL!
  ",
  			     pcmcia_schlvl);
5a1c3e1aa   Julia Lawall   drivers/pcmcia: A...
1133
  		iounmap(pcmcia);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1134
1135
  		return -1;
  	}
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1136
  	w = (void *)&pcmcia->pcmc_pbr0;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1137

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1138
  	out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1139
  	clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1140

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1141
  	/* connect interrupt and disable CxOE */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1142

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1143
1144
1145
1146
  	out_be32(M8XX_PGCRX(0),
  		 M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
  	out_be32(M8XX_PGCRX(1),
  		 M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1147

b595076a1   Uwe Kleine-König   tree-wide: fix co...
1148
  	/* initialize the fixed memory windows */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1149

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1150
  	for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1151
  		for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1152
  			out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1153
1154
  				 (PCMCIA_MEM_WIN_SIZE
  				  * (m + i * PCMCIA_MEM_WIN_NO)));
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1155

99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1156
  			out_be32(&w->or, 0);	/* set to not valid */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1157
1158
1159
1160
  
  			w++;
  		}
  	}
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1161
  	/* turn off voltage */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1162
1163
  	voltage_set(0, 0, 0);
  	voltage_set(1, 0, 0);
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1164
  	/* Enable external hardware */
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1165
1166
  	hardware_enable(0);
  	hardware_enable(1);
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1167
  	for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1168
1169
  		socket[i].slot = i;
  		socket[i].socket.owner = THIS_MODULE;
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1170
1171
  		socket[i].socket.features =
  		    SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1172
1173
1174
  		socket[i].socket.irq_mask = 0x000;
  		socket[i].socket.map_size = 0x1000;
  		socket[i].socket.io_offset = 0;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1175
  		socket[i].socket.pci_irq = pcmcia_schlvl;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1176
  		socket[i].socket.ops = &m8xx_services;
4e8804ff6   Dominik Brodowski   pcmcia: m8xx_pcmc...
1177
  		socket[i].socket.resource_ops = &pccard_iodyn_ops;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1178
  		socket[i].socket.cb_dev = NULL;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1179
1180
1181
1182
  		socket[i].socket.dev.parent = &ofdev->dev;
  		socket[i].pcmcia = pcmcia;
  		socket[i].bus_freq = ppc_proc_freq;
  		socket[i].hwirq = hwirq;
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1183
  	}
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1184
1185
1186
1187
1188
1189
  	for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
  		status = pcmcia_register_socket(&socket[i].socket);
  		if (status < 0)
  			pcmcia_error("Socket register failed
  ");
  	}
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1190
1191
1192
  
  	return 0;
  }
2dc115813   Grant Likely   of/device: Replac...
1193
  static int m8xx_remove(struct platform_device *ofdev)
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1194
  {
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1195
1196
1197
1198
1199
  	u32 m, i;
  	struct pcmcia_win *w;
  	pcmconf8xx_t *pcmcia = socket[0].pcmcia;
  
  	for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1200
  		w = (void *)&pcmcia->pcmc_pbr0;
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1201
1202
1203
  
  		out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
  		out_be32(&pcmcia->pcmc_per,
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1204
  			 in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1205

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1206
1207
1208
1209
1210
  		/* turn off interrupt and disable CxOE */
  		out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
  
  		/* turn off memory windows */
  		for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1211
  			out_be32(&w->or, 0);	/* set to not valid */
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1212
1213
1214
1215
1216
1217
1218
1219
1220
  			w++;
  		}
  
  		/* turn off voltage */
  		voltage_set(i, 0, 0);
  
  		/* disable external hardware */
  		hardware_disable(i);
  	}
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1221
1222
  	for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
  		pcmcia_unregister_socket(&socket[i].socket);
5a1c3e1aa   Julia Lawall   drivers/pcmcia: A...
1223
  	iounmap(pcmcia);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1224

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1225
  	free_irq(pcmcia_schlvl, NULL);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1226

80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1227
1228
  	return 0;
  }
63c9a8b30   Márton Németh   pcmcia: make Open...
1229
  static const struct of_device_id m8xx_pcmcia_match[] = {
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1230
  	{
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1231
1232
1233
  	 .type = "pcmcia",
  	 .compatible = "fsl,pq-pcmcia",
  	 },
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1234
1235
1236
1237
  	{},
  };
  
  MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
1c48a5c93   Grant Likely   dt: Eliminate of_...
1238
  static struct platform_driver m8xx_pcmcia_driver = {
4018294b5   Grant Likely   of: Remove duplic...
1239
1240
1241
  	.driver = {
  		.name = driver_name,
  		.owner = THIS_MODULE,
2005ce352   Anatolij Gustschin   of/pcmcia: m8xx_p...
1242
  		.of_match_table = m8xx_pcmcia_match,
4018294b5   Grant Likely   of: Remove duplic...
1243
  	},
99121c0da   Vitaly Bordug   powerpc: 8xx: fix...
1244
1245
  	.probe = m8xx_probe,
  	.remove = m8xx_remove,
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1246
1247
1248
1249
  };
  
  static int __init m8xx_init(void)
  {
1c48a5c93   Grant Likely   dt: Eliminate of_...
1250
  	return platform_driver_register(&m8xx_pcmcia_driver);
80128ff79   Vitaly Bordug   [POWERPC] 8xx: mp...
1251
1252
1253
1254
  }
  
  static void __exit m8xx_exit(void)
  {
1c48a5c93   Grant Likely   dt: Eliminate of_...
1255
  	platform_driver_unregister(&m8xx_pcmcia_driver);
de957c89b   Marcelo Tosatti   [PATCH] MPC8xx PC...
1256
1257
1258
1259
  }
  
  module_init(m8xx_init);
  module_exit(m8xx_exit);