summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorYauhen Kharuzhy <yauhen.kharuzhy@promwad.com>2010-11-25 12:11:51 +0200
committerChris Ball <cjb@laptop.org>2010-12-21 11:46:32 -0800
commita2255ff45143001fecbc5e5a4b58fcb999d393ae (patch)
tree6f524cb891b60e8c2ce40beba94b6dbb71c9f8bf /drivers/mmc
parent0a59228168d3722b71f8e3dbc623316fb4be78f4 (diff)
mmc: at91_mci: fix multiblock SDIO transfers
The AT91 MCI has special SDIO transfer types: SDIO block and SDIO byte transfers, but at91_mci driver doesn't use them and handles all SDIO transfers as ordinary MMC block transfers. This causes problems for multiple-block SDIO transfers (in particular for 256-bytes blocks). Fix this situation by checking the opcode for SDIO CMD53 and setting the transfer type in the AT91_MCI_CMDR register properly. This patch was tested with libertas SDIO driver: problem with TX timeouts on big packets was eliminated. Signed-off-by: Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com> Cc: <stable@kernel.org> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/at91_mci.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 591ab540b40..d3e6a962f42 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -69,6 +69,7 @@
#include <linux/highmem.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sdio.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -493,10 +494,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
else if (data->flags & MMC_DATA_WRITE)
cmdr |= AT91_MCI_TRCMD_START;
- if (data->flags & MMC_DATA_STREAM)
- cmdr |= AT91_MCI_TRTYP_STREAM;
- if (data->blocks > 1)
- cmdr |= AT91_MCI_TRTYP_MULTIPLE;
+ if (cmd->opcode == SD_IO_RW_EXTENDED) {
+ cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK;
+ } else {
+ if (data->flags & MMC_DATA_STREAM)
+ cmdr |= AT91_MCI_TRTYP_STREAM;
+ if (data->blocks > 1)
+ cmdr |= AT91_MCI_TRTYP_MULTIPLE;
+ }
}
else {
block_length = 0;