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