As is custom, use a big switch statement to transition between the edges of the state machine inside the ux500 ->busy_complete callback. Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> --- drivers/mmc/host/mmci.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 734e8364b2f6..626467c212d6 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -676,6 +676,12 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) goto out_ret_state; } + /* + * The state transitions are encoded in a state machine crossing + * the edges in this switch statement. + */ + switch (host->busy_state) { + /* * Before unmasking for the busy end IRQ, confirm that the * command was sent successfully. To keep track of having a @@ -686,7 +692,7 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) * it starts signaling busy on DAT0, hence re-read the * MMCISTATUS register here, to allow the busy bit to be set. */ - if (host->busy_state == MMCI_BUSY_IDLE) { + case MMCI_BUSY_IDLE: host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND); while (retries) { status = readl(base + MMCISTATUS); @@ -706,8 +712,7 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) writel(readl(base + MMCIMASK0) & ~host->variant->busy_detect_mask, base + MMCIMASK0); host->busy_state = MMCI_BUSY_DONE; - goto out_ret_state; - } + break; /* * If there is a command in-progress that has been successfully @@ -720,12 +725,11 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) * both the start and the end interrupts needs to be cleared, * one after the other. So, clear the busy start IRQ here. */ - if (host->busy_state == MMCI_BUSY_WAITING_FOR_IRQS) { + case MMCI_BUSY_WAITING_FOR_IRQS: if (status & host->variant->busy_detect_flag) { host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND); writel(host->variant->busy_detect_mask, base + MMCICLEAR); host->busy_state = MMCI_BUSY_START_IRQ; - goto out_ret_state; } else { dev_dbg(mmc_dev(host->mmc), "lost busy status when waiting for busy start IRQ\n"); @@ -734,16 +738,14 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) ~host->variant->busy_detect_mask, base + MMCIMASK0); host->busy_state = MMCI_BUSY_DONE; host->busy_status = 0; - goto out_ret_state; } - } + break; - if (host->busy_state == MMCI_BUSY_START_IRQ) { + case MMCI_BUSY_START_IRQ: if (status & host->variant->busy_detect_flag) { host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND); writel(host->variant->busy_detect_mask, base + MMCICLEAR); host->busy_state = MMCI_BUSY_END_IRQ; - goto out_ret_state; } else { dev_dbg(mmc_dev(host->mmc), "lost busy status when waiting for busy end IRQ\n"); @@ -752,9 +754,8 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) ~host->variant->busy_detect_mask, base + MMCIMASK0); host->busy_state = MMCI_BUSY_DONE; host->busy_status = 0; - goto out_ret_state; } - } + break; /* * If there is a command in-progress that has been successfully @@ -762,11 +763,10 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) * the busy end IRQ. Clear and mask the IRQ, then continue to * process the command. */ - if (host->busy_state == MMCI_BUSY_END_IRQ) { + case MMCI_BUSY_END_IRQ: if (status & host->variant->busy_detect_flag) { /* We should just get two IRQs for busy detect */ dev_err(mmc_dev(host->mmc), "spurious busy detect IRQ\n"); - goto out_ret_state; } writel(host->variant->busy_detect_mask, base + MMCICLEAR); @@ -775,9 +775,15 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) host->busy_state = MMCI_BUSY_DONE; host->busy_status = 0; - } else { + break; + + case MMCI_BUSY_DONE: + break; + + default: dev_dbg(mmc_dev(host->mmc), "fell through on state %d\n", host->busy_state); + break; } out_ret_state: -- 2.39.2