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