Merge branch 'platforms' of git://git.linaro.org/people/rmk/linux-arm
[linux-2.6.git] / drivers / pcmcia / m32r_pcc.c
1 /*
2  *  drivers/pcmcia/m32r_pcc.c
3  *
4  *  Device driver for the PCMCIA 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 #include <asm/system.h>
28 #include <asm/addrspace.h>
29
30 #include <pcmcia/ss.h>
31
32 /* XXX: should be moved into asm/irq.h */
33 #define PCC0_IRQ 24
34 #define PCC1_IRQ 25
35
36 #include "m32r_pcc.h"
37
38 #define CHAOS_PCC_DEBUG
39 #ifdef CHAOS_PCC_DEBUG
40         static volatile u_short dummy_readbuf;
41 #endif
42
43 #define PCC_DEBUG_DBEX
44
45
46 /* Poll status interval -- 0 means default to interrupt */
47 static int poll_interval = 0;
48
49 typedef enum pcc_space { as_none = 0, as_comm, as_attr, as_io } pcc_as_t;
50
51 typedef struct pcc_socket {
52         u_short                 type, flags;
53         struct pcmcia_socket    socket;
54         unsigned int            number;
55         unsigned int            ioaddr;
56         u_long                  mapaddr;
57         u_long                  base;   /* PCC register base */
58         u_char                  cs_irq, intr;
59         pccard_io_map           io_map[MAX_IO_WIN];
60         pccard_mem_map          mem_map[MAX_WIN];
61         u_char                  io_win;
62         u_char                  mem_win;
63         pcc_as_t                current_space;
64         u_char                  last_iodbex;
65 #ifdef CHAOS_PCC_DEBUG
66         u_char                  last_iosize;
67 #endif
68 #ifdef CONFIG_PROC_FS
69         struct proc_dir_entry *proc;
70 #endif
71 } pcc_socket_t;
72
73 static int pcc_sockets = 0;
74 static pcc_socket_t socket[M32R_MAX_PCC] = {
75         { 0, }, /* ... */
76 };
77
78 /*====================================================================*/
79
80 static unsigned int pcc_get(u_short, unsigned int);
81 static void pcc_set(u_short, unsigned int , unsigned int );
82
83 static DEFINE_SPINLOCK(pcc_lock);
84
85 void pcc_iorw(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int wr, int flag)
86 {
87         u_long addr;
88         u_long flags;
89         int need_ex;
90 #ifdef PCC_DEBUG_DBEX
91         int _dbex;
92 #endif
93         pcc_socket_t *t = &socket[sock];
94 #ifdef CHAOS_PCC_DEBUG
95         int map_changed = 0;
96 #endif
97
98         /* Need lock ? */
99         spin_lock_irqsave(&pcc_lock, flags);
100
101         /*
102          * Check if need dbex
103          */
104         need_ex = (size > 1 && flag == 0) ? PCMOD_DBEX : 0;
105 #ifdef PCC_DEBUG_DBEX
106         _dbex = need_ex;
107         need_ex = 0;
108 #endif
109
110         /*
111          * calculate access address
112          */
113         addr = t->mapaddr + port - t->ioaddr + KSEG1; /* XXX */
114
115         /*
116          * Check current mapping
117          */
118         if (t->current_space != as_io || t->last_iodbex != need_ex) {
119
120                 u_long cbsz;
121
122                 /*
123                  * Disable first
124                  */
125                 pcc_set(sock, PCCR, 0);
126
127                 /*
128                  * Set mode and io address
129                  */
130                 cbsz = (t->flags & MAP_16BIT) ? 0 : PCMOD_CBSZ;
131                 pcc_set(sock, PCMOD, PCMOD_AS_IO | cbsz | need_ex);
132                 pcc_set(sock, PCADR, addr & 0x1ff00000);
133
134                 /*
135                  * Enable and read it
136                  */
137                 pcc_set(sock, PCCR, 1);
138
139 #ifdef CHAOS_PCC_DEBUG
140 #if 0
141                 map_changed = (t->current_space == as_attr && size == 2); /* XXX */
142 #else
143                 map_changed = 1;
144 #endif
145 #endif
146                 t->current_space = as_io;
147         }
148
149         /*
150          * access to IO space
151          */
152         if (size == 1) {
153                 /* Byte */
154                 unsigned char *bp = (unsigned char *)buf;
155
156 #ifdef CHAOS_DEBUG
157                 if (map_changed) {
158                         dummy_readbuf = readb(addr);
159                 }
160 #endif
161                 if (wr) {
162                         /* write Byte */
163                         while (nmemb--) {
164                                 writeb(*bp++, addr);
165                         }
166                 } else {
167                         /* read Byte */
168                         while (nmemb--) {
169                         *bp++ = readb(addr);
170                         }
171                 }
172         } else {
173                 /* Word */
174                 unsigned short *bp = (unsigned short *)buf;
175
176 #ifdef CHAOS_PCC_DEBUG
177                 if (map_changed) {
178                         dummy_readbuf = readw(addr);
179                 }
180 #endif
181                 if (wr) {
182                         /* write Word */
183                         while (nmemb--) {
184 #ifdef PCC_DEBUG_DBEX
185                                 if (_dbex) {
186                                         unsigned char *cp = (unsigned char *)bp;
187                                         unsigned short tmp;
188                                         tmp = cp[1] << 8 | cp[0];
189                                         writew(tmp, addr);
190                                         bp++;
191                                 } else
192 #endif
193                                 writew(*bp++, addr);
194                 }
195             } else {
196                 /* read Word */
197                 while (nmemb--) {
198 #ifdef  PCC_DEBUG_DBEX
199                                 if (_dbex) {
200                                         unsigned char *cp = (unsigned char *)bp;
201                                         unsigned short tmp;
202                                         tmp = readw(addr);
203                                         cp[0] = tmp & 0xff;
204                                         cp[1] = (tmp >> 8) & 0xff;
205                                         bp++;
206                                 } else
207 #endif
208                                 *bp++ = readw(addr);
209                 }
210             }
211         }
212
213 #if 1
214         /* addr is no longer used */
215         if ((addr = pcc_get(sock, PCIRC)) & PCIRC_BWERR) {
216           printk("m32r_pcc: BWERR detected : port 0x%04lx : iosize %dbit\n",
217                          port, size * 8);
218           pcc_set(sock, PCIRC, addr);
219         }
220 #endif
221         /*
222          * save state
223          */
224         t->last_iosize = size;
225         t->last_iodbex = need_ex;
226
227         /* Need lock ? */
228
229         spin_unlock_irqrestore(&pcc_lock,flags);
230
231         return;
232 }
233
234 void pcc_ioread(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int flag) {
235         pcc_iorw(sock, port, buf, size, nmemb, 0, flag);
236 }
237
238 void pcc_iowrite(int sock, unsigned long port, void *buf, size_t size, size_t nmemb, int flag) {
239     pcc_iorw(sock, port, buf, size, nmemb, 1, flag);
240 }
241
242 /*====================================================================*/
243
244 #define IS_REGISTERED           0x2000
245 #define IS_ALIVE                0x8000
246
247 typedef struct pcc_t {
248         char                    *name;
249         u_short                 flags;
250 } pcc_t;
251
252 static pcc_t pcc[] = {
253         { "xnux2", 0 }, { "xnux2", 0 },
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         return inl(socket[sock].base + reg);
265 }
266
267
268 static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
269 {
270         outl(data, socket[sock].base + reg);
271 }
272
273 /*======================================================================
274
275         See if a card is present, powered up, in IO mode, and already
276         bound to a (non PC Card) Linux driver.  We leave these alone.
277
278         We make an exception for cards that seem to be serial devices.
279
280 ======================================================================*/
281
282 static int __init is_alive(u_short sock)
283 {
284         unsigned int stat;
285         unsigned int f;
286
287         stat = pcc_get(sock, PCIRC);
288         f = (stat & (PCIRC_CDIN1 | PCIRC_CDIN2)) >> 16;
289         if(!f){
290                 printk("m32r_pcc: No Card is detected at socket %d : stat = 0x%08x\n",stat,sock);
291                 return 0;
292         }
293         if(f!=3)
294                 printk("m32r_pcc: Insertion fail (%.8x) at socket %d\n",stat,sock);
295         else
296                 printk("m32r_pcc: Card is Inserted at socket %d(%.8x)\n",sock,stat);
297         return 0;
298 }
299
300 static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
301                            unsigned int ioaddr)
302 {
303         pcc_socket_t *t = &socket[pcc_sockets];
304
305         /* add sockets */
306         t->ioaddr = ioaddr;
307         t->mapaddr = mapaddr;
308         t->base = base;
309 #ifdef CHAOS_PCC_DEBUG
310         t->flags = MAP_16BIT;
311 #else
312         t->flags = 0;
313 #endif
314         if (is_alive(pcc_sockets))
315                 t->flags |= IS_ALIVE;
316
317         /* add pcc */
318         if (t->base > 0) {
319                 request_region(t->base, 0x20, "m32r-pcc");
320         }
321
322         printk(KERN_INFO "  %s ", pcc[pcc_sockets].name);
323         printk("pcc at 0x%08lx\n", t->base);
324
325         /* Update socket interrupt information, capabilities */
326         t->socket.features |= (SS_CAP_PCCARD | SS_CAP_STATIC_MAP);
327         t->socket.map_size = M32R_PCC_MAPSIZE;
328         t->socket.io_offset = ioaddr;   /* use for io access offset */
329         t->socket.irq_mask = 0;
330         t->socket.pci_irq = 2 + pcc_sockets; /* XXX */
331
332         request_irq(irq, pcc_interrupt, 0, "m32r-pcc", pcc_interrupt);
333
334         pcc_sockets++;
335
336         return;
337 }
338
339
340 /*====================================================================*/
341
342 static irqreturn_t pcc_interrupt(int irq, void *dev)
343 {
344         int i, j, irc;
345         u_int events, active;
346         int handled = 0;
347
348         pr_debug("m32r_pcc: pcc_interrupt(%d)\n", irq);
349
350         for (j = 0; j < 20; j++) {
351                 active = 0;
352                 for (i = 0; i < pcc_sockets; i++) {
353                         if ((socket[i].cs_irq != irq) &&
354                                 (socket[i].socket.pci_irq != irq))
355                                 continue;
356                         handled = 1;
357                         irc = pcc_get(i, PCIRC);
358                         irc >>=16;
359                         pr_debug("m32r_pcc: interrupt: socket %d pcirc 0x%02x ",
360                                 i, irc);
361                         if (!irc)
362                                 continue;
363
364                         events = (irc) ? SS_DETECT : 0;
365                         events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
366                         pr_debug("m32r_pcc: event 0x%02x\n", events);
367
368                         if (events)
369                                 pcmcia_parse_events(&socket[i].socket, events);
370
371                         active |= events;
372                         active = 0;
373                 }
374                 if (!active) break;
375         }
376         if (j == 20)
377                 printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
378
379         pr_debug("m32r_pcc: interrupt done\n");
380
381         return IRQ_RETVAL(handled);
382 } /* pcc_interrupt */
383
384 static void pcc_interrupt_wrapper(u_long data)
385 {
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         status = pcc_get(sock,PCIRC);
399         *value = ((status & PCIRC_CDIN1) && (status & PCIRC_CDIN2))
400                 ? SS_DETECT : 0;
401
402         status = pcc_get(sock,PCCR);
403
404 #if 0
405         *value |= (status & PCCR_PCEN) ? SS_READY : 0;
406 #else
407         *value |= SS_READY; /* XXX: always */
408 #endif
409
410         status = pcc_get(sock,PCCSIGCR);
411         *value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
412
413         pr_debug("m32r_pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
414         return 0;
415 } /* _get_status */
416
417 /*====================================================================*/
418
419 static int _pcc_set_socket(u_short sock, socket_state_t *state)
420 {
421         u_long reg = 0;
422
423         pr_debug("m32r_pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
424                   "io_irq %d, csc_mask %#2.2x)", sock, state->flags,
425                   state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
426
427         if (state->Vcc) {
428                 /*
429                  * 5V only
430                  */
431                 if (state->Vcc == 50) {
432                         reg |= PCCSIGCR_VEN;
433                 } else {
434                         return -EINVAL;
435                 }
436         }
437
438         if (state->flags & SS_RESET) {
439                 pr_debug("m32r_pcc: :RESET\n");
440                 reg |= PCCSIGCR_CRST;
441         }
442         if (state->flags & SS_OUTPUT_ENA){
443                 pr_debug("m32r_pcc: :OUTPUT_ENA\n");
444                 /* bit clear */
445         } else {
446                 reg |= PCCSIGCR_SEN;
447         }
448
449         pcc_set(sock,PCCSIGCR,reg);
450
451         if(state->flags & SS_IOCARD){
452                 pr_debug("m32r_pcc: :IOCARD");
453         }
454         if (state->flags & SS_PWR_AUTO) {
455                 pr_debug("m32r_pcc: :PWR_AUTO");
456         }
457         if (state->csc_mask & SS_DETECT)
458                 pr_debug("m32r_pcc: :csc-SS_DETECT");
459         if (state->flags & SS_IOCARD) {
460                 if (state->csc_mask & SS_STSCHG)
461                         pr_debug("m32r_pcc: :STSCHG");
462         } else {
463                 if (state->csc_mask & SS_BATDEAD)
464                         pr_debug("m32r_pcc: :BATDEAD");
465                 if (state->csc_mask & SS_BATWARN)
466                         pr_debug("m32r_pcc: :BATWARN");
467                 if (state->csc_mask & SS_READY)
468                         pr_debug("m32r_pcc: :READY");
469         }
470         pr_debug("m32r_pcc: \n");
471         return 0;
472 } /* _set_socket */
473
474 /*====================================================================*/
475
476 static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
477 {
478         u_char map;
479
480         pr_debug("m32r_pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
481                   "%#llx-%#llx)\n", sock, io->map, io->flags,
482                   io->speed, (unsigned long long)io->start,
483                   (unsigned long long)io->stop);
484         map = io->map;
485
486         return 0;
487 } /* _set_io_map */
488
489 /*====================================================================*/
490
491 static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
492 {
493
494         u_char map = mem->map;
495         u_long mode;
496         u_long addr;
497         pcc_socket_t *t = &socket[sock];
498 #ifdef CHAOS_PCC_DEBUG
499 #if 0
500         pcc_as_t last = t->current_space;
501 #endif
502 #endif
503
504         pr_debug("m32r_pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
505                  "%#llx,  %#x)\n", sock, map, mem->flags,
506                  mem->speed, (unsigned long long)mem->static_start,
507                  mem->card_start);
508
509         /*
510          * sanity check
511          */
512         if ((map > MAX_WIN) || (mem->card_start > 0x3ffffff)){
513                 return -EINVAL;
514         }
515
516         /*
517          * de-activate
518          */
519         if ((mem->flags & MAP_ACTIVE) == 0) {
520                 t->current_space = as_none;
521                 return 0;
522         }
523
524         /*
525          * Disable first
526          */
527         pcc_set(sock, PCCR, 0);
528
529         /*
530          * Set mode
531          */
532         if (mem->flags & MAP_ATTRIB) {
533                 mode = PCMOD_AS_ATTRIB | PCMOD_CBSZ;
534                 t->current_space = as_attr;
535         } else {
536                 mode = 0; /* common memory */
537                 t->current_space = as_comm;
538         }
539         pcc_set(sock, PCMOD, mode);
540
541         /*
542          * Set address
543          */
544         addr = t->mapaddr + (mem->card_start & M32R_PCC_MAPMASK);
545         pcc_set(sock, PCADR, addr);
546
547         mem->static_start = addr + mem->card_start;
548
549         /*
550          * Enable again
551          */
552         pcc_set(sock, PCCR, 1);
553
554 #ifdef CHAOS_PCC_DEBUG
555 #if 0
556         if (last != as_attr) {
557 #else
558         if (1) {
559 #endif
560                 dummy_readbuf = *(u_char *)(addr + KSEG1);
561         }
562 #endif
563
564         return 0;
565
566 } /* _set_mem_map */
567
568 #if 0 /* driver model ordering issue */
569 /*======================================================================
570
571         Routines for accessing socket information and register dumps via
572         /proc/bus/pccard/...
573
574 ======================================================================*/
575
576 static ssize_t show_info(struct class_device *class_dev, char *buf)
577 {
578         pcc_socket_t *s = container_of(class_dev, struct pcc_socket,
579                 socket.dev);
580
581         return sprintf(buf, "type:     %s\nbase addr:    0x%08lx\n",
582                 pcc[s->type].name, s->base);
583 }
584
585 static ssize_t show_exca(struct class_device *class_dev, char *buf)
586 {
587         /* FIXME */
588
589         return 0;
590 }
591
592 static CLASS_DEVICE_ATTR(info, S_IRUGO, show_info, NULL);
593 static CLASS_DEVICE_ATTR(exca, S_IRUGO, show_exca, NULL);
594 #endif
595
596 /*====================================================================*/
597
598 /* this is horribly ugly... proper locking needs to be done here at
599  * some time... */
600 #define LOCKED(x) do {                                  \
601         int retval;                                     \
602         unsigned long flags;                            \
603         spin_lock_irqsave(&pcc_lock, flags);            \
604         retval = x;                                     \
605         spin_unlock_irqrestore(&pcc_lock, flags);       \
606         return retval;                                  \
607 } while (0)
608
609
610 static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
611 {
612         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
613
614         if (socket[sock].flags & IS_ALIVE) {
615                 *value = 0;
616                 return -EINVAL;
617         }
618         LOCKED(_pcc_get_status(sock, value));
619 }
620
621 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
622 {
623         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
624
625         if (socket[sock].flags & IS_ALIVE)
626                 return -EINVAL;
627
628         LOCKED(_pcc_set_socket(sock, state));
629 }
630
631 static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
632 {
633         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
634
635         if (socket[sock].flags & IS_ALIVE)
636                 return -EINVAL;
637         LOCKED(_pcc_set_io_map(sock, io));
638 }
639
640 static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
641 {
642         unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
643
644         if (socket[sock].flags & IS_ALIVE)
645                 return -EINVAL;
646         LOCKED(_pcc_set_mem_map(sock, mem));
647 }
648
649 static int pcc_init(struct pcmcia_socket *s)
650 {
651         pr_debug("m32r_pcc: init call\n");
652         return 0;
653 }
654
655 static struct pccard_operations pcc_operations = {
656         .init                   = pcc_init,
657         .get_status             = pcc_get_status,
658         .set_socket             = pcc_set_socket,
659         .set_io_map             = pcc_set_io_map,
660         .set_mem_map            = pcc_set_mem_map,
661 };
662
663 /*====================================================================*/
664
665 static struct platform_driver pcc_driver = {
666         .driver = {
667                 .name           = "pcc",
668                 .owner          = THIS_MODULE,
669         },
670 };
671
672 static struct platform_device pcc_device = {
673         .name = "pcc",
674         .id = 0,
675 };
676
677 /*====================================================================*/
678
679 static int __init init_m32r_pcc(void)
680 {
681         int i, ret;
682
683         ret = platform_driver_register(&pcc_driver);
684         if (ret)
685                 return ret;
686
687         ret = platform_device_register(&pcc_device);
688         if (ret){
689                 platform_driver_unregister(&pcc_driver);
690                 return ret;
691         }
692
693         printk(KERN_INFO "m32r PCC probe:\n");
694
695         pcc_sockets = 0;
696
697         add_pcc_socket(M32R_PCC0_BASE, PCC0_IRQ, M32R_PCC0_MAPBASE, 0x1000);
698
699 #ifdef CONFIG_M32RPCC_SLOT2
700         add_pcc_socket(M32R_PCC1_BASE, PCC1_IRQ, M32R_PCC1_MAPBASE, 0x2000);
701 #endif
702
703         if (pcc_sockets == 0) {
704                 printk("socket is not found.\n");
705                 platform_device_unregister(&pcc_device);
706                 platform_driver_unregister(&pcc_driver);
707                 return -ENODEV;
708         }
709
710         /* Set up interrupt handler(s) */
711
712         for (i = 0 ; i < pcc_sockets ; i++) {
713                 socket[i].socket.dev.parent = &pcc_device.dev;
714                 socket[i].socket.ops = &pcc_operations;
715                 socket[i].socket.resource_ops = &pccard_static_ops;
716                 socket[i].socket.owner = THIS_MODULE;
717                 socket[i].number = i;
718                 ret = pcmcia_register_socket(&socket[i].socket);
719                 if (!ret)
720                         socket[i].flags |= IS_REGISTERED;
721
722 #if 0   /* driver model ordering issue */
723                 class_device_create_file(&socket[i].socket.dev,
724                                          &class_device_attr_info);
725                 class_device_create_file(&socket[i].socket.dev,
726                                          &class_device_attr_exca);
727 #endif
728         }
729
730         /* Finally, schedule a polling interrupt */
731         if (poll_interval != 0) {
732                 poll_timer.function = pcc_interrupt_wrapper;
733                 poll_timer.data = 0;
734                 init_timer(&poll_timer);
735                 poll_timer.expires = jiffies + poll_interval;
736                 add_timer(&poll_timer);
737         }
738
739         return 0;
740 } /* init_m32r_pcc */
741
742 static void __exit exit_m32r_pcc(void)
743 {
744         int i;
745
746         for (i = 0; i < pcc_sockets; i++)
747                 if (socket[i].flags & IS_REGISTERED)
748                         pcmcia_unregister_socket(&socket[i].socket);
749
750         platform_device_unregister(&pcc_device);
751         if (poll_interval != 0)
752                 del_timer_sync(&poll_timer);
753
754         platform_driver_unregister(&pcc_driver);
755 } /* exit_m32r_pcc */
756
757 module_init(init_m32r_pcc);
758 module_exit(exit_m32r_pcc);
759 MODULE_LICENSE("Dual MPL/GPL");
760 /*====================================================================*/