Skip to content

mmc: retry a failed SD card resume after a power cycle - #3304

Draft
Jacob-Matthew-Cook wants to merge 1 commit into
ROCKNIX:nextfrom
Jacob-Matthew-Cook:mmc-sd-resume-fixes
Draft

Jacob-Matthew-Cook wants to merge 1 commit into
ROCKNIX:nextfrom
Jacob-Matthew-Cook:mmc-sd-resume-fixes

Conversation

@Jacob-Matthew-Cook

@Jacob-Matthew-Cook Jacob-Matthew-Cook commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This kernel patch is a mainline candidate and will be submitted to linux-mmc shortly. It is carried here only until it lands upstream, and should be dropped the moment it does. It is not a ROCKNIX-specific workaround — it fixes a generic drivers/mmc/core/sd.c bug that affects any device with an SD card, and is written as an upstream submission (failure logs, rejected alternatives, no device-specific conditionals).

This addresses @sydarn's point on #3220 about being uneasy carrying custom mmc patches. Agreed — the intent was always to report these upstream, and splitting them out here makes that easier to track independently of the rk817 work.

  • 0008 — a failed resume is reported as success. _mmc_sd_resume() hands its result to mmc_sd_runtime_resume(), which logs it and returns 0, so the PM core is told the resume worked even though the card was never brought back. Every queued request then waits forever: jbd2, the writeback worker and the block queue end up in uninterruptible sleep, and on a boot medium that takes the whole machine down — userspace stops responding while the kernel carries on answering pings. Retry once from a clean slate after a power cycle.
  • 99-automount — a card that drops off the bus leaves its mounts behind with the filesystem shut down. The add rule then sees the stale entry in /proc/mounts, skips the remount, and the card stays unusable until reboot even though the kernel re-detected it immediately. Clear them on removal.

The second patch was dropped after hardware testing (2026-09-11)

This PR previously also carried 0007-mmc-sd-do-not-fail-card-init-when-the-cache-cannot-be.patch, which made a failed SD "Cache Enable" write non-fatal to card init. Testing on the RG353M that produced the original failure removed it:

  • The patch fired exactly as designed — could not enable card cache (-110), continuing without it — and the card was still removed 0.16 ms later, because the post-resume presence check found it unresponsive. ext4 aborted its journal, and only the automount rule above brought the card back.
  • Worse, by turning the init error into a success it stopped 0008's retry from ever running.
  • Rebuilt without it, the same card on the same device hit the same trigger and the retry recovered it with the mount intact.

The cache failure is therefore not a separate bug needing its own fix. It is one more way a resume fails, and the retry covers it. What is broken at that moment is the card's state, not the return value, so suppressing the error only hides it from the code that can repair it.

Testing

Two triggers, two devices, two cards — the retry handles both.

  • Card still busy when the host re-initialises it — GKD Pixel2 (PX30), boot/root card, kernel 7.1.2. 8 rapid suspend/resume cycles reproduced the failure twice, and the retry recovered the card both times at SDR104: no card removal, no ext4 or journal errors, no D-state tasks, root filesystem verified read-write seconds after each recovery. Unpatched, the same sequence wedges the machine until a hard reset.
  • Card times out the optional cache-enable write — Anbernic RG353M (RK3566), games card (Phison, manfid 0x000027, oemid 0x5048, 03/2025), ext4, kernel 7.0.2, 2026-09-11. With the retry alone: the trigger fired, the retry fired 11 µs later, the card was back and re-tuned 212 ms later, and for that whole boot there were 0 card removals, 0 ext4 aborts and 0 failed retries. The mount never left /proc/mounts and userspace never re-ran its automount, so the filesystem was never torn down.
  • Applies at strict zero fuzz (-F0) across every kernel in the tree: 6.18.45 (RK3399), 7.0.2 (RK3566/76), 7.1.2 (RK3326) and 7.2 (H700/SM6115/SM8xxx), and to mainline 7.3-rc3.

Additional Context

  • Not device-specific. The trigger on the Pixel2 is a card still busy when host re-init starts — dw_mmc waits 500 ms for DAT0 and then issues the command regardless, and a card is entitled to be busy longer than that. The trigger on the RG353M is an optional feature failing to enable. Any card can hit either; the handhelds just suspend and resume far more often than most hardware.
  • Raising dw_mmc's busy timeout was considered instead and rejected: that poll is readl_poll_timeout_atomic(), so a longer wait means spinning longer in atomic context, and it would only help one host driver.
  • mainline/ rather than mainline-rockchip/ deliberately — this benefits every device with an SD card, not just the Rockchip ones.

AI Usage

Did you use AI tools to help write this code? PARTIALLY

@Jacob-Matthew-Cook
Jacob-Matthew-Cook marked this pull request as draft September 11, 2026 08:31
_mmc_sd_resume() hands its result to mmc_sd_runtime_resume(), which
logs it and returns 0, so the PM core is told a resume succeeded even
when the card was never brought back. Every request queued against it
then hangs forever, and on a boot medium that wedges the machine.
Retry once from a power cycle instead.

Proven on two cards and two triggers: the GKD Pixel2's boot card still
busy when the host re-initialises it, and the RG353M's games card
timing out the optional SD cache-enable write. Both cards are healthy
and come back on the retry.

A second patch carried here previously made that cache-enable failure
non-fatal. Hardware testing on 2026-09-11 dropped it: it fired, the
card was removed anyway by the post-resume presence check, and by
swallowing the error it stopped the retry from running at all.

99-automount.rules handles ACTION=="remove" so a card that does drop
off the bus is remounted, instead of the stale mount blocking the add
rule and leaving /storage/roms empty until reboot.
@Jacob-Matthew-Cook Jacob-Matthew-Cook changed the title mmc: sd: keep cards alive across suspend and resume mmc: retry a failed SD card resume after a power cycle Sep 11, 2026
@Jacob-Matthew-Cook

Copy link
Copy Markdown
Contributor Author

Dropped the cache-enable patch: the retry alone covers both failures.

Same RG353M, same card, same day. With the cache patch, it fired exactly as designed and the card was removed anyway:

mmc2: error -110 writing Cache Enable bit
mmc2: could not enable card cache (-110), continuing without it
mmc2: card 5048 removed
Aborting journal on device mmcblk2p1-8.

Rebuilt without it, so the retry sees the error:

mmc2: error -110 writing Cache Enable bit
mmc2: resume failed (-110), retrying after a power cycle
dwmmc_rockchip fe2c0000.mmc: Successfully tuned phase to 265

That boot: 0 card removals, 0 ext4 aborts, and the mount never left /proc/mounts. Suppressing the error left a card the kernel then removed on its next status check, and hid the failure from the code that could repair it. What breaks at that moment is the card's state, not the return value.

@sydarn @porschemad911 this is now a single generic patch in drivers/mmc/core/sd.c, proven on two triggers: the Pixel2's boot card still busy at resume, and the RG353M's second-slot games card timing out the cache write. Same code path for both, so single-card and dual-card devices are covered alike.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant