From: lintao Date: Tue, 30 Sep 2014 09:45:24 +0000 (+0800) Subject: mmc: fixup edma stop when data err occur, cause edma halt X-Git-Tag: firefly_0821_release~4617 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=6b919533a0fd5b296489a143f1d4dcd7c3e45846;p=firefly-linux-kernel-4.4.55.git mmc: fixup edma stop when data err occur, cause edma halt 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 --- diff --git a/drivers/mmc/host/rk_sdmmc.c b/drivers/mmc/host/rk_sdmmc.c index f225ba135d7a..4d3cf7c67862 100755 --- a/drivers/mmc/host/rk_sdmmc.c +++ b/drivers/mmc/host/rk_sdmmc.c @@ -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");