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
 -----BEGIN PGP SIGNATURE-----
 
 iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmHEdk4XHHVsZi5oYW5z
 c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCmfYhAAy66DW8YmcXkXMwpiIRh/aTsr
 Bo60fTk1U1Q4bxC8BsQqItuVKaC5XaiMaJZC0GSQI9pDLI8L8MYGzUfACr8hJI5x
 QGAqajPceAyaX2v5jRkCTxtA7nkIc482/ylCvLLH1cahBFMKMV8ULEoOIzjglcjc
 ZIGwoY8mK+NMMeyRjMalASTK415AdRmlqOhJkXVJ0bsQs+Or+xzEI2RC5UKoZHhg
 LqXCf8F9YHCWtRjYlFfY+wliyFea6bkhq2mnb3KOx4ieXzCC471Ttnz4rR+rAFMs
 XgzfTQ0/W4Yb/UJ4UeiEAdZoBAyiz6q8Pl35GaV8q2MuNvDgPPekLBiVG82ILXCB
 x+CqREzyjmQqqLzVD6f3kl9TPIHXxP3wySLCraGgi7/rKd1Bg//EyhCemRQ2cxEa
 buVlrOQR6bTXqb+qeImjzXBB0/HV4hNPceLNAAbUR6N5lVp1ERsyxi/f20Z7keAU
 Z4Ib6rm1oco3hFHGbjoS87HjeLowduGqmRsEqkcGCjblWudVBqX8Wb/pR6QToGCq
 jjz1ZAk4ZOCvv5uwR1/DhJyreekA6Ce9b8e7FH+wIMHT/tz2kbhxGmPe7u5vcTTX
 8A4CubzdXhOiX5ZtxfRyU0tr3Roe183MaA+Cwgw+l1OmHeuwvfQ3QLxTy1b776kd
 qiAakPQRnumE7RLzw0I=
 =0qCG
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2021-12-23 09:37:59 -08:00
commit 0d81b5faa2
6 changed files with 60 additions and 18 deletions

View File

@ -2264,7 +2264,7 @@ void mmc_start_host(struct mmc_host *host)
_mmc_detect_change(host, 0, false);
}
void mmc_stop_host(struct mmc_host *host)
void __mmc_stop_host(struct mmc_host *host)
{
if (host->slot.cd_irq >= 0) {
mmc_gpio_set_cd_wake(host, false);
@ -2273,6 +2273,11 @@ void mmc_stop_host(struct mmc_host *host)
host->rescan_disable = 1;
cancel_delayed_work_sync(&host->detect);
}
void mmc_stop_host(struct mmc_host *host)
{
__mmc_stop_host(host);
/* clear pm flags now and let card drivers set them as needed */
host->pm_flags = 0;

View File

@ -70,6 +70,7 @@ static inline void mmc_delay(unsigned int ms)
void mmc_rescan(struct work_struct *work);
void mmc_start_host(struct mmc_host *host);
void __mmc_stop_host(struct mmc_host *host);
void mmc_stop_host(struct mmc_host *host);
void _mmc_detect_change(struct mmc_host *host, unsigned long delay,

View File

@ -80,9 +80,18 @@ static void mmc_host_classdev_release(struct device *dev)
kfree(host);
}
static int mmc_host_classdev_shutdown(struct device *dev)
{
struct mmc_host *host = cls_dev_to_mmc_host(dev);
__mmc_stop_host(host);
return 0;
}
static struct class mmc_host_class = {
.name = "mmc_host",
.dev_release = mmc_host_classdev_release,
.shutdown_pre = mmc_host_classdev_shutdown,
.pm = MMC_HOST_CLASS_DEV_PM_OPS,
};

View File

@ -135,6 +135,7 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc,
struct mmc_command *cmd)
{
struct meson_mx_sdhc_host *host = mmc_priv(mmc);
bool manual_stop = false;
u32 ictl, send;
int pack_len;
@ -172,12 +173,27 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc,
else
/* software flush: */
ictl |= MESON_SDHC_ICTL_DATA_XFER_OK;
/*
* Mimic the logic from the vendor driver where (only)
* SD_IO_RW_EXTENDED commands with more than one block set the
* MESON_SDHC_MISC_MANUAL_STOP bit. This fixes the firmware
* download in the brcmfmac driver for a BCM43362/1 card.
* Without this sdio_memcpy_toio() (with a size of 219557
* bytes) times out if MESON_SDHC_MISC_MANUAL_STOP is not set.
*/
manual_stop = cmd->data->blocks > 1 &&
cmd->opcode == SD_IO_RW_EXTENDED;
} else {
pack_len = 0;
ictl |= MESON_SDHC_ICTL_RESP_OK;
}
regmap_update_bits(host->regmap, MESON_SDHC_MISC,
MESON_SDHC_MISC_MANUAL_STOP,
manual_stop ? MESON_SDHC_MISC_MANUAL_STOP : 0);
if (cmd->opcode == MMC_STOP_TRANSMISSION)
send |= MESON_SDHC_SEND_DATA_STOP;

View File

@ -441,6 +441,8 @@ static int sdmmc_dlyb_phase_tuning(struct mmci_host *host, u32 opcode)
return -EINVAL;
}
writel_relaxed(0, dlyb->base + DLYB_CR);
phase = end_of_len - max_len / 2;
sdmmc_dlyb_set_cfgr(dlyb, dlyb->unit, phase, false);

View File

@ -356,23 +356,6 @@ static void tegra_sdhci_set_tap(struct sdhci_host *host, unsigned int tap)
}
}
static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc,
struct mmc_ios *ios)
{
struct sdhci_host *host = mmc_priv(mmc);
u32 val;
val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);
if (ios->enhanced_strobe)
val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
else
val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);
}
static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@ -793,6 +776,32 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
}
}
static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc,
struct mmc_ios *ios)
{
struct sdhci_host *host = mmc_priv(mmc);
u32 val;
val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);
if (ios->enhanced_strobe) {
val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
/*
* When CMD13 is sent from mmc_select_hs400es() after
* switching to HS400ES mode, the bus is operating at
* either MMC_HIGH_26_MAX_DTR or MMC_HIGH_52_MAX_DTR.
* To meet Tegra SDHCI requirement at HS400ES mode, force SDHCI
* interface clock to MMC_HS200_MAX_DTR (200 MHz) so that host
* controller CAR clock and the interface clock are rate matched.
*/
tegra_sdhci_set_clock(host, MMC_HS200_MAX_DTR);
} else {
val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
}
sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);
}
static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);