diff options
author | Andrew Victor <andrew@sanpeople.com> | 2006-10-23 08:50:09 -0400 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2006-12-11 03:47:12 -0500 |
commit | df05a303e3b8a0c32764941200bec76d729126bc (patch) | |
tree | 099cc16615b73c72f8e0f60e6bce2b8f66804524 /drivers | |
parent | 3dd3b039d489dfbc907c64a161fd2231ddcdea48 (diff) |
AT91 MMC 4 : Interrupt handler cleanup
This patch simplifies the AT91RM9200 MMC interrupt handler code so that
it doesn't re-read the Interrupt Status and Interrupt Mask registers
multiple times.
Also defined AT91_MCI_ERRORS instead of using the hard-coded 0xffff0000.
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/at91_mci.c | 88 |
1 files changed, 43 insertions, 45 deletions
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c index 567119e93dff..2f11d67d8d07 100644 --- a/drivers/mmc/at91_mci.c +++ b/drivers/mmc/at91_mci.c | |||
@@ -80,10 +80,12 @@ | |||
80 | 80 | ||
81 | #undef SUPPORT_4WIRE | 81 | #undef SUPPORT_4WIRE |
82 | 82 | ||
83 | #define FL_SENT_COMMAND (1 << 0) | 83 | #define FL_SENT_COMMAND (1 << 0) |
84 | #define FL_SENT_STOP (1 << 1) | 84 | #define FL_SENT_STOP (1 << 1) |
85 | |||
86 | 85 | ||
86 | #define AT91_MCI_ERRORS (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE \ | ||
87 | | AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE \ | ||
88 | | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE) | ||
87 | 89 | ||
88 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) | 90 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) |
89 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) | 91 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) |
@@ -507,7 +509,7 @@ static void at91mci_process_command(struct at91mci_host *host, struct mmc_comman | |||
507 | pr_debug("setting ier to %08X\n", ier); | 509 | pr_debug("setting ier to %08X\n", ier); |
508 | 510 | ||
509 | /* Stop on errors or the required value */ | 511 | /* Stop on errors or the required value */ |
510 | at91_mci_write(host, AT91_MCI_IER, 0xffff0000 | ier); | 512 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier); |
511 | } | 513 | } |
512 | 514 | ||
513 | /* | 515 | /* |
@@ -652,39 +654,40 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) | |||
652 | { | 654 | { |
653 | struct at91mci_host *host = devid; | 655 | struct at91mci_host *host = devid; |
654 | int completed = 0; | 656 | int completed = 0; |
655 | 657 | unsigned int int_status, int_mask; | |
656 | unsigned int int_status; | ||
657 | 658 | ||
658 | int_status = at91_mci_read(host, AT91_MCI_SR); | 659 | int_status = at91_mci_read(host, AT91_MCI_SR); |
659 | pr_debug("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(host, AT91_MCI_IMR), | 660 | int_mask = at91_mci_read(host, AT91_MCI_IMR); |
660 | int_status & at91_mci_read(host, AT91_MCI_IMR)); | 661 | |
661 | 662 | pr_debug("MCI irq: status = %08X, %08lX, %08lX\n", int_status, int_mask, | |
662 | if ((int_status & at91_mci_read(host, AT91_MCI_IMR)) & 0xffff0000) | 663 | int_status & int_mask); |
664 | |||
665 | int_status = int_status & int_mask; | ||
666 | |||
667 | if (int_status & AT91_MCI_ERRORS) { | ||
663 | completed = 1; | 668 | completed = 1; |
669 | |||
670 | if (int_status & AT91_MCI_UNRE) | ||
671 | pr_debug("MMC: Underrun error\n"); | ||
672 | if (int_status & AT91_MCI_OVRE) | ||
673 | pr_debug("MMC: Overrun error\n"); | ||
674 | if (int_status & AT91_MCI_DTOE) | ||
675 | pr_debug("MMC: Data timeout\n"); | ||
676 | if (int_status & AT91_MCI_DCRCE) | ||
677 | pr_debug("MMC: CRC error in data\n"); | ||
678 | if (int_status & AT91_MCI_RTOE) | ||
679 | pr_debug("MMC: Response timeout\n"); | ||
680 | if (int_status & AT91_MCI_RENDE) | ||
681 | pr_debug("MMC: Response end bit error\n"); | ||
682 | if (int_status & AT91_MCI_RCRCE) | ||
683 | pr_debug("MMC: Response CRC error\n"); | ||
684 | if (int_status & AT91_MCI_RDIRE) | ||
685 | pr_debug("MMC: Response direction error\n"); | ||
686 | if (int_status & AT91_MCI_RINDE) | ||
687 | pr_debug("MMC: Response index error\n"); | ||
688 | } else { | ||
689 | /* Only continue processing if no errors */ | ||
664 | 690 | ||
665 | int_status &= at91_mci_read(host, AT91_MCI_IMR); | ||
666 | |||
667 | if (int_status & AT91_MCI_UNRE) | ||
668 | pr_debug("MMC: Underrun error\n"); | ||
669 | if (int_status & AT91_MCI_OVRE) | ||
670 | pr_debug("MMC: Overrun error\n"); | ||
671 | if (int_status & AT91_MCI_DTOE) | ||
672 | pr_debug("MMC: Data timeout\n"); | ||
673 | if (int_status & AT91_MCI_DCRCE) | ||
674 | pr_debug("MMC: CRC error in data\n"); | ||
675 | if (int_status & AT91_MCI_RTOE) | ||
676 | pr_debug("MMC: Response timeout\n"); | ||
677 | if (int_status & AT91_MCI_RENDE) | ||
678 | pr_debug("MMC: Response end bit error\n"); | ||
679 | if (int_status & AT91_MCI_RCRCE) | ||
680 | pr_debug("MMC: Response CRC error\n"); | ||
681 | if (int_status & AT91_MCI_RDIRE) | ||
682 | pr_debug("MMC: Response direction error\n"); | ||
683 | if (int_status & AT91_MCI_RINDE) | ||
684 | pr_debug("MMC: Response index error\n"); | ||
685 | |||
686 | /* Only continue processing if no errors */ | ||
687 | if (!completed) { | ||
688 | if (int_status & AT91_MCI_TXBUFE) { | 691 | if (int_status & AT91_MCI_TXBUFE) { |
689 | pr_debug("TX buffer empty\n"); | 692 | pr_debug("TX buffer empty\n"); |
690 | at91_mci_handle_transmitted(host); | 693 | at91_mci_handle_transmitted(host); |
@@ -695,9 +698,8 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) | |||
695 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); | 698 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); |
696 | } | 699 | } |
697 | 700 | ||
698 | if (int_status & AT91_MCI_ENDTX) { | 701 | if (int_status & AT91_MCI_ENDTX) |
699 | pr_debug("Transmit has ended\n"); | 702 | pr_debug("Transmit has ended\n"); |
700 | } | ||
701 | 703 | ||
702 | if (int_status & AT91_MCI_ENDRX) { | 704 | if (int_status & AT91_MCI_ENDRX) { |
703 | pr_debug("Receive has ended\n"); | 705 | pr_debug("Receive has ended\n"); |
@@ -709,34 +711,30 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) | |||
709 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); | 711 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); |
710 | } | 712 | } |
711 | 713 | ||
712 | if (int_status & AT91_MCI_DTIP) { | 714 | if (int_status & AT91_MCI_DTIP) |
713 | pr_debug("Data transfer in progress\n"); | 715 | pr_debug("Data transfer in progress\n"); |
714 | } | ||
715 | 716 | ||
716 | if (int_status & AT91_MCI_BLKE) { | 717 | if (int_status & AT91_MCI_BLKE) |
717 | pr_debug("Block transfer has ended\n"); | 718 | pr_debug("Block transfer has ended\n"); |
718 | } | ||
719 | 719 | ||
720 | if (int_status & AT91_MCI_TXRDY) { | 720 | if (int_status & AT91_MCI_TXRDY) |
721 | pr_debug("Ready to transmit\n"); | 721 | pr_debug("Ready to transmit\n"); |
722 | } | ||
723 | 722 | ||
724 | if (int_status & AT91_MCI_RXRDY) { | 723 | if (int_status & AT91_MCI_RXRDY) |
725 | pr_debug("Ready to receive\n"); | 724 | pr_debug("Ready to receive\n"); |
726 | } | ||
727 | 725 | ||
728 | if (int_status & AT91_MCI_CMDRDY) { | 726 | if (int_status & AT91_MCI_CMDRDY) { |
729 | pr_debug("Command ready\n"); | 727 | pr_debug("Command ready\n"); |
730 | completed = 1; | 728 | completed = 1; |
731 | } | 729 | } |
732 | } | 730 | } |
733 | at91_mci_write(host, AT91_MCI_IDR, int_status); | ||
734 | 731 | ||
735 | if (completed) { | 732 | if (completed) { |
736 | pr_debug("Completed command\n"); | 733 | pr_debug("Completed command\n"); |
737 | at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); | 734 | at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); |
738 | at91mci_completed_command(host); | 735 | at91mci_completed_command(host); |
739 | } | 736 | } else |
737 | at91_mci_write(host, AT91_MCI_IDR, int_status); | ||
740 | 738 | ||
741 | return IRQ_HANDLED; | 739 | return IRQ_HANDLED; |
742 | } | 740 | } |