ARM: 7551/1: mmc: mmci: Fix incorrect handling of HW flow control for SDIO
authorUlf Hansson <ulf.hansson@linaro.org>
Fri, 12 Oct 2012 13:01:50 +0000 (14:01 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 18 Oct 2012 10:06:22 +0000 (11:06 +0100)
For data writes <= 8 bytes, HW flow control was disabled but
never re-enabled when the transfer was completed. This meant
that a following read request would give buffer overrun errors.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Johan Rudholm <johan.rudholm@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/mmc/host/mmci.c

index edc3e9baf0e7bea7be23841c11692968ad2a344b..877079e778cd43f64d59383bb7cd6fa4d1f9e062 100644 (file)
@@ -654,9 +654,29 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
 
        /* The ST Micro variants has a special bit to enable SDIO */
        if (variant->sdio && host->mmc->card)
-               if (mmc_card_sdio(host->mmc->card))
+               if (mmc_card_sdio(host->mmc->card)) {
+                       /*
+                        * The ST Micro variants has a special bit
+                        * to enable SDIO.
+                        */
+                       u32 clk;
+
                        datactrl |= MCI_ST_DPSM_SDIOEN;
 
+                       /*
+                        * The ST Micro variant for SDIO transfer sizes
+                        * less then 8 bytes should have clock H/W flow
+                        * control disabled.
+                        */
+                       if ((host->size < 8) &&
+                           (data->flags & MMC_DATA_WRITE))
+                               clk = host->clk_reg & ~variant->clkreg_enable;
+                       else
+                               clk = host->clk_reg | variant->clkreg_enable;
+
+                       mmci_write_clkreg(host, clk);
+               }
+
        /*
         * Attempt to use DMA operation mode, if this
         * should fail, fall back to PIO mode
@@ -876,22 +896,6 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
                         variant->fifosize : variant->fifohalfsize;
                count = min(remain, maxcnt);
 
-               /*
-                * The ST Micro variant for SDIO transfer sizes
-                * less then 8 bytes should have clock H/W flow
-                * control disabled.
-                */
-               if (variant->sdio &&
-                   mmc_card_sdio(host->mmc->card)) {
-                       u32 clk;
-                       if (count < 8)
-                               clk = host->clk_reg & ~variant->clkreg_enable;
-                       else
-                               clk = host->clk_reg | variant->clkreg_enable;
-
-                       mmci_write_clkreg(host, clk);
-               }
-
                /*
                 * SDIO especially may want to send something that is
                 * not divisible by 4 (as opposed to card sectors