]> err.no Git - linux-2.6/blob - drivers/pcmcia/m32r_cfc.c
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[linux-2.6] / drivers / pcmcia / m32r_cfc.c
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 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         kio_addr_t              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)
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 */
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
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
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
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
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
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
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
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
301 static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr)
302 {
303         pcc_socket_t *t = &socket[pcc_sockets];
304
305         debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
306                  "mapaddr=%#lx, ioaddr=%08x\n",
307                  base, irq, mapaddr, ioaddr);
308
309         /* add sockets */
310         t->ioaddr = ioaddr;
311         t->mapaddr = mapaddr;
312 #if !defined(CONFIG_PLAT_USRV)
313         t->base = 0;
314         t->flags = 0;
315         t->cs_irq1 = irq;               // insert irq
316         t->cs_irq2 = irq + 1;           // eject irq
317 #else   /* CONFIG_PLAT_USRV */
318         t->base = base;
319         t->flags = 0;
320         t->cs_irq1 = 0;                 // insert irq
321         t->cs_irq2 = 0;                 // eject irq
322 #endif  /* CONFIG_PLAT_USRV */
323
324         if (is_alive(pcc_sockets))
325                 t->flags |= IS_ALIVE;
326
327         /* add pcc */
328 #if !defined(CONFIG_PLAT_USRV)
329         request_region((unsigned int)PLD_CFRSTCR, 0x20, "m32r_cfc");
330 #else   /* CONFIG_PLAT_USRV */
331         {
332                 unsigned int reg_base;
333
334                 reg_base = (unsigned int)PLD_CFRSTCR;
335                 reg_base |= pcc_sockets << 8;
336                 request_region(reg_base, 0x20, "m32r_cfc");
337         }
338 #endif  /* CONFIG_PLAT_USRV */
339         printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
340         printk("pcc at 0x%08lx\n", t->base);
341
342         /* Update socket interrupt information, capabilities */
343         t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
344         t->socket.map_size = M32R_PCC_MAPSIZE;
345         t->socket.io_offset = ioaddr;   /* use for io access offset */
346         t->socket.irq_mask = 0;
347 #if !defined(CONFIG_PLAT_USRV)
348         t->socket.pci_irq = PLD_IRQ_CFIREQ ;    /* card interrupt */
349 #else   /* CONFIG_PLAT_USRV */
350         t->socket.pci_irq = PLD_IRQ_CF0 + pcc_sockets;
351 #endif  /* CONFIG_PLAT_USRV */
352
353 #ifndef CONFIG_PLAT_USRV
354         /* insert interrupt */
355         request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
356 #ifndef CONFIG_PLAT_MAPPI3
357         /* eject interrupt */
358         request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
359 #endif
360         debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
361         pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
362 #endif  /* CONFIG_PLAT_USRV */
363 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
364         pcc_set(pcc_sockets, (unsigned int)PLD_CFCR1, 0x0200);
365 #endif
366         pcc_sockets++;
367
368         return;
369 }
370
371
372 /*====================================================================*/
373
374 static irqreturn_t pcc_interrupt(int irq, void *dev)
375 {
376         int i;
377         u_int events = 0;
378         int handled = 0;
379
380         debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
381         for (i = 0; i < pcc_sockets; i++) {
382                 if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
383                         continue;
384
385                 handled = 1;
386                 debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
387                         i, irq);
388                 events |= SS_DETECT;    /* insert or eject */
389                 if (events)
390                         pcmcia_parse_events(&socket[i].socket, events);
391         }
392         debug(3, "m32r_cfc: pcc_interrupt: done\n");
393
394         return IRQ_RETVAL(handled);
395 } /* pcc_interrupt */
396
397 static void pcc_interrupt_wrapper(u_long data)
398 {
399         debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
400         pcc_interrupt(0, NULL);
401         init_timer(&poll_timer);
402         poll_timer.expires = jiffies + poll_interval;
403         add_timer(&poll_timer);
404 }
405
406 /*====================================================================*/
407
408 static int _pcc_get_status(u_short sock, u_int *value)
409 {
410         u_int status;
411
412         debug(3, "m32r_cfc: _pcc_get_status:\n");
413         status = pcc_get(sock, (unsigned int)PLD_CFSTS);
414         *value = (status) ? SS_DETECT : 0;
415         debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
416
417 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
418         if ( status ) {
419                 /* enable CF power */
420                 status = inw((unsigned int)PLD_CPCR);
421                 if (!(status & PLD_CPCR_CF)) {
422                         debug(3, "m32r_cfc: _pcc_get_status: "
423                                  "power on (CPCR=0x%08x)\n", status);
424                         status |= PLD_CPCR_CF;
425                         outw(status, (unsigned int)PLD_CPCR);
426                         udelay(100);
427                 }
428                 *value |= SS_POWERON;
429
430                 pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);/* enable buffer */
431                 udelay(100);
432
433                 *value |= SS_READY;             /* always ready */
434                 *value |= SS_3VCARD;
435         } else {
436                 /* disable CF power */
437                 status = inw((unsigned int)PLD_CPCR);
438                 status &= ~PLD_CPCR_CF;
439                 outw(status, (unsigned int)PLD_CPCR);
440                 udelay(100);
441                 debug(3, "m32r_cfc: _pcc_get_status: "
442                          "power off (CPCR=0x%08x)\n", status);
443         }
444 #elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
445         if ( status ) {
446                 status = pcc_get(sock, (unsigned int)PLD_CPCR);
447                 if (status == 0) { /* power off */
448                         pcc_set(sock, (unsigned int)PLD_CPCR, 1);
449                         pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
450                         udelay(50);
451                 }
452                 *value |= SS_POWERON;
453
454                 pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
455                 udelay(50);
456                 pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
457                 udelay(25); /* for IDE reset */
458                 pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
459                 mdelay(2);  /* for IDE reset */
460
461                 *value |= SS_READY;
462                 *value |= SS_3VCARD;
463         } else {
464                 /* disable CF power */
465                 pcc_set(sock, (unsigned int)PLD_CPCR, 0);
466                 udelay(100);
467                 debug(3, "m32r_cfc: _pcc_get_status: "
468                          "power off (CPCR=0x%08x)\n", status);
469         }
470 #else
471 #error no platform configuration
472 #endif
473         debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
474                  sock, *value);
475         return 0;
476 } /* _get_status */
477
478 /*====================================================================*/
479
480 static int _pcc_set_socket(u_short sock, socket_state_t *state)
481 {
482         debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
483                   "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
484                   state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
485
486 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
487         if (state->Vcc) {
488                 if ((state->Vcc != 50) && (state->Vcc != 33))
489                         return -EINVAL;
490                 /* accept 5V and 3.3V */
491         }
492 #endif
493         if (state->flags & SS_RESET) {
494                 debug(3, ":RESET\n");
495                 pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
496         }else{
497                 pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
498         }
499         if (state->flags & SS_OUTPUT_ENA){
500                 debug(3, ":OUTPUT_ENA\n");
501                 /* bit clear */
502                 pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
503         } else {
504                 pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
505         }
506
507 #ifdef DEBUG
508         if(state->flags & SS_IOCARD){
509                 debug(3, ":IOCARD");
510         }
511         if (state->flags & SS_PWR_AUTO) {
512                 debug(3, ":PWR_AUTO");
513         }
514         if (state->csc_mask & SS_DETECT)
515                 debug(3, ":csc-SS_DETECT");
516         if (state->flags & SS_IOCARD) {
517                 if (state->csc_mask & SS_STSCHG)
518                         debug(3, ":STSCHG");
519         } else {
520                 if (state->csc_mask & SS_BATDEAD)
521                         debug(3, ":BATDEAD");
522                 if (state->csc_mask & SS_BATWARN)
523                         debug(3, ":BATWARN");
524                 if (state->csc_mask & SS_READY)
525                         debug(3, ":READY");
526         }
527         debug(3, "\n");
528 #endif
529         return 0;
530 } /* _set_socket */
531
532 /*====================================================================*/
533
534 static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
535 {
536         u_char map;
537
538         debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
539                   "%#lx-%#lx)\n", sock, io->map, io->flags,
540                   io->speed, io->start, io->stop);
541         map = io->map;
542
543         return 0;
544 } /* _set_io_map */
545
546 /*====================================================================*/
547
548 static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
549 {
550
551         u_char map = mem->map;
552         u_long addr;
553         pcc_socket_t *t = &socket[sock];
554
555         debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
556                  "%#lx, %#x)\n", sock, map, mem->flags,
557                  mem->speed, mem->static_start, mem->card_start);
558
559         /*
560          * sanity check
561          */
562         if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
563                 return -EINVAL;
564         }
565
566         /*
567          * de-activate
568          */
569         if ((mem->flags & MAP_ACTIVE) == 0) {
570                 t->current_space = as_none;
571                 return 0;
572         }
573
574         /*
575          * Set mode
576          */
577         if (mem->flags & MAP_ATTRIB) {
578                 t->current_space = as_attr;
579         } else {
580                 t->current_space = as_comm;
581         }
582
583         /*
584          * Set address
585          */
586         addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
587         mem->static_start = addr + mem->card_start;
588
589         return 0;
590
591 } /* _set_mem_map */
592
593 #if 0 /* driver model ordering issue */
594 /*======================================================================
595
596         Routines for accessing socket information and register dumps via
597         /proc/bus/pccard/...
598
599 ======================================================================*/
600
601 static ssize_t show_info(struct class_device *class_dev, char *buf)
602 {
603         pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
604                 socket.dev);
605
606         return sprintf(buf, "type:     %s\nbase addr:    0x%08lx\n",
607                 pcc[s->type].name, s->base);
608 }
609
610 static ssize_t show_exca(struct class_device *class_dev, char *buf)
611 {
612         /* FIXME */
613
614         return 0;
615 }
616
617 static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
618 static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
619 #endif
620
621 /*====================================================================*/
622
623 /* this is horribly ugly... proper locking needs to be done here at
624  * some time... */
625 #define LOCKED(x) do {                                  \
626         int retval;                                     \
627         unsigned long flags;                            \
628         spin_lock_irqsave(&pcc_lock, flags);            \
629         retval = x;                                     \
630         spin_unlock_irqrestore(&pcc_lock, flags);       \
631         return retval;                                  \
632 } while (0)
633
634
635 static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
636 {
637         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
638
639         if (socket[sock].flags & IS_ALIVE) {
640                 debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
641                 *value = 0;
642                 return -EINVAL;
643         }
644         debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
645         LOCKED(_pcc_get_status(sock, value));
646 }
647
648 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
649 {
650         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
651
652         if (socket[sock].flags & IS_ALIVE) {
653                 debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
654                 return -EINVAL;
655         }
656         debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
657         LOCKED(_pcc_set_socket(sock, state));
658 }
659
660 static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
661 {
662         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
663
664         if (socket[sock].flags & IS_ALIVE) {
665                 debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
666                 return -EINVAL;
667         }
668         debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
669         LOCKED(_pcc_set_io_map(sock, io));
670 }
671
672 static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
673 {
674         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
675
676         if (socket[sock].flags & IS_ALIVE) {
677                 debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
678                 return -EINVAL;
679         }
680         debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
681         LOCKED(_pcc_set_mem_map(sock, mem));
682 }
683
684 static int pcc_init(struct pcmcia_socket *s)
685 {
686         debug(3, "m32r_cfc: pcc_init()\n");
687         return 0;
688 }
689
690 static struct pccard_operations pcc_operations = {
691         .init                   = pcc_init,
692         .get_status             = pcc_get_status,
693         .set_socket             = pcc_set_socket,
694         .set_io_map             = pcc_set_io_map,
695         .set_mem_map            = pcc_set_mem_map,
696 };
697
698 /*====================================================================*/
699
700 static struct device_driver pcc_driver = {
701         .name = "cfc",
702         .bus = &platform_bus_type,
703         .suspend = pcmcia_socket_dev_suspend,
704         .resume = pcmcia_socket_dev_resume,
705 };
706
707 static struct platform_device pcc_device = {
708         .name = "cfc",
709         .id = 0,
710 };
711
712 /*====================================================================*/
713
714 static int __init init_m32r_pcc(void)
715 {
716         int i, ret;
717
718         ret = driver_register(&pcc_driver);
719         if (ret)
720                 return ret;
721
722         ret = platform_device_register(&pcc_device);
723         if (ret){
724                 driver_unregister(&pcc_driver);
725                 return ret;
726         }
727
728 #if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
729         pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
730         pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
731 #endif
732
733         pcc_sockets = 0;
734
735 #if !defined(CONFIG_PLAT_USRV)
736         add_pcc_socket(M32R_PCC0_BASE, PLD_IRQ_CFC_INSERT, CFC_ATTR_MAPBASE,
737                        CFC_IOPORT_BASE);
738 #else   /* CONFIG_PLAT_USRV */
739         {
740                 ulong base, mapaddr;
741                 kio_addr_t ioaddr;
742
743                 for (i = 0 ; i < M32R_MAX_PCC ; i++) {
744                         base = (ulong)PLD_CFRSTCR;
745                         base = base | (i << 8);
746                         ioaddr = (i + 1) << 12;
747                         mapaddr = CFC_ATTR_MAPBASE | (i << 20);
748                         add_pcc_socket(base, 0, mapaddr, ioaddr);
749                 }
750         }
751 #endif  /* CONFIG_PLAT_USRV */
752
753         if (pcc_sockets == 0) {
754                 printk("socket is not found.\n");
755                 platform_device_unregister(&pcc_device);
756                 driver_unregister(&pcc_driver);
757                 return -ENODEV;
758         }
759
760         /* Set up interrupt handler(s) */
761
762         for (i = 0 ; i < pcc_sockets ; i++) {
763                 socket[i].socket.dev.parent = &pcc_device.dev;
764                 socket[i].socket.ops = &pcc_operations;
765                 socket[i].socket.resource_ops = &pccard_nonstatic_ops;
766                 socket[i].socket.owner = THIS_MODULE;
767                 socket[i].number = i;
768                 ret = pcmcia_register_socket(&socket[i].socket);
769                 if (!ret)
770                         socket[i].flags |= IS_REGISTERED;
771
772 #if 0   /* driver model ordering issue */
773                 class_device_create_file(&socket[i].socket.dev,
774                                          &class_device_attr_info);
775                 class_device_create_file(&socket[i].socket.dev,
776                                          &class_device_attr_exca);
777 #endif
778         }
779
780         /* Finally, schedule a polling interrupt */
781         if (poll_interval != 0) {
782                 poll_timer.function = pcc_interrupt_wrapper;
783                 poll_timer.data = 0;
784                 init_timer(&poll_timer);
785                 poll_timer.expires = jiffies + poll_interval;
786                 add_timer(&poll_timer);
787         }
788
789         return 0;
790 } /* init_m32r_pcc */
791
792 static void __exit exit_m32r_pcc(void)
793 {
794         int i;
795
796         for (i = 0; i < pcc_sockets; i++)
797                 if (socket[i].flags & IS_REGISTERED)
798                         pcmcia_unregister_socket(&socket[i].socket);
799
800         platform_device_unregister(&pcc_device);
801         if (poll_interval != 0)
802                 del_timer_sync(&poll_timer);
803
804         driver_unregister(&pcc_driver);
805 } /* exit_m32r_pcc */
806
807 module_init(init_m32r_pcc);
808 module_exit(exit_m32r_pcc);
809 MODULE_LICENSE("Dual MPL/GPL");
810 /*====================================================================*/