diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/omap.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index c80cd58cfa07..535499f11e7c 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -547,11 +547,12 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
547 | u16 status; | 547 | u16 status; |
548 | int end_command; | 548 | int end_command; |
549 | int end_transfer; | 549 | int end_transfer; |
550 | int transfer_error; | 550 | int transfer_error, cmd_error; |
551 | 551 | ||
552 | if (host->cmd == NULL && host->data == NULL) { | 552 | if (host->cmd == NULL && host->data == NULL) { |
553 | status = OMAP_MMC_READ(host, STAT); | 553 | status = OMAP_MMC_READ(host, STAT); |
554 | dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status); | 554 | dev_info(mmc_dev(host->slots[0]->mmc), |
555 | "Spurious IRQ 0x%04x\n", status); | ||
555 | if (status != 0) { | 556 | if (status != 0) { |
556 | OMAP_MMC_WRITE(host, STAT, status); | 557 | OMAP_MMC_WRITE(host, STAT, status); |
557 | OMAP_MMC_WRITE(host, IE, 0); | 558 | OMAP_MMC_WRITE(host, IE, 0); |
@@ -562,12 +563,19 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
562 | end_command = 0; | 563 | end_command = 0; |
563 | end_transfer = 0; | 564 | end_transfer = 0; |
564 | transfer_error = 0; | 565 | transfer_error = 0; |
566 | cmd_error = 0; | ||
565 | 567 | ||
566 | while ((status = OMAP_MMC_READ(host, STAT)) != 0) { | 568 | while ((status = OMAP_MMC_READ(host, STAT)) != 0) { |
569 | int cmd; | ||
570 | |||
567 | OMAP_MMC_WRITE(host, STAT, status); | 571 | OMAP_MMC_WRITE(host, STAT, status); |
572 | if (host->cmd != NULL) | ||
573 | cmd = host->cmd->opcode; | ||
574 | else | ||
575 | cmd = -1; | ||
568 | #ifdef CONFIG_MMC_DEBUG | 576 | #ifdef CONFIG_MMC_DEBUG |
569 | dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ", | 577 | dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ", |
570 | status, host->cmd != NULL ? host->cmd->opcode : -1); | 578 | status, cmd); |
571 | mmc_omap_report_irq(status); | 579 | mmc_omap_report_irq(status); |
572 | printk("\n"); | 580 | printk("\n"); |
573 | #endif | 581 | #endif |
@@ -579,12 +587,12 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
579 | mmc_omap_xfer_data(host, 1); | 587 | mmc_omap_xfer_data(host, 1); |
580 | } | 588 | } |
581 | 589 | ||
582 | if (status & OMAP_MMC_STAT_END_OF_DATA) { | 590 | if (status & OMAP_MMC_STAT_END_OF_DATA) |
583 | end_transfer = 1; | 591 | end_transfer = 1; |
584 | } | ||
585 | 592 | ||
586 | if (status & OMAP_MMC_STAT_DATA_TOUT) { | 593 | if (status & OMAP_MMC_STAT_DATA_TOUT) { |
587 | dev_dbg(mmc_dev(host->mmc), "data timeout\n"); | 594 | dev_dbg(mmc_dev(host->mmc), "data timeout (CMD%d)\n", |
595 | cmd); | ||
588 | if (host->data) { | 596 | if (host->data) { |
589 | host->data->error = -ETIMEDOUT; | 597 | host->data->error = -ETIMEDOUT; |
590 | transfer_error = 1; | 598 | transfer_error = 1; |
@@ -608,12 +616,14 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
608 | if (host->cmd) { | 616 | if (host->cmd) { |
609 | struct mmc_omap_slot *slot = | 617 | struct mmc_omap_slot *slot = |
610 | host->current_slot; | 618 | host->current_slot; |
611 | if (!mmc_omap_cover_is_open(slot)) | 619 | if (slot == NULL || |
620 | !mmc_omap_cover_is_open(slot)) | ||
612 | dev_err(mmc_dev(host->mmc), | 621 | dev_err(mmc_dev(host->mmc), |
613 | "command timeout, CMD %d\n", | 622 | "command timeout (CMD%d)\n", |
614 | host->cmd->opcode); | 623 | cmd); |
615 | host->cmd->error = -ETIMEDOUT; | 624 | host->cmd->error = -ETIMEDOUT; |
616 | end_command = 1; | 625 | end_command = 1; |
626 | cmd_error = 1; | ||
617 | } | 627 | } |
618 | } | 628 | } |
619 | 629 | ||
@@ -621,9 +631,10 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
621 | if (host->cmd) { | 631 | if (host->cmd) { |
622 | dev_err(mmc_dev(host->mmc), | 632 | dev_err(mmc_dev(host->mmc), |
623 | "command CRC error (CMD%d, arg 0x%08x)\n", | 633 | "command CRC error (CMD%d, arg 0x%08x)\n", |
624 | host->cmd->opcode, host->cmd->arg); | 634 | cmd, host->cmd->arg); |
625 | host->cmd->error = -EILSEQ; | 635 | host->cmd->error = -EILSEQ; |
626 | end_command = 1; | 636 | end_command = 1; |
637 | cmd_error = 1; | ||
627 | } else | 638 | } else |
628 | dev_err(mmc_dev(host->mmc), | 639 | dev_err(mmc_dev(host->mmc), |
629 | "command CRC error without cmd?\n"); | 640 | "command CRC error without cmd?\n"); |
@@ -632,13 +643,13 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
632 | if (status & OMAP_MMC_STAT_CARD_ERR) { | 643 | if (status & OMAP_MMC_STAT_CARD_ERR) { |
633 | dev_dbg(mmc_dev(host->mmc), | 644 | dev_dbg(mmc_dev(host->mmc), |
634 | "ignoring card status error (CMD%d)\n", | 645 | "ignoring card status error (CMD%d)\n", |
635 | host->cmd->opcode); | 646 | cmd); |
636 | end_command = 1; | 647 | end_command = 1; |
637 | } | 648 | } |
638 | 649 | ||
639 | /* | 650 | /* |
640 | * NOTE: On 1610 the END_OF_CMD may come too early when | 651 | * NOTE: On 1610 the END_OF_CMD may come too early when |
641 | * starting a write | 652 | * starting a write |
642 | */ | 653 | */ |
643 | if ((status & OMAP_MMC_STAT_END_OF_CMD) && | 654 | if ((status & OMAP_MMC_STAT_END_OF_CMD) && |
644 | (!(status & OMAP_MMC_STAT_A_EMPTY))) { | 655 | (!(status & OMAP_MMC_STAT_A_EMPTY))) { |
@@ -646,13 +657,14 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
646 | } | 657 | } |
647 | } | 658 | } |
648 | 659 | ||
649 | if (end_command) { | 660 | if (end_command) |
650 | mmc_omap_cmd_done(host, host->cmd); | 661 | mmc_omap_cmd_done(host, host->cmd); |
662 | if (host->data != NULL) { | ||
663 | if (transfer_error) | ||
664 | mmc_omap_xfer_done(host, host->data); | ||
665 | else if (end_transfer) | ||
666 | mmc_omap_end_of_data(host, host->data); | ||
651 | } | 667 | } |
652 | if (transfer_error) | ||
653 | mmc_omap_xfer_done(host, host->data); | ||
654 | else if (end_transfer) | ||
655 | mmc_omap_end_of_data(host, host->data); | ||
656 | 668 | ||
657 | return IRQ_HANDLED; | 669 | return IRQ_HANDLED; |
658 | } | 670 | } |