[PATCH] mmc: omap: synchronize clock timer before disabling fclk

From: Runyu Xiao

Date: Tue Sep 29 2026 - 08:46:29 EST


mmc_omap_select_slot() removes clk_timer with timer_delete() before
switching slots and changing the functional clock state. timer_delete()
only removes a pending timer and does not wait for a callback that is
already running.

If mmc_omap_clk_timer() is already running, it can therefore call
mmc_omap_fclk_enable() while the request or slot-switch path changes the
same clock state. During host removal, the same window can overlap the
final clock shutdown.

Use timer_delete_sync() so the callback has completed before slot switching
or changing the functional clock state. Keep the timer restartable for
normal request handling.

Fixes: 0807a9b5739a ("MMC: OMAP: Lazy clock shutdown")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
drivers/mmc/host/omap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 527b89a5e..02d288e4e 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -214,7 +214,7 @@ static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed)
host->mmc = slot->mmc;
spin_unlock_irqrestore(&host->slot_lock, flags);
no_claim:
- timer_delete(&host->clk_timer);
+ timer_delete_sync(&host->clk_timer);
if (host->current_slot != slot || !claimed)
mmc_omap_fclk_offdelay(host->current_slot);

@@ -273,7 +273,7 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled)
/* Keeps clock running for at least 8 cycles on valid freq */
mod_timer(&host->clk_timer, jiffies + HZ/10);
else {
- timer_delete(&host->clk_timer);
+ timer_delete_sync(&host->clk_timer);
mmc_omap_fclk_offdelay(slot);
mmc_omap_fclk_enable(host, 0);
}
--
2.34.1