mmc: host: rockchip: setup max hold time for cmd_rto
authorlintao <lintao@rock-chips.com>
Thu, 27 Mar 2014 02:32:31 +0000 (10:32 +0800)
committerlintao <lintao@rock-chips.com>
Thu, 27 Mar 2014 02:32:45 +0000 (10:32 +0800)
drivers/mmc/host/rk_sdmmc.c
include/linux/mmc/rk_mmc.h

index 9edfa35867e71db1523e27ee1c0f422359884815..f3520b63cc0036923a8d8eeb93bdc64f7576c727 100755 (executable)
@@ -62,6 +62,7 @@
 #define SDMMC_DATA_TIMEOUT_SDIO        250
 #define SDMMC_DATA_TIMEOUT_EMMC        2500
 
+#define SDMMC_CMD_RTO_MAX_HOLD 200 
 //#define SDMMC_WAIT_FOR_UNBUSY        2500
 
 #ifdef CONFIG_MMC_DW_IDMAC
@@ -1457,7 +1458,15 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd
        }
 
        if (status & SDMMC_INT_RTO)
-               cmd->error = -ETIMEDOUT;
+       {
+           if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
+           {
+               host->cmd_rto += 1;
+              (host->cmd_rto >= SDMMC_CMD_RTO_MAX_HOLD)?(cmd->error = -ETIMEDOUT):(cmd->error = 0);    
+               }
+               else
+                   cmd->error = -ETIMEDOUT;
+       }
        else if ((cmd->flags & MMC_RSP_CRC) && (status & SDMMC_INT_RCRC))
                cmd->error = -EILSEQ;
        else if (status & SDMMC_INT_RESP_ERR)
@@ -2115,8 +2124,8 @@ done:
 static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status)
 {
        if (!host->cmd_status)
-               host->cmd_status = status;
-
+           host->cmd_status = status;
+           
        smp_wmb();
 
        set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
index 4e4c5a31cc66abe065f707b41903a54cdf69f052..62696369ebf48b665fc40ddc0ecd9af5133e7670 100755 (executable)
@@ -195,6 +195,7 @@ struct dw_mci {
        struct regulator        *vmmc;  /* Power regulator */
        unsigned long           irq_flags; /* IRQ flags */
        int                     irq;
+       u32         cmd_rto;     /*cmd response timeout hold times*/
        struct pinctrl *pinctrl; /*Pinctrl state*/
        struct pinctrl_state    *pins_default;
        struct pinctrl_state    *pins_idle;