static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk)
{
void __iomem *base = host->base;
+ int retries = 10;
if (status & err_msk) {
/* Stop any ongoing busy detection if an error occurs */
* Note that, the card may need a couple of clock cycles before
* it starts signaling busy on DAT0, hence re-read the
* MMCISTATUS register here, to allow the busy bit to be set.
- * Potentially we may even need to poll the register for a
- * while, to allow it to be set, but tests indicates that it
- * isn't needed.
*/
if (host->busy_state == MMCI_BUSY_DONE) {
- 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);
- host->busy_state = MMCI_BUSY_WAITING_FOR_START_IRQ;
- return false;
+ /*
+ * Save the first status register read to be sure to catch
+ * all bits that may be lost will retrying. If the command
+ * is still busy this will result in assigning 0 to
+ * host->busy_status, which is what it should be in IDLE.
+ */
+ host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND);
+ while (retries) {
+ status = readl(base + MMCISTATUS);
+ /* Keep accumulating status bits */
+ host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND);
+ if (status & host->variant->busy_detect_flag) {
+ writel(readl(base + MMCIMASK0) |
+ host->variant->busy_detect_mask,
+ base + MMCIMASK0);
+ host->busy_state = MMCI_BUSY_WAITING_FOR_START_IRQ;
+ return false;
+ }
+ retries--;
}
+ dev_dbg(mmc_dev(host->mmc), "no busy signalling in time\n");
+ writel(host->variant->busy_detect_mask, base + MMCICLEAR);
+ writel(readl(base + MMCIMASK0) &
+ ~host->variant->busy_detect_mask, base + MMCIMASK0);
+ host->busy_state = MMCI_BUSY_DONE;
+ host->busy_status = 0;
+ return true;
}
/*