OSDN Git Service

mmc: meson: Fix usage of meson_mmc_post_req()
authorRong Chen <rong.chen@amlogic.com>
Wed, 16 Feb 2022 12:42:39 +0000 (20:42 +0800)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 28 Feb 2022 12:18:12 +0000 (13:18 +0100)
Currently meson_mmc_post_req() is called in meson_mmc_request() right
after meson_mmc_start_cmd(). This could lead to DMA unmapping before the request
is actually finished.

To fix, don't call meson_mmc_post_req() until meson_mmc_request_done().

Signed-off-by: Rong Chen <rong.chen@amlogic.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Fixes: 79ed05e329c3 ("mmc: meson-gx: add support for descriptor chain mode")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20220216124239.4007667-1-rong.chen@amlogic.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/meson-gx-mmc.c

index 8f36536..58ab9d9 100644 (file)
@@ -173,6 +173,8 @@ struct meson_host {
        int irq;
 
        bool vqmmc_enabled;
+       bool needs_pre_post_req;
+
 };
 
 #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
@@ -663,6 +665,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
        struct meson_host *host = mmc_priv(mmc);
 
        host->cmd = NULL;
+       if (host->needs_pre_post_req)
+               meson_mmc_post_req(mmc, mrq, 0);
        mmc_request_done(host->mmc, mrq);
 }
 
@@ -880,7 +884,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data
 static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
        struct meson_host *host = mmc_priv(mmc);
-       bool needs_pre_post_req = mrq->data &&
+       host->needs_pre_post_req = mrq->data &&
                        !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
 
        /*
@@ -896,22 +900,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
                }
        }
 
-       if (needs_pre_post_req) {
+       if (host->needs_pre_post_req) {
                meson_mmc_get_transfer_mode(mmc, mrq);
                if (!meson_mmc_desc_chain_mode(mrq->data))
-                       needs_pre_post_req = false;
+                       host->needs_pre_post_req = false;
        }
 
-       if (needs_pre_post_req)
+       if (host->needs_pre_post_req)
                meson_mmc_pre_req(mmc, mrq);
 
        /* Stop execution */
        writel(0, host->regs + SD_EMMC_START);
 
        meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
-
-       if (needs_pre_post_req)
-               meson_mmc_post_req(mmc, mrq, 0);
 }
 
 static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)