From a2255ff45143001fecbc5e5a4b58fcb999d393ae Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Thu, 25 Nov 2010 12:11:51 +0200 Subject: [PATCH 1/3] 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 Cc: Signed-off-by: Nicolas Ferre Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Chris Ball --- arch/arm/mach-at91/include/mach/at91_mci.h | 2 ++ drivers/mmc/host/at91_mci.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h index 57f8ee154943..27ac6f550fe3 100644 --- a/arch/arm/mach-at91/include/mach/at91_mci.h +++ b/arch/arm/mach-at91/include/mach/at91_mci.h @@ -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 */ diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 591ab540b407..d3e6a962f423 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -69,6 +69,7 @@ #include #include +#include #include #include @@ -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; From 2f1d791882d21a4002a719fb016a1ac21c8bd6b7 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Fri, 10 Dec 2010 19:14:32 +0100 Subject: [PATCH 2/3] mmc: atmel-mci: fix multiblock SDIO transfers Based on report made by Yauhen in: "MMC: Fix multiblock SDIO transfers in AT91 MCI" patch, I report those changes to the brother driver: atmel-mci. So, this patch sets SDIO transfer types: SDIO block and SDIO byte transfers instead of using ordinary MMC block transfers. It is checking opcode for SDIO CMD53 and setting transfer type in MCI_CMDR register properly. Reported-by: Yauhen Kharuzhy Cc: Signed-off-by: Nicolas Ferre Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Chris Ball --- drivers/mmc/host/atmel-mci.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 301351a5d838..ad2a7a032cdf 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -532,12 +533,17 @@ static u32 atmci_prepare_command(struct mmc_host *mmc, data = cmd->data; if (data) { cmdr |= MCI_CMDR_START_XFER; - if (data->flags & MMC_DATA_STREAM) - cmdr |= MCI_CMDR_STREAM; - else if (data->blocks > 1) - cmdr |= MCI_CMDR_MULTI_BLOCK; - else - cmdr |= MCI_CMDR_BLOCK; + + if (cmd->opcode == SD_IO_RW_EXTENDED) { + cmdr |= MCI_CMDR_SDIO_BLOCK; + } else { + if (data->flags & MMC_DATA_STREAM) + cmdr |= MCI_CMDR_STREAM; + else if (data->blocks > 1) + cmdr |= MCI_CMDR_MULTI_BLOCK; + else + cmdr |= MCI_CMDR_BLOCK; + } if (data->flags & MMC_DATA_READ) cmdr |= MCI_CMDR_TRDIR_READ; From 274476f8fe0b6ac9bac542cc39de12c3dd0f43f6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 10 Dec 2010 08:40:31 +0100 Subject: [PATCH 3/3] mmc: Fix re-probing with PM_POST_RESTORE notification In the error-path where PM notifies PM_POST_RESTORE, the rescan-blockage should be cleared as well. Otherwise it'll be never re-probed. Also, as a bonus, this fixes a bug in S4 with user-mode suspend in the current code, as it sends PM_POST_RESTORE instead of PM_POST_HIBERNATION wrongly. Cc: Signed-off-by: Takashi Iwai Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 31ae07a36576..57dcf8fa774a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1773,6 +1773,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, case PM_POST_SUSPEND: case PM_POST_HIBERNATION: + case PM_POST_RESTORE: spin_lock_irqsave(&host->lock, flags); host->rescan_disable = 0;