Skip to content

Commit 7892497

Browse files
Linus WalleijUlf Hansson
authored andcommitted
mmc: mmci: Retry the busy start condition
This makes the ux500 ->busy_complete() callback re-read the status register 10 times while waiting for the busy signal to assert in the status register. If this does not happen, we bail out regarding the command completed already, i.e. before we managed to start to check the busy status. There is a comment in the code about this, let's just implement it to be certain that we can catch this glitch if it happens. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20230405-pl180-busydetect-fix-v7-6-69a7164f2a61@linaro.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 7be5ac5 commit 7892497

1 file changed

Lines changed: 27 additions & 12 deletions

File tree

drivers/mmc/host/mmci.c

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host)
674674
static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk)
675675
{
676676
void __iomem *base = host->base;
677+
int retries = 10;
677678

678679
if (status & err_msk) {
679680
/* Stop any ongoing busy detection if an error occurs */
@@ -694,21 +695,35 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk)
694695
* Note that, the card may need a couple of clock cycles before
695696
* it starts signaling busy on DAT0, hence re-read the
696697
* MMCISTATUS register here, to allow the busy bit to be set.
697-
* Potentially we may even need to poll the register for a
698-
* while, to allow it to be set, but tests indicates that it
699-
* isn't needed.
700698
*/
701699
if (host->busy_state == MMCI_BUSY_DONE) {
702-
status = readl(base + MMCISTATUS);
703-
if (status & host->variant->busy_detect_flag) {
704-
writel(readl(base + MMCIMASK0) |
705-
host->variant->busy_detect_mask,
706-
base + MMCIMASK0);
707-
708-
host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND);
709-
host->busy_state = MMCI_BUSY_WAITING_FOR_START_IRQ;
710-
return false;
700+
/*
701+
* Save the first status register read to be sure to catch
702+
* all bits that may be lost will retrying. If the command
703+
* is still busy this will result in assigning 0 to
704+
* host->busy_status, which is what it should be in IDLE.
705+
*/
706+
host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND);
707+
while (retries) {
708+
status = readl(base + MMCISTATUS);
709+
/* Keep accumulating status bits */
710+
host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND);
711+
if (status & host->variant->busy_detect_flag) {
712+
writel(readl(base + MMCIMASK0) |
713+
host->variant->busy_detect_mask,
714+
base + MMCIMASK0);
715+
host->busy_state = MMCI_BUSY_WAITING_FOR_START_IRQ;
716+
return false;
717+
}
718+
retries--;
711719
}
720+
dev_dbg(mmc_dev(host->mmc), "no busy signalling in time\n");
721+
writel(host->variant->busy_detect_mask, base + MMCICLEAR);
722+
writel(readl(base + MMCIMASK0) &
723+
~host->variant->busy_detect_mask, base + MMCIMASK0);
724+
host->busy_state = MMCI_BUSY_DONE;
725+
host->busy_status = 0;
726+
return true;
712727
}
713728

714729
/*

0 commit comments

Comments
 (0)