vrc4171_card.c (17477B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services. 4 * 5 * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@linux-mips.org> 6 */ 7#include <linux/init.h> 8#include <linux/ioport.h> 9#include <linux/interrupt.h> 10#include <linux/module.h> 11#include <linux/spinlock.h> 12#include <linux/types.h> 13#include <linux/platform_device.h> 14 15#include <asm/io.h> 16 17#include <pcmcia/ss.h> 18 19#include "i82365.h" 20 21MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services"); 22MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>"); 23MODULE_LICENSE("GPL"); 24 25#define CARD_MAX_SLOTS 2 26#define CARD_SLOTA 0 27#define CARD_SLOTB 1 28#define CARD_SLOTB_OFFSET 0x40 29 30#define CARD_MEM_START 0x10000000 31#define CARD_MEM_END 0x13ffffff 32#define CARD_MAX_MEM_OFFSET 0x3ffffff 33#define CARD_MAX_MEM_SPEED 1000 34 35#define CARD_CONTROLLER_INDEX 0x03e0 36#define CARD_CONTROLLER_DATA 0x03e1 37 /* Power register */ 38 #define VPP_GET_VCC 0x01 39 #define POWER_ENABLE 0x10 40 #define CARD_VOLTAGE_SENSE 0x1f 41 #define VCC_3VORXV_CAPABLE 0x00 42 #define VCC_XV_ONLY 0x01 43 #define VCC_3V_CAPABLE 0x02 44 #define VCC_5V_ONLY 0x03 45 #define CARD_VOLTAGE_SELECT 0x2f 46 #define VCC_3V 0x01 47 #define VCC_5V 0x00 48 #define VCC_XV 0x02 49 #define VCC_STATUS_3V 0x02 50 #define VCC_STATUS_5V 0x01 51 #define VCC_STATUS_XV 0x03 52 #define GLOBAL_CONTROL 0x1e 53 #define EXWRBK 0x04 54 #define IRQPM_EN 0x08 55 #define CLRPMIRQ 0x10 56 57#define INTERRUPT_STATUS 0x05fa 58 #define IRQ_A 0x02 59 #define IRQ_B 0x04 60 61#define CONFIGURATION1 0x05fe 62 #define SLOTB_CONFIG 0xc000 63 #define SLOTB_NONE 0x0000 64 #define SLOTB_PCCARD 0x4000 65 #define SLOTB_CF 0x8000 66 #define SLOTB_FLASHROM 0xc000 67 68#define CARD_CONTROLLER_START CARD_CONTROLLER_INDEX 69#define CARD_CONTROLLER_END CARD_CONTROLLER_DATA 70 71#define IO_MAX_MAPS 2 72#define MEM_MAX_MAPS 5 73 74enum vrc4171_slot { 75 SLOT_PROBE = 0, 76 SLOT_NOPROBE_IO, 77 SLOT_NOPROBE_MEM, 78 SLOT_NOPROBE_ALL, 79 SLOT_INITIALIZED, 80}; 81 82enum vrc4171_slotb { 83 SLOTB_IS_NONE, 84 SLOTB_IS_PCCARD, 85 SLOTB_IS_CF, 86 SLOTB_IS_FLASHROM, 87}; 88 89struct vrc4171_socket { 90 enum vrc4171_slot slot; 91 struct pcmcia_socket pcmcia_socket; 92 char name[24]; 93 int csc_irq; 94 int io_irq; 95 spinlock_t lock; 96}; 97 98static struct vrc4171_socket vrc4171_sockets[CARD_MAX_SLOTS]; 99static enum vrc4171_slotb vrc4171_slotb = SLOTB_IS_NONE; 100static char vrc4171_card_name[] = "NEC VRC4171 Card Controller"; 101static unsigned int vrc4171_irq; 102static uint16_t vrc4171_irq_mask = 0xdeb8; 103 104static struct resource vrc4171_card_resource[3] = { 105 { .name = vrc4171_card_name, 106 .start = CARD_CONTROLLER_START, 107 .end = CARD_CONTROLLER_END, 108 .flags = IORESOURCE_IO, }, 109 { .name = vrc4171_card_name, 110 .start = INTERRUPT_STATUS, 111 .end = INTERRUPT_STATUS, 112 .flags = IORESOURCE_IO, }, 113 { .name = vrc4171_card_name, 114 .start = CONFIGURATION1, 115 .end = CONFIGURATION1, 116 .flags = IORESOURCE_IO, }, 117}; 118 119static struct platform_device vrc4171_card_device = { 120 .name = vrc4171_card_name, 121 .id = 0, 122 .num_resources = 3, 123 .resource = vrc4171_card_resource, 124}; 125 126static inline uint16_t vrc4171_get_irq_status(void) 127{ 128 return inw(INTERRUPT_STATUS); 129} 130 131static inline void vrc4171_set_multifunction_pin(enum vrc4171_slotb config) 132{ 133 uint16_t config1; 134 135 config1 = inw(CONFIGURATION1); 136 config1 &= ~SLOTB_CONFIG; 137 138 switch (config) { 139 case SLOTB_IS_NONE: 140 config1 |= SLOTB_NONE; 141 break; 142 case SLOTB_IS_PCCARD: 143 config1 |= SLOTB_PCCARD; 144 break; 145 case SLOTB_IS_CF: 146 config1 |= SLOTB_CF; 147 break; 148 case SLOTB_IS_FLASHROM: 149 config1 |= SLOTB_FLASHROM; 150 break; 151 default: 152 break; 153 } 154 155 outw(config1, CONFIGURATION1); 156} 157 158static inline uint8_t exca_read_byte(int slot, uint8_t index) 159{ 160 if (slot == CARD_SLOTB) 161 index += CARD_SLOTB_OFFSET; 162 163 outb(index, CARD_CONTROLLER_INDEX); 164 return inb(CARD_CONTROLLER_DATA); 165} 166 167static inline uint16_t exca_read_word(int slot, uint8_t index) 168{ 169 uint16_t data; 170 171 if (slot == CARD_SLOTB) 172 index += CARD_SLOTB_OFFSET; 173 174 outb(index++, CARD_CONTROLLER_INDEX); 175 data = inb(CARD_CONTROLLER_DATA); 176 177 outb(index, CARD_CONTROLLER_INDEX); 178 data |= ((uint16_t)inb(CARD_CONTROLLER_DATA)) << 8; 179 180 return data; 181} 182 183static inline uint8_t exca_write_byte(int slot, uint8_t index, uint8_t data) 184{ 185 if (slot == CARD_SLOTB) 186 index += CARD_SLOTB_OFFSET; 187 188 outb(index, CARD_CONTROLLER_INDEX); 189 outb(data, CARD_CONTROLLER_DATA); 190 191 return data; 192} 193 194static inline uint16_t exca_write_word(int slot, uint8_t index, uint16_t data) 195{ 196 if (slot == CARD_SLOTB) 197 index += CARD_SLOTB_OFFSET; 198 199 outb(index++, CARD_CONTROLLER_INDEX); 200 outb(data, CARD_CONTROLLER_DATA); 201 202 outb(index, CARD_CONTROLLER_INDEX); 203 outb((uint8_t)(data >> 8), CARD_CONTROLLER_DATA); 204 205 return data; 206} 207 208static inline int search_nonuse_irq(void) 209{ 210 int i; 211 212 for (i = 0; i < 16; i++) { 213 if (vrc4171_irq_mask & (1 << i)) { 214 vrc4171_irq_mask &= ~(1 << i); 215 return i; 216 } 217 } 218 219 return -1; 220} 221 222static int pccard_init(struct pcmcia_socket *sock) 223{ 224 struct vrc4171_socket *socket; 225 unsigned int slot; 226 227 sock->features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS; 228 sock->irq_mask = 0; 229 sock->map_size = 0x1000; 230 sock->pci_irq = vrc4171_irq; 231 232 slot = sock->sock; 233 socket = &vrc4171_sockets[slot]; 234 socket->csc_irq = search_nonuse_irq(); 235 socket->io_irq = search_nonuse_irq(); 236 spin_lock_init(&socket->lock); 237 238 return 0; 239} 240 241static int pccard_get_status(struct pcmcia_socket *sock, u_int *value) 242{ 243 unsigned int slot; 244 uint8_t status, sense; 245 u_int val = 0; 246 247 if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || value == NULL) 248 return -EINVAL; 249 250 slot = sock->sock; 251 252 status = exca_read_byte(slot, I365_STATUS); 253 if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) { 254 if (status & I365_CS_STSCHG) 255 val |= SS_STSCHG; 256 } else { 257 if (!(status & I365_CS_BVD1)) 258 val |= SS_BATDEAD; 259 else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1) 260 val |= SS_BATWARN; 261 } 262 if ((status & I365_CS_DETECT) == I365_CS_DETECT) 263 val |= SS_DETECT; 264 if (status & I365_CS_WRPROT) 265 val |= SS_WRPROT; 266 if (status & I365_CS_READY) 267 val |= SS_READY; 268 if (status & I365_CS_POWERON) 269 val |= SS_POWERON; 270 271 sense = exca_read_byte(slot, CARD_VOLTAGE_SENSE); 272 switch (sense) { 273 case VCC_3VORXV_CAPABLE: 274 val |= SS_3VCARD | SS_XVCARD; 275 break; 276 case VCC_XV_ONLY: 277 val |= SS_XVCARD; 278 break; 279 case VCC_3V_CAPABLE: 280 val |= SS_3VCARD; 281 break; 282 default: 283 /* 5V only */ 284 break; 285 } 286 287 *value = val; 288 289 return 0; 290} 291 292static inline uint8_t set_Vcc_value(u_char Vcc) 293{ 294 switch (Vcc) { 295 case 33: 296 return VCC_3V; 297 case 50: 298 return VCC_5V; 299 } 300 301 /* Small voltage is chosen for safety. */ 302 return VCC_3V; 303} 304 305static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state) 306{ 307 struct vrc4171_socket *socket; 308 unsigned int slot; 309 uint8_t voltage, power, control, cscint; 310 311 if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || 312 (state->Vpp != state->Vcc && state->Vpp != 0) || 313 (state->Vcc != 50 && state->Vcc != 33 && state->Vcc != 0)) 314 return -EINVAL; 315 316 slot = sock->sock; 317 socket = &vrc4171_sockets[slot]; 318 319 spin_lock_irq(&socket->lock); 320 321 voltage = set_Vcc_value(state->Vcc); 322 exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage); 323 324 power = POWER_ENABLE; 325 if (state->Vpp == state->Vcc) 326 power |= VPP_GET_VCC; 327 if (state->flags & SS_OUTPUT_ENA) 328 power |= I365_PWR_OUT; 329 exca_write_byte(slot, I365_POWER, power); 330 331 control = 0; 332 if (state->io_irq != 0) 333 control |= socket->io_irq; 334 if (state->flags & SS_IOCARD) 335 control |= I365_PC_IOCARD; 336 if (state->flags & SS_RESET) 337 control &= ~I365_PC_RESET; 338 else 339 control |= I365_PC_RESET; 340 exca_write_byte(slot, I365_INTCTL, control); 341 342 cscint = 0; 343 exca_write_byte(slot, I365_CSCINT, cscint); 344 exca_read_byte(slot, I365_CSC); /* clear CardStatus change */ 345 if (state->csc_mask != 0) 346 cscint |= socket->csc_irq << 8; 347 if (state->flags & SS_IOCARD) { 348 if (state->csc_mask & SS_STSCHG) 349 cscint |= I365_CSC_STSCHG; 350 } else { 351 if (state->csc_mask & SS_BATDEAD) 352 cscint |= I365_CSC_BVD1; 353 if (state->csc_mask & SS_BATWARN) 354 cscint |= I365_CSC_BVD2; 355 } 356 if (state->csc_mask & SS_READY) 357 cscint |= I365_CSC_READY; 358 if (state->csc_mask & SS_DETECT) 359 cscint |= I365_CSC_DETECT; 360 exca_write_byte(slot, I365_CSCINT, cscint); 361 362 spin_unlock_irq(&socket->lock); 363 364 return 0; 365} 366 367static int pccard_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io) 368{ 369 unsigned int slot; 370 uint8_t ioctl, addrwin; 371 u_char map; 372 373 if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || 374 io == NULL || io->map >= IO_MAX_MAPS || 375 io->start > 0xffff || io->stop > 0xffff || io->start > io->stop) 376 return -EINVAL; 377 378 slot = sock->sock; 379 map = io->map; 380 381 addrwin = exca_read_byte(slot, I365_ADDRWIN); 382 if (addrwin & I365_ENA_IO(map)) { 383 addrwin &= ~I365_ENA_IO(map); 384 exca_write_byte(slot, I365_ADDRWIN, addrwin); 385 } 386 387 exca_write_word(slot, I365_IO(map)+I365_W_START, io->start); 388 exca_write_word(slot, I365_IO(map)+I365_W_STOP, io->stop); 389 390 ioctl = 0; 391 if (io->speed > 0) 392 ioctl |= I365_IOCTL_WAIT(map); 393 if (io->flags & MAP_16BIT) 394 ioctl |= I365_IOCTL_16BIT(map); 395 if (io->flags & MAP_AUTOSZ) 396 ioctl |= I365_IOCTL_IOCS16(map); 397 if (io->flags & MAP_0WS) 398 ioctl |= I365_IOCTL_0WS(map); 399 exca_write_byte(slot, I365_IOCTL, ioctl); 400 401 if (io->flags & MAP_ACTIVE) { 402 addrwin |= I365_ENA_IO(map); 403 exca_write_byte(slot, I365_ADDRWIN, addrwin); 404 } 405 406 return 0; 407} 408 409static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem) 410{ 411 unsigned int slot; 412 uint16_t start, stop, offset; 413 uint8_t addrwin; 414 u_char map; 415 416 if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || 417 mem == NULL || mem->map >= MEM_MAX_MAPS || 418 mem->res->start < CARD_MEM_START || mem->res->start > CARD_MEM_END || 419 mem->res->end < CARD_MEM_START || mem->res->end > CARD_MEM_END || 420 mem->res->start > mem->res->end || 421 mem->card_start > CARD_MAX_MEM_OFFSET || 422 mem->speed > CARD_MAX_MEM_SPEED) 423 return -EINVAL; 424 425 slot = sock->sock; 426 map = mem->map; 427 428 addrwin = exca_read_byte(slot, I365_ADDRWIN); 429 if (addrwin & I365_ENA_MEM(map)) { 430 addrwin &= ~I365_ENA_MEM(map); 431 exca_write_byte(slot, I365_ADDRWIN, addrwin); 432 } 433 434 start = (mem->res->start >> 12) & 0x3fff; 435 if (mem->flags & MAP_16BIT) 436 start |= I365_MEM_16BIT; 437 exca_write_word(slot, I365_MEM(map)+I365_W_START, start); 438 439 stop = (mem->res->end >> 12) & 0x3fff; 440 switch (mem->speed) { 441 case 0: 442 break; 443 case 1: 444 stop |= I365_MEM_WS0; 445 break; 446 case 2: 447 stop |= I365_MEM_WS1; 448 break; 449 default: 450 stop |= I365_MEM_WS0 | I365_MEM_WS1; 451 break; 452 } 453 exca_write_word(slot, I365_MEM(map)+I365_W_STOP, stop); 454 455 offset = (mem->card_start >> 12) & 0x3fff; 456 if (mem->flags & MAP_ATTRIB) 457 offset |= I365_MEM_REG; 458 if (mem->flags & MAP_WRPROT) 459 offset |= I365_MEM_WRPROT; 460 exca_write_word(slot, I365_MEM(map)+I365_W_OFF, offset); 461 462 if (mem->flags & MAP_ACTIVE) { 463 addrwin |= I365_ENA_MEM(map); 464 exca_write_byte(slot, I365_ADDRWIN, addrwin); 465 } 466 467 return 0; 468} 469 470static struct pccard_operations vrc4171_pccard_operations = { 471 .init = pccard_init, 472 .get_status = pccard_get_status, 473 .set_socket = pccard_set_socket, 474 .set_io_map = pccard_set_io_map, 475 .set_mem_map = pccard_set_mem_map, 476}; 477 478static inline unsigned int get_events(int slot) 479{ 480 unsigned int events = 0; 481 uint8_t status, csc; 482 483 status = exca_read_byte(slot, I365_STATUS); 484 csc = exca_read_byte(slot, I365_CSC); 485 486 if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) { 487 if ((csc & I365_CSC_STSCHG) && (status & I365_CS_STSCHG)) 488 events |= SS_STSCHG; 489 } else { 490 if (csc & (I365_CSC_BVD1 | I365_CSC_BVD2)) { 491 if (!(status & I365_CS_BVD1)) 492 events |= SS_BATDEAD; 493 else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1) 494 events |= SS_BATWARN; 495 } 496 } 497 if ((csc & I365_CSC_READY) && (status & I365_CS_READY)) 498 events |= SS_READY; 499 if ((csc & I365_CSC_DETECT) && ((status & I365_CS_DETECT) == I365_CS_DETECT)) 500 events |= SS_DETECT; 501 502 return events; 503} 504 505static irqreturn_t pccard_interrupt(int irq, void *dev_id) 506{ 507 struct vrc4171_socket *socket; 508 unsigned int events; 509 irqreturn_t retval = IRQ_NONE; 510 uint16_t status; 511 512 status = vrc4171_get_irq_status(); 513 if (status & IRQ_A) { 514 socket = &vrc4171_sockets[CARD_SLOTA]; 515 if (socket->slot == SLOT_INITIALIZED) { 516 if (status & (1 << socket->csc_irq)) { 517 events = get_events(CARD_SLOTA); 518 if (events != 0) { 519 pcmcia_parse_events(&socket->pcmcia_socket, events); 520 retval = IRQ_HANDLED; 521 } 522 } 523 } 524 } 525 526 if (status & IRQ_B) { 527 socket = &vrc4171_sockets[CARD_SLOTB]; 528 if (socket->slot == SLOT_INITIALIZED) { 529 if (status & (1 << socket->csc_irq)) { 530 events = get_events(CARD_SLOTB); 531 if (events != 0) { 532 pcmcia_parse_events(&socket->pcmcia_socket, events); 533 retval = IRQ_HANDLED; 534 } 535 } 536 } 537 } 538 539 return retval; 540} 541 542static inline void reserve_using_irq(int slot) 543{ 544 unsigned int irq; 545 546 irq = exca_read_byte(slot, I365_INTCTL); 547 irq &= 0x0f; 548 vrc4171_irq_mask &= ~(1 << irq); 549 550 irq = exca_read_byte(slot, I365_CSCINT); 551 irq = (irq & 0xf0) >> 4; 552 vrc4171_irq_mask &= ~(1 << irq); 553} 554 555static int vrc4171_add_sockets(void) 556{ 557 struct vrc4171_socket *socket; 558 int slot, retval; 559 560 for (slot = 0; slot < CARD_MAX_SLOTS; slot++) { 561 if (slot == CARD_SLOTB && vrc4171_slotb == SLOTB_IS_NONE) 562 continue; 563 564 socket = &vrc4171_sockets[slot]; 565 if (socket->slot != SLOT_PROBE) { 566 uint8_t addrwin; 567 568 switch (socket->slot) { 569 case SLOT_NOPROBE_MEM: 570 addrwin = exca_read_byte(slot, I365_ADDRWIN); 571 addrwin &= 0x1f; 572 exca_write_byte(slot, I365_ADDRWIN, addrwin); 573 break; 574 case SLOT_NOPROBE_IO: 575 addrwin = exca_read_byte(slot, I365_ADDRWIN); 576 addrwin &= 0xc0; 577 exca_write_byte(slot, I365_ADDRWIN, addrwin); 578 break; 579 default: 580 break; 581 } 582 583 reserve_using_irq(slot); 584 continue; 585 } 586 587 sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot); 588 socket->pcmcia_socket.dev.parent = &vrc4171_card_device.dev; 589 socket->pcmcia_socket.ops = &vrc4171_pccard_operations; 590 socket->pcmcia_socket.owner = THIS_MODULE; 591 592 retval = pcmcia_register_socket(&socket->pcmcia_socket); 593 if (retval < 0) 594 return retval; 595 596 exca_write_byte(slot, I365_ADDRWIN, 0); 597 exca_write_byte(slot, GLOBAL_CONTROL, 0); 598 599 socket->slot = SLOT_INITIALIZED; 600 } 601 602 return 0; 603} 604 605static void vrc4171_remove_sockets(void) 606{ 607 struct vrc4171_socket *socket; 608 int slot; 609 610 for (slot = 0; slot < CARD_MAX_SLOTS; slot++) { 611 if (slot == CARD_SLOTB && vrc4171_slotb == SLOTB_IS_NONE) 612 continue; 613 614 socket = &vrc4171_sockets[slot]; 615 if (socket->slot == SLOT_INITIALIZED) 616 pcmcia_unregister_socket(&socket->pcmcia_socket); 617 618 socket->slot = SLOT_PROBE; 619 } 620} 621 622static int vrc4171_card_setup(char *options) 623{ 624 if (options == NULL || *options == '\0') 625 return 1; 626 627 if (strncmp(options, "irq:", 4) == 0) { 628 int irq; 629 options += 4; 630 irq = simple_strtoul(options, &options, 0); 631 if (irq >= 0 && irq < nr_irqs) 632 vrc4171_irq = irq; 633 634 if (*options != ',') 635 return 1; 636 options++; 637 } 638 639 if (strncmp(options, "slota:", 6) == 0) { 640 options += 6; 641 if (*options != '\0') { 642 if (strncmp(options, "memnoprobe", 10) == 0) { 643 vrc4171_sockets[CARD_SLOTA].slot = SLOT_NOPROBE_MEM; 644 options += 10; 645 } else if (strncmp(options, "ionoprobe", 9) == 0) { 646 vrc4171_sockets[CARD_SLOTA].slot = SLOT_NOPROBE_IO; 647 options += 9; 648 } else if ( strncmp(options, "noprobe", 7) == 0) { 649 vrc4171_sockets[CARD_SLOTA].slot = SLOT_NOPROBE_ALL; 650 options += 7; 651 } 652 653 if (*options != ',') 654 return 1; 655 options++; 656 } else 657 return 1; 658 659 } 660 661 if (strncmp(options, "slotb:", 6) == 0) { 662 options += 6; 663 if (*options != '\0') { 664 if (strncmp(options, "pccard", 6) == 0) { 665 vrc4171_slotb = SLOTB_IS_PCCARD; 666 options += 6; 667 } else if (strncmp(options, "cf", 2) == 0) { 668 vrc4171_slotb = SLOTB_IS_CF; 669 options += 2; 670 } else if (strncmp(options, "flashrom", 8) == 0) { 671 vrc4171_slotb = SLOTB_IS_FLASHROM; 672 options += 8; 673 } else if (strncmp(options, "none", 4) == 0) { 674 vrc4171_slotb = SLOTB_IS_NONE; 675 options += 4; 676 } 677 678 if (*options != ',') 679 return 1; 680 options++; 681 682 if (strncmp(options, "memnoprobe", 10) == 0) 683 vrc4171_sockets[CARD_SLOTB].slot = SLOT_NOPROBE_MEM; 684 if (strncmp(options, "ionoprobe", 9) == 0) 685 vrc4171_sockets[CARD_SLOTB].slot = SLOT_NOPROBE_IO; 686 if (strncmp(options, "noprobe", 7) == 0) 687 vrc4171_sockets[CARD_SLOTB].slot = SLOT_NOPROBE_ALL; 688 } 689 } 690 691 return 1; 692} 693 694__setup("vrc4171_card=", vrc4171_card_setup); 695 696static struct platform_driver vrc4171_card_driver = { 697 .driver = { 698 .name = vrc4171_card_name, 699 }, 700}; 701 702static int vrc4171_card_init(void) 703{ 704 int retval; 705 706 retval = platform_driver_register(&vrc4171_card_driver); 707 if (retval < 0) 708 return retval; 709 710 retval = platform_device_register(&vrc4171_card_device); 711 if (retval < 0) { 712 platform_driver_unregister(&vrc4171_card_driver); 713 return retval; 714 } 715 716 vrc4171_set_multifunction_pin(vrc4171_slotb); 717 718 retval = vrc4171_add_sockets(); 719 if (retval == 0) 720 retval = request_irq(vrc4171_irq, pccard_interrupt, IRQF_SHARED, 721 vrc4171_card_name, vrc4171_sockets); 722 723 if (retval < 0) { 724 vrc4171_remove_sockets(); 725 platform_device_unregister(&vrc4171_card_device); 726 platform_driver_unregister(&vrc4171_card_driver); 727 return retval; 728 } 729 730 printk(KERN_INFO "%s, connected to IRQ %d\n", 731 vrc4171_card_driver.driver.name, vrc4171_irq); 732 733 return 0; 734} 735 736static void vrc4171_card_exit(void) 737{ 738 free_irq(vrc4171_irq, vrc4171_sockets); 739 vrc4171_remove_sockets(); 740 platform_device_unregister(&vrc4171_card_device); 741 platform_driver_unregister(&vrc4171_card_driver); 742} 743 744module_init(vrc4171_card_init); 745module_exit(vrc4171_card_exit);