summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2023-06-16 22:42:20 +0200
committerUlf Hansson <ulf.hansson@linaro.org>2023-06-19 13:14:26 +0200
commit479d8e61f6244286e629e157ea831e8c4f783826 (patch)
treef3db6c5625ecf6ea6b9c052f30682f52ce602be6 /drivers/mmc/host/mmci.c
parent2673493fdfe78a1a8df1f802755cc2448ca98df6 (diff)
mmc: mmci: Unwind big if() clause
This does two things: firsr replace the hard-to-read long if-expression: if (!host->busy_status && !(status & err_msk) && (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { With the more readable: if (!host->busy_status && !(status & err_msk)) { status = readl(base + MMCISTATUS); if (status & host->variant->busy_detect_flag) { Second notice that the re-read MMCISTATUS register is now stored into the status variable, using logic OR because what if something else changed too? While we are at it, explain what the function is doing. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20230405-pl180-busydetect-fix-v7-2-69a7164f2a61@linaro.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 267f88d9daec..a3713e9a0ef4 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -654,6 +654,23 @@ static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host)
return MCI_DPSM_ENABLE | (host->data->blksz << 16);
}
+/*
+ * ux500_busy_complete() - this will wait until the busy status
+ * goes off, saving any status that occur in the meantime into
+ * host->busy_status until we know the card is not busy any more.
+ * The function returns true when the busy detection is ended
+ * and we should continue processing the command.
+ *
+ * The Ux500 typically fires two IRQs over a busy cycle like this:
+ *
+ * DAT0 busy +-----------------+
+ * | |
+ * DAT0 not busy ----+ +--------
+ *
+ * ^ ^
+ * | |
+ * IRQ1 IRQ2
+ */
static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk)
{
void __iomem *base = host->base;
@@ -671,14 +688,16 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk)
* while, to allow it to be set, but tests indicates that it
* isn't needed.
*/
- if (!host->busy_status && !(status & err_msk) &&
- (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) {
- writel(readl(base + MMCIMASK0) |
- host->variant->busy_detect_mask,
- base + MMCIMASK0);
+ if (!host->busy_status && !(status & err_msk)) {
+ status = readl(base + MMCISTATUS);
+ if (status & host->variant->busy_detect_flag) {
+ writel(readl(base + MMCIMASK0) |
+ host->variant->busy_detect_mask,
+ base + MMCIMASK0);
- host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND);
- return false;
+ host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND);
+ return false;
+ }
}
/*