Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2255ff4 authored by Yauhen Kharuzhy's avatar Yauhen Kharuzhy Committed by Chris Ball
Browse files

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: default avatarYauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
Cc: <stable@kernel.org>
Signed-off-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: default avatarJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 0a592281
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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 */
+9 −4
Original line number Diff line number Diff line
@@ -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,11 +494,15 @@ 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 (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;
		blocks = 0;