diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2023-06-16 22:42:26 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2023-06-19 13:14:26 +0200 |
commit | ddb5a92da5f32779958303716429d50a46c3177d (patch) | |
tree | da2cb6f9a0103a48dd44ff64d729a3f7e1a9f955 /drivers/mmc | |
parent | mmc: mmci: Use state machine state as exit condition (diff) | |
download | linux-ddb5a92da5f32779958303716429d50a46c3177d.tar.xz linux-ddb5a92da5f32779958303716429d50a46c3177d.zip |
mmc: mmci: Use a switch statement machine
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@linaro.org>
Link: https://lore.kernel.org/r/20230405-pl180-busydetect-fix-v7-8-69a7164f2a61@linaro.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/mmci.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f59c6eb5258b..6bd8b367bb8f 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -687,6 +687,12 @@ static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) } /* + * 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 * command in-progress, waiting for busy signaling to end, @@ -696,7 +702,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_DONE) { + case MMCI_BUSY_DONE: /* * Save the first status register read to be sure to catch * all bits that may be lost will retrying. If the command @@ -722,8 +728,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 @@ -736,12 +741,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_START_IRQ) { + case MMCI_BUSY_WAITING_FOR_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_WAITING_FOR_END_IRQ; - goto out_ret_state; } else { dev_dbg(mmc_dev(host->mmc), "lost busy status when waiting for busy start IRQ\n"); @@ -750,23 +754,24 @@ 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_WAITING_FOR_END_IRQ) { + case MMCI_BUSY_WAITING_FOR_END_IRQ: if (!(status & host->variant->busy_detect_flag)) { host->busy_status |= status & (MCI_CMDSENT | MCI_CMDRESPEND); host->busy_state = MMCI_BUSY_DONE; - goto out_ret_state; } else { dev_dbg(mmc_dev(host->mmc), "busy status still asserted when handling busy end IRQ - will keep waiting\n"); - goto out_ret_state; } - } + break; - return true; + default: + dev_dbg(mmc_dev(host->mmc), "fell through on state %d\n", + host->busy_state); + break; + } out_ret_state: return (host->busy_state == MMCI_BUSY_DONE); |