mmc: mmci: Use a switch statement machine
authorLinus Walleij <linus.walleij@linaro.org>
Fri, 16 Jun 2023 20:42:26 +0000 (22:42 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 19 Jun 2023 11:14:26 +0000 (13:14 +0200)
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>
drivers/mmc/host/mmci.c

index f59c6eb..6bd8b36 100644 (file)
@@ -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);