Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mmc-v5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
"MMC core:
- Disable card detect during shutdown

MMC host:
- mmci: Fixup tuning support for stm32_sdmmc
- meson-mx-sdhc: Fix support for multi-block SDIO commands
- sdhci-tegra: Fix support for eMMC HS400ES mode"

* tag 'mmc-v5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
mmc: mmci: stm32: clear DLYB_CR after sending tuning command
mmc: meson-mx-sdhc: Set MANUAL_STOP for multi-block SDIO commands
mmc: core: Disable card detect during shutdown
mmc: sdhci-tegra: Fix switch to HS400ES mode

+60 -18
+6 -1
drivers/mmc/core/core.c
··· 2264 2264 _mmc_detect_change(host, 0, false); 2265 2265 } 2266 2266 2267 - void mmc_stop_host(struct mmc_host *host) 2267 + void __mmc_stop_host(struct mmc_host *host) 2268 2268 { 2269 2269 if (host->slot.cd_irq >= 0) { 2270 2270 mmc_gpio_set_cd_wake(host, false); ··· 2273 2273 2274 2274 host->rescan_disable = 1; 2275 2275 cancel_delayed_work_sync(&host->detect); 2276 + } 2277 + 2278 + void mmc_stop_host(struct mmc_host *host) 2279 + { 2280 + __mmc_stop_host(host); 2276 2281 2277 2282 /* clear pm flags now and let card drivers set them as needed */ 2278 2283 host->pm_flags = 0;
+1
drivers/mmc/core/core.h
··· 70 70 71 71 void mmc_rescan(struct work_struct *work); 72 72 void mmc_start_host(struct mmc_host *host); 73 + void __mmc_stop_host(struct mmc_host *host); 73 74 void mmc_stop_host(struct mmc_host *host); 74 75 75 76 void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
+9
drivers/mmc/core/host.c
··· 80 80 kfree(host); 81 81 } 82 82 83 + static int mmc_host_classdev_shutdown(struct device *dev) 84 + { 85 + struct mmc_host *host = cls_dev_to_mmc_host(dev); 86 + 87 + __mmc_stop_host(host); 88 + return 0; 89 + } 90 + 83 91 static struct class mmc_host_class = { 84 92 .name = "mmc_host", 85 93 .dev_release = mmc_host_classdev_release, 94 + .shutdown_pre = mmc_host_classdev_shutdown, 86 95 .pm = MMC_HOST_CLASS_DEV_PM_OPS, 87 96 }; 88 97
+16
drivers/mmc/host/meson-mx-sdhc-mmc.c
··· 135 135 struct mmc_command *cmd) 136 136 { 137 137 struct meson_mx_sdhc_host *host = mmc_priv(mmc); 138 + bool manual_stop = false; 138 139 u32 ictl, send; 139 140 int pack_len; 140 141 ··· 173 172 else 174 173 /* software flush: */ 175 174 ictl |= MESON_SDHC_ICTL_DATA_XFER_OK; 175 + 176 + /* 177 + * Mimic the logic from the vendor driver where (only) 178 + * SD_IO_RW_EXTENDED commands with more than one block set the 179 + * MESON_SDHC_MISC_MANUAL_STOP bit. This fixes the firmware 180 + * download in the brcmfmac driver for a BCM43362/1 card. 181 + * Without this sdio_memcpy_toio() (with a size of 219557 182 + * bytes) times out if MESON_SDHC_MISC_MANUAL_STOP is not set. 183 + */ 184 + manual_stop = cmd->data->blocks > 1 && 185 + cmd->opcode == SD_IO_RW_EXTENDED; 176 186 } else { 177 187 pack_len = 0; 178 188 179 189 ictl |= MESON_SDHC_ICTL_RESP_OK; 180 190 } 191 + 192 + regmap_update_bits(host->regmap, MESON_SDHC_MISC, 193 + MESON_SDHC_MISC_MANUAL_STOP, 194 + manual_stop ? MESON_SDHC_MISC_MANUAL_STOP : 0); 181 195 182 196 if (cmd->opcode == MMC_STOP_TRANSMISSION) 183 197 send |= MESON_SDHC_SEND_DATA_STOP;
+2
drivers/mmc/host/mmci_stm32_sdmmc.c
··· 441 441 return -EINVAL; 442 442 } 443 443 444 + writel_relaxed(0, dlyb->base + DLYB_CR); 445 + 444 446 phase = end_of_len - max_len / 2; 445 447 sdmmc_dlyb_set_cfgr(dlyb, dlyb->unit, phase, false); 446 448
+26 -17
drivers/mmc/host/sdhci-tegra.c
··· 356 356 } 357 357 } 358 358 359 - static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc, 360 - struct mmc_ios *ios) 361 - { 362 - struct sdhci_host *host = mmc_priv(mmc); 363 - u32 val; 364 - 365 - val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); 366 - 367 - if (ios->enhanced_strobe) 368 - val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; 369 - else 370 - val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; 371 - 372 - sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); 373 - 374 - } 375 - 376 359 static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask) 377 360 { 378 361 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ··· 774 791 tegra_sdhci_pad_autocalib(host); 775 792 tegra_host->pad_calib_required = false; 776 793 } 794 + } 795 + 796 + static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc, 797 + struct mmc_ios *ios) 798 + { 799 + struct sdhci_host *host = mmc_priv(mmc); 800 + u32 val; 801 + 802 + val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); 803 + 804 + if (ios->enhanced_strobe) { 805 + val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; 806 + /* 807 + * When CMD13 is sent from mmc_select_hs400es() after 808 + * switching to HS400ES mode, the bus is operating at 809 + * either MMC_HIGH_26_MAX_DTR or MMC_HIGH_52_MAX_DTR. 810 + * To meet Tegra SDHCI requirement at HS400ES mode, force SDHCI 811 + * interface clock to MMC_HS200_MAX_DTR (200 MHz) so that host 812 + * controller CAR clock and the interface clock are rate matched. 813 + */ 814 + tegra_sdhci_set_clock(host, MMC_HS200_MAX_DTR); 815 + } else { 816 + val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; 817 + } 818 + 819 + sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); 777 820 } 778 821 779 822 static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host)