• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  drivers/pcmcia/m32r_cfc.c
3  *
4  *  Device driver for the CFC functionality of M32R.
5  *
6  *  Copyright (c) 2001, 2002, 2003, 2004
7  *    Hiroyuki Kondo, Naoto Sugai, Hayato Fujiwara
8  */
9 
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/init.h>
13 #include <linux/types.h>
14 #include <linux/fcntl.h>
15 #include <linux/string.h>
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/timer.h>
19 #include <linux/slab.h>
20 #include <linux/ioport.h>
21 #include <linux/delay.h>
22 #include <linux/workqueue.h>
23 #include <linux/interrupt.h>
24 #include <linux/platform_device.h>
25 #include <linux/bitops.h>
26 #include <asm/irq.h>
27 #include <asm/io.h>
28 #include <asm/system.h>
29 
30 #include <pcmcia/cs_types.h>
31 #include <pcmcia/ss.h>
32 #include <pcmcia/cs.h>
33 
34 #undef MAX_IO_WIN	/* FIXME */
35 #define MAX_IO_WIN 1
36 #undef MAX_WIN		/* FIXME */
37 #define MAX_WIN 1
38 
39 #include "m32r_cfc.h"
40 
41 #ifdef CONFIG_PCMCIA_DEBUG
42 static int m32r_cfc_debug;
43 module_param(m32r_cfc_debug, int, 0644);
44 #define debug(lvl, fmt, arg...) do {				\
45 	if (m32r_cfc_debug > (lvl))				\
46 		printk(KERN_DEBUG "m32r_cfc: " fmt , ## arg);	\
47 } while (0)
48 #else
49 #define debug(n, args...) do { } while (0)
50 #endif
51 
52 /* Poll status interval -- 0 means default to interrupt */
53 static int poll_interval = 0;
54 
55 typedef enum pcc_space { as_none = 0, as_comm, as_attr, as_io } pcc_as_t;
56 
57 typedef struct pcc_socket {
58 	u_short			type, flags;
59 	struct pcmcia_socket	socket;
60 	unsigned int		number;
61 	unsigned int		ioaddr;
62 	u_long			mapaddr;
63 	u_long			base;	/* PCC register base */
64 	u_char			cs_irq1, cs_irq2, intr;
65 	pccard_io_map		io_map[MAX_IO_WIN];
66 	pccard_mem_map		mem_map[MAX_WIN];
67 	u_char			io_win;
68 	u_char			mem_win;
69 	pcc_as_t		current_space;
70 	u_char			last_iodbex;
71 #ifdef CONFIG_PROC_FS
72 	struct proc_dir_entry *proc;
73 #endif
74 } pcc_socket_t;
75 
76 static int pcc_sockets = 0;
77 static pcc_socket_t socket[M32R_MAX_PCC] = {
78 	{ 0, }, /* ... */
79 };
80 
81 /*====================================================================*/
82 
83 static unsigned int pcc_get(u_short, unsigned int);
84 static void pcc_set(u_short, unsigned int , unsigned int );
85 
86 static DEFINE_SPINLOCK(pcc_lock);
87 
88 #if !defined(CONFIG_PLAT_USRV)
pcc_port2addr(unsigned long port,int size)89 static inline u_long pcc_port2addr(unsigned long port, int size) {
90 	u_long addr = 0;
91 	u_long odd;
92 
93 	if (size == 1) {	/* byte access */
94 		odd = (port&1) << 11;
95 		port -= port & 1;
96 		addr = CFC_IO_MAPBASE_BYTE - CFC_IOPORT_BASE + odd + port;
97 	} else if (size == 2)
98 		addr = CFC_IO_MAPBASE_WORD - CFC_IOPORT_BASE + port;
99 
100 	return addr;
101 }
102 #else	/* CONFIG_PLAT_USRV */
pcc_port2addr(unsigned long port,int size)103 static inline u_long pcc_port2addr(unsigned long port, int size) {
104 	u_long odd;
105 	u_long addr = ((port - CFC_IOPORT_BASE) & 0xf000) << 8;
106 
107 	if (size == 1) {	/* byte access */
108 		odd = port & 1;
109 		port -= odd;
110 		odd <<= 11;
111 		addr = (addr | CFC_IO_MAPBASE_BYTE) + odd + (port & 0xfff);
112 	} else if (size == 2)	/* word access */
113 		addr = (addr | CFC_IO_MAPBASE_WORD) + (port & 0xfff);
114 
115 	return addr;
116 }
117 #endif	/* CONFIG_PLAT_USRV */
118 
pcc_ioread_byte(int sock,unsigned long port,void * buf,size_t size,size_t nmemb,int flag)119 void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
120 	size_t nmemb, int flag)
121 {
122 	u_long addr;
123 	unsigned char *bp = (unsigned char *)buf;
124 	unsigned long flags;
125 
126 	debug(3, "m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
127 		 "size=%u, nmemb=%d, flag=%d\n",
128 		  sock, port, buf, size, nmemb, flag);
129 
130 	addr = pcc_port2addr(port, 1);
131 	if (!addr) {
132 		printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
133 		return;
134 	}
135 	debug(3, "m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
136 
137 	spin_lock_irqsave(&pcc_lock, flags);
138 	/* read Byte */
139 	while (nmemb--)
140 		*bp++ = readb(addr);
141 	spin_unlock_irqrestore(&pcc_lock, flags);
142 }
143 
pcc_ioread_word(int sock,unsigned long port,void * buf,size_t size,size_t nmemb,int flag)144 void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
145 	size_t nmemb, int flag)
146 {
147 	u_long addr;
148 	unsigned short *bp = (unsigned short *)buf;
149 	unsigned long flags;
150 
151 	debug(3, "m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
152 		 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
153 		 sock, port, buf, size, nmemb, flag);
154 
155 	if (size != 2)
156 		printk("m32r_cfc: ioread_word :illigal size %u : %#lx\n", size,
157 			port);
158 	if (size == 9)
159 		printk("m32r_cfc: ioread_word :insw \n");
160 
161 	addr = pcc_port2addr(port, 2);
162 	if (!addr) {
163 		printk("m32r_cfc:ioread_word null port :%#lx\n",port);
164 		return;
165 	}
166 	debug(3, "m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
167 
168 	spin_lock_irqsave(&pcc_lock, flags);
169 	/* read Word */
170 	while (nmemb--)
171 		*bp++ = readw(addr);
172 	spin_unlock_irqrestore(&pcc_lock, flags);
173 }
174 
pcc_iowrite_byte(int sock,unsigned long port,void * buf,size_t size,size_t nmemb,int flag)175 void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
176 	size_t nmemb, int flag)
177 {
178 	u_long addr;
179 	unsigned char *bp = (unsigned char *)buf;
180 	unsigned long flags;
181 
182 	debug(3, "m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
183 		 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
184 		 sock, port, buf, size, nmemb, flag);
185 
186 	/* write Byte */
187 	addr = pcc_port2addr(port, 1);
188 	if (!addr) {
189 		printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
190 		return;
191 	}
192 	debug(3, "m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
193 
194 	spin_lock_irqsave(&pcc_lock, flags);
195 	while (nmemb--)
196 		writeb(*bp++, addr);
197 	spin_unlock_irqrestore(&pcc_lock, flags);
198 }
199 
pcc_iowrite_word(int sock,unsigned long port,void * buf,size_t size,size_t nmemb,int flag)200 void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
201 	size_t nmemb, int flag)
202 {
203 	u_long addr;
204 	unsigned short *bp = (unsigned short *)buf;
205 	unsigned long flags;
206 
207 	debug(3, "m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
208 		 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
209 		 sock, port, buf, size, nmemb, flag);
210 
211 	if(size != 2)
212 		printk("m32r_cfc: iowrite_word :illigal size %u : %#lx\n",
213 			size, port);
214 	if(size == 9)
215 		printk("m32r_cfc: iowrite_word :outsw \n");
216 
217 	addr = pcc_port2addr(port, 2);
218 	if (!addr) {
219 		printk("m32r_cfc:iowrite_word null addr :%#lx\n",port);
220 		return;
221 	}
222 #if 1
223 	if (addr & 1) {
224 		printk("m32r_cfc:iowrite_word port addr (%#lx):%#lx\n", port,
225 			addr);
226 		return;
227 	}
228 #endif
229 	debug(3, "m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
230 
231 	spin_lock_irqsave(&pcc_lock, flags);
232 	while (nmemb--)
233 		writew(*bp++, addr);
234 	spin_unlock_irqrestore(&pcc_lock, flags);
235 }
236 
237 /*====================================================================*/
238 
239 #define IS_REGISTERED		0x2000
240 #define IS_ALIVE		0x8000
241 
242 typedef struct pcc_t {
243 	char			*name;
244 	u_short			flags;
245 } pcc_t;
246 
247 static pcc_t pcc[] = {
248 #if !defined(CONFIG_PLAT_USRV)
249 	{ "m32r_cfc", 0 }, { "", 0 },
250 #else	/* CONFIG_PLAT_USRV */
251 	{ "m32r_cfc", 0 }, { "m32r_cfc", 0 }, { "m32r_cfc", 0 },
252 	{ "m32r_cfc", 0 }, { "m32r_cfc", 0 }, { "", 0 },
253 #endif	/* CONFIG_PLAT_USRV */
254 };
255 
256 static irqreturn_t pcc_interrupt(int, void *);
257 
258 /*====================================================================*/
259 
260 static struct timer_list poll_timer;
261 
pcc_get(u_short sock,unsigned int reg)262 static unsigned int pcc_get(u_short sock, unsigned int reg)
263 {
264 	unsigned int val = inw(reg);
265 	debug(3, "m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
266 	return val;
267 }
268 
269 
pcc_set(u_short sock,unsigned int reg,unsigned int data)270 static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
271 {
272 	outw(data, reg);
273 	debug(3, "m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
274 }
275 
276 /*======================================================================
277 
278 	See if a card is present, powered up, in IO mode, and already
279 	bound to a (non PC Card) Linux driver.  We leave these alone.
280 
281 	We make an exception for cards that seem to be serial devices.
282 
283 ======================================================================*/
284 
is_alive(u_short sock)285 static int __init is_alive(u_short sock)
286 {
287 	unsigned int stat;
288 
289 	debug(3, "m32r_cfc: is_alive:\n");
290 
291 	printk("CF: ");
292 	stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
293 	if (!stat)
294 		printk("No ");
295 	printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
296 	debug(3, "m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
297 
298 	return 0;
299 }
300 
add_pcc_socket(ulong base,int irq,ulong mapaddr,unsigned int ioaddr)301 static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
302 			   unsigned int ioaddr)
303 {
304 	pcc_socket_t *t = &socket[pcc_sockets];
305 
306 	debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
307 		 "mapaddr=%#lx, ioaddr=%08x\n",
308 		 base, irq, mapaddr, ioaddr);
309 
310 	/* add sockets */
311 	t->ioaddr = ioaddr;
312 	t->mapaddr = mapaddr;
313 #if !defined(CONFIG_PLAT_USRV)
314 	t->base = 0;
315 	t->flags = 0;
316 	t->cs_irq1 = irq;		// insert irq
317 	t->cs_irq2 = irq + 1;		// eject irq
318 #else	/* CONFIG_PLAT_USRV */
319 	t->base = base;
320 	t->flags = 0;
321 	t->cs_irq1 = 0;			// insert irq
322 	t->cs_irq2 = 0;			// eject irq
323 #endif	/* CONFIG_PLAT_USRV */
324 
325 	if (is_alive(pcc_sockets))
326 		t->flags |= IS_ALIVE;
327 
328 	/* add pcc */
329 #if !defined(CONFIG_PLAT_USRV)
330 	request_region((unsigned int)PLD_CFRSTCR, 0x20, "m32r_cfc");
331 #else	/* CONFIG_PLAT_USRV */
332 	{
333 		unsigned int reg_base;
334 
335 		reg_base = (unsigned int)PLD_CFRSTCR;
336 		reg_base |= pcc_sockets << 8;
337 		request_region(reg_base, 0x20, "m32r_cfc");
338 	}
339 #endif	/* CONFIG_PLAT_USRV */
340 	printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
341 	printk("pcc at 0x%08lx\n", t->base);
342 
343 	/* Update socket interrupt information, capabilities */
344 	t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
345 	t->socket.map_size = M32R_PCC_MAPSIZE;
346 	t->socket.io_offset = ioaddr;	/* use for io access offset */
347 	t->socket.irq_mask = 0;
348 #if !defined(CONFIG_PLAT_USRV)
349 	t->socket.pci_irq = PLD_IRQ_CFIREQ ;	/* card interrupt */
350 #else	/* CONFIG_PLAT_USRV */
351 	t->socket.pci_irq = PLD_IRQ_CF0 + pcc_sockets;
352 #endif	/* CONFIG_PLAT_USRV */
353 
354 #ifndef CONFIG_PLAT_USRV
355 	/* insert interrupt */
356 	request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
357 #ifndef CONFIG_PLAT_MAPPI3
358 	/* eject interrupt */
359 	request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
360 #endif
361 	debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
362 	pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
363 #endif	/* CONFIG_PLAT_USRV */
364 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
365 	pcc_set(pcc_sockets, (unsigned int)PLD_CFCR1, 0x0200);
366 #endif
367 	pcc_sockets++;
368 
369 	return;
370 }
371 
372 
373 /*====================================================================*/
374 
pcc_interrupt(int irq,void * dev)375 static irqreturn_t pcc_interrupt(int irq, void *dev)
376 {
377 	int i;
378 	u_int events = 0;
379 	int handled = 0;
380 
381 	debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
382 	for (i = 0; i < pcc_sockets; i++) {
383 		if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
384 			continue;
385 
386 		handled = 1;
387 		debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
388 			i, irq);
389 		events |= SS_DETECT;	/* insert or eject */
390 		if (events)
391 			pcmcia_parse_events(&socket[i].socket, events);
392 	}
393 	debug(3, "m32r_cfc: pcc_interrupt: done\n");
394 
395 	return IRQ_RETVAL(handled);
396 } /* pcc_interrupt */
397 
pcc_interrupt_wrapper(u_long data)398 static void pcc_interrupt_wrapper(u_long data)
399 {
400 	debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
401 	pcc_interrupt(0, NULL);
402 	init_timer(&poll_timer);
403 	poll_timer.expires = jiffies + poll_interval;
404 	add_timer(&poll_timer);
405 }
406 
407 /*====================================================================*/
408 
_pcc_get_status(u_short sock,u_int * value)409 static int _pcc_get_status(u_short sock, u_int *value)
410 {
411 	u_int status;
412 
413 	debug(3, "m32r_cfc: _pcc_get_status:\n");
414 	status = pcc_get(sock, (unsigned int)PLD_CFSTS);
415 	*value = (status) ? SS_DETECT : 0;
416  	debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
417 
418 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
419 	if ( status ) {
420 		/* enable CF power */
421 		status = inw((unsigned int)PLD_CPCR);
422 		if (!(status & PLD_CPCR_CF)) {
423 			debug(3, "m32r_cfc: _pcc_get_status: "
424 				 "power on (CPCR=0x%08x)\n", status);
425 			status |= PLD_CPCR_CF;
426 			outw(status, (unsigned int)PLD_CPCR);
427 			udelay(100);
428 		}
429 		*value |= SS_POWERON;
430 
431 		pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);/* enable buffer */
432 		udelay(100);
433 
434 		*value |= SS_READY; 		/* always ready */
435 		*value |= SS_3VCARD;
436 	} else {
437 		/* disable CF power */
438 		status = inw((unsigned int)PLD_CPCR);
439 		status &= ~PLD_CPCR_CF;
440 		outw(status, (unsigned int)PLD_CPCR);
441 		udelay(100);
442 		debug(3, "m32r_cfc: _pcc_get_status: "
443 			 "power off (CPCR=0x%08x)\n", status);
444 	}
445 #elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
446 	if ( status ) {
447 		status = pcc_get(sock, (unsigned int)PLD_CPCR);
448 		if (status == 0) { /* power off */
449 			pcc_set(sock, (unsigned int)PLD_CPCR, 1);
450 			pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
451 			udelay(50);
452 		}
453 		*value |= SS_POWERON;
454 
455 		pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
456 		udelay(50);
457 		pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
458 		udelay(25); /* for IDE reset */
459 		pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
460 		mdelay(2);  /* for IDE reset */
461 
462 		*value |= SS_READY;
463 		*value |= SS_3VCARD;
464 	} else {
465 		/* disable CF power */
466 	        pcc_set(sock, (unsigned int)PLD_CPCR, 0);
467 		udelay(100);
468 		debug(3, "m32r_cfc: _pcc_get_status: "
469 			 "power off (CPCR=0x%08x)\n", status);
470 	}
471 #else
472 #error no platform configuration
473 #endif
474 	debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
475 		 sock, *value);
476 	return 0;
477 } /* _get_status */
478 
479 /*====================================================================*/
480 
_pcc_set_socket(u_short sock,socket_state_t * state)481 static int _pcc_set_socket(u_short sock, socket_state_t *state)
482 {
483 	debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
484 		  "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
485 		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
486 
487 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
488 	if (state->Vcc) {
489 		if ((state->Vcc != 50) && (state->Vcc != 33))
490 			return -EINVAL;
491 		/* accept 5V and 3.3V */
492 	}
493 #endif
494 	if (state->flags & SS_RESET) {
495 		debug(3, ":RESET\n");
496 		pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
497 	}else{
498 		pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
499 	}
500 	if (state->flags & SS_OUTPUT_ENA){
501 		debug(3, ":OUTPUT_ENA\n");
502 		/* bit clear */
503 		pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
504 	} else {
505 		pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
506 	}
507 
508 #ifdef CONFIG_PCMCIA_DEBUG
509 	if(state->flags & SS_IOCARD){
510 		debug(3, ":IOCARD");
511 	}
512 	if (state->flags & SS_PWR_AUTO) {
513 		debug(3, ":PWR_AUTO");
514 	}
515 	if (state->csc_mask & SS_DETECT)
516 		debug(3, ":csc-SS_DETECT");
517 	if (state->flags & SS_IOCARD) {
518 		if (state->csc_mask & SS_STSCHG)
519 			debug(3, ":STSCHG");
520 	} else {
521 		if (state->csc_mask & SS_BATDEAD)
522 			debug(3, ":BATDEAD");
523 		if (state->csc_mask & SS_BATWARN)
524 			debug(3, ":BATWARN");
525 		if (state->csc_mask & SS_READY)
526 			debug(3, ":READY");
527 	}
528 	debug(3, "\n");
529 #endif
530 	return 0;
531 } /* _set_socket */
532 
533 /*====================================================================*/
534 
_pcc_set_io_map(u_short sock,struct pccard_io_map * io)535 static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
536 {
537 	u_char map;
538 
539 	debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
540 		  "%#lx-%#lx)\n", sock, io->map, io->flags,
541 		  io->speed, io->start, io->stop);
542 	map = io->map;
543 
544 	return 0;
545 } /* _set_io_map */
546 
547 /*====================================================================*/
548 
_pcc_set_mem_map(u_short sock,struct pccard_mem_map * mem)549 static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
550 {
551 
552 	u_char map = mem->map;
553 	u_long addr;
554 	pcc_socket_t *t = &socket[sock];
555 
556 	debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
557 		 "%#lx, %#x)\n", sock, map, mem->flags,
558 		 mem->speed, mem->static_start, mem->card_start);
559 
560 	/*
561 	 * sanity check
562 	 */
563 	if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
564 		return -EINVAL;
565 	}
566 
567 	/*
568 	 * de-activate
569 	 */
570 	if ((mem->flags & MAP_ACTIVE) == 0) {
571 		t->current_space = as_none;
572 		return 0;
573 	}
574 
575 	/*
576 	 * Set mode
577 	 */
578 	if (mem->flags & MAP_ATTRIB) {
579 		t->current_space = as_attr;
580 	} else {
581 		t->current_space = as_comm;
582 	}
583 
584 	/*
585 	 * Set address
586 	 */
587 	addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
588 	mem->static_start = addr + mem->card_start;
589 
590 	return 0;
591 
592 } /* _set_mem_map */
593 
594 #if 0 /* driver model ordering issue */
595 /*======================================================================
596 
597 	Routines for accessing socket information and register dumps via
598 	/proc/bus/pccard/...
599 
600 ======================================================================*/
601 
602 static ssize_t show_info(struct class_device *class_dev, char *buf)
603 {
604 	pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
605 		socket.dev);
606 
607 	return sprintf(buf, "type:     %s\nbase addr:    0x%08lx\n",
608 		pcc[s->type].name, s->base);
609 }
610 
611 static ssize_t show_exca(struct class_device *class_dev, char *buf)
612 {
613 	/* FIXME */
614 
615 	return 0;
616 }
617 
618 static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
619 static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
620 #endif
621 
622 /*====================================================================*/
623 
624 /* this is horribly ugly... proper locking needs to be done here at
625  * some time... */
626 #define LOCKED(x) do {					\
627 	int retval;					\
628 	unsigned long flags;				\
629 	spin_lock_irqsave(&pcc_lock, flags);		\
630 	retval = x;					\
631 	spin_unlock_irqrestore(&pcc_lock, flags);	\
632 	return retval;					\
633 } while (0)
634 
635 
pcc_get_status(struct pcmcia_socket * s,u_int * value)636 static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
637 {
638 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
639 
640 	if (socket[sock].flags & IS_ALIVE) {
641 		debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
642 		*value = 0;
643 		return -EINVAL;
644 	}
645 	debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
646 	LOCKED(_pcc_get_status(sock, value));
647 }
648 
pcc_set_socket(struct pcmcia_socket * s,socket_state_t * state)649 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
650 {
651 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
652 
653 	if (socket[sock].flags & IS_ALIVE) {
654 		debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
655 		return -EINVAL;
656 	}
657 	debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
658 	LOCKED(_pcc_set_socket(sock, state));
659 }
660 
pcc_set_io_map(struct pcmcia_socket * s,struct pccard_io_map * io)661 static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
662 {
663 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
664 
665 	if (socket[sock].flags & IS_ALIVE) {
666 		debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
667 		return -EINVAL;
668 	}
669 	debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
670 	LOCKED(_pcc_set_io_map(sock, io));
671 }
672 
pcc_set_mem_map(struct pcmcia_socket * s,struct pccard_mem_map * mem)673 static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
674 {
675 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
676 
677 	if (socket[sock].flags & IS_ALIVE) {
678 		debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
679 		return -EINVAL;
680 	}
681 	debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
682 	LOCKED(_pcc_set_mem_map(sock, mem));
683 }
684 
pcc_init(struct pcmcia_socket * s)685 static int pcc_init(struct pcmcia_socket *s)
686 {
687 	debug(3, "m32r_cfc: pcc_init()\n");
688 	return 0;
689 }
690 
691 static struct pccard_operations pcc_operations = {
692 	.init			= pcc_init,
693 	.get_status		= pcc_get_status,
694 	.set_socket		= pcc_set_socket,
695 	.set_io_map		= pcc_set_io_map,
696 	.set_mem_map		= pcc_set_mem_map,
697 };
698 
699 /*====================================================================*/
700 
701 static struct device_driver pcc_driver = {
702 	.name = "cfc",
703 	.bus = &platform_bus_type,
704 	.suspend = pcmcia_socket_dev_suspend,
705 	.resume = pcmcia_socket_dev_resume,
706 };
707 
708 static struct platform_device pcc_device = {
709 	.name = "cfc",
710 	.id = 0,
711 };
712 
713 /*====================================================================*/
714 
init_m32r_pcc(void)715 static int __init init_m32r_pcc(void)
716 {
717 	int i, ret;
718 
719 	ret = driver_register(&pcc_driver);
720 	if (ret)
721 		return ret;
722 
723 	ret = platform_device_register(&pcc_device);
724 	if (ret){
725 		driver_unregister(&pcc_driver);
726 		return ret;
727 	}
728 
729 #if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
730 	pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
731 	pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
732 #endif
733 
734 	pcc_sockets = 0;
735 
736 #if !defined(CONFIG_PLAT_USRV)
737 	add_pcc_socket(M32R_PCC0_BASE, PLD_IRQ_CFC_INSERT, CFC_ATTR_MAPBASE,
738 		       CFC_IOPORT_BASE);
739 #else	/* CONFIG_PLAT_USRV */
740 	{
741 		ulong base, mapaddr;
742 		unsigned int ioaddr;
743 
744 		for (i = 0 ; i < M32R_MAX_PCC ; i++) {
745 			base = (ulong)PLD_CFRSTCR;
746 			base = base | (i << 8);
747 			ioaddr = (i + 1) << 12;
748 			mapaddr = CFC_ATTR_MAPBASE | (i << 20);
749 			add_pcc_socket(base, 0, mapaddr, ioaddr);
750 		}
751 	}
752 #endif	/* CONFIG_PLAT_USRV */
753 
754 	if (pcc_sockets == 0) {
755 		printk("socket is not found.\n");
756 		platform_device_unregister(&pcc_device);
757 		driver_unregister(&pcc_driver);
758 		return -ENODEV;
759 	}
760 
761 	/* Set up interrupt handler(s) */
762 
763 	for (i = 0 ; i < pcc_sockets ; i++) {
764 		socket[i].socket.dev.parent = &pcc_device.dev;
765 		socket[i].socket.ops = &pcc_operations;
766 		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
767 		socket[i].socket.owner = THIS_MODULE;
768 		socket[i].number = i;
769 		ret = pcmcia_register_socket(&socket[i].socket);
770 		if (!ret)
771 			socket[i].flags |= IS_REGISTERED;
772 
773 #if 0	/* driver model ordering issue */
774 		class_device_create_file(&socket[i].socket.dev,
775 					 &class_device_attr_info);
776 		class_device_create_file(&socket[i].socket.dev,
777 					 &class_device_attr_exca);
778 #endif
779 	}
780 
781 	/* Finally, schedule a polling interrupt */
782 	if (poll_interval != 0) {
783 		poll_timer.function = pcc_interrupt_wrapper;
784 		poll_timer.data = 0;
785 		init_timer(&poll_timer);
786 		poll_timer.expires = jiffies + poll_interval;
787 		add_timer(&poll_timer);
788 	}
789 
790 	return 0;
791 } /* init_m32r_pcc */
792 
exit_m32r_pcc(void)793 static void __exit exit_m32r_pcc(void)
794 {
795 	int i;
796 
797 	for (i = 0; i < pcc_sockets; i++)
798 		if (socket[i].flags & IS_REGISTERED)
799 			pcmcia_unregister_socket(&socket[i].socket);
800 
801 	platform_device_unregister(&pcc_device);
802 	if (poll_interval != 0)
803 		del_timer_sync(&poll_timer);
804 
805 	driver_unregister(&pcc_driver);
806 } /* exit_m32r_pcc */
807 
808 module_init(init_m32r_pcc);
809 module_exit(exit_m32r_pcc);
810 MODULE_LICENSE("Dual MPL/GPL");
811 /*====================================================================*/
812