aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-10-06 14:09:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-06 17:26:24 -0400
commite683b423007b9befec30c672c695d0e6abf87493 (patch)
tree5486cdf01cd6e8f23978170fe8505a5e4b5413c9 /drivers/mmc
parente84956f92a846246b09b34f2a728329c386d250f (diff)
atmel-mci: Initialize BLKR before sending data transfer command
The atmel-mci driver sometimes fails data transfers like this: mmcblk0: error -5 transferring data end_request: I/O error, dev mmcblk0, sector 2749769 end_request: I/O error, dev mmcblk0, sector 2749777 It turns out that this might be caused by the BLKR register (which contains the block size and the number of blocks being transfered) being initialized too late. This patch moves the initialization of BLKR so that it contains the correct value before the block transfer command is sent. This error is difficult to reproduce, but if you insert a long delay (mdelay(10) or thereabouts) between the calls to atmci_start_command() and atmci_submit_data(), all transfers seem to fail without this patch, while I haven't seen any failures with this patch. Reported-by: Hein_Tibosch <hein_tibosch@yahoo.es> Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/atmel-mci.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 917035e16da4..00008967ef7a 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -426,8 +426,6 @@ static u32 atmci_submit_data(struct mmc_host *mmc, struct mmc_data *data)
426 host->sg = NULL; 426 host->sg = NULL;
427 host->data = data; 427 host->data = data;
428 428
429 mci_writel(host, BLKR, MCI_BCNT(data->blocks)
430 | MCI_BLKLEN(data->blksz));
431 dev_vdbg(&mmc->class_dev, "BLKR=0x%08x\n", 429 dev_vdbg(&mmc->class_dev, "BLKR=0x%08x\n",
432 MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz)); 430 MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));
433 431
@@ -483,6 +481,10 @@ static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
483 if (data->blocks > 1 && data->blksz & 3) 481 if (data->blocks > 1 && data->blksz & 3)
484 goto fail; 482 goto fail;
485 atmci_set_timeout(host, data); 483 atmci_set_timeout(host, data);
484
485 /* Must set block count/size before sending command */
486 mci_writel(host, BLKR, MCI_BCNT(data->blocks)
487 | MCI_BLKLEN(data->blksz));
486 } 488 }
487 489
488 iflags = MCI_CMDRDY; 490 iflags = MCI_CMDRDY;