blob: 3b40f9623cc9bb2c1bda5ea4d8f8c4d98ad50b47 [file] [log] [blame]
Marcelo Tosattide957c82005-10-28 17:46:13 -07001/*
2 * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
3 *
4 * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
5 * (C) 2001-2002 Montavista Software, Inc.
6 * <mlocke@mvista.com>
7 *
8 * Support for two slots by Cyclades Corporation
9 * <oliver.kurth@cyclades.de>
10 * Further fixes, v2.6 kernel port
11 * <marcelo.tosatti@cyclades.com>
Vitaly Bordug1371d3b2005-12-08 13:56:12 -020012 *
Vitaly Bordug80128ff2007-07-09 11:37:35 -070013 * Some fixes, additions (C) 2005-2007 Montavista Software, Inc.
Vitaly Bordug1371d3b2005-12-08 13:56:12 -020014 * <vbordug@ru.mvista.com>
Marcelo Tosattide957c82005-10-28 17:46:13 -070015 *
16 * "The ExCA standard specifies that socket controllers should provide
17 * two IO and five memory windows per socket, which can be independently
18 * configured and positioned in the host address space and mapped to
19 * arbitrary segments of card address space. " - David A Hinds. 1999
20 *
21 * This controller does _not_ meet the ExCA standard.
22 *
23 * m8xx pcmcia controller brief info:
24 * + 8 windows (attrib, mem, i/o)
25 * + up to two slots (SLOT_A and SLOT_B)
26 * + inputpins, outputpins, event and mask registers.
27 * - no offset register. sigh.
28 *
29 * Because of the lacking offset register we must map the whole card.
30 * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
31 * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO
32 * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
33 * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
34 * They are maximum 64KByte each...
35 */
36
37#include <linux/module.h>
38#include <linux/init.h>
39#include <linux/types.h>
40#include <linux/fcntl.h>
41#include <linux/string.h>
42
Marcelo Tosattide957c82005-10-28 17:46:13 -070043#include <linux/kernel.h>
44#include <linux/errno.h>
Marcelo Tosattide957c82005-10-28 17:46:13 -070045#include <linux/slab.h>
46#include <linux/timer.h>
47#include <linux/ioport.h>
48#include <linux/delay.h>
49#include <linux/interrupt.h>
Vitaly Bordug80128ff2007-07-09 11:37:35 -070050#include <linux/fsl_devices.h>
Marcelo Tosattide957c82005-10-28 17:46:13 -070051
Vitaly Bordug80128ff2007-07-09 11:37:35 -070052#include <asm/io.h>
53#include <asm/bitops.h>
54#include <asm/system.h>
55#include <asm/time.h>
Marcelo Tosattide957c82005-10-28 17:46:13 -070056#include <asm/mpc8xx.h>
57#include <asm/8xx_immap.h>
58#include <asm/irq.h>
Vitaly Bordug80128ff2007-07-09 11:37:35 -070059#include <asm/fs_pd.h>
60#include <asm/of_device.h>
61#include <asm/of_platform.h>
Marcelo Tosattide957c82005-10-28 17:46:13 -070062
63#include <pcmcia/version.h>
64#include <pcmcia/cs_types.h>
65#include <pcmcia/cs.h>
66#include <pcmcia/ss.h>
67
68#ifdef PCMCIA_DEBUG
69static int pc_debug = PCMCIA_DEBUG;
70module_param(pc_debug, int, 0);
71#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
72#else
73#define dprintk(args...)
74#endif
75
76#define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
77#define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
78
79static const char *version = "Version 0.06, Aug 2005";
80MODULE_LICENSE("Dual MPL/GPL");
81
82#if !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B)
83
84/* The RPX series use SLOT_B */
85#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
86#define CONFIG_PCMCIA_SLOT_B
87#define CONFIG_BD_IS_MHZ
88#endif
89
90/* The ADS board use SLOT_A */
91#ifdef CONFIG_ADS
92#define CONFIG_PCMCIA_SLOT_A
93#define CONFIG_BD_IS_MHZ
94#endif
95
96/* The FADS series are a mess */
97#ifdef CONFIG_FADS
98#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC860) || defined(CONFIG_MPC821)
99#define CONFIG_PCMCIA_SLOT_A
100#else
101#define CONFIG_PCMCIA_SLOT_B
102#endif
103#endif
104
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200105#if defined(CONFIG_MPC885ADS)
106#define CONFIG_PCMCIA_SLOT_A
107#define PCMCIA_GLITCHY_CD
108#endif
109
Marcelo Tosattide957c82005-10-28 17:46:13 -0700110/* Cyclades ACS uses both slots */
111#ifdef CONFIG_PRxK
112#define CONFIG_PCMCIA_SLOT_A
113#define CONFIG_PCMCIA_SLOT_B
114#endif
115
116#endif /* !defined(CONFIG_PCMCIA_SLOT_A) && !defined(CONFIG_PCMCIA_SLOT_B) */
117
118#if defined(CONFIG_PCMCIA_SLOT_A) && defined(CONFIG_PCMCIA_SLOT_B)
119
120#define PCMCIA_SOCKETS_NO 2
121/* We have only 8 windows, dualsocket support will be limited. */
122#define PCMCIA_MEM_WIN_NO 2
123#define PCMCIA_IO_WIN_NO 2
124#define PCMCIA_SLOT_MSG "SLOT_A and SLOT_B"
125
126#elif defined(CONFIG_PCMCIA_SLOT_A) || defined(CONFIG_PCMCIA_SLOT_B)
127
128#define PCMCIA_SOCKETS_NO 1
129/* full support for one slot */
130#define PCMCIA_MEM_WIN_NO 5
131#define PCMCIA_IO_WIN_NO 2
132
133/* define _slot_ to be able to optimize macros */
134
135#ifdef CONFIG_PCMCIA_SLOT_A
136#define _slot_ 0
137#define PCMCIA_SLOT_MSG "SLOT_A"
138#else
139#define _slot_ 1
140#define PCMCIA_SLOT_MSG "SLOT_B"
141#endif
142
143#else
144#error m8xx_pcmcia: Bad configuration!
145#endif
146
147/* ------------------------------------------------------------------------- */
148
149#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0 */
150#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte */
151#define PCMCIA_IO_WIN_BASE _IO_BASE /* base address for io window 0 */
Marcelo Tosattide957c82005-10-28 17:46:13 -0700152/* ------------------------------------------------------------------------- */
153
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700154static int pcmcia_schlvl;
Marcelo Tosattide957c82005-10-28 17:46:13 -0700155
Ingo Molnar34af9462006-06-27 02:53:55 -0700156static DEFINE_SPINLOCK(events_lock);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700157
Marcelo Tosattide957c82005-10-28 17:46:13 -0700158#define PCMCIA_SOCKET_KEY_5V 1
159#define PCMCIA_SOCKET_KEY_LV 2
160
161/* look up table for pgcrx registers */
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700162static u32 *m8xx_pgcrx[2];
Marcelo Tosattide957c82005-10-28 17:46:13 -0700163
164/*
165 * This structure is used to address each window in the PCMCIA controller.
166 *
167 * Keep in mind that we assume that pcmcia_win[n+1] is mapped directly
168 * after pcmcia_win[n]...
169 */
170
171struct pcmcia_win {
172 u32 br;
173 u32 or;
174};
175
176/*
177 * For some reason the hardware guys decided to make both slots share
178 * some registers.
179 *
180 * Could someone invent object oriented hardware ?
181 *
182 * The macros are used to get the right bit from the registers.
183 * SLOT_A : slot = 0
184 * SLOT_B : slot = 1
185 */
186
187#define M8XX_PCMCIA_VS1(slot) (0x80000000 >> (slot << 4))
188#define M8XX_PCMCIA_VS2(slot) (0x40000000 >> (slot << 4))
189#define M8XX_PCMCIA_VS_MASK(slot) (0xc0000000 >> (slot << 4))
190#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
191
192#define M8XX_PCMCIA_WP(slot) (0x20000000 >> (slot << 4))
193#define M8XX_PCMCIA_CD2(slot) (0x10000000 >> (slot << 4))
194#define M8XX_PCMCIA_CD1(slot) (0x08000000 >> (slot << 4))
195#define M8XX_PCMCIA_BVD2(slot) (0x04000000 >> (slot << 4))
196#define M8XX_PCMCIA_BVD1(slot) (0x02000000 >> (slot << 4))
197#define M8XX_PCMCIA_RDY(slot) (0x01000000 >> (slot << 4))
198#define M8XX_PCMCIA_RDY_L(slot) (0x00800000 >> (slot << 4))
199#define M8XX_PCMCIA_RDY_H(slot) (0x00400000 >> (slot << 4))
200#define M8XX_PCMCIA_RDY_R(slot) (0x00200000 >> (slot << 4))
201#define M8XX_PCMCIA_RDY_F(slot) (0x00100000 >> (slot << 4))
202#define M8XX_PCMCIA_MASK(slot) (0xFFFF0000 >> (slot << 4))
203
204#define M8XX_PCMCIA_POR_VALID 0x00000001
205#define M8XX_PCMCIA_POR_WRPROT 0x00000002
206#define M8XX_PCMCIA_POR_ATTRMEM 0x00000010
207#define M8XX_PCMCIA_POR_IO 0x00000018
208#define M8XX_PCMCIA_POR_16BIT 0x00000040
209
210#define M8XX_PGCRX(slot) m8xx_pgcrx[slot]
211
212#define M8XX_PGCRX_CXOE 0x00000080
213#define M8XX_PGCRX_CXRESET 0x00000040
214
215/* we keep one lookup table per socket to check flags */
216
217#define PCMCIA_EVENTS_MAX 5 /* 4 max at a time + termination */
218
219struct event_table {
220 u32 regbit;
221 u32 eventbit;
222};
223
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700224static const char driver_name[] = "m8xx-pcmcia";
225
Marcelo Tosattide957c82005-10-28 17:46:13 -0700226struct socket_info {
227 void (*handler)(void *info, u32 events);
228 void *info;
229
230 u32 slot;
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700231 pcmconf8xx_t *pcmcia;
232 u32 bus_freq;
233 int hwirq;
Marcelo Tosattide957c82005-10-28 17:46:13 -0700234
235 socket_state_t state;
236 struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
237 struct pccard_io_map io_win[PCMCIA_IO_WIN_NO];
238 struct event_table events[PCMCIA_EVENTS_MAX];
239 struct pcmcia_socket socket;
240};
241
242static struct socket_info socket[PCMCIA_SOCKETS_NO];
243
244/*
245 * Search this table to see if the windowsize is
246 * supported...
247 */
248
249#define M8XX_SIZES_NO 32
250
251static const u32 m8xx_size_to_gray[M8XX_SIZES_NO] =
252{
253 0x00000001, 0x00000002, 0x00000008, 0x00000004,
254 0x00000080, 0x00000040, 0x00000010, 0x00000020,
255 0x00008000, 0x00004000, 0x00001000, 0x00002000,
256 0x00000100, 0x00000200, 0x00000800, 0x00000400,
257
258 0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
259 0x01000000, 0x02000000, 0xffffffff, 0x04000000,
260 0x00010000, 0x00020000, 0x00080000, 0x00040000,
261 0x00800000, 0x00400000, 0x00100000, 0x00200000
262};
263
264/* ------------------------------------------------------------------------- */
265
David Howells7d12e782006-10-05 14:55:46 +0100266static irqreturn_t m8xx_interrupt(int irq, void *dev);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700267
268#define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */
269
270/* ------------------------------------------------------------------------- */
271/* board specific stuff: */
272/* voltage_set(), hardware_enable() and hardware_disable() */
273/* ------------------------------------------------------------------------- */
274/* RPX Boards from Embedded Planet */
275
276#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
277
278/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
279 * SYPCR is write once only, therefore must the slowest memory be faster
280 * than the bus monitor or we will get a machine check due to the bus timeout.
281 */
282
283#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
284
285#undef PCMCIA_BMT_LIMIT
286#define PCMCIA_BMT_LIMIT (6*8)
287
288static int voltage_set(int slot, int vcc, int vpp)
289{
290 u32 reg = 0;
291
292 switch(vcc) {
293 case 0: break;
294 case 33:
295 reg |= BCSR1_PCVCTL4;
296 break;
297 case 50:
298 reg |= BCSR1_PCVCTL5;
299 break;
300 default:
301 return 1;
302 }
303
304 switch(vpp) {
305 case 0: break;
306 case 33:
307 case 50:
308 if(vcc == vpp)
309 reg |= BCSR1_PCVCTL6;
310 else
311 return 1;
312 break;
313 case 120:
314 reg |= BCSR1_PCVCTL7;
315 default:
316 return 1;
317 }
318
319 if(!((vcc == 50) || (vcc == 0)))
320 return 1;
321
322 /* first, turn off all power */
323
324 out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7));
325
326 /* enable new powersettings */
327
328 out_be32(((u32 *)RPX_CSR_ADDR), in_be32(((u32 *)RPX_CSR_ADDR)) | reg);
329
330 return 0;
331}
332
333#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
334#define hardware_enable(_slot_) /* No hardware to enable */
335#define hardware_disable(_slot_) /* No hardware to disable */
336
337#endif /* CONFIG_RPXCLASSIC */
338
339/* FADS Boards from Motorola */
340
341#if defined(CONFIG_FADS)
342
343#define PCMCIA_BOARD_MSG "FADS"
344
345static int voltage_set(int slot, int vcc, int vpp)
346{
347 u32 reg = 0;
348
349 switch(vcc) {
350 case 0:
351 break;
352 case 33:
353 reg |= BCSR1_PCCVCC0;
354 break;
355 case 50:
356 reg |= BCSR1_PCCVCC1;
357 break;
358 default:
359 return 1;
360 }
361
362 switch(vpp) {
363 case 0:
364 break;
365 case 33:
366 case 50:
367 if(vcc == vpp)
368 reg |= BCSR1_PCCVPP1;
369 else
370 return 1;
371 break;
372 case 120:
373 if ((vcc == 33) || (vcc == 50))
374 reg |= BCSR1_PCCVPP0;
375 else
376 return 1;
377 default:
378 return 1;
379 }
380
381 /* first, turn off all power */
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200382 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
Marcelo Tosattide957c82005-10-28 17:46:13 -0700383
384 /* enable new powersettings */
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200385 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700386
387 return 0;
388}
389
390#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
391
392static void hardware_enable(int slot)
393{
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200394 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700395}
396
397static void hardware_disable(int slot)
398{
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200399 out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | BCSR1_PCCEN);
400}
401
402#endif
403
404/* MPC885ADS Boards */
405
406#if defined(CONFIG_MPC885ADS)
407
408#define PCMCIA_BOARD_MSG "MPC885ADS"
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200409#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
410
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700411static inline void hardware_enable(int slot)
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200412{
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700413 m8xx_pcmcia_ops.hw_ctrl(slot, 1);
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200414}
415
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700416static inline void hardware_disable(int slot)
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200417{
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700418 m8xx_pcmcia_ops.hw_ctrl(slot, 0);
419}
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200420
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700421static inline int voltage_set(int slot, int vcc, int vpp)
422{
423 return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700424}
425
426#endif
427
428/* ------------------------------------------------------------------------- */
429/* Motorola MBX860 */
430
431#if defined(CONFIG_MBX)
432
433#define PCMCIA_BOARD_MSG "MBX"
434
435static int voltage_set(int slot, int vcc, int vpp)
436{
437 u8 reg = 0;
438
439 switch(vcc) {
440 case 0:
441 break;
442 case 33:
443 reg |= CSR2_VCC_33;
444 break;
445 case 50:
446 reg |= CSR2_VCC_50;
447 break;
448 default:
449 return 1;
450 }
451
452 switch(vpp) {
453 case 0:
454 break;
455 case 33:
456 case 50:
457 if(vcc == vpp)
458 reg |= CSR2_VPP_VCC;
459 else
460 return 1;
461 break;
462 case 120:
463 if ((vcc == 33) || (vcc == 50))
464 reg |= CSR2_VPP_12;
465 else
466 return 1;
467 default:
468 return 1;
469 }
470
471 /* first, turn off all power */
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200472 out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
Marcelo Tosattide957c82005-10-28 17:46:13 -0700473
474 /* enable new powersettings */
Vitaly Bordug1371d3b2005-12-08 13:56:12 -0200475 out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700476
477 return 0;
478}
479
480#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
481#define hardware_enable(_slot_) /* No hardware to enable */
482#define hardware_disable(_slot_) /* No hardware to disable */
483
484#endif /* CONFIG_MBX */
485
486#if defined(CONFIG_PRxK)
487#include <asm/cpld.h>
488extern volatile fpga_pc_regs *fpga_pc;
489
490#define PCMCIA_BOARD_MSG "MPC855T"
491
492static int voltage_set(int slot, int vcc, int vpp)
493{
494 u8 reg = 0;
495 u8 regread;
496 cpld_regs *ccpld = get_cpld();
497
498 switch(vcc) {
499 case 0:
500 break;
501 case 33:
502 reg |= PCMCIA_VCC_33;
503 break;
504 case 50:
505 reg |= PCMCIA_VCC_50;
506 break;
507 default:
508 return 1;
509 }
510
511 switch(vpp) {
512 case 0:
513 break;
514 case 33:
515 case 50:
516 if(vcc == vpp)
517 reg |= PCMCIA_VPP_VCC;
518 else
519 return 1;
520 break;
521 case 120:
522 if ((vcc == 33) || (vcc == 50))
523 reg |= PCMCIA_VPP_12;
524 else
525 return 1;
526 default:
527 return 1;
528 }
529
530 reg = reg >> (slot << 2);
531 regread = in_8(&ccpld->fpga_pc_ctl);
532 if (reg != (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) {
533 /* enable new powersettings */
534 regread = regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2));
535 out_8(&ccpld->fpga_pc_ctl, reg | regread);
536 msleep(100);
537 }
538
539 return 0;
540}
541
542#define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV
543#define hardware_enable(_slot_) /* No hardware to enable */
544#define hardware_disable(_slot_) /* No hardware to disable */
545
546#endif /* CONFIG_PRxK */
547
Marcelo Tosattide957c82005-10-28 17:46:13 -0700548static u32 pending_events[PCMCIA_SOCKETS_NO];
Ingo Molnar34af9462006-06-27 02:53:55 -0700549static DEFINE_SPINLOCK(pending_event_lock);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700550
David Howells7d12e782006-10-05 14:55:46 +0100551static irqreturn_t m8xx_interrupt(int irq, void *dev)
Marcelo Tosattide957c82005-10-28 17:46:13 -0700552{
553 struct socket_info *s;
554 struct event_table *e;
555 unsigned int i, events, pscr, pipr, per;
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700556 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
Marcelo Tosattide957c82005-10-28 17:46:13 -0700557
558 dprintk("Interrupt!\n");
559 /* get interrupt sources */
560
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700561 pscr = in_be32(&pcmcia->pcmc_pscr);
562 pipr = in_be32(&pcmcia->pcmc_pipr);
563 per = in_be32(&pcmcia->pcmc_per);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700564
565 for(i = 0; i < PCMCIA_SOCKETS_NO; i++) {
566 s = &socket[i];
567 e = &s->events[0];
568 events = 0;
569
570 while(e->regbit) {
571 if(pscr & e->regbit)
572 events |= e->eventbit;
573
574 e++;
575 }
576
577 /*
578 * report only if both card detect signals are the same
579 * not too nice done,
580 * we depend on that CD2 is the bit to the left of CD1...
581 */
582 if(events & SS_DETECT)
583 if(((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^
584 (pipr & M8XX_PCMCIA_CD1(i)))
585 {
586 events &= ~SS_DETECT;
587 }
588
589#ifdef PCMCIA_GLITCHY_CD
590 /*
591 * I've experienced CD problems with my ADS board.
592 * We make an extra check to see if there was a
593 * real change of Card detection.
594 */
595
596 if((events & SS_DETECT) &&
597 ((pipr &
598 (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) &&
599 (s->state.Vcc | s->state.Vpp)) {
600 events &= ~SS_DETECT;
601 /*printk( "CD glitch workaround - CD = 0x%08x!\n",
602 (pipr & (M8XX_PCMCIA_CD2(i)
603 | M8XX_PCMCIA_CD1(i))));*/
604 }
605#endif
606
607 /* call the handler */
608
609 dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
610 "pipr = 0x%08x\n",
611 i, events, pscr, pipr);
612
613 if(events) {
614 spin_lock(&pending_event_lock);
615 pending_events[i] |= events;
616 spin_unlock(&pending_event_lock);
617 /*
618 * Turn off RDY_L bits in the PER mask on
619 * CD interrupt receival.
620 *
621 * They can generate bad interrupts on the
622 * ACS4,8,16,32. - marcelo
623 */
624 per &= ~M8XX_PCMCIA_RDY_L(0);
625 per &= ~M8XX_PCMCIA_RDY_L(1);
626
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700627 out_be32(&pcmcia->pcmc_per, per);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700628
629 if (events)
630 pcmcia_parse_events(&socket[i].socket, events);
631 }
632 }
633
634 /* clear the interrupt sources */
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700635 out_be32(&pcmcia->pcmc_pscr, pscr);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700636
637 dprintk("Interrupt done.\n");
638
639 return IRQ_HANDLED;
640}
641
642static u32 m8xx_get_graycode(u32 size)
643{
644 u32 k;
645
646 for(k = 0; k < M8XX_SIZES_NO; k++)
647 if(m8xx_size_to_gray[k] == size)
648 break;
649
650 if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
651 k = -1;
652
653 return k;
654}
655
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700656static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq)
Marcelo Tosattide957c82005-10-28 17:46:13 -0700657{
658 u32 reg, clocks, psst, psl, psht;
659
660 if(!ns) {
661
662 /*
663 * We get called with IO maps setup to 0ns
664 * if not specified by the user.
665 * They should be 255ns.
666 */
667
668 if(is_io)
669 ns = 255;
670 else
671 ns = 100; /* fast memory if 0 */
672 }
673
674 /*
675 * In PSST, PSL, PSHT fields we tell the controller
676 * timing parameters in CLKOUT clock cycles.
677 * CLKOUT is the same as GCLK2_50.
678 */
679
680/* how we want to adjust the timing - in percent */
681
682#define ADJ 180 /* 80 % longer accesstime - to be sure */
683
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700684 clocks = ((bus_freq / 1000) * ns) / 1000;
Marcelo Tosattide957c82005-10-28 17:46:13 -0700685 clocks = (clocks * ADJ) / (100*1000);
686 if(clocks >= PCMCIA_BMT_LIMIT) {
687 printk( "Max access time limit reached\n");
688 clocks = PCMCIA_BMT_LIMIT-1;
689 }
690
691 psst = clocks / 7; /* setup time */
692 psht = clocks / 7; /* hold time */
693 psl = (clocks * 5) / 7; /* strobe length */
694
695 psst += clocks - (psst + psht + psl);
696
697 reg = psst << 12;
698 reg |= psl << 7;
699 reg |= psht << 16;
700
701 return reg;
702}
703
704static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
705{
706 int lsock = container_of(sock, struct socket_info, socket)->slot;
707 struct socket_info *s = &socket[lsock];
708 unsigned int pipr, reg;
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700709 pcmconf8xx_t *pcmcia = s->pcmcia;
Marcelo Tosattide957c82005-10-28 17:46:13 -0700710
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700711 pipr = in_be32(&pcmcia->pcmc_pipr);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700712
713 *value = ((pipr & (M8XX_PCMCIA_CD1(lsock)
714 | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0;
715 *value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0;
716
717 if (s->state.flags & SS_IOCARD)
718 *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0;
719 else {
720 *value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0;
721 *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0;
722 *value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0;
723 }
724
725 if (s->state.Vcc | s->state.Vpp)
726 *value |= SS_POWERON;
727
728 /*
729 * Voltage detection:
730 * This driver only supports 16-Bit pc-cards.
731 * Cardbus is not handled here.
732 *
733 * To determine what voltage to use we must read the VS1 and VS2 pin.
734 * Depending on what socket type is present,
735 * different combinations mean different things.
736 *
737 * Card Key Socket Key VS1 VS2 Card Vcc for CIS parse
738 *
739 * 5V 5V, LV* NC NC 5V only 5V (if available)
740 *
741 * 5V 5V, LV* GND NC 5 or 3.3V as low as possible
742 *
743 * 5V 5V, LV* GND GND 5, 3.3, x.xV as low as possible
744 *
745 * LV* 5V - - shall not fit into socket
746 *
747 * LV* LV* GND NC 3.3V only 3.3V
748 *
749 * LV* LV* NC GND x.xV x.xV (if avail.)
750 *
751 * LV* LV* GND GND 3.3 or x.xV as low as possible
752 *
753 * *LV means Low Voltage
754 *
755 *
756 * That gives us the following table:
757 *
758 * Socket VS1 VS2 Voltage
759 *
760 * 5V NC NC 5V
761 * 5V NC GND none (should not be possible)
762 * 5V GND NC >= 3.3V
763 * 5V GND GND >= x.xV
764 *
765 * LV NC NC 5V (if available)
766 * LV NC GND x.xV (if available)
767 * LV GND NC 3.3V
768 * LV GND GND >= x.xV
769 *
770 * So, how do I determine if I have a 5V or a LV
771 * socket on my board? Look at the socket!
772 *
773 *
774 * Socket with 5V key:
775 * ++--------------------------------------------+
776 * || |
777 * || ||
778 * || ||
779 * | |
780 * +---------------------------------------------+
781 *
782 * Socket with LV key:
783 * ++--------------------------------------------+
784 * || |
785 * | ||
786 * | ||
787 * | |
788 * +---------------------------------------------+
789 *
790 *
791 * With other words - LV only cards does not fit
792 * into the 5V socket!
793 */
794
795 /* read out VS1 and VS2 */
796
797 reg = (pipr & M8XX_PCMCIA_VS_MASK(lsock))
798 >> M8XX_PCMCIA_VS_SHIFT(lsock);
799
800 if(socket_get(lsock) == PCMCIA_SOCKET_KEY_LV) {
801 switch(reg) {
802 case 1:
803 *value |= SS_3VCARD;
804 break; /* GND, NC - 3.3V only */
805 case 2:
806 *value |= SS_XVCARD;
807 break; /* NC. GND - x.xV only */
808 };
809 }
810
811 dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
812 return 0;
813}
814
Marcelo Tosattide957c82005-10-28 17:46:13 -0700815static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
816{
817 int lsock = container_of(sock, struct socket_info, socket)->slot;
818 struct socket_info *s = &socket[lsock];
819 struct event_table *e;
820 unsigned int reg;
821 unsigned long flags;
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700822 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
Marcelo Tosattide957c82005-10-28 17:46:13 -0700823
824 dprintk( "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
825 "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
826 state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
827
828 /* First, set voltage - bail out if invalid */
829 if(voltage_set(lsock, state->Vcc, state->Vpp))
830 return -EINVAL;
831
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700832
Marcelo Tosattide957c82005-10-28 17:46:13 -0700833 /* Take care of reset... */
834 if(state->flags & SS_RESET)
835 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXRESET); /* active high */
836 else
837 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXRESET);
838
839 /* ... and output enable. */
840
841 /* The CxOE signal is connected to a 74541 on the ADS.
842 I guess most other boards used the ADS as a reference.
843 I tried to control the CxOE signal with SS_OUTPUT_ENA,
844 but the reset signal seems connected via the 541.
845 If the CxOE is left high are some signals tristated and
846 no pullups are present -> the cards act wierd.
847 So right now the buffers are enabled if the power is on. */
848
849 if(state->Vcc || state->Vpp)
850 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & ~M8XX_PGCRX_CXOE); /* active low */
851 else
852 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) | M8XX_PGCRX_CXOE);
853
854 /*
855 * We'd better turn off interrupts before
856 * we mess with the events-table..
857 */
858
859 spin_lock_irqsave(&events_lock, flags);
860
861 /*
862 * Play around with the interrupt mask to be able to
863 * give the events the generic pcmcia driver wants us to.
864 */
865
866 e = &s->events[0];
867 reg = 0;
868
869 if(state->csc_mask & SS_DETECT) {
870 e->eventbit = SS_DETECT;
871 reg |= e->regbit = (M8XX_PCMCIA_CD2(lsock)
872 | M8XX_PCMCIA_CD1(lsock));
873 e++;
874 }
875 if(state->flags & SS_IOCARD) {
876 /*
877 * I/O card
878 */
879 if(state->csc_mask & SS_STSCHG) {
880 e->eventbit = SS_STSCHG;
881 reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
882 e++;
883 }
884 /*
885 * If io_irq is non-zero we should enable irq.
886 */
887 if(state->io_irq) {
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700888 out_be32(M8XX_PGCRX(lsock),
889 in_be32(M8XX_PGCRX(lsock)) | mk_int_int_mask(s->hwirq) << 24);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700890 /*
891 * Strange thing here:
892 * The manual does not tell us which interrupt
893 * the sources generate.
894 * Anyhow, I found out that RDY_L generates IREQLVL.
895 *
896 * We use level triggerd interrupts, and they don't
897 * have to be cleared in PSCR in the interrupt handler.
898 */
899 reg |= M8XX_PCMCIA_RDY_L(lsock);
900 }
901 else
902 out_be32(M8XX_PGCRX(lsock), in_be32(M8XX_PGCRX(lsock)) & 0x00ffffff);
903 }
904 else {
905 /*
906 * Memory card
907 */
908 if(state->csc_mask & SS_BATDEAD) {
909 e->eventbit = SS_BATDEAD;
910 reg |= e->regbit = M8XX_PCMCIA_BVD1(lsock);
911 e++;
912 }
913 if(state->csc_mask & SS_BATWARN) {
914 e->eventbit = SS_BATWARN;
915 reg |= e->regbit = M8XX_PCMCIA_BVD2(lsock);
916 e++;
917 }
918 /* What should I trigger on - low/high,raise,fall? */
919 if(state->csc_mask & SS_READY) {
920 e->eventbit = SS_READY;
921 reg |= e->regbit = 0; //??
922 e++;
923 }
924 }
925
926 e->regbit = 0; /* terminate list */
927
928 /*
929 * Clear the status changed .
930 * Port A and Port B share the same port.
931 * Writing ones will clear the bits.
932 */
933
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700934 out_be32(&pcmcia->pcmc_pscr, reg);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700935
936 /*
937 * Write the mask.
938 * Port A and Port B share the same port.
939 * Need for read-modify-write.
940 * Ones will enable the interrupt.
941 */
942
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700943 reg |= in_be32(&pcmcia->pcmc_per) & (M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
944 out_be32(&pcmcia->pcmc_per, reg);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700945
946 spin_unlock_irqrestore(&events_lock, flags);
947
948 /* copy the struct and modify the copy */
949
950 s->state = *state;
951
952 return 0;
953}
954
955static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
956{
957 int lsock = container_of(sock, struct socket_info, socket)->slot;
958
959 struct socket_info *s = &socket[lsock];
960 struct pcmcia_win *w;
961 unsigned int reg, winnr;
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700962 pcmconf8xx_t *pcmcia = s->pcmcia;
963
Marcelo Tosattide957c82005-10-28 17:46:13 -0700964
965#define M8XX_SIZE (io->stop - io->start + 1)
966#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
967
968 dprintk( "SetIOMap(%d, %d, %#2.2x, %d ns, "
969 "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
970 io->speed, io->start, io->stop);
971
972 if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff)
973 || (io->stop > 0xffff) || (io->stop < io->start))
974 return -EINVAL;
975
976 if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
977 return -EINVAL;
978
979 if(io->flags & MAP_ACTIVE) {
980
981 dprintk( "io->flags & MAP_ACTIVE\n");
982
983 winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
984 + (lsock * PCMCIA_IO_WIN_NO) + io->map;
985
986 /* setup registers */
987
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700988 w = (void *) &pcmcia->pcmc_pbr0;
Marcelo Tosattide957c82005-10-28 17:46:13 -0700989 w += winnr;
990
991 out_be32(&w->or, 0); /* turn off window first */
992 out_be32(&w->br, M8XX_BASE);
993
994 reg <<= 27;
995 reg |= M8XX_PCMCIA_POR_IO |(lsock << 2);
996
Vitaly Bordug80128ff2007-07-09 11:37:35 -0700997 reg |= m8xx_get_speed(io->speed, 1, s->bus_freq);
Marcelo Tosattide957c82005-10-28 17:46:13 -0700998
999 if(io->flags & MAP_WRPROT)
1000 reg |= M8XX_PCMCIA_POR_WRPROT;
1001
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001002 /*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
1003 if(io->flags & MAP_16BIT)
Marcelo Tosattide957c82005-10-28 17:46:13 -07001004 reg |= M8XX_PCMCIA_POR_16BIT;
1005
1006 if(io->flags & MAP_ACTIVE)
1007 reg |= M8XX_PCMCIA_POR_VALID;
1008
1009 out_be32(&w->or, reg);
1010
1011 dprintk("Socket %u: Mapped io window %u at %#8.8x, "
1012 "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
1013 } else {
1014 /* shutdown IO window */
1015 winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
1016 + (lsock * PCMCIA_IO_WIN_NO) + io->map;
1017
1018 /* setup registers */
1019
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001020 w = (void *) &pcmcia->pcmc_pbr0;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001021 w += winnr;
1022
1023 out_be32(&w->or, 0); /* turn off window */
1024 out_be32(&w->br, 0); /* turn off base address */
1025
1026 dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
1027 "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
1028 }
1029
1030 /* copy the struct and modify the copy */
1031 s->io_win[io->map] = *io;
1032 s->io_win[io->map].flags &= (MAP_WRPROT
1033 | MAP_16BIT
1034 | MAP_ACTIVE);
1035 dprintk("SetIOMap exit\n");
1036
1037 return 0;
1038}
1039
1040static int m8xx_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
1041{
1042 int lsock = container_of(sock, struct socket_info, socket)->slot;
1043 struct socket_info *s = &socket[lsock];
1044 struct pcmcia_win *w;
1045 struct pccard_mem_map *old;
1046 unsigned int reg, winnr;
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001047 pcmconf8xx_t *pcmcia = s->pcmcia;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001048
1049 dprintk( "SetMemMap(%d, %d, %#2.2x, %d ns, "
1050 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1051 mem->speed, mem->static_start, mem->card_start);
1052
1053 if ((mem->map >= PCMCIA_MEM_WIN_NO)
1054// || ((mem->s) >= PCMCIA_MEM_WIN_SIZE)
1055 || (mem->card_start >= 0x04000000)
1056 || (mem->static_start & 0xfff) /* 4KByte resolution */
1057 || (mem->card_start & 0xfff))
1058 return -EINVAL;
1059
1060 if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
1061 printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
1062 return -EINVAL;
1063 }
1064 reg <<= 27;
1065
1066 winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
1067
1068 /* Setup the window in the pcmcia controller */
1069
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001070 w = (void *) &pcmcia->pcmc_pbr0;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001071 w += winnr;
1072
1073 reg |= lsock << 2;
1074
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001075 reg |= m8xx_get_speed(mem->speed, 0, s->bus_freq);
Marcelo Tosattide957c82005-10-28 17:46:13 -07001076
1077 if(mem->flags & MAP_ATTRIB)
1078 reg |= M8XX_PCMCIA_POR_ATTRMEM;
1079
1080 if(mem->flags & MAP_WRPROT)
1081 reg |= M8XX_PCMCIA_POR_WRPROT;
1082
1083 if(mem->flags & MAP_16BIT)
1084 reg |= M8XX_PCMCIA_POR_16BIT;
1085
1086 if(mem->flags & MAP_ACTIVE)
1087 reg |= M8XX_PCMCIA_POR_VALID;
1088
1089 out_be32(&w->or, reg);
1090
1091 dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
1092 "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
1093
1094 if(mem->flags & MAP_ACTIVE) {
1095 /* get the new base address */
1096 mem->static_start = PCMCIA_MEM_WIN_BASE +
1097 (PCMCIA_MEM_WIN_SIZE * winnr)
1098 + mem->card_start;
1099 }
1100
1101 dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
1102 "%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
1103 mem->speed, mem->static_start, mem->card_start);
1104
1105 /* copy the struct and modify the copy */
1106
1107 old = &s->mem_win[mem->map];
1108
1109 *old = *mem;
1110 old->flags &= (MAP_ATTRIB
1111 | MAP_WRPROT
1112 | MAP_16BIT
1113 | MAP_ACTIVE);
1114
1115 return 0;
1116}
1117
1118static int m8xx_sock_init(struct pcmcia_socket *sock)
1119{
1120 int i;
1121 pccard_io_map io = { 0, 0, 0, 0, 1 };
1122 pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
1123
1124 dprintk( "sock_init(%d)\n", s);
1125
1126 m8xx_set_socket(sock, &dead_socket);
1127 for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
1128 io.map = i;
1129 m8xx_set_io_map(sock, &io);
1130 }
1131 for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
1132 mem.map = i;
1133 m8xx_set_mem_map(sock, &mem);
1134 }
1135
1136 return 0;
1137
1138}
1139
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001140static int m8xx_sock_suspend(struct pcmcia_socket *sock)
Marcelo Tosattide957c82005-10-28 17:46:13 -07001141{
1142 return m8xx_set_socket(sock, &dead_socket);
1143}
1144
1145static struct pccard_operations m8xx_services = {
1146 .init = m8xx_sock_init,
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001147 .suspend = m8xx_sock_suspend,
Marcelo Tosattide957c82005-10-28 17:46:13 -07001148 .get_status = m8xx_get_status,
Marcelo Tosattide957c82005-10-28 17:46:13 -07001149 .set_socket = m8xx_set_socket,
1150 .set_io_map = m8xx_set_io_map,
1151 .set_mem_map = m8xx_set_mem_map,
1152};
1153
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001154static int __init m8xx_probe(struct of_device *ofdev, const struct of_device_id *match)
Marcelo Tosattide957c82005-10-28 17:46:13 -07001155{
1156 struct pcmcia_win *w;
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001157 unsigned int i, m, hwirq;
1158 pcmconf8xx_t *pcmcia;
1159 int status;
1160 struct device_node *np = ofdev->node;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001161
1162 pcmcia_info("%s\n", version);
1163
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001164 pcmcia = of_iomap(np, 0);
1165 if(pcmcia == NULL)
1166 return -EINVAL;
1167
1168 pcmcia_schlvl = irq_of_parse_and_map(np, 0);
1169 hwirq = irq_map[pcmcia_schlvl].hwirq;
1170 if (pcmcia_schlvl < 0)
1171 return -EINVAL;
1172
1173 m8xx_pgcrx[0] = &pcmcia->pcmc_pgcra;
1174 m8xx_pgcrx[1] = &pcmcia->pcmc_pgcrb;
1175
Marcelo Tosattide957c82005-10-28 17:46:13 -07001176
1177 pcmcia_info(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001178 " with IRQ %u (%d). \n", pcmcia_schlvl, hwirq);
Marcelo Tosattide957c82005-10-28 17:46:13 -07001179
1180 /* Configure Status change interrupt */
1181
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001182 if(request_irq(pcmcia_schlvl, m8xx_interrupt, IRQF_SHARED,
1183 driver_name, socket)) {
Marcelo Tosattide957c82005-10-28 17:46:13 -07001184 pcmcia_error("Cannot allocate IRQ %u for SCHLVL!\n",
1185 pcmcia_schlvl);
1186 return -1;
1187 }
1188
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001189 w = (void *) &pcmcia->pcmc_pbr0;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001190
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001191 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(0)| M8XX_PCMCIA_MASK(1));
1192 clrbits32(&pcmcia->pcmc_per, M8XX_PCMCIA_MASK(0) | M8XX_PCMCIA_MASK(1));
Marcelo Tosattide957c82005-10-28 17:46:13 -07001193
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001194 /* connect interrupt and disable CxOE */
Marcelo Tosattide957c82005-10-28 17:46:13 -07001195
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001196 out_be32(M8XX_PGCRX(0), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
1197 out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16));
Marcelo Tosattide957c82005-10-28 17:46:13 -07001198
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001199 /* intialize the fixed memory windows */
Marcelo Tosattide957c82005-10-28 17:46:13 -07001200
1201 for(i = 0; i < PCMCIA_SOCKETS_NO; i++){
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001202 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
Marcelo Tosattide957c82005-10-28 17:46:13 -07001203 out_be32(&w->br, PCMCIA_MEM_WIN_BASE +
1204 (PCMCIA_MEM_WIN_SIZE
1205 * (m + i * PCMCIA_MEM_WIN_NO)));
1206
1207 out_be32(&w->or, 0); /* set to not valid */
1208
1209 w++;
1210 }
1211 }
1212
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001213 /* turn off voltage */
Marcelo Tosattide957c82005-10-28 17:46:13 -07001214 voltage_set(0, 0, 0);
1215 voltage_set(1, 0, 0);
1216
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001217 /* Enable external hardware */
Marcelo Tosattide957c82005-10-28 17:46:13 -07001218 hardware_enable(0);
1219 hardware_enable(1);
1220
Marcelo Tosattide957c82005-10-28 17:46:13 -07001221 for (i = 0 ; i < PCMCIA_SOCKETS_NO; i++) {
1222 socket[i].slot = i;
1223 socket[i].socket.owner = THIS_MODULE;
1224 socket[i].socket.features = SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP;
1225 socket[i].socket.irq_mask = 0x000;
1226 socket[i].socket.map_size = 0x1000;
1227 socket[i].socket.io_offset = 0;
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001228 socket[i].socket.pci_irq = pcmcia_schlvl;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001229 socket[i].socket.ops = &m8xx_services;
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001230 socket[i].socket.resource_ops = &pccard_nonstatic_ops;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001231 socket[i].socket.cb_dev = NULL;
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001232 socket[i].socket.dev.parent = &ofdev->dev;
1233 socket[i].pcmcia = pcmcia;
1234 socket[i].bus_freq = ppc_proc_freq;
1235 socket[i].hwirq = hwirq;
1236
1237
Marcelo Tosattide957c82005-10-28 17:46:13 -07001238 }
1239
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001240 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1241 status = pcmcia_register_socket(&socket[i].socket);
1242 if (status < 0)
1243 pcmcia_error("Socket register failed\n");
1244 }
Marcelo Tosattide957c82005-10-28 17:46:13 -07001245
1246 return 0;
1247}
1248
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001249static int m8xx_remove(struct of_device* ofdev)
Marcelo Tosattide957c82005-10-28 17:46:13 -07001250{
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001251 u32 m, i;
1252 struct pcmcia_win *w;
1253 pcmconf8xx_t *pcmcia = socket[0].pcmcia;
Marcelo Tosattide957c82005-10-28 17:46:13 -07001254
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001255 for (i = 0; i < PCMCIA_SOCKETS_NO; i++) {
1256 w = (void *) &pcmcia->pcmc_pbr0;
1257
1258 out_be32(&pcmcia->pcmc_pscr, M8XX_PCMCIA_MASK(i));
1259 out_be32(&pcmcia->pcmc_per,
1260 in_be32(&pcmcia->pcmc_per) & ~M8XX_PCMCIA_MASK(i));
1261
1262 /* turn off interrupt and disable CxOE */
1263 out_be32(M8XX_PGCRX(i), M8XX_PGCRX_CXOE);
1264
1265 /* turn off memory windows */
1266 for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
1267 out_be32(&w->or, 0); /* set to not valid */
1268 w++;
1269 }
1270
1271 /* turn off voltage */
1272 voltage_set(i, 0, 0);
1273
1274 /* disable external hardware */
1275 hardware_disable(i);
1276 }
Marcelo Tosattide957c82005-10-28 17:46:13 -07001277 for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
1278 pcmcia_unregister_socket(&socket[i].socket);
1279
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001280 free_irq(pcmcia_schlvl, NULL);
Marcelo Tosattide957c82005-10-28 17:46:13 -07001281
Vitaly Bordug80128ff2007-07-09 11:37:35 -07001282 return 0;
1283}
1284
1285#ifdef CONFIG_PM
1286static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
1287{
1288 return pcmcia_socket_dev_suspend(&pdev->dev, state);
1289}
1290
1291static int m8xx_resume(struct platform_device *pdev)
1292{
1293 return pcmcia_socket_dev_resume(&pdev->dev);
1294}
1295#else
1296#define m8xx_suspend NULL
1297#define m8xx_resume NULL
1298#endif
1299
1300static struct of_device_id m8xx_pcmcia_match[] = {
1301 {
1302 .type = "pcmcia",
1303 .compatible = "fsl,pq-pcmcia",
1304 },
1305 {},
1306};
1307
1308MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
1309
1310static struct of_platform_driver m8xx_pcmcia_driver = {
1311 .name = (char *) driver_name,
1312 .match_table = m8xx_pcmcia_match,
1313 .probe = m8xx_probe,
1314 .remove = m8xx_remove,
1315 .suspend = m8xx_suspend,
1316 .resume = m8xx_resume,
1317};
1318
1319static int __init m8xx_init(void)
1320{
1321 return of_register_platform_driver(&m8xx_pcmcia_driver);
1322}
1323
1324static void __exit m8xx_exit(void)
1325{
1326 of_unregister_platform_driver(&m8xx_pcmcia_driver);
Marcelo Tosattide957c82005-10-28 17:46:13 -07001327}
1328
1329module_init(m8xx_init);
1330module_exit(m8xx_exit);