mmc: fixup edma stop when data err occur, cause edma halt
authorlintao <lintao@rock-chips.com>
Tue, 30 Sep 2014 09:45:24 +0000 (17:45 +0800)
committerlintao <lintao@rock-chips.com>
Tue, 30 Sep 2014 09:55:40 +0000 (17:55 +0800)
Fast insert and remove sd card make edma equeue, dequeue
frequently. And with unstable fifo data err, if we stop edma, it
terminate all data will been sent later and flush that desc. However,
MHSC hardware fifo byte counter in fault state  because avaliable data
isn't enough, and remain data been teminated by stop edma. So edma req
signal in fault state event we restart edma. We just let edma sent remain
data, and reset fifo to drop these unused data.

<6>[ 1137.707403] mmc0: new SD card at address 1234
<6>[ 1137.708095] mmcblk0: mmc0:1234 SA02G 1.83 GiB
<3>[ 1141.654157] dwmmc_rockchip 10214000.rksdmmc: data_over interrupt timeout!

Signed-off-by: lintao <lintao@rock-chips.com>
drivers/mmc/host/rk_sdmmc.c

index f225ba135d7a2380f7285e5f97230a21ca34fe6b..4d3cf7c6786204e9465d0da9db12af41671a887a 100755 (executable)
@@ -396,7 +396,9 @@ static void send_stop_cmd(struct dw_mci *host, struct mmc_data *data)
 static void dw_mci_stop_dma(struct dw_mci *host)
 {
        if (host->using_dma) {
-               host->dma_ops->stop(host);
+               /* Fixme: No need to terminate edma, may cause flush op */
+               if(!(cpu_is_rk3036() || cpu_is_rk312x()))
+                       host->dma_ops->stop(host);
                host->dma_ops->cleanup(host);
        }
 
@@ -883,7 +885,9 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
 
        sg_len = dw_mci_pre_dma_transfer(host, data, 0);
        if (sg_len < 0) {
-               host->dma_ops->stop(host);
+               /* Fixme: No need terminate edma, may cause flush op */
+               if(!(cpu_is_rk3036() || cpu_is_rk312x()))
+                       host->dma_ops->stop(host);
                return sg_len;
        }
 
@@ -2954,6 +2958,12 @@ static void dw_mci_work_routine_card(struct work_struct *work)
 
                present = dw_mci_get_cd(mmc);
                dw_mci_ctrl_all_reset(host);
+
+                /* Stop edma when rountine card triggered */
+                if(cpu_is_rk3036() || cpu_is_rk312x())
+                       if(host->dma_ops->stop)
+                               host->dma_ops->stop(host);
+
                while (present != slot->last_detect_state) {
                        dev_dbg(&slot->mmc->class_dev, "card %s\n",
                                present ? "inserted" : "removed");