Re: [PATCH] mmc: core: Fix max_dtr passed to SD drive strength selection

From: Ulf Hansson

Date: Wed Oct 28 2026 - 13:21:23 EST


On Tue, Oct 6, 2026 at 3:19 PM Shawn Lin <shawn.lin@xxxxxxxxx> wrote:
>
> sd_select_driver_type() passes card->sw_caps.uhs_max_dtr to
> mmc_select_drive_strength(), but that field is only assigned later by
> sd_set_bus_speed_mode(). A card initialized for the first time thus
> gets max_dtr=0, while a re-initialized card (system resume or
> hw reset recovery reuse the card struct) gets the stale value from the
> previous initialization.
>
> No in-tree driver implementing ->select_drive_strength() (AMD and Intel
> SDHCI) actually looks at max_dtr, so there is no functional impact
> today. Still, compute the frequency from the bus speed mode that
> sd_update_bus_speed_mode() has already selected, so the core doesn't
> hand out a bogus value, and use the same helper in sd_set_bus_speed_mode()
> to keep a single mapping.
>
> Signed-off-by: Shawn Lin <shawn.lin@xxxxxxxxx>

Applied for next, thanks!

Kind regards
Uffe


> ---
>
> drivers/mmc/core/sd.c | 25 +++++++++++++++++++------
> 1 file changed, 19 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index c763efb..5ba4e2d 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -417,6 +417,22 @@ int mmc_sd_switch_hs(struct mmc_card *card)
> return err;
> }
>
> +static unsigned int sd_get_bus_speed_dtr(struct mmc_card *card)
> +{
> + switch (card->sd_bus_speed) {
> + case UHS_SDR104_BUS_SPEED:
> + return UHS_SDR104_MAX_DTR;
> + case UHS_DDR50_BUS_SPEED:
> + return UHS_DDR50_MAX_DTR;
> + case UHS_SDR50_BUS_SPEED:
> + return UHS_SDR50_MAX_DTR;
> + case UHS_SDR25_BUS_SPEED:
> + return UHS_SDR25_MAX_DTR;
> + default:
> + return UHS_SDR12_MAX_DTR;
> + }
> +}
> +
> static int sd_select_driver_type(struct mmc_card *card, u8 *status)
> {
> int card_drv_type, drive_strength, drv_type;
> @@ -427,7 +443,7 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
> card_drv_type = card->sw_caps.sd3_drv_type | SD_DRIVER_TYPE_B;
>
> drive_strength = mmc_select_drive_strength(card,
> - card->sw_caps.uhs_max_dtr,
> + sd_get_bus_speed_dtr(card),
> card_drv_type, &drv_type);
>
> if (drive_strength) {
> @@ -490,28 +506,25 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
> switch (card->sd_bus_speed) {
> case UHS_SDR104_BUS_SPEED:
> timing = MMC_TIMING_UHS_SDR104;
> - card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
> break;
> case UHS_DDR50_BUS_SPEED:
> timing = MMC_TIMING_UHS_DDR50;
> - card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
> break;
> case UHS_SDR50_BUS_SPEED:
> timing = MMC_TIMING_UHS_SDR50;
> - card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
> break;
> case UHS_SDR25_BUS_SPEED:
> timing = MMC_TIMING_UHS_SDR25;
> - card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
> break;
> case UHS_SDR12_BUS_SPEED:
> timing = MMC_TIMING_UHS_SDR12;
> - card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
> break;
> default:
> return 0;
> }
>
> + card->sw_caps.uhs_max_dtr = sd_get_bus_speed_dtr(card);
> +
> err = mmc_sd_switch(card, SD_SWITCH_SET, 0, card->sd_bus_speed, status);
> if (err)
> return err;
> --
> 2.7.4
>