aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorJayeeta Banerjee <jayeeta.banerjee@stericsson.com>2010-06-23 16:18:36 +0530
committerJohn Rigby <john.rigby@linaro.org>2010-09-02 22:45:48 -0600
commit71a14cad06ffcec597c99c9fbfb1a1e7d44fe7df (patch)
tree95a9963a39d0b2190e083bf8968d49d6e2195215 /drivers/mmc
parent307783b375d2f14e8e43dcb3e8b69cbc54552a47 (diff)
SDIO: Fix for non word-aligned address for SDIO host in DMA mode
For SDIO host in DMA mode, when memory address is not aligned to DMA element size, switch to polling mode for that transfer. ST-Ericsson Id:ER 264340 Signed-off-by: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/1922 Reviewed-by: Jayeeta BANDYOPADHYAY <jayeeta.banerjee@stericsson.com> Tested-by: Jayeeta BANDYOPADHYAY <jayeeta.banerjee@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com> Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> Change-Id: I9fa83f070f11a272c2a8cce299bfe81b769edf8b Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/2638
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mmc-u8500.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/mmc/host/mmc-u8500.c b/drivers/mmc/host/mmc-u8500.c
index 9316c6d3224..dc8617ceeb5 100644
--- a/drivers/mmc/host/mmc-u8500.c
+++ b/drivers/mmc/host/mmc-u8500.c
@@ -137,6 +137,10 @@ static void u8500_mmci_cmd_irq(struct u8500_mmci_host *host,
static struct u8500_mmci_host *sdio_host_ptr;
#define CARD_DETECT_DELAY_MSEC (10)
+/* For SDIO host DMA mode, min data transfer size in bytes */
+#define MIN_DATA_SIZE_DMA 32
+/* DMA element size in bytes */
+#define DMA_ELEMENT_SZ 4
/**
* u8500_sdio_detect_card() - Initiates card scan for sdio host
*
@@ -1148,6 +1152,7 @@ static void u8500_mmci_start_data(struct u8500_mmci_host *host,
u32 temp_reg;
u32 polling_freq_clk_div = 0x0;
unsigned long flag_lock = 0;
+ unsigned int mem_addr;
spin_lock_irqsave(&host->lock, flag_lock);
host->data = data;
@@ -1162,13 +1167,21 @@ static void u8500_mmci_start_data(struct u8500_mmci_host *host,
/**
* Required for SDIO DMA mode, dynamic switching between polling
- * and DMA mode, depending on transfer size
+ * and DMA mode, depending on transfer size, and address alignment.
+ * For transfer size < 32 and for element size unaligned address
+ * SDIO host is configured in polling mode.
*/
- if ((host->cmd->opcode == SD_IO_RW_EXTENDED) && (sdio_mode == MCI_DMAMODE)) {
- if (host->size >= 32)
- host->devicemode = MCI_DMAMODE;
- else
+ if ((host->cmd->opcode == SD_IO_RW_EXTENDED) &&
+ (sdio_mode == MCI_DMAMODE)) {
+ mem_addr = (unsigned int)(page_address(sg_page(host->sg_ptr)) +
+ host->sg_ptr->offset) + host->sg_off;
+
+ if ((mem_addr % DMA_ELEMENT_SZ) ||
+ (host->size < MIN_DATA_SIZE_DMA))
host->devicemode = MCI_POLLINGMODE;
+ else
+ host->devicemode = MCI_DMAMODE;
+
}
#ifdef SDIO_MULTIBYTE_WORKAROUND
/**