summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hansson <(address hidden)>2011-11-08 10:53:22 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:02:57 +0200
commit79ba4708658f7503c5b9ff3a771a3c37c5d3f7ef (patch)
tree92aee296a548c9c785b001052dfc87289de6f60c
parent7cb48060b2f5907d7fc67ade5eeb29f81afff480 (diff)
mmci: Fix incorrect handling of HW flow control for SDIO
For data writes smaller <= 8 bytes (only SDIO case), HW flow control was disabled but never re-enabled again. This meant that a following large read request would randomly give buffer overrun errors. Moreover HW flow control is not needed for transfers that fits in the FIFO of PL18x. Thus it is disabled for write operations <= the FIFO size. Signed-off-by: Ulf Hansson <(address hidden)> Signed-off-by: Stefan Nilsson XK <(address hidden)>
-rw-r--r--drivers/mmc/host/mmci.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 2ad77daff3c..beb2d963c4d 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -643,9 +643,32 @@ 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 or equal to 8 bytes needs to have clock
+ * H/W flow control disabled. Since flow control is
+ * not really needed for anything that fits in the
+ * FIFO, we can disable it for any write smaller
+ * than the FIFO size.
+ */
+ if ((host->size <= variant->fifosize) &&
+ (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
@@ -866,22 +889,6 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
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
* etc), and the FIFO only accept full 32-bit writes.