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