From: Erick Shepherd erick.shepherd@ni.com
[ Upstream commit 5f755ba95ae10fd4fa28d64345056ffc18d12c5a ]
Per the SD Host Controller Simplified Specification v4.20 §3.2.3, change the SD card clock parameters only after first disabling the external card clock. Doing this fixes a spurious clock pulse on Baytrail and Apollo Lake SD controllers which otherwise breaks voltage switching with a specific Swissbit SD card. This change is limited to Intel host controllers to avoid an issue reported on ARM64 devices.
Signed-off-by: Kyle Roeschley kyle.roeschley@ni.com Signed-off-by: Brad Mouring brad.mouring@ni.com Signed-off-by: Erick Shepherd erick.shepherd@ni.com Acked-by: Adrian Hunter adrian.hunter@intel.com Link: https://lore.kernel.org/r/20250724185354.815888-1-erick.shepherd@ni.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Backport Status: YES
## Comprehensive Analysis
After conducting an exhaustive investigation of this commit, including its history, related changes, bug reports, and mailing list discussions, I strongly recommend **YES** for backporting this commit to stable kernel trees.
### Critical Context: This is Version 2 of a Previously Reverted Fix
**Timeline of Events:**
1. **February 11, 2025 (fb3bbc46c94f2)**: Original fix applied to **ALL** sdhci controllers in `drivers/mmc/host/sdhci.c` - Modified the generic `sdhci_set_clock()` function - Affected every platform using SDHCI
2. **June 24, 2025 (dcc3bcfc5b50c)**: **REVERT** of the generic version - Caused boot failures on eMMC devices (Debian bug #1108065) - Broke Lenovo IdeaPad 1 15ADA7 and other ARM64 devices - Error: "mmc1: mmc_select_hs400 failed, error -110" - Revert commit message states: "It has turned out the trying to strictly conform to the SDHCI specification is causing problems"
3. **July 24, 2025 (5f755ba95ae10)**: **THIS COMMIT** - Intel-only revised version - Limited scope to Intel Baytrail and Apollo Lake controllers ONLY - Does NOT modify generic sdhci code - Commit message explicitly states: "This change is limited to Intel host controllers to avoid an issue reported on ARM64 devices"
### Code Changes Analysis
The commit creates a new Intel-specific function `sdhci_intel_set_clock()` in `drivers/mmc/host/sdhci-pci-core.c`:
```c static void sdhci_intel_set_clock(struct sdhci_host *host, unsigned int clock) { u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
/* Stop card clock separately to avoid glitches on clock line */ if (clk & SDHCI_CLOCK_CARD_EN) sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, SDHCI_CLOCK_CONTROL);
sdhci_set_clock(host, clock); } ```
**Key Implementation Details:** - Reads current clock control register value (lines 682-684 in sdhci- pci-core.c) - Disables ONLY the card clock enable bit (SDHCI_CLOCK_CARD_EN) if it's set - Then calls the standard `sdhci_set_clock()` function - Only affects `sdhci_intel_byt_ops` (Baytrail) and `sdhci_intel_glk_ops` (Apollo Lake/Gemini Lake)
**Comparison with Generic Version:** - **Generic version**: Modified `sdhci_set_clock()` in `drivers/mmc/host/sdhci.c` → Affected ALL platforms → REVERTED - **Intel-only version**: Creates wrapper in `drivers/mmc/host/sdhci- pci-core.c` → Affects ONLY Intel BYT/GLK → STABLE
### Bug Being Fixed
**Problem**: Spurious clock pulse during voltage switching on Intel Baytrail and Apollo Lake SD controllers breaks compatibility with specific Swissbit SD cards.
**Root Cause**: Not following SD Host Controller Simplified Specification v4.20 §3.2.3, which requires disabling the external card clock before changing clock parameters.
**Impact**: Users with affected Intel platforms cannot use certain SD cards due to voltage switching failures.
### Evidence of Stability and Safety
1. **No Regression Reports**: Extensive git log searches found NO fixes or reverts for commit 5f755ba95ae10 - `git log --grep="Fixes: 5f755ba95ae10"` → No results - `git log --grep="Revert.*5f755ba95ae10"` → No results
2. **Already Backported**: Commit 3d55ad9d6ad57 is the backport of this fix to a stable tree, indicating stable maintainers already accepted it
3. **Limited Scope**: Changes are confined to: - Single file: `drivers/mmc/host/sdhci-pci-core.c` - Two specific controller types: Intel Baytrail and Apollo Lake - Does NOT touch generic SDHCI code
4. **Testing Confirmation**: Mailing list discussion (lore.kernel.org) shows author tested on Baytrail SD controller with Swissbit SD card with no issues
5. **Specification Compliant**: Follows official SD Host Controller Specification v4.20 §3.2.3
### Risk Assessment
**Risk Level: VERY LOW**
**Why Low Risk:** - **Surgical Change**: Only 13 lines added (one small function + two pointer updates) - **Platform-Specific**: Cannot affect any non-Intel platforms - **Controller-Specific**: Even among Intel platforms, only affects Baytrail and Apollo Lake - **No Side Effects**: Simply wraps existing `sdhci_set_clock()` with additional clock disable step - **Learned from Previous Mistake**: The generic version was reverted; this version specifically avoids those issues by limiting scope
**Potential Impact if NOT Backported:** - Users with Intel Baytrail/Apollo Lake platforms + specific SD cards continue experiencing voltage switching failures - No workaround available without this fix
### Stable Kernel Criteria Compliance
✅ **Fixes important bug**: Yes - voltage switching failures affect real users ✅ **No new features**: Correct - only fixes existing functionality ✅ **No architectural changes**: Correct - minimal, targeted fix ✅ **Minimal regression risk**: Yes - isolated to specific Intel controllers ✅ **Confined to subsystem**: Yes - only affects Intel MMC/SD controllers ✅ **Has maintainer approval**: Yes - Acked-by: Adrian Hunter (Intel maintainer)
### Backporting Recommendation
**STRONG YES** - This commit should be backported to all applicable stable kernel trees.
**Justification:** 1. Fixes a real user-impacting bug (voltage switching failures) 2. Extremely low regression risk (Intel-specific, already proven stable) 3. Small, well-contained change 4. Learned from and avoids the issues of the previously-reverted generic version 5. Already successfully backported to at least one stable tree 6. Follows kernel stable tree rules perfectly 7. No known issues or follow-up fixes needed
**Recommended Stable Trees:** All stable trees that include Intel Baytrail/Apollo Lake support (likely 6.1+, 6.6+, 6.12+, etc.)
drivers/mmc/host/sdhci-pci-core.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 826958992dfe2..47a0a738862b5 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c @@ -679,8 +679,19 @@ static int intel_start_signal_voltage_switch(struct mmc_host *mmc, return 0; }
+static void sdhci_intel_set_clock(struct sdhci_host *host, unsigned int clock) +{ + u16 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + + /* Stop card clock separately to avoid glitches on clock line */ + if (clk & SDHCI_CLOCK_CARD_EN) + sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, SDHCI_CLOCK_CONTROL); + + sdhci_set_clock(host, clock); +} + static const struct sdhci_ops sdhci_intel_byt_ops = { - .set_clock = sdhci_set_clock, + .set_clock = sdhci_intel_set_clock, .set_power = sdhci_intel_set_power, .enable_dma = sdhci_pci_enable_dma, .set_bus_width = sdhci_set_bus_width, @@ -690,7 +701,7 @@ static const struct sdhci_ops sdhci_intel_byt_ops = { };
static const struct sdhci_ops sdhci_intel_glk_ops = { - .set_clock = sdhci_set_clock, + .set_clock = sdhci_intel_set_clock, .set_power = sdhci_intel_set_power, .enable_dma = sdhci_pci_enable_dma, .set_bus_width = sdhci_set_bus_width,