diff options
Diffstat (limited to 'drivers/ide/arm/icside.c')
| -rw-r--r-- | drivers/ide/arm/icside.c | 105 |
1 files changed, 55 insertions, 50 deletions
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 061456914ca3..52f58c885783 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <asm/dma.h> | 21 | #include <asm/dma.h> |
| 22 | #include <asm/ecard.h> | 22 | #include <asm/ecard.h> |
| 23 | 23 | ||
| 24 | #define DRV_NAME "icside" | ||
| 25 | |||
| 24 | #define ICS_IDENT_OFFSET 0x2280 | 26 | #define ICS_IDENT_OFFSET 0x2280 |
| 25 | 27 | ||
| 26 | #define ICS_ARCIN_V5_INTRSTAT 0x0000 | 28 | #define ICS_ARCIN_V5_INTRSTAT 0x0000 |
| @@ -68,6 +70,7 @@ struct icside_state { | |||
| 68 | unsigned int enabled; | 70 | unsigned int enabled; |
| 69 | void __iomem *irq_port; | 71 | void __iomem *irq_port; |
| 70 | void __iomem *ioc_base; | 72 | void __iomem *ioc_base; |
| 73 | unsigned int sel; | ||
| 71 | unsigned int type; | 74 | unsigned int type; |
| 72 | ide_hwif_t *hwif[2]; | 75 | ide_hwif_t *hwif[2]; |
| 73 | }; | 76 | }; |
| @@ -165,7 +168,8 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = { | |||
| 165 | static void icside_maskproc(ide_drive_t *drive, int mask) | 168 | static void icside_maskproc(ide_drive_t *drive, int mask) |
| 166 | { | 169 | { |
| 167 | ide_hwif_t *hwif = HWIF(drive); | 170 | ide_hwif_t *hwif = HWIF(drive); |
| 168 | struct icside_state *state = hwif->hwif_data; | 171 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
| 172 | struct icside_state *state = ecard_get_drvdata(ec); | ||
| 169 | unsigned long flags; | 173 | unsigned long flags; |
| 170 | 174 | ||
| 171 | local_irq_save(flags); | 175 | local_irq_save(flags); |
| @@ -308,6 +312,7 @@ static int icside_dma_setup(ide_drive_t *drive) | |||
| 308 | { | 312 | { |
| 309 | ide_hwif_t *hwif = HWIF(drive); | 313 | ide_hwif_t *hwif = HWIF(drive); |
| 310 | struct expansion_card *ec = ECARD_DEV(hwif->dev); | 314 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
| 315 | struct icside_state *state = ecard_get_drvdata(ec); | ||
| 311 | struct request *rq = hwif->hwgroup->rq; | 316 | struct request *rq = hwif->hwgroup->rq; |
| 312 | unsigned int dma_mode; | 317 | unsigned int dma_mode; |
| 313 | 318 | ||
| @@ -331,7 +336,7 @@ static int icside_dma_setup(ide_drive_t *drive) | |||
| 331 | /* | 336 | /* |
| 332 | * Route the DMA signals to the correct interface. | 337 | * Route the DMA signals to the correct interface. |
| 333 | */ | 338 | */ |
| 334 | writeb(hwif->select_data, hwif->config_data); | 339 | writeb(state->sel | hwif->channel, state->ioc_base); |
| 335 | 340 | ||
| 336 | /* | 341 | /* |
| 337 | * Select the correct timing for this drive. | 342 | * Select the correct timing for this drive. |
| @@ -359,7 +364,8 @@ static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd) | |||
| 359 | static int icside_dma_test_irq(ide_drive_t *drive) | 364 | static int icside_dma_test_irq(ide_drive_t *drive) |
| 360 | { | 365 | { |
| 361 | ide_hwif_t *hwif = HWIF(drive); | 366 | ide_hwif_t *hwif = HWIF(drive); |
| 362 | struct icside_state *state = hwif->hwif_data; | 367 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
| 368 | struct icside_state *state = ecard_get_drvdata(ec); | ||
| 363 | 369 | ||
| 364 | return readb(state->irq_port + | 370 | return readb(state->irq_port + |
| 365 | (hwif->channel ? | 371 | (hwif->channel ? |
| @@ -411,36 +417,24 @@ static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
| 411 | return -EOPNOTSUPP; | 417 | return -EOPNOTSUPP; |
| 412 | } | 418 | } |
| 413 | 419 | ||
| 414 | static ide_hwif_t * | 420 | static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, |
| 415 | icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec) | 421 | struct cardinfo *info, struct expansion_card *ec) |
| 416 | { | 422 | { |
| 417 | unsigned long port = (unsigned long)base + info->dataoffset; | 423 | unsigned long port = (unsigned long)base + info->dataoffset; |
| 418 | ide_hwif_t *hwif; | ||
| 419 | 424 | ||
| 420 | hwif = ide_find_port(); | 425 | hw->io_ports.data_addr = port; |
| 421 | if (hwif) { | 426 | hw->io_ports.error_addr = port + (1 << info->stepping); |
| 422 | /* | 427 | hw->io_ports.nsect_addr = port + (2 << info->stepping); |
| 423 | * Ensure we're using MMIO | 428 | hw->io_ports.lbal_addr = port + (3 << info->stepping); |
| 424 | */ | 429 | hw->io_ports.lbam_addr = port + (4 << info->stepping); |
| 425 | default_hwif_mmiops(hwif); | 430 | hw->io_ports.lbah_addr = port + (5 << info->stepping); |
| 426 | 431 | hw->io_ports.device_addr = port + (6 << info->stepping); | |
| 427 | hwif->io_ports.data_addr = port; | 432 | hw->io_ports.status_addr = port + (7 << info->stepping); |
| 428 | hwif->io_ports.error_addr = port + (1 << info->stepping); | 433 | hw->io_ports.ctl_addr = (unsigned long)base + info->ctrloffset; |
| 429 | hwif->io_ports.nsect_addr = port + (2 << info->stepping); | 434 | |
| 430 | hwif->io_ports.lbal_addr = port + (3 << info->stepping); | 435 | hw->irq = ec->irq; |
| 431 | hwif->io_ports.lbam_addr = port + (4 << info->stepping); | 436 | hw->dev = &ec->dev; |
| 432 | hwif->io_ports.lbah_addr = port + (5 << info->stepping); | 437 | hw->chipset = ide_acorn; |
| 433 | hwif->io_ports.device_addr = port + (6 << info->stepping); | ||
| 434 | hwif->io_ports.status_addr = port + (7 << info->stepping); | ||
| 435 | hwif->io_ports.ctl_addr = | ||
| 436 | (unsigned long)base + info->ctrloffset; | ||
| 437 | hwif->irq = ec->irq; | ||
| 438 | hwif->chipset = ide_acorn; | ||
| 439 | hwif->gendev.parent = &ec->dev; | ||
| 440 | hwif->dev = &ec->dev; | ||
| 441 | } | ||
| 442 | |||
| 443 | return hwif; | ||
| 444 | } | 438 | } |
| 445 | 439 | ||
| 446 | static int __init | 440 | static int __init |
| @@ -449,6 +443,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) | |||
| 449 | ide_hwif_t *hwif; | 443 | ide_hwif_t *hwif; |
| 450 | void __iomem *base; | 444 | void __iomem *base; |
| 451 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 445 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
| 446 | hw_regs_t hw; | ||
| 452 | 447 | ||
| 453 | base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); | 448 | base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); |
| 454 | if (!base) | 449 | if (!base) |
| @@ -466,12 +461,19 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) | |||
| 466 | */ | 461 | */ |
| 467 | icside_irqdisable_arcin_v5(ec, 0); | 462 | icside_irqdisable_arcin_v5(ec, 0); |
| 468 | 463 | ||
| 469 | hwif = icside_setup(base, &icside_cardinfo_v5, ec); | 464 | icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec); |
| 465 | |||
| 466 | hwif = ide_find_port(); | ||
| 470 | if (!hwif) | 467 | if (!hwif) |
| 471 | return -ENODEV; | 468 | return -ENODEV; |
| 472 | 469 | ||
| 470 | ide_init_port_hw(hwif, &hw); | ||
| 471 | default_hwif_mmiops(hwif); | ||
| 472 | |||
| 473 | state->hwif[0] = hwif; | 473 | state->hwif[0] = hwif; |
| 474 | 474 | ||
| 475 | ecard_set_drvdata(ec, state); | ||
| 476 | |||
| 475 | idx[0] = hwif->index; | 477 | idx[0] = hwif->index; |
| 476 | 478 | ||
| 477 | ide_device_add(idx, NULL); | 479 | ide_device_add(idx, NULL); |
| @@ -497,6 +499,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) | |||
| 497 | int ret; | 499 | int ret; |
| 498 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 500 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
| 499 | struct ide_port_info d = icside_v6_port_info; | 501 | struct ide_port_info d = icside_v6_port_info; |
| 502 | hw_regs_t hw[2]; | ||
| 500 | 503 | ||
| 501 | ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); | 504 | ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); |
| 502 | if (!ioc_base) { | 505 | if (!ioc_base) { |
| @@ -525,43 +528,47 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) | |||
| 525 | 528 | ||
| 526 | state->irq_port = easi_base; | 529 | state->irq_port = easi_base; |
| 527 | state->ioc_base = ioc_base; | 530 | state->ioc_base = ioc_base; |
| 531 | state->sel = sel; | ||
| 528 | 532 | ||
| 529 | /* | 533 | /* |
| 530 | * Be on the safe side - disable interrupts | 534 | * Be on the safe side - disable interrupts |
| 531 | */ | 535 | */ |
| 532 | icside_irqdisable_arcin_v6(ec, 0); | 536 | icside_irqdisable_arcin_v6(ec, 0); |
| 533 | 537 | ||
| 538 | icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec); | ||
| 539 | icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec); | ||
| 540 | |||
| 534 | /* | 541 | /* |
| 535 | * Find and register the interfaces. | 542 | * Find and register the interfaces. |
| 536 | */ | 543 | */ |
| 537 | hwif = icside_setup(easi_base, &icside_cardinfo_v6_1, ec); | 544 | hwif = ide_find_port(); |
| 538 | mate = icside_setup(easi_base, &icside_cardinfo_v6_2, ec); | 545 | if (hwif == NULL) |
| 546 | return -ENODEV; | ||
| 539 | 547 | ||
| 540 | if (!hwif || !mate) { | 548 | ide_init_port_hw(hwif, &hw[0]); |
| 541 | ret = -ENODEV; | 549 | default_hwif_mmiops(hwif); |
| 542 | goto out; | 550 | |
| 551 | idx[0] = hwif->index; | ||
| 552 | |||
| 553 | mate = ide_find_port(); | ||
| 554 | if (mate) { | ||
| 555 | ide_init_port_hw(mate, &hw[1]); | ||
| 556 | default_hwif_mmiops(mate); | ||
| 557 | |||
| 558 | idx[1] = mate->index; | ||
| 543 | } | 559 | } |
| 544 | 560 | ||
| 545 | state->hwif[0] = hwif; | 561 | state->hwif[0] = hwif; |
| 546 | state->hwif[1] = mate; | 562 | state->hwif[1] = mate; |
| 547 | 563 | ||
| 548 | hwif->hwif_data = state; | 564 | ecard_set_drvdata(ec, state); |
| 549 | hwif->config_data = (unsigned long)ioc_base; | ||
| 550 | hwif->select_data = sel; | ||
| 551 | |||
| 552 | mate->hwif_data = state; | ||
| 553 | mate->config_data = (unsigned long)ioc_base; | ||
| 554 | mate->select_data = sel | 1; | ||
| 555 | 565 | ||
| 556 | if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) { | 566 | if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { |
| 557 | d.init_dma = icside_dma_init; | 567 | d.init_dma = icside_dma_init; |
| 558 | d.port_ops = &icside_v6_port_ops; | 568 | d.port_ops = &icside_v6_port_ops; |
| 559 | d.dma_ops = NULL; | 569 | d.dma_ops = NULL; |
| 560 | } | 570 | } |
| 561 | 571 | ||
| 562 | idx[0] = hwif->index; | ||
| 563 | idx[1] = mate->index; | ||
| 564 | |||
| 565 | ide_device_add(idx, &d); | 572 | ide_device_add(idx, &d); |
| 566 | 573 | ||
| 567 | return 0; | 574 | return 0; |
| @@ -627,10 +634,8 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
| 627 | break; | 634 | break; |
| 628 | } | 635 | } |
| 629 | 636 | ||
| 630 | if (ret == 0) { | 637 | if (ret == 0) |
| 631 | ecard_set_drvdata(ec, state); | ||
| 632 | goto out; | 638 | goto out; |
| 633 | } | ||
| 634 | 639 | ||
| 635 | kfree(state); | 640 | kfree(state); |
| 636 | release: | 641 | release: |
