Commit 7e8ba228d9f43a4e4b3ed0e6aa3399e8f30d7bc1

Authored by Ludovic Desroches
Committed by Chris Ball
1 parent 341fa4c3af

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,