]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
mmc: sdhci: Fix PIO mode transfer sequence
authorPavan Kunapuli <pkunapuli@nvidia.com>
Tue, 11 Nov 2014 08:11:38 +0000 (13:41 +0530)
committerPavan Kunapuli <pkunapuli@nvidia.com>
Wed, 6 May 2015 14:46:31 +0000 (07:46 -0700)
As per SD host specification, in PIO data transfer, the driver should
wait for buffer ready interrupt from the host, transfer one block of
data and wait for the next interrupt before transferring the next block.

Bug 1507868

Reviewed-on: http://git-master/r/601081
(cherry picked from commit d5bb467761f33241e0aefc4d5a7d4ac6e263d7b8)
Change-Id: I6b36091a1826e4c264bd1589bb7421a22bc9f051
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Reviewed-on: http://git-master/r/739656
Reviewed-by: Automatic_Commit_Validation_User
drivers/mmc/host/sdhci.c

index 49c182070bf4a425a1dcf3ac588e8c385301c306..23e08a04c70ea8ebdc5b15562d33a71de44f2eef 100644 (file)
@@ -434,9 +434,6 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
 
        BUG_ON(!host->data);
 
-       if (host->blocks == 0)
-               return;
-
        if (host->data->flags & MMC_DATA_READ)
                mask = SDHCI_DATA_AVAILABLE;
        else
@@ -451,7 +448,13 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
                (host->data->blocks == 1))
                mask = ~0;
 
-       while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+       /*
+        * Start the transfer if the present state register indicates
+        * SDHCI_DATA_AVAILABLE or SDHCI_SPACE_AVAILABLE. The driver should
+        * transfer one complete block of data and wait for the buffer ready
+        * interrupt to transfer the next block of data.
+        */
+       if (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
                if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
                        udelay(100);
 
@@ -459,10 +462,6 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
                        sdhci_read_block_pio(host);
                else
                        sdhci_write_block_pio(host);
-
-               host->blocks--;
-               if (host->blocks == 0)
-                       break;
        }
 
        DBG("PIO transfer complete.\n");