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: |