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