Linux MultiMedia Card development
 help / color / mirror / Atom feed
* [PATCH 0/4] mmc: dw_mmc: replace three fallback timers with a single watchdog
@ 2026-08-27  7:58 Shawn Lin
  2026-08-27  7:58 ` [PATCH 1/4] mmc: dw_mmc: add central watchdog and convert CTO onto it Shawn Lin
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Shawn Lin @ 2026-08-27  7:58 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Jaehoon Chung, Marek Szyprowski, linux-mmc, linux-kernel,
	Shawn Lin


The driver carries three fallback timers (cmd11_timer, cto_timer,
dto_timer) added piecemeal after the hardware failed in the field.
dto_timer exists because Synopsys confirmed that the DTO interrupt can
be lost entirely, leaving no hardware fallback and blocking the request
forever without software help (57e104864bc4); cto_timer came later,
when Rockchip's reworked sample circuit was root-caused to swallow both
CMD_DONE and response-timeout interrupts across their whole dwmmc
family (03de19212ea3); cmd11_timer papered over voltage-switch hangs
that reproduced reliably when ejecting/inserting UHS cards on rk3288
(5c935165da79).

Because each callback races against the very interrupt it supplements,
all three grew the same copy-pasted defenses: re-read MINTSTS in case
the interrupt is merely late, check whether pending_events has been set
meanwhile, validate host->state against the leg being guarded, and only
then synthesize the missed event -- with timer_delete_sync() calls from
softirq context eventually needed just to contain them.  Meanwhile the
special cases keep piling up: the EXTENDED_TMOUT quirk makes the DTO
story differ per platform, fault injection can post DATA_ERROR ahead of
any real completion, and every future change has to reason about up to
three timers at once.

The observation enabling the cleanup is that command, data and
voltage-switch legs run strictly serially within a request, so a single
hrtimer suffices.  Under irq_lock it records which pending_events bits
are awaited along with a snapshot of host->state (dw_mci_wd_arm()),
and producers clear that awaited mask instead of deleting any timer
(dw_mci_wd_deliver()).  On expiry the one callback classifies what
expired by comparing the awaited set against the named
DW_MCI_WD_{CMD,DATA}_EVENTS masks, keeps the old MINTSTS latency check
but re-arms instead of going passive so an interrupt lost for good
can no longer wedge the request forever, and only then synthesizes
exactly what its predecessor would have (RTO + command complete, or
DRTO + data error/complete).  The per-leg deadlines -- CTO formula,
DRTO formula, 500ms CMD11 budget -- are carried over unchanged.

Apart from three behavioral deltas called out in the individual commit
messages as well -- a single surviving watch during voltage switch
instead of two timers racing, a stuck CMD11 aborting after exactly
500ms instead of racing min(cto_ms, 500ms) with -ETIMEDOUT unchanged,
and bounded recovery from interrupt-latency peaks instead of an
unbounded hang -- no functional change is intended.

Tested on Rockchip platforms with SD card and eMMC (rv1126/rk3568/
rk3576 boards): normal IO, suspend/resume and card removal during
transfer.  Compile tested on every variant consuming dw_mmc.h.

Next steps: first split dw_mci_work_func() into per-state handlers to
make the transitions explicit, then go further in the sdhci direction:
shrink the eight-state machine, drop the redundant completed_events
bookkeeping, and end up where other host drivers already are: one state
machine, one timer, no separate event flags.



Shawn Lin (4):
  mmc: dw_mmc: add central watchdog and convert CTO onto it
  mmc: dw_mmc: convert DTO onto the central watchdog
  mmc: dw_mmc: absorb CMD11 timeout into the central watchdog
  mmc: dw_mmc: expose the watchdog state in debugfs

 drivers/mmc/host/dw_mmc.c | 316 +++++++++++++++++++++++-----------------------
 drivers/mmc/host/dw_mmc.h |  15 ++-
 2 files changed, 165 insertions(+), 166 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-10 16:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-27  7:58 [PATCH 0/4] mmc: dw_mmc: replace three fallback timers with a single watchdog Shawn Lin
2026-08-27  7:58 ` [PATCH 1/4] mmc: dw_mmc: add central watchdog and convert CTO onto it Shawn Lin
2026-08-27  7:58 ` [PATCH 2/4] mmc: dw_mmc: convert DTO onto the central watchdog Shawn Lin
2026-08-27  7:58 ` [PATCH 3/4] mmc: dw_mmc: absorb CMD11 timeout into " Shawn Lin
2026-08-27  7:58 ` [PATCH 4/4] mmc: dw_mmc: expose the watchdog state in debugfs Shawn Lin
2026-09-10 16:05 ` [PATCH 0/4] mmc: dw_mmc: replace three fallback timers with a single watchdog Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox