[PATCH 16/18] mmc: meson-gx: improve response reading and sending stop command
Heiner Kallweit
hkallweit1 at gmail.com
Tue Feb 14 12:07:09 PST 2017
Stopping execution at the beginning of command processing (again) is
not needed as reading SD_EMMC_CMD_RSP implicitely stops execution.
We just have to take care of the case that a command doesn't return a
response. Therefore read SD_EMMC_CMD_RSP always.
In addition we can read the response in the main irq handler already,
we don't have to do this in the threaded handler.
Signed-off-by: Heiner Kallweit <hkallweit1 at gmail.com>
---
drivers/mmc/host/meson-gx-mmc.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 25b46d36..6721aee2 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -510,9 +510,6 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
WARN_ON(host->mrq != NULL);
- /* Stop execution */
- writel(0, host->regs + SD_EMMC_START);
-
host->mrq = mrq;
meson_mmc_start_cmd(mmc, mrq->cmd);
}
@@ -521,12 +518,16 @@ static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
{
struct meson_host *host = mmc_priv(mmc);
+ /*
+ * reading SD_EMMC_CMD_RSP stops processing, therefore read
+ * this register even if command has no response
+ */
if (cmd->flags & MMC_RSP_136) {
cmd->resp[0] = readl(host->regs + SD_EMMC_CMD_RSP3);
cmd->resp[1] = readl(host->regs + SD_EMMC_CMD_RSP2);
cmd->resp[2] = readl(host->regs + SD_EMMC_CMD_RSP1);
cmd->resp[3] = readl(host->regs + SD_EMMC_CMD_RSP);
- } else if (cmd->flags & MMC_RSP_PRESENT) {
+ } else {
cmd->resp[0] = readl(host->regs + SD_EMMC_CMD_RSP);
}
}
@@ -564,6 +565,8 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
goto out;
}
+ meson_mmc_read_resp(host->mmc, cmd);
+
cmd->error = 0;
if (status & IRQ_RXD_ERR_MASK) {
dev_dbg(host->dev, "Unhandled IRQ: RXD error\n");
@@ -610,10 +613,8 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
/* ack all (enabled) interrupts */
writel(status, host->regs + SD_EMMC_STATUS);
- if (ret == IRQ_HANDLED) {
- meson_mmc_read_resp(host->mmc, cmd);
+ if (ret == IRQ_HANDLED)
meson_mmc_request_done(host->mmc, cmd->mrq);
- }
spin_unlock(&host->lock);
return ret;
@@ -643,7 +644,6 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
data->bytes_xfered = xfer_bytes;
}
- meson_mmc_read_resp(host->mmc, cmd);
if (mmc_op_multi(cmd->opcode))
meson_mmc_start_cmd(host->mmc, data->stop);
else
--
2.11.1
More information about the linux-amlogic
mailing list