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