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.15-rc7 870 lines 20 kB view raw
1/* 2 * linux/drivers/ide/arm/icside.c 3 * 4 * Copyright (c) 1996-2004 Russell King. 5 * 6 * Please note that this platform does not support 32-bit IDE IO. 7 */ 8 9#include <linux/config.h> 10#include <linux/string.h> 11#include <linux/module.h> 12#include <linux/ioport.h> 13#include <linux/slab.h> 14#include <linux/blkdev.h> 15#include <linux/errno.h> 16#include <linux/hdreg.h> 17#include <linux/ide.h> 18#include <linux/dma-mapping.h> 19#include <linux/device.h> 20#include <linux/init.h> 21#include <linux/scatterlist.h> 22 23#include <asm/dma.h> 24#include <asm/ecard.h> 25#include <asm/io.h> 26 27#define ICS_IDENT_OFFSET 0x2280 28 29#define ICS_ARCIN_V5_INTRSTAT 0x0000 30#define ICS_ARCIN_V5_INTROFFSET 0x0004 31#define ICS_ARCIN_V5_IDEOFFSET 0x2800 32#define ICS_ARCIN_V5_IDEALTOFFSET 0x2b80 33#define ICS_ARCIN_V5_IDESTEPPING 6 34 35#define ICS_ARCIN_V6_IDEOFFSET_1 0x2000 36#define ICS_ARCIN_V6_INTROFFSET_1 0x2200 37#define ICS_ARCIN_V6_INTRSTAT_1 0x2290 38#define ICS_ARCIN_V6_IDEALTOFFSET_1 0x2380 39#define ICS_ARCIN_V6_IDEOFFSET_2 0x3000 40#define ICS_ARCIN_V6_INTROFFSET_2 0x3200 41#define ICS_ARCIN_V6_INTRSTAT_2 0x3290 42#define ICS_ARCIN_V6_IDEALTOFFSET_2 0x3380 43#define ICS_ARCIN_V6_IDESTEPPING 6 44 45struct cardinfo { 46 unsigned int dataoffset; 47 unsigned int ctrloffset; 48 unsigned int stepping; 49}; 50 51static struct cardinfo icside_cardinfo_v5 = { 52 .dataoffset = ICS_ARCIN_V5_IDEOFFSET, 53 .ctrloffset = ICS_ARCIN_V5_IDEALTOFFSET, 54 .stepping = ICS_ARCIN_V5_IDESTEPPING, 55}; 56 57static struct cardinfo icside_cardinfo_v6_1 = { 58 .dataoffset = ICS_ARCIN_V6_IDEOFFSET_1, 59 .ctrloffset = ICS_ARCIN_V6_IDEALTOFFSET_1, 60 .stepping = ICS_ARCIN_V6_IDESTEPPING, 61}; 62 63static struct cardinfo icside_cardinfo_v6_2 = { 64 .dataoffset = ICS_ARCIN_V6_IDEOFFSET_2, 65 .ctrloffset = ICS_ARCIN_V6_IDEALTOFFSET_2, 66 .stepping = ICS_ARCIN_V6_IDESTEPPING, 67}; 68 69struct icside_state { 70 unsigned int channel; 71 unsigned int enabled; 72 void __iomem *irq_port; 73 void __iomem *ioc_base; 74 unsigned int type; 75 /* parent device... until the IDE core gets one of its own */ 76 struct device *dev; 77 ide_hwif_t *hwif[2]; 78}; 79 80#define ICS_TYPE_A3IN 0 81#define ICS_TYPE_A3USER 1 82#define ICS_TYPE_V6 3 83#define ICS_TYPE_V5 15 84#define ICS_TYPE_NOTYPE ((unsigned int)-1) 85 86/* ---------------- Version 5 PCB Support Functions --------------------- */ 87/* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr) 88 * Purpose : enable interrupts from card 89 */ 90static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr) 91{ 92 struct icside_state *state = ec->irq_data; 93 94 writeb(0, state->irq_port + ICS_ARCIN_V5_INTROFFSET); 95} 96 97/* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr) 98 * Purpose : disable interrupts from card 99 */ 100static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr) 101{ 102 struct icside_state *state = ec->irq_data; 103 104 readb(state->irq_port + ICS_ARCIN_V5_INTROFFSET); 105} 106 107static const expansioncard_ops_t icside_ops_arcin_v5 = { 108 .irqenable = icside_irqenable_arcin_v5, 109 .irqdisable = icside_irqdisable_arcin_v5, 110}; 111 112 113/* ---------------- Version 6 PCB Support Functions --------------------- */ 114/* Prototype: icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) 115 * Purpose : enable interrupts from card 116 */ 117static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) 118{ 119 struct icside_state *state = ec->irq_data; 120 void __iomem *base = state->irq_port; 121 122 state->enabled = 1; 123 124 switch (state->channel) { 125 case 0: 126 writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1); 127 readb(base + ICS_ARCIN_V6_INTROFFSET_2); 128 break; 129 case 1: 130 writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2); 131 readb(base + ICS_ARCIN_V6_INTROFFSET_1); 132 break; 133 } 134} 135 136/* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) 137 * Purpose : disable interrupts from card 138 */ 139static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) 140{ 141 struct icside_state *state = ec->irq_data; 142 143 state->enabled = 0; 144 145 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); 146 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); 147} 148 149/* Prototype: icside_irqprobe(struct expansion_card *ec) 150 * Purpose : detect an active interrupt from card 151 */ 152static int icside_irqpending_arcin_v6(struct expansion_card *ec) 153{ 154 struct icside_state *state = ec->irq_data; 155 156 return readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 || 157 readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1; 158} 159 160static const expansioncard_ops_t icside_ops_arcin_v6 = { 161 .irqenable = icside_irqenable_arcin_v6, 162 .irqdisable = icside_irqdisable_arcin_v6, 163 .irqpending = icside_irqpending_arcin_v6, 164}; 165 166/* 167 * Handle routing of interrupts. This is called before 168 * we write the command to the drive. 169 */ 170static void icside_maskproc(ide_drive_t *drive, int mask) 171{ 172 ide_hwif_t *hwif = HWIF(drive); 173 struct icside_state *state = hwif->hwif_data; 174 unsigned long flags; 175 176 local_irq_save(flags); 177 178 state->channel = hwif->channel; 179 180 if (state->enabled && !mask) { 181 switch (hwif->channel) { 182 case 0: 183 writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); 184 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); 185 break; 186 case 1: 187 writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); 188 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); 189 break; 190 } 191 } else { 192 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); 193 readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); 194 } 195 196 local_irq_restore(flags); 197} 198 199#ifdef CONFIG_BLK_DEV_IDEDMA_ICS 200 201#ifndef CONFIG_IDEDMA_ICS_AUTO 202#warning CONFIG_IDEDMA_ICS_AUTO=n support is obsolete, and will be removed soon. 203#endif 204 205/* 206 * SG-DMA support. 207 * 208 * Similar to the BM-DMA, but we use the RiscPCs IOMD DMA controllers. 209 * There is only one DMA controller per card, which means that only 210 * one drive can be accessed at one time. NOTE! We do not enforce that 211 * here, but we rely on the main IDE driver spotting that both 212 * interfaces use the same IRQ, which should guarantee this. 213 */ 214 215static void icside_build_sglist(ide_drive_t *drive, struct request *rq) 216{ 217 ide_hwif_t *hwif = drive->hwif; 218 struct icside_state *state = hwif->hwif_data; 219 struct scatterlist *sg = hwif->sg_table; 220 221 ide_map_sg(drive, rq); 222 223 if (rq_data_dir(rq) == READ) 224 hwif->sg_dma_direction = DMA_FROM_DEVICE; 225 else 226 hwif->sg_dma_direction = DMA_TO_DEVICE; 227 228 hwif->sg_nents = dma_map_sg(state->dev, sg, hwif->sg_nents, 229 hwif->sg_dma_direction); 230} 231 232/* 233 * Configure the IOMD to give the appropriate timings for the transfer 234 * mode being requested. We take the advice of the ATA standards, and 235 * calculate the cycle time based on the transfer mode, and the EIDE 236 * MW DMA specs that the drive provides in the IDENTIFY command. 237 * 238 * We have the following IOMD DMA modes to choose from: 239 * 240 * Type Active Recovery Cycle 241 * A 250 (250) 312 (550) 562 (800) 242 * B 187 250 437 243 * C 125 (125) 125 (375) 250 (500) 244 * D 62 125 187 245 * 246 * (figures in brackets are actual measured timings) 247 * 248 * However, we also need to take care of the read/write active and 249 * recovery timings: 250 * 251 * Read Write 252 * Mode Active -- Recovery -- Cycle IOMD type 253 * MW0 215 50 215 480 A 254 * MW1 80 50 50 150 C 255 * MW2 70 25 25 120 C 256 */ 257static int icside_set_speed(ide_drive_t *drive, u8 xfer_mode) 258{ 259 int on = 0, cycle_time = 0, use_dma_info = 0; 260 261 /* 262 * Limit the transfer speed to MW_DMA_2. 263 */ 264 if (xfer_mode > XFER_MW_DMA_2) 265 xfer_mode = XFER_MW_DMA_2; 266 267 switch (xfer_mode) { 268 case XFER_MW_DMA_2: 269 cycle_time = 250; 270 use_dma_info = 1; 271 break; 272 273 case XFER_MW_DMA_1: 274 cycle_time = 250; 275 use_dma_info = 1; 276 break; 277 278 case XFER_MW_DMA_0: 279 cycle_time = 480; 280 break; 281 282 case XFER_SW_DMA_2: 283 case XFER_SW_DMA_1: 284 case XFER_SW_DMA_0: 285 cycle_time = 480; 286 break; 287 } 288 289 /* 290 * If we're going to be doing MW_DMA_1 or MW_DMA_2, we should 291 * take care to note the values in the ID... 292 */ 293 if (use_dma_info && drive->id->eide_dma_time > cycle_time) 294 cycle_time = drive->id->eide_dma_time; 295 296 drive->drive_data = cycle_time; 297 298 if (cycle_time && ide_config_drive_speed(drive, xfer_mode) == 0) 299 on = 1; 300 else 301 drive->drive_data = 480; 302 303 printk("%s: %s selected (peak %dMB/s)\n", drive->name, 304 ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); 305 306 drive->current_speed = xfer_mode; 307 308 return on; 309} 310 311static int icside_dma_host_off(ide_drive_t *drive) 312{ 313 return 0; 314} 315 316static int icside_dma_off_quietly(ide_drive_t *drive) 317{ 318 drive->using_dma = 0; 319 return icside_dma_host_off(drive); 320} 321 322static int icside_dma_host_on(ide_drive_t *drive) 323{ 324 return 0; 325} 326 327static int icside_dma_on(ide_drive_t *drive) 328{ 329 drive->using_dma = 1; 330 return icside_dma_host_on(drive); 331} 332 333static int icside_dma_check(ide_drive_t *drive) 334{ 335 struct hd_driveid *id = drive->id; 336 ide_hwif_t *hwif = HWIF(drive); 337 int xfer_mode = XFER_PIO_2; 338 int on; 339 340 if (!(id->capability & 1) || !hwif->autodma) 341 goto out; 342 343 /* 344 * Consult the list of known "bad" drives 345 */ 346 if (__ide_dma_bad_drive(drive)) 347 goto out; 348 349 /* 350 * Enable DMA on any drive that has multiword DMA 351 */ 352 if (id->field_valid & 2) { 353 xfer_mode = ide_dma_speed(drive, 0); 354 goto out; 355 } 356 357 /* 358 * Consult the list of known "good" drives 359 */ 360 if (__ide_dma_good_drive(drive)) { 361 if (id->eide_dma_time > 150) 362 goto out; 363 xfer_mode = XFER_MW_DMA_1; 364 } 365 366out: 367 on = icside_set_speed(drive, xfer_mode); 368 369 if (on) 370 return icside_dma_on(drive); 371 else 372 return icside_dma_off_quietly(drive); 373} 374 375static int icside_dma_end(ide_drive_t *drive) 376{ 377 ide_hwif_t *hwif = HWIF(drive); 378 struct icside_state *state = hwif->hwif_data; 379 380 drive->waiting_for_dma = 0; 381 382 disable_dma(hwif->hw.dma); 383 384 /* Teardown mappings after DMA has completed. */ 385 dma_unmap_sg(state->dev, hwif->sg_table, hwif->sg_nents, 386 hwif->sg_dma_direction); 387 388 return get_dma_residue(hwif->hw.dma) != 0; 389} 390 391static void icside_dma_start(ide_drive_t *drive) 392{ 393 ide_hwif_t *hwif = HWIF(drive); 394 395 /* We can not enable DMA on both channels simultaneously. */ 396 BUG_ON(dma_channel_active(hwif->hw.dma)); 397 enable_dma(hwif->hw.dma); 398} 399 400static int icside_dma_setup(ide_drive_t *drive) 401{ 402 ide_hwif_t *hwif = HWIF(drive); 403 struct request *rq = hwif->hwgroup->rq; 404 unsigned int dma_mode; 405 406 if (rq_data_dir(rq)) 407 dma_mode = DMA_MODE_WRITE; 408 else 409 dma_mode = DMA_MODE_READ; 410 411 /* 412 * We can not enable DMA on both channels. 413 */ 414 BUG_ON(dma_channel_active(hwif->hw.dma)); 415 416 icside_build_sglist(drive, rq); 417 418 /* 419 * Ensure that we have the right interrupt routed. 420 */ 421 icside_maskproc(drive, 0); 422 423 /* 424 * Route the DMA signals to the correct interface. 425 */ 426 writeb(hwif->select_data, hwif->config_data); 427 428 /* 429 * Select the correct timing for this drive. 430 */ 431 set_dma_speed(hwif->hw.dma, drive->drive_data); 432 433 /* 434 * Tell the DMA engine about the SG table and 435 * data direction. 436 */ 437 set_dma_sg(hwif->hw.dma, hwif->sg_table, hwif->sg_nents); 438 set_dma_mode(hwif->hw.dma, dma_mode); 439 440 drive->waiting_for_dma = 1; 441 442 return 0; 443} 444 445static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd) 446{ 447 /* issue cmd to drive */ 448 ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL); 449} 450 451static int icside_dma_test_irq(ide_drive_t *drive) 452{ 453 ide_hwif_t *hwif = HWIF(drive); 454 struct icside_state *state = hwif->hwif_data; 455 456 return readb(state->irq_port + 457 (hwif->channel ? 458 ICS_ARCIN_V6_INTRSTAT_2 : 459 ICS_ARCIN_V6_INTRSTAT_1)) & 1; 460} 461 462static int icside_dma_timeout(ide_drive_t *drive) 463{ 464 printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); 465 466 if (icside_dma_test_irq(drive)) 467 return 0; 468 469 ide_dump_status(drive, "DMA timeout", 470 HWIF(drive)->INB(IDE_STATUS_REG)); 471 472 return icside_dma_end(drive); 473} 474 475static int icside_dma_lostirq(ide_drive_t *drive) 476{ 477 printk(KERN_ERR "%s: IRQ lost\n", drive->name); 478 return 1; 479} 480 481static void icside_dma_init(ide_hwif_t *hwif) 482{ 483 int autodma = 0; 484 485#ifdef CONFIG_IDEDMA_ICS_AUTO 486 autodma = 1; 487#endif 488 489 printk(" %s: SG-DMA", hwif->name); 490 491 hwif->atapi_dma = 1; 492 hwif->mwdma_mask = 7; /* MW0..2 */ 493 hwif->swdma_mask = 7; /* SW0..2 */ 494 495 hwif->dmatable_cpu = NULL; 496 hwif->dmatable_dma = 0; 497 hwif->speedproc = icside_set_speed; 498 hwif->autodma = autodma; 499 500 hwif->ide_dma_check = icside_dma_check; 501 hwif->ide_dma_host_off = icside_dma_host_off; 502 hwif->ide_dma_off_quietly = icside_dma_off_quietly; 503 hwif->ide_dma_host_on = icside_dma_host_on; 504 hwif->ide_dma_on = icside_dma_on; 505 hwif->dma_setup = icside_dma_setup; 506 hwif->dma_exec_cmd = icside_dma_exec_cmd; 507 hwif->dma_start = icside_dma_start; 508 hwif->ide_dma_end = icside_dma_end; 509 hwif->ide_dma_test_irq = icside_dma_test_irq; 510 hwif->ide_dma_timeout = icside_dma_timeout; 511 hwif->ide_dma_lostirq = icside_dma_lostirq; 512 513 hwif->drives[0].autodma = hwif->autodma; 514 hwif->drives[1].autodma = hwif->autodma; 515 516 printk(" capable%s\n", hwif->autodma ? ", auto-enable" : ""); 517} 518#else 519#define icside_dma_init(hwif) (0) 520#endif 521 522static ide_hwif_t *icside_find_hwif(unsigned long dataport) 523{ 524 ide_hwif_t *hwif; 525 int index; 526 527 for (index = 0; index < MAX_HWIFS; ++index) { 528 hwif = &ide_hwifs[index]; 529 if (hwif->io_ports[IDE_DATA_OFFSET] == dataport) 530 goto found; 531 } 532 533 for (index = 0; index < MAX_HWIFS; ++index) { 534 hwif = &ide_hwifs[index]; 535 if (!hwif->io_ports[IDE_DATA_OFFSET]) 536 goto found; 537 } 538 539 hwif = NULL; 540found: 541 return hwif; 542} 543 544static ide_hwif_t * 545icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec) 546{ 547 unsigned long port = (unsigned long)base + info->dataoffset; 548 ide_hwif_t *hwif; 549 550 hwif = icside_find_hwif(port); 551 if (hwif) { 552 int i; 553 554 memset(&hwif->hw, 0, sizeof(hw_regs_t)); 555 556 /* 557 * Ensure we're using MMIO 558 */ 559 default_hwif_mmiops(hwif); 560 hwif->mmio = 2; 561 562 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { 563 hwif->hw.io_ports[i] = port; 564 hwif->io_ports[i] = port; 565 port += 1 << info->stepping; 566 } 567 hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset; 568 hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset; 569 hwif->hw.irq = ec->irq; 570 hwif->irq = ec->irq; 571 hwif->noprobe = 0; 572 hwif->chipset = ide_acorn; 573 hwif->gendev.parent = &ec->dev; 574 } 575 576 return hwif; 577} 578 579static int __init 580icside_register_v5(struct icside_state *state, struct expansion_card *ec) 581{ 582 ide_hwif_t *hwif; 583 void __iomem *base; 584 585 base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), 586 ecard_resource_len(ec, ECARD_RES_MEMC)); 587 if (!base) 588 return -ENOMEM; 589 590 state->irq_port = base; 591 592 ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT; 593 ec->irqmask = 1; 594 ec->irq_data = state; 595 ec->ops = &icside_ops_arcin_v5; 596 597 /* 598 * Be on the safe side - disable interrupts 599 */ 600 icside_irqdisable_arcin_v5(ec, 0); 601 602 hwif = icside_setup(base, &icside_cardinfo_v5, ec); 603 if (!hwif) { 604 iounmap(base); 605 return -ENODEV; 606 } 607 608 state->hwif[0] = hwif; 609 610 probe_hwif_init(hwif); 611 create_proc_ide_interfaces(); 612 613 return 0; 614} 615 616static int __init 617icside_register_v6(struct icside_state *state, struct expansion_card *ec) 618{ 619 ide_hwif_t *hwif, *mate; 620 void __iomem *ioc_base, *easi_base; 621 unsigned int sel = 0; 622 int ret; 623 624 ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), 625 ecard_resource_len(ec, ECARD_RES_IOCFAST)); 626 if (!ioc_base) { 627 ret = -ENOMEM; 628 goto out; 629 } 630 631 easi_base = ioc_base; 632 633 if (ecard_resource_flags(ec, ECARD_RES_EASI)) { 634 easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI), 635 ecard_resource_len(ec, ECARD_RES_EASI)); 636 if (!easi_base) { 637 ret = -ENOMEM; 638 goto unmap_slot; 639 } 640 641 /* 642 * Enable access to the EASI region. 643 */ 644 sel = 1 << 5; 645 } 646 647 writeb(sel, ioc_base); 648 649 ec->irq_data = state; 650 ec->ops = &icside_ops_arcin_v6; 651 652 state->irq_port = easi_base; 653 state->ioc_base = ioc_base; 654 655 /* 656 * Be on the safe side - disable interrupts 657 */ 658 icside_irqdisable_arcin_v6(ec, 0); 659 660 /* 661 * Find and register the interfaces. 662 */ 663 hwif = icside_setup(easi_base, &icside_cardinfo_v6_1, ec); 664 mate = icside_setup(easi_base, &icside_cardinfo_v6_2, ec); 665 666 if (!hwif || !mate) { 667 ret = -ENODEV; 668 goto unmap_port; 669 } 670 671 state->hwif[0] = hwif; 672 state->hwif[1] = mate; 673 674 hwif->maskproc = icside_maskproc; 675 hwif->channel = 0; 676 hwif->hwif_data = state; 677 hwif->mate = mate; 678 hwif->serialized = 1; 679 hwif->config_data = (unsigned long)ioc_base; 680 hwif->select_data = sel; 681 hwif->hw.dma = ec->dma; 682 683 mate->maskproc = icside_maskproc; 684 mate->channel = 1; 685 mate->hwif_data = state; 686 mate->mate = hwif; 687 mate->serialized = 1; 688 mate->config_data = (unsigned long)ioc_base; 689 mate->select_data = sel | 1; 690 mate->hw.dma = ec->dma; 691 692 if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) { 693 icside_dma_init(hwif); 694 icside_dma_init(mate); 695 } 696 697 probe_hwif_init(hwif); 698 probe_hwif_init(mate); 699 create_proc_ide_interfaces(); 700 701 return 0; 702 703 unmap_port: 704 if (easi_base != ioc_base) 705 iounmap(easi_base); 706 unmap_slot: 707 iounmap(ioc_base); 708 out: 709 return ret; 710} 711 712static int __devinit 713icside_probe(struct expansion_card *ec, const struct ecard_id *id) 714{ 715 struct icside_state *state; 716 void __iomem *idmem; 717 int ret; 718 719 ret = ecard_request_resources(ec); 720 if (ret) 721 goto out; 722 723 state = kmalloc(sizeof(struct icside_state), GFP_KERNEL); 724 if (!state) { 725 ret = -ENOMEM; 726 goto release; 727 } 728 729 memset(state, 0, sizeof(state)); 730 state->type = ICS_TYPE_NOTYPE; 731 state->dev = &ec->dev; 732 733 idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), 734 ecard_resource_len(ec, ECARD_RES_IOCFAST)); 735 if (idmem) { 736 unsigned int type; 737 738 type = readb(idmem + ICS_IDENT_OFFSET) & 1; 739 type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1; 740 type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2; 741 type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3; 742 iounmap(idmem); 743 744 state->type = type; 745 } 746 747 switch (state->type) { 748 case ICS_TYPE_A3IN: 749 dev_warn(&ec->dev, "A3IN unsupported\n"); 750 ret = -ENODEV; 751 break; 752 753 case ICS_TYPE_A3USER: 754 dev_warn(&ec->dev, "A3USER unsupported\n"); 755 ret = -ENODEV; 756 break; 757 758 case ICS_TYPE_V5: 759 ret = icside_register_v5(state, ec); 760 break; 761 762 case ICS_TYPE_V6: 763 ret = icside_register_v6(state, ec); 764 break; 765 766 default: 767 dev_warn(&ec->dev, "unknown interface type\n"); 768 ret = -ENODEV; 769 break; 770 } 771 772 if (ret == 0) { 773 ecard_set_drvdata(ec, state); 774 goto out; 775 } 776 777 kfree(state); 778 release: 779 ecard_release_resources(ec); 780 out: 781 return ret; 782} 783 784static void __devexit icside_remove(struct expansion_card *ec) 785{ 786 struct icside_state *state = ecard_get_drvdata(ec); 787 788 switch (state->type) { 789 case ICS_TYPE_V5: 790 /* FIXME: tell IDE to stop using the interface */ 791 792 /* Disable interrupts */ 793 icside_irqdisable_arcin_v5(ec, 0); 794 break; 795 796 case ICS_TYPE_V6: 797 /* FIXME: tell IDE to stop using the interface */ 798 if (ec->dma != NO_DMA) 799 free_dma(ec->dma); 800 801 /* Disable interrupts */ 802 icside_irqdisable_arcin_v6(ec, 0); 803 804 /* Reset the ROM pointer/EASI selection */ 805 writeb(0, state->ioc_base); 806 break; 807 } 808 809 ecard_set_drvdata(ec, NULL); 810 ec->ops = NULL; 811 ec->irq_data = NULL; 812 813 if (state->ioc_base) 814 iounmap(state->ioc_base); 815 if (state->ioc_base != state->irq_port) 816 iounmap(state->irq_port); 817 818 kfree(state); 819 ecard_release_resources(ec); 820} 821 822static void icside_shutdown(struct expansion_card *ec) 823{ 824 struct icside_state *state = ecard_get_drvdata(ec); 825 unsigned long flags; 826 827 /* 828 * Disable interrupts from this card. We need to do 829 * this before disabling EASI since we may be accessing 830 * this register via that region. 831 */ 832 local_irq_save(flags); 833 ec->ops->irqdisable(ec, 0); 834 local_irq_restore(flags); 835 836 /* 837 * Reset the ROM pointer so that we can read the ROM 838 * after a soft reboot. This also disables access to 839 * the IDE taskfile via the EASI region. 840 */ 841 if (state->ioc_base) 842 writeb(0, state->ioc_base); 843} 844 845static const struct ecard_id icside_ids[] = { 846 { MANU_ICS, PROD_ICS_IDE }, 847 { MANU_ICS2, PROD_ICS2_IDE }, 848 { 0xffff, 0xffff } 849}; 850 851static struct ecard_driver icside_driver = { 852 .probe = icside_probe, 853 .remove = __devexit_p(icside_remove), 854 .shutdown = icside_shutdown, 855 .id_table = icside_ids, 856 .drv = { 857 .name = "icside", 858 }, 859}; 860 861static int __init icside_init(void) 862{ 863 return ecard_register_driver(&icside_driver); 864} 865 866MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); 867MODULE_LICENSE("GPL"); 868MODULE_DESCRIPTION("ICS IDE driver"); 869 870module_init(icside_init);