Commit 7e8ba228d9f43a4e4b3ed0e6aa3399e8f30d7bc1
Committed by
Chris Ball
1 parent
341fa4c3af
Exists in
master
and in
6 other branches
mmc: atmel-mci: fix a potential issue about pending PDC interrupts
This patch fixes a potential issue about PDC interrupts. For example we have a ENDRX pending interrupt and a RXBUFF pending interrupt. We have received the RXBUFF interrupt but the transfer is not finished (so we didn't have time to give a new buffer to the PDC controller). Then we will compute ENDRX interrupt and we will give a new buffer to the PDC controller, just after we will compute the RXBUFF interrupt and give one or two new buffers to the PDC controller but we are not sure that the first buffer given has been filled. So in this situation we may have "lost" one sg buffer. It's the same for transmission. Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Showing 1 changed file with 17 additions and 15 deletions Side-by-side Diff
drivers/mmc/host/atmel-mci.c
... | ... | @@ -1729,17 +1729,9 @@ |
1729 | 1729 | tasklet_schedule(&host->tasklet); |
1730 | 1730 | } |
1731 | 1731 | |
1732 | - if (pending & ATMCI_ENDTX) { | |
1733 | - atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX); | |
1734 | - if (host->data_size) { | |
1735 | - atmci_pdc_set_single_buf(host, | |
1736 | - XFER_TRANSMIT, PDC_SECOND_BUF); | |
1737 | - atmci_writel(host, ATMCI_IER, ATMCI_ENDTX); | |
1738 | - } | |
1739 | - } | |
1740 | - | |
1741 | 1732 | if (pending & ATMCI_TXBUFE) { |
1742 | 1733 | atmci_writel(host, ATMCI_IDR, ATMCI_TXBUFE); |
1734 | + atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX); | |
1743 | 1735 | /* |
1744 | 1736 | * We can receive this interruption before having configured |
1745 | 1737 | * the second pdc buffer, so we need to reconfigure first and |
1746 | 1738 | |
1747 | 1739 | |
1748 | 1740 | |
1749 | 1741 | |
... | ... | @@ -1747,24 +1739,24 @@ |
1747 | 1739 | */ |
1748 | 1740 | if (host->data_size) { |
1749 | 1741 | atmci_pdc_set_both_buf(host, XFER_TRANSMIT); |
1742 | + atmci_writel(host, ATMCI_IER, ATMCI_ENDTX); | |
1750 | 1743 | atmci_writel(host, ATMCI_IER, ATMCI_TXBUFE); |
1751 | 1744 | } else { |
1752 | 1745 | atmci_pdc_complete(host); |
1753 | 1746 | } |
1754 | - } | |
1747 | + } else if (pending & ATMCI_ENDTX) { | |
1748 | + atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX); | |
1755 | 1749 | |
1756 | - if (pending & ATMCI_ENDRX) { | |
1757 | - atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX); | |
1758 | - | |
1759 | 1750 | if (host->data_size) { |
1760 | 1751 | atmci_pdc_set_single_buf(host, |
1761 | - XFER_RECEIVE, PDC_SECOND_BUF); | |
1762 | - atmci_writel(host, ATMCI_IER, ATMCI_ENDRX); | |
1752 | + XFER_TRANSMIT, PDC_SECOND_BUF); | |
1753 | + atmci_writel(host, ATMCI_IER, ATMCI_ENDTX); | |
1763 | 1754 | } |
1764 | 1755 | } |
1765 | 1756 | |
1766 | 1757 | if (pending & ATMCI_RXBUFF) { |
1767 | 1758 | atmci_writel(host, ATMCI_IDR, ATMCI_RXBUFF); |
1759 | + atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX); | |
1768 | 1760 | /* |
1769 | 1761 | * We can receive this interruption before having configured |
1770 | 1762 | * the second pdc buffer, so we need to reconfigure first and |
1771 | 1763 | |
1772 | 1764 | |
... | ... | @@ -1772,11 +1764,21 @@ |
1772 | 1764 | */ |
1773 | 1765 | if (host->data_size) { |
1774 | 1766 | atmci_pdc_set_both_buf(host, XFER_RECEIVE); |
1767 | + atmci_writel(host, ATMCI_IER, ATMCI_ENDRX); | |
1775 | 1768 | atmci_writel(host, ATMCI_IER, ATMCI_RXBUFF); |
1776 | 1769 | } else { |
1777 | 1770 | atmci_pdc_complete(host); |
1778 | 1771 | } |
1772 | + } else if (pending & ATMCI_ENDRX) { | |
1773 | + atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX); | |
1774 | + | |
1775 | + if (host->data_size) { | |
1776 | + atmci_pdc_set_single_buf(host, | |
1777 | + XFER_RECEIVE, PDC_SECOND_BUF); | |
1778 | + atmci_writel(host, ATMCI_IER, ATMCI_ENDRX); | |
1779 | + } | |
1779 | 1780 | } |
1781 | + | |
1780 | 1782 | |
1781 | 1783 | if (pending & ATMCI_NOTBUSY) { |
1782 | 1784 | atmci_writel(host, ATMCI_IDR, |