diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-12 21:11:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-12 21:11:33 -0400 |
commit | f7d02ae76ebbf5b8a9531fe150c49e126a397704 (patch) | |
tree | bcfdcab6e70658d55a3c843694e04e938bf9168f /drivers/ata | |
parent | 78db2ad6f4df9145bfd6aab1c0f1c56d615288ec (diff) | |
parent | 158304ef09a28c7f2dd37d78f536a4e09ba084a1 (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (30 commits)
[ARM] Use new get_irqnr_preamble
[ARM] Ensure machine class menu is sorted alphabetically
[ARM] 4333/2: KS8695: Micrel Development board
[ARM] 4332/2: KS8695: Serial driver
[ARM] 4331/3: Support for Micrel/Kendin KS8695 processor
[ARM] 4371/1: AT91: Support for Atmel AT91SAM9RL-EK development board
[ARM] 4372/1: Define byte sizes in asm-arm/sizes.h
[ARM] 4370/3: AT91: Support for Atmel AT91SAM9RL processors.
[ARM] Update mach-types
[ARM] export symbol csum_partial_copy_from_user
[ARM] iop13xx: msi support
[ARM] stacktrace fix
[ARM] Spinlock initializer cleanup
[ARM] remove useless config option GENERIC_BUST_SPINLOCK
[ARM] 4303/3: base kernel support for TI DaVinci
[ARM] 4369/1: AT91: Fix circular dependency in header files
[ARM] 4368/1: S3C24xx: build fix
[ARM] 4364/1: AT91: LEDS on AT91SAM9261-EK
[ARM] Fix iop32x/iop33x build
[ARM] EBSA110: fix build errors caused by missing "const"
...
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/pata_icside.c | 184 |
1 files changed, 96 insertions, 88 deletions
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c index dbc8ee2adcf0..c791a46df461 100644 --- a/drivers/ata/pata_icside.c +++ b/drivers/ata/pata_icside.c | |||
@@ -60,6 +60,18 @@ struct pata_icside_state { | |||
60 | struct scatterlist sg[PATA_ICSIDE_MAX_SG]; | 60 | struct scatterlist sg[PATA_ICSIDE_MAX_SG]; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | struct pata_icside_info { | ||
64 | struct pata_icside_state *state; | ||
65 | struct expansion_card *ec; | ||
66 | void __iomem *base; | ||
67 | void __iomem *irqaddr; | ||
68 | unsigned int irqmask; | ||
69 | const expansioncard_ops_t *irqops; | ||
70 | unsigned int mwdma_mask; | ||
71 | unsigned int nr_ports; | ||
72 | const struct portinfo *port[2]; | ||
73 | }; | ||
74 | |||
63 | #define ICS_TYPE_A3IN 0 | 75 | #define ICS_TYPE_A3IN 0 |
64 | #define ICS_TYPE_A3USER 1 | 76 | #define ICS_TYPE_A3USER 1 |
65 | #define ICS_TYPE_V6 3 | 77 | #define ICS_TYPE_V6 3 |
@@ -269,9 +281,10 @@ static u8 pata_icside_bmdma_status(struct ata_port *ap) | |||
269 | return readb(irq_port) & 1 ? ATA_DMA_INTR : 0; | 281 | return readb(irq_port) & 1 ? ATA_DMA_INTR : 0; |
270 | } | 282 | } |
271 | 283 | ||
272 | static int icside_dma_init(struct ata_probe_ent *ae, struct expansion_card *ec) | 284 | static int icside_dma_init(struct pata_icside_info *info) |
273 | { | 285 | { |
274 | struct pata_icside_state *state = ae->private_data; | 286 | struct pata_icside_state *state = info->state; |
287 | struct expansion_card *ec = info->ec; | ||
275 | int i; | 288 | int i; |
276 | 289 | ||
277 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 290 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
@@ -281,7 +294,7 @@ static int icside_dma_init(struct ata_probe_ent *ae, struct expansion_card *ec) | |||
281 | 294 | ||
282 | if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { | 295 | if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { |
283 | state->dma = ec->dma; | 296 | state->dma = ec->dma; |
284 | ae->mwdma_mask = 0x07; /* MW0..2 */ | 297 | info->mwdma_mask = 0x07; /* MW0..2 */ |
285 | } | 298 | } |
286 | 299 | ||
287 | return 0; | 300 | return 0; |
@@ -371,6 +384,8 @@ static struct ata_port_operations pata_icside_port_ops = { | |||
371 | .check_status = ata_check_status, | 384 | .check_status = ata_check_status, |
372 | .dev_select = ata_std_dev_select, | 385 | .dev_select = ata_std_dev_select, |
373 | 386 | ||
387 | .cable_detect = ata_cable_40wire, | ||
388 | |||
374 | .bmdma_setup = pata_icside_bmdma_setup, | 389 | .bmdma_setup = pata_icside_bmdma_setup, |
375 | .bmdma_start = pata_icside_bmdma_start, | 390 | .bmdma_start = pata_icside_bmdma_start, |
376 | 391 | ||
@@ -385,7 +400,6 @@ static struct ata_port_operations pata_icside_port_ops = { | |||
385 | .error_handler = ata_bmdma_error_handler, | 400 | .error_handler = ata_bmdma_error_handler, |
386 | .post_internal_cmd = pata_icside_bmdma_stop, | 401 | .post_internal_cmd = pata_icside_bmdma_stop, |
387 | 402 | ||
388 | .irq_handler = ata_interrupt, | ||
389 | .irq_clear = ata_dummy_noret, | 403 | .irq_clear = ata_dummy_noret, |
390 | .irq_on = ata_irq_on, | 404 | .irq_on = ata_irq_on, |
391 | .irq_ack = pata_icside_irq_ack, | 405 | .irq_ack = pata_icside_irq_ack, |
@@ -396,11 +410,10 @@ static struct ata_port_operations pata_icside_port_ops = { | |||
396 | .bmdma_status = pata_icside_bmdma_status, | 410 | .bmdma_status = pata_icside_bmdma_status, |
397 | }; | 411 | }; |
398 | 412 | ||
399 | static void | 413 | static void __devinit |
400 | pata_icside_add_port(struct ata_probe_ent *ae, void __iomem *base, | 414 | pata_icside_setup_ioaddr(struct ata_ioports *ioaddr, void __iomem *base, |
401 | const struct portinfo *info) | 415 | const struct portinfo *info) |
402 | { | 416 | { |
403 | struct ata_ioports *ioaddr = &ae->port[ae->n_ports++]; | ||
404 | void __iomem *cmd = base + info->dataoffset; | 417 | void __iomem *cmd = base + info->dataoffset; |
405 | 418 | ||
406 | ioaddr->cmd_addr = cmd; | 419 | ioaddr->cmd_addr = cmd; |
@@ -419,58 +432,44 @@ pata_icside_add_port(struct ata_probe_ent *ae, void __iomem *base, | |||
419 | ioaddr->altstatus_addr = ioaddr->ctl_addr; | 432 | ioaddr->altstatus_addr = ioaddr->ctl_addr; |
420 | } | 433 | } |
421 | 434 | ||
422 | static int __init | 435 | static int __devinit pata_icside_register_v5(struct pata_icside_info *info) |
423 | pata_icside_register_v5(struct ata_probe_ent *ae, struct expansion_card *ec) | ||
424 | { | 436 | { |
425 | struct pata_icside_state *state = ae->private_data; | 437 | struct pata_icside_state *state = info->state; |
426 | void __iomem *base; | 438 | void __iomem *base; |
427 | 439 | ||
428 | base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), | 440 | base = ecardm_iomap(info->ec, ECARD_RES_MEMC, 0, 0); |
429 | ecard_resource_len(ec, ECARD_RES_MEMC)); | ||
430 | if (!base) | 441 | if (!base) |
431 | return -ENOMEM; | 442 | return -ENOMEM; |
432 | 443 | ||
433 | state->irq_port = base; | 444 | state->irq_port = base; |
434 | 445 | ||
435 | ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT; | 446 | info->base = base; |
436 | ec->irqmask = 1; | 447 | info->irqaddr = base + ICS_ARCIN_V5_INTRSTAT; |
437 | ec->irq_data = state; | 448 | info->irqmask = 1; |
438 | ec->ops = &pata_icside_ops_arcin_v5; | 449 | info->irqops = &pata_icside_ops_arcin_v5; |
439 | 450 | info->nr_ports = 1; | |
440 | /* | 451 | info->port[0] = &pata_icside_portinfo_v5; |
441 | * Be on the safe side - disable interrupts | ||
442 | */ | ||
443 | ec->ops->irqdisable(ec, ec->irq); | ||
444 | |||
445 | pata_icside_add_port(ae, base, &pata_icside_portinfo_v5); | ||
446 | 452 | ||
447 | return 0; | 453 | return 0; |
448 | } | 454 | } |
449 | 455 | ||
450 | static int __init | 456 | static int __devinit pata_icside_register_v6(struct pata_icside_info *info) |
451 | pata_icside_register_v6(struct ata_probe_ent *ae, struct expansion_card *ec) | ||
452 | { | 457 | { |
453 | struct pata_icside_state *state = ae->private_data; | 458 | struct pata_icside_state *state = info->state; |
459 | struct expansion_card *ec = info->ec; | ||
454 | void __iomem *ioc_base, *easi_base; | 460 | void __iomem *ioc_base, *easi_base; |
455 | unsigned int sel = 0; | 461 | unsigned int sel = 0; |
456 | int ret; | ||
457 | 462 | ||
458 | ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), | 463 | ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); |
459 | ecard_resource_len(ec, ECARD_RES_IOCFAST)); | 464 | if (!ioc_base) |
460 | if (!ioc_base) { | 465 | return -ENOMEM; |
461 | ret = -ENOMEM; | ||
462 | goto out; | ||
463 | } | ||
464 | 466 | ||
465 | easi_base = ioc_base; | 467 | easi_base = ioc_base; |
466 | 468 | ||
467 | if (ecard_resource_flags(ec, ECARD_RES_EASI)) { | 469 | if (ecard_resource_flags(ec, ECARD_RES_EASI)) { |
468 | easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI), | 470 | easi_base = ecardm_iomap(ec, ECARD_RES_EASI, 0, 0); |
469 | ecard_resource_len(ec, ECARD_RES_EASI)); | 471 | if (!easi_base) |
470 | if (!easi_base) { | 472 | return -ENOMEM; |
471 | ret = -ENOMEM; | ||
472 | goto unmap_slot; | ||
473 | } | ||
474 | 473 | ||
475 | /* | 474 | /* |
476 | * Enable access to the EASI region. | 475 | * Enable access to the EASI region. |
@@ -480,45 +479,72 @@ pata_icside_register_v6(struct ata_probe_ent *ae, struct expansion_card *ec) | |||
480 | 479 | ||
481 | writeb(sel, ioc_base); | 480 | writeb(sel, ioc_base); |
482 | 481 | ||
483 | ec->irq_data = state; | ||
484 | ec->ops = &pata_icside_ops_arcin_v6; | ||
485 | |||
486 | state->irq_port = easi_base; | 482 | state->irq_port = easi_base; |
487 | state->ioc_base = ioc_base; | 483 | state->ioc_base = ioc_base; |
488 | state->port[0].port_sel = sel; | 484 | state->port[0].port_sel = sel; |
489 | state->port[1].port_sel = sel | 1; | 485 | state->port[1].port_sel = sel | 1; |
490 | 486 | ||
491 | /* | 487 | /* |
492 | * Be on the safe side - disable interrupts | ||
493 | */ | ||
494 | ec->ops->irqdisable(ec, ec->irq); | ||
495 | |||
496 | /* | ||
497 | * Find and register the interfaces. | ||
498 | */ | ||
499 | pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_1); | ||
500 | pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_2); | ||
501 | |||
502 | /* | ||
503 | * FIXME: work around libata's aversion to calling port_disable. | 488 | * FIXME: work around libata's aversion to calling port_disable. |
504 | * This permanently disables interrupts on port 0 - bad luck if | 489 | * This permanently disables interrupts on port 0 - bad luck if |
505 | * you have a drive on that port. | 490 | * you have a drive on that port. |
506 | */ | 491 | */ |
507 | state->port[0].disabled = 1; | 492 | state->port[0].disabled = 1; |
508 | 493 | ||
509 | return icside_dma_init(ae, ec); | 494 | info->base = easi_base; |
495 | info->irqops = &pata_icside_ops_arcin_v6; | ||
496 | info->nr_ports = 2; | ||
497 | info->port[0] = &pata_icside_portinfo_v6_1; | ||
498 | info->port[1] = &pata_icside_portinfo_v6_2; | ||
510 | 499 | ||
511 | unmap_slot: | 500 | return icside_dma_init(info); |
512 | iounmap(ioc_base); | 501 | } |
513 | out: | 502 | |
514 | return ret; | 503 | static int __devinit pata_icside_add_ports(struct pata_icside_info *info) |
504 | { | ||
505 | struct expansion_card *ec = info->ec; | ||
506 | struct ata_host *host; | ||
507 | int i; | ||
508 | |||
509 | if (info->irqaddr) { | ||
510 | ec->irqaddr = info->irqaddr; | ||
511 | ec->irqmask = info->irqmask; | ||
512 | } | ||
513 | if (info->irqops) | ||
514 | ecard_setirq(ec, info->irqops, info->state); | ||
515 | |||
516 | /* | ||
517 | * Be on the safe side - disable interrupts | ||
518 | */ | ||
519 | ec->ops->irqdisable(ec, ec->irq); | ||
520 | |||
521 | host = ata_host_alloc(&ec->dev, info->nr_ports); | ||
522 | if (!host) | ||
523 | return -ENOMEM; | ||
524 | |||
525 | host->private_data = info->state; | ||
526 | host->flags = ATA_HOST_SIMPLEX; | ||
527 | |||
528 | for (i = 0; i < info->nr_ports; i++) { | ||
529 | struct ata_port *ap = host->ports[i]; | ||
530 | |||
531 | ap->pio_mask = 0x1f; | ||
532 | ap->mwdma_mask = info->mwdma_mask; | ||
533 | ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; | ||
534 | ap->ops = &pata_icside_port_ops; | ||
535 | |||
536 | pata_icside_setup_ioaddr(&ap->ioaddr, info->base, info->port[i]); | ||
537 | } | ||
538 | |||
539 | return ata_host_activate(host, ec->irq, ata_interrupt, 0, | ||
540 | &pata_icside_sht); | ||
515 | } | 541 | } |
516 | 542 | ||
517 | static int __devinit | 543 | static int __devinit |
518 | pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) | 544 | pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) |
519 | { | 545 | { |
520 | struct pata_icside_state *state; | 546 | struct pata_icside_state *state; |
521 | struct ata_probe_ent ae; | 547 | struct pata_icside_info info; |
522 | void __iomem *idmem; | 548 | void __iomem *idmem; |
523 | int ret; | 549 | int ret; |
524 | 550 | ||
@@ -526,7 +552,7 @@ pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
526 | if (ret) | 552 | if (ret) |
527 | goto out; | 553 | goto out; |
528 | 554 | ||
529 | state = kzalloc(sizeof(struct pata_icside_state), GFP_KERNEL); | 555 | state = devm_kzalloc(&ec->dev, sizeof(*state), GFP_KERNEL); |
530 | if (!state) { | 556 | if (!state) { |
531 | ret = -ENOMEM; | 557 | ret = -ENOMEM; |
532 | goto release; | 558 | goto release; |
@@ -535,8 +561,7 @@ pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
535 | state->type = ICS_TYPE_NOTYPE; | 561 | state->type = ICS_TYPE_NOTYPE; |
536 | state->dma = NO_DMA; | 562 | state->dma = NO_DMA; |
537 | 563 | ||
538 | idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), | 564 | idmem = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); |
539 | ecard_resource_len(ec, ECARD_RES_IOCFAST)); | ||
540 | if (idmem) { | 565 | if (idmem) { |
541 | unsigned int type; | 566 | unsigned int type; |
542 | 567 | ||
@@ -544,21 +569,14 @@ pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
544 | type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1; | 569 | type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1; |
545 | type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2; | 570 | type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2; |
546 | type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3; | 571 | type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3; |
547 | iounmap(idmem); | 572 | ecardm_iounmap(ec, idmem); |
548 | 573 | ||
549 | state->type = type; | 574 | state->type = type; |
550 | } | 575 | } |
551 | 576 | ||
552 | memset(&ae, 0, sizeof(ae)); | 577 | memset(&info, 0, sizeof(info)); |
553 | INIT_LIST_HEAD(&ae.node); | 578 | info.state = state; |
554 | ae.dev = &ec->dev; | 579 | info.ec = ec; |
555 | ae.port_ops = &pata_icside_port_ops; | ||
556 | ae.sht = &pata_icside_sht; | ||
557 | ae.pio_mask = 0x1f; | ||
558 | ae.irq = ec->irq; | ||
559 | ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; | ||
560 | ae._host_flags = ATA_HOST_SIMPLEX; | ||
561 | ae.private_data = state; | ||
562 | 580 | ||
563 | switch (state->type) { | 581 | switch (state->type) { |
564 | case ICS_TYPE_A3IN: | 582 | case ICS_TYPE_A3IN: |
@@ -572,11 +590,11 @@ pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
572 | break; | 590 | break; |
573 | 591 | ||
574 | case ICS_TYPE_V5: | 592 | case ICS_TYPE_V5: |
575 | ret = pata_icside_register_v5(&ae, ec); | 593 | ret = pata_icside_register_v5(&info); |
576 | break; | 594 | break; |
577 | 595 | ||
578 | case ICS_TYPE_V6: | 596 | case ICS_TYPE_V6: |
579 | ret = pata_icside_register_v6(&ae, ec); | 597 | ret = pata_icside_register_v6(&info); |
580 | break; | 598 | break; |
581 | 599 | ||
582 | default: | 600 | default: |
@@ -586,12 +604,11 @@ pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
586 | } | 604 | } |
587 | 605 | ||
588 | if (ret == 0) | 606 | if (ret == 0) |
589 | ret = ata_device_add(&ae) == 0 ? -ENODEV : 0; | 607 | ret = pata_icside_add_ports(&info); |
590 | 608 | ||
591 | if (ret == 0) | 609 | if (ret == 0) |
592 | goto out; | 610 | goto out; |
593 | 611 | ||
594 | kfree(state); | ||
595 | release: | 612 | release: |
596 | ecard_release_resources(ec); | 613 | ecard_release_resources(ec); |
597 | out: | 614 | out: |
@@ -609,8 +626,7 @@ static void pata_icside_shutdown(struct expansion_card *ec) | |||
609 | * this register via that region. | 626 | * this register via that region. |
610 | */ | 627 | */ |
611 | local_irq_save(flags); | 628 | local_irq_save(flags); |
612 | if (ec->ops) | 629 | ec->ops->irqdisable(ec, ec->irq); |
613 | ec->ops->irqdisable(ec, ec->irq); | ||
614 | local_irq_restore(flags); | 630 | local_irq_restore(flags); |
615 | 631 | ||
616 | /* | 632 | /* |
@@ -638,17 +654,9 @@ static void __devexit pata_icside_remove(struct expansion_card *ec) | |||
638 | * don't NULL out the drvdata - devres/libata wants it | 654 | * don't NULL out the drvdata - devres/libata wants it |
639 | * to free the ata_host structure. | 655 | * to free the ata_host structure. |
640 | */ | 656 | */ |
641 | ec->ops = NULL; | ||
642 | ec->irq_data = NULL; | ||
643 | |||
644 | if (state->dma != NO_DMA) | 657 | if (state->dma != NO_DMA) |
645 | free_dma(state->dma); | 658 | free_dma(state->dma); |
646 | if (state->ioc_base) | ||
647 | iounmap(state->ioc_base); | ||
648 | if (state->ioc_base != state->irq_port) | ||
649 | iounmap(state->irq_port); | ||
650 | 659 | ||
651 | kfree(state); | ||
652 | ecard_release_resources(ec); | 660 | ecard_release_resources(ec); |
653 | } | 661 | } |
654 | 662 | ||