Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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