Skip to content

Commit

Permalink
mmc: at91_mci: fix multiblock SDIO transfers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Yauhen Kharuzhy authored and Chris Ball committed Dec 21, 2010
1 parent 0a59228 commit a2255ff
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 4 deletions.
2 changes: 2 additions & 0 deletions arch/arm/mach-at91/include/mach/at91_mci.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
#define AT91_MCI_TRTYP_BLOCK (0 << 19)
#define AT91_MCI_TRTYP_MULTIPLE (1 << 19)
#define AT91_MCI_TRTYP_STREAM (2 << 19)
#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19)
#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19)

#define AT91_MCI_BLKR 0x18 /* Block Register */
#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
Expand Down
13 changes: 9 additions & 4 deletions drivers/mmc/host/at91_mci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a2255ff

Please sign in to comment.