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