aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@nokia.com>2009-09-22 19:45:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:36 -0400
commite2bf08d643a244ccb9d9b70aff655340a0d98626 (patch)
tree1eff5c6f2c8897775f3496653de10d4abfe2822b
parent2bec08937e3cdf6828d29421c7f870dca84f3b02 (diff)
omap_hsmmc: set a large data timeout for commands with busy signal
Commands like SWITCH (CMD6) send a response and then signal busy while the operation is completed. These commands are expected to always succeed (otherwise the response would have indicated an error). Set an arbitrarily large data timeout value (100ms) for these commands to ensure that premature timeouts do not occur. Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com> Acked-by: Matt Fleming <matt@console-pimps.org> Cc: Ian Molton <ian@mnementh.co.uk> Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com> Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com> Cc: Denis Karpov <ext-denis.2.karpov@nokia.com> Cc: Pierre Ossman <pierre@ossman.eu> Cc: Philip Langdale <philipl@overt.org> Cc: "Madhusudhan" <madhu.cr@ti.com> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/mmc/host/omap_hsmmc.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 14c58caac990..a4dd43f117f0 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -997,7 +997,8 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
997} 997}
998 998
999static void set_data_timeout(struct omap_hsmmc_host *host, 999static void set_data_timeout(struct omap_hsmmc_host *host,
1000 struct mmc_request *req) 1000 unsigned int timeout_ns,
1001 unsigned int timeout_clks)
1001{ 1002{
1002 unsigned int timeout, cycle_ns; 1003 unsigned int timeout, cycle_ns;
1003 uint32_t reg, clkd, dto = 0; 1004 uint32_t reg, clkd, dto = 0;
@@ -1008,8 +1009,8 @@ static void set_data_timeout(struct omap_hsmmc_host *host,
1008 clkd = 1; 1009 clkd = 1;
1009 1010
1010 cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd); 1011 cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd);
1011 timeout = req->data->timeout_ns / cycle_ns; 1012 timeout = timeout_ns / cycle_ns;
1012 timeout += req->data->timeout_clks; 1013 timeout += timeout_clks;
1013 if (timeout) { 1014 if (timeout) {
1014 while ((timeout & 0x80000000) == 0) { 1015 while ((timeout & 0x80000000) == 0) {
1015 dto += 1; 1016 dto += 1;
@@ -1043,12 +1044,18 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req)
1043 1044
1044 if (req->data == NULL) { 1045 if (req->data == NULL) {
1045 OMAP_HSMMC_WRITE(host->base, BLK, 0); 1046 OMAP_HSMMC_WRITE(host->base, BLK, 0);
1047 /*
1048 * Set an arbitrary 100ms data timeout for commands with
1049 * busy signal.
1050 */
1051 if (req->cmd->flags & MMC_RSP_BUSY)
1052 set_data_timeout(host, 100000000U, 0);
1046 return 0; 1053 return 0;
1047 } 1054 }
1048 1055
1049 OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) 1056 OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz)
1050 | (req->data->blocks << 16)); 1057 | (req->data->blocks << 16));
1051 set_data_timeout(host, req); 1058 set_data_timeout(host, req->data->timeout_ns, req->data->timeout_clks);
1052 1059
1053 if (host->use_dma) { 1060 if (host->use_dma) {
1054 ret = omap_hsmmc_start_dma_transfer(host, req); 1061 ret = omap_hsmmc_start_dma_transfer(host, req);