]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/pcmcia/m32r_cfc.c
Merge branch 'dts-fixes' into omap-for-v4.15/fixes-dt
[linux.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(struct timer_list *unused)
384 {
385         pr_debug("m32r_cfc: pcc_interrupt_wrapper:\n");
386         pcc_interrupt(0, NULL);
387         poll_timer.expires = jiffies + poll_interval;
388         add_timer(&poll_timer);
389 }
390
391 /*====================================================================*/
392
393 static int _pcc_get_status(u_short sock, u_int *value)
394 {
395         u_int status;
396
397         pr_debug("m32r_cfc: _pcc_get_status:\n");
398         status = pcc_get(sock, (unsigned int)PLD_CFSTS);
399         *value = (status) ? SS_DETECT : 0;
400         pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
401
402 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
403         if ( status ) {
404                 /* enable CF power */
405                 status = inw((unsigned int)PLD_CPCR);
406                 if (!(status & PLD_CPCR_CF)) {
407                         pr_debug("m32r_cfc: _pcc_get_status: "
408                                  "power on (CPCR=0x%08x)\n", status);
409                         status |= PLD_CPCR_CF;
410                         outw(status, (unsigned int)PLD_CPCR);
411                         udelay(100);
412                 }
413                 *value |= SS_POWERON;
414
415                 pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);/* enable buffer */
416                 udelay(100);
417
418                 *value |= SS_READY;             /* always ready */
419                 *value |= SS_3VCARD;
420         } else {
421                 /* disable CF power */
422                 status = inw((unsigned int)PLD_CPCR);
423                 status &= ~PLD_CPCR_CF;
424                 outw(status, (unsigned int)PLD_CPCR);
425                 udelay(100);
426                 pr_debug("m32r_cfc: _pcc_get_status: "
427                          "power off (CPCR=0x%08x)\n", status);
428         }
429 #elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
430         if ( status ) {
431                 status = pcc_get(sock, (unsigned int)PLD_CPCR);
432                 if (status == 0) { /* power off */
433                         pcc_set(sock, (unsigned int)PLD_CPCR, 1);
434                         pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
435                         udelay(50);
436                 }
437                 *value |= SS_POWERON;
438
439                 pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
440                 udelay(50);
441                 pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
442                 udelay(25); /* for IDE reset */
443                 pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
444                 mdelay(2);  /* for IDE reset */
445
446                 *value |= SS_READY;
447                 *value |= SS_3VCARD;
448         } else {
449                 /* disable CF power */
450                 pcc_set(sock, (unsigned int)PLD_CPCR, 0);
451                 udelay(100);
452                 pr_debug("m32r_cfc: _pcc_get_status: "
453                          "power off (CPCR=0x%08x)\n", status);
454         }
455 #else
456 #error no platform configuration
457 #endif
458         pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
459                  sock, *value);
460         return 0;
461 } /* _get_status */
462
463 /*====================================================================*/
464
465 static int _pcc_set_socket(u_short sock, socket_state_t *state)
466 {
467         pr_debug("m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
468                   "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
469                   state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
470
471 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
472         if (state->Vcc) {
473                 if ((state->Vcc != 50) && (state->Vcc != 33))
474                         return -EINVAL;
475                 /* accept 5V and 3.3V */
476         }
477 #endif
478         if (state->flags & SS_RESET) {
479                 pr_debug(":RESET\n");
480                 pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
481         }else{
482                 pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
483         }
484         if (state->flags & SS_OUTPUT_ENA){
485                 pr_debug(":OUTPUT_ENA\n");
486                 /* bit clear */
487                 pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
488         } else {
489                 pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
490         }
491
492         if(state->flags & SS_IOCARD){
493                 pr_debug(":IOCARD");
494         }
495         if (state->flags & SS_PWR_AUTO) {
496                 pr_debug(":PWR_AUTO");
497         }
498         if (state->csc_mask & SS_DETECT)
499                 pr_debug(":csc-SS_DETECT");
500         if (state->flags & SS_IOCARD) {
501                 if (state->csc_mask & SS_STSCHG)
502                         pr_debug(":STSCHG");
503         } else {
504                 if (state->csc_mask & SS_BATDEAD)
505                         pr_debug(":BATDEAD");
506                 if (state->csc_mask & SS_BATWARN)
507                         pr_debug(":BATWARN");
508                 if (state->csc_mask & SS_READY)
509                         pr_debug(":READY");
510         }
511         pr_debug("\n");
512         return 0;
513 } /* _set_socket */
514
515 /*====================================================================*/
516
517 static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
518 {
519         u_char map;
520
521         pr_debug("m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
522                   "%#llx-%#llx)\n", sock, io->map, io->flags,
523                   io->speed, (unsigned long long)io->start,
524                   (unsigned long long)io->stop);
525         map = io->map;
526
527         return 0;
528 } /* _set_io_map */
529
530 /*====================================================================*/
531
532 static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
533 {
534
535         u_char map = mem->map;
536         u_long addr;
537         pcc_socket_t *t = &socket[sock];
538
539         pr_debug("m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
540                  "%#llx, %#x)\n", sock, map, mem->flags,
541                  mem->speed, (unsigned long long)mem->static_start,
542                  mem->card_start);
543
544         /*
545          * sanity check
546          */
547         if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
548                 return -EINVAL;
549         }
550
551         /*
552          * de-activate
553          */
554         if ((mem->flags & MAP_ACTIVE) == 0) {
555                 t->current_space = as_none;
556                 return 0;
557         }
558
559         /*
560          * Set mode
561          */
562         if (mem->flags & MAP_ATTRIB) {
563                 t->current_space = as_attr;
564         } else {
565                 t->current_space = as_comm;
566         }
567
568         /*
569          * Set address
570          */
571         addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
572         mem->static_start = addr + mem->card_start;
573
574         return 0;
575
576 } /* _set_mem_map */
577
578 #if 0 /* driver model ordering issue */
579 /*======================================================================
580
581         Routines for accessing socket information and register dumps via
582         /proc/bus/pccard/...
583
584 ======================================================================*/
585
586 static ssize_t show_info(struct class_device *class_dev, char *buf)
587 {
588         pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
589                 socket.dev);
590
591         return sprintf(buf, "type:     %s\nbase addr:    0x%08lx\n",
592                 pcc[s->type].name, s->base);
593 }
594
595 static ssize_t show_exca(struct class_device *class_dev, char *buf)
596 {
597         /* FIXME */
598
599         return 0;
600 }
601
602 static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
603 static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
604 #endif
605
606 /*====================================================================*/
607
608 /* this is horribly ugly... proper locking needs to be done here at
609  * some time... */
610 #define LOCKED(x) do {                                  \
611         int retval;                                     \
612         unsigned long flags;                            \
613         spin_lock_irqsave(&pcc_lock, flags);            \
614         retval = x;                                     \
615         spin_unlock_irqrestore(&pcc_lock, flags);       \
616         return retval;                                  \
617 } while (0)
618
619
620 static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
621 {
622         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
623
624         if (socket[sock].flags & IS_ALIVE) {
625                 dev_dbg(&s->dev, "pcc_get_status: sock(%d) -EINVAL\n", sock);
626                 *value = 0;
627                 return -EINVAL;
628         }
629         dev_dbg(&s->dev, "pcc_get_status: sock(%d)\n", sock);
630         LOCKED(_pcc_get_status(sock, value));
631 }
632
633 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
634 {
635         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
636
637         if (socket[sock].flags & IS_ALIVE) {
638                 dev_dbg(&s->dev, "pcc_set_socket: sock(%d) -EINVAL\n", sock);
639                 return -EINVAL;
640         }
641         dev_dbg(&s->dev, "pcc_set_socket: sock(%d)\n", sock);
642         LOCKED(_pcc_set_socket(sock, state));
643 }
644
645 static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
646 {
647         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
648
649         if (socket[sock].flags & IS_ALIVE) {
650                 dev_dbg(&s->dev, "pcc_set_io_map: sock(%d) -EINVAL\n", sock);
651                 return -EINVAL;
652         }
653         dev_dbg(&s->dev, "pcc_set_io_map: sock(%d)\n", sock);
654         LOCKED(_pcc_set_io_map(sock, io));
655 }
656
657 static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
658 {
659         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
660
661         if (socket[sock].flags & IS_ALIVE) {
662                 dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
663                 return -EINVAL;
664         }
665         dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d)\n", sock);
666         LOCKED(_pcc_set_mem_map(sock, mem));
667 }
668
669 static int pcc_init(struct pcmcia_socket *s)
670 {
671         dev_dbg(&s->dev, "pcc_init()\n");
672         return 0;
673 }
674
675 static struct pccard_operations pcc_operations = {
676         .init                   = pcc_init,
677         .get_status             = pcc_get_status,
678         .set_socket             = pcc_set_socket,
679         .set_io_map             = pcc_set_io_map,
680         .set_mem_map            = pcc_set_mem_map,
681 };
682
683
684 /*====================================================================*/
685
686 static struct platform_driver pcc_driver = {
687         .driver = {
688                 .name           = "cfc",
689         },
690 };
691
692 static struct platform_device pcc_device = {
693         .name = "cfc",
694         .id = 0,
695 };
696
697 /*====================================================================*/
698
699 static int __init init_m32r_pcc(void)
700 {
701         int i, ret;
702
703         ret = platform_driver_register(&pcc_driver);
704         if (ret)
705                 return ret;
706
707         ret = platform_device_register(&pcc_device);
708         if (ret){
709                 platform_driver_unregister(&pcc_driver);
710                 return ret;
711         }
712
713 #if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
714         pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
715         pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
716 #endif
717
718         pcc_sockets = 0;
719
720 #if !defined(CONFIG_PLAT_USRV)
721         add_pcc_socket(M32R_PCC0_BASE, PLD_IRQ_CFC_INSERT, CFC_ATTR_MAPBASE,
722                        CFC_IOPORT_BASE);
723 #else   /* CONFIG_PLAT_USRV */
724         {
725                 ulong base, mapaddr;
726                 unsigned int ioaddr;
727
728                 for (i = 0 ; i < M32R_MAX_PCC ; i++) {
729                         base = (ulong)PLD_CFRSTCR;
730                         base = base | (i << 8);
731                         ioaddr = (i + 1) << 12;
732                         mapaddr = CFC_ATTR_MAPBASE | (i << 20);
733                         add_pcc_socket(base, 0, mapaddr, ioaddr);
734                 }
735         }
736 #endif  /* CONFIG_PLAT_USRV */
737
738         if (pcc_sockets == 0) {
739                 printk("socket is not found.\n");
740                 platform_device_unregister(&pcc_device);
741                 platform_driver_unregister(&pcc_driver);
742                 return -ENODEV;
743         }
744
745         /* Set up interrupt handler(s) */
746
747         for (i = 0 ; i < pcc_sockets ; i++) {
748                 socket[i].socket.dev.parent = &pcc_device.dev;
749                 socket[i].socket.ops = &pcc_operations;
750                 socket[i].socket.resource_ops = &pccard_static_ops;
751                 socket[i].socket.owner = THIS_MODULE;
752                 socket[i].number = i;
753                 ret = pcmcia_register_socket(&socket[i].socket);
754                 if (!ret)
755                         socket[i].flags |= IS_REGISTERED;
756         }
757
758         /* Finally, schedule a polling interrupt */
759         if (poll_interval != 0) {
760                 timer_setup(&poll_timer, pcc_interrupt_wrapper, 0);
761                 poll_timer.expires = jiffies + poll_interval;
762                 add_timer(&poll_timer);
763         }
764
765         return 0;
766 } /* init_m32r_pcc */
767
768 static void __exit exit_m32r_pcc(void)
769 {
770         int i;
771
772         for (i = 0; i < pcc_sockets; i++)
773                 if (socket[i].flags & IS_REGISTERED)
774                         pcmcia_unregister_socket(&socket[i].socket);
775
776         platform_device_unregister(&pcc_device);
777         if (poll_interval != 0)
778                 del_timer_sync(&poll_timer);
779
780         platform_driver_unregister(&pcc_driver);
781 } /* exit_m32r_pcc */
782
783 module_init(init_m32r_pcc);
784 module_exit(exit_m32r_pcc);
785 MODULE_LICENSE("Dual MPL/GPL");
786 /*====================================================================*/