Skip to content

Commit 0d81b5f

Browse files
committed
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
2 parents c8cc50a + ff31ee0 commit 0d81b5f

6 files changed

Lines changed: 60 additions & 18 deletions

File tree

drivers/mmc/core/core.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2264,7 +2264,7 @@ void mmc_start_host(struct mmc_host *host)
22642264
_mmc_detect_change(host, 0, false);
22652265
}
22662266

2267-
void mmc_stop_host(struct mmc_host *host)
2267+
void __mmc_stop_host(struct mmc_host *host)
22682268
{
22692269
if (host->slot.cd_irq >= 0) {
22702270
mmc_gpio_set_cd_wake(host, false);
@@ -2273,6 +2273,11 @@ void mmc_stop_host(struct mmc_host *host)
22732273

22742274
host->rescan_disable = 1;
22752275
cancel_delayed_work_sync(&host->detect);
2276+
}
2277+
2278+
void mmc_stop_host(struct mmc_host *host)
2279+
{
2280+
__mmc_stop_host(host);
22762281

22772282
/* clear pm flags now and let card drivers set them as needed */
22782283
host->pm_flags = 0;

drivers/mmc/core/core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static inline void mmc_delay(unsigned int ms)
7070

7171
void mmc_rescan(struct work_struct *work);
7272
void mmc_start_host(struct mmc_host *host);
73+
void __mmc_stop_host(struct mmc_host *host);
7374
void mmc_stop_host(struct mmc_host *host);
7475

7576
void _mmc_detect_change(struct mmc_host *host, unsigned long delay,

drivers/mmc/core/host.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,18 @@ static void mmc_host_classdev_release(struct device *dev)
8080
kfree(host);
8181
}
8282

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+
8391
static struct class mmc_host_class = {
8492
.name = "mmc_host",
8593
.dev_release = mmc_host_classdev_release,
94+
.shutdown_pre = mmc_host_classdev_shutdown,
8695
.pm = MMC_HOST_CLASS_DEV_PM_OPS,
8796
};
8897

drivers/mmc/host/meson-mx-sdhc-mmc.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc,
135135
struct mmc_command *cmd)
136136
{
137137
struct meson_mx_sdhc_host *host = mmc_priv(mmc);
138+
bool manual_stop = false;
138139
u32 ictl, send;
139140
int pack_len;
140141

@@ -172,12 +173,27 @@ static void meson_mx_sdhc_start_cmd(struct mmc_host *mmc,
172173
else
173174
/* software flush: */
174175
ictl |= MESON_SDHC_ICTL_DATA_XFER_OK;
176+
177+
/*
178+
* Mimic the logic from the vendor driver where (only)
179+
* SD_IO_RW_EXTENDED commands with more than one block set the
180+
* MESON_SDHC_MISC_MANUAL_STOP bit. This fixes the firmware
181+
* download in the brcmfmac driver for a BCM43362/1 card.
182+
* Without this sdio_memcpy_toio() (with a size of 219557
183+
* bytes) times out if MESON_SDHC_MISC_MANUAL_STOP is not set.
184+
*/
185+
manual_stop = cmd->data->blocks > 1 &&
186+
cmd->opcode == SD_IO_RW_EXTENDED;
175187
} else {
176188
pack_len = 0;
177189

178190
ictl |= MESON_SDHC_ICTL_RESP_OK;
179191
}
180192

193+
regmap_update_bits(host->regmap, MESON_SDHC_MISC,
194+
MESON_SDHC_MISC_MANUAL_STOP,
195+
manual_stop ? MESON_SDHC_MISC_MANUAL_STOP : 0);
196+
181197
if (cmd->opcode == MMC_STOP_TRANSMISSION)
182198
send |= MESON_SDHC_SEND_DATA_STOP;
183199

drivers/mmc/host/mmci_stm32_sdmmc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,8 @@ static int sdmmc_dlyb_phase_tuning(struct mmci_host *host, u32 opcode)
441441
return -EINVAL;
442442
}
443443

444+
writel_relaxed(0, dlyb->base + DLYB_CR);
445+
444446
phase = end_of_len - max_len / 2;
445447
sdmmc_dlyb_set_cfgr(dlyb, dlyb->unit, phase, false);
446448

drivers/mmc/host/sdhci-tegra.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -356,23 +356,6 @@ static void tegra_sdhci_set_tap(struct sdhci_host *host, unsigned int tap)
356356
}
357357
}
358358

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-
376359
static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
377360
{
378361
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)
793776
}
794777
}
795778

779+
static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc,
780+
struct mmc_ios *ios)
781+
{
782+
struct sdhci_host *host = mmc_priv(mmc);
783+
u32 val;
784+
785+
val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);
786+
787+
if (ios->enhanced_strobe) {
788+
val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
789+
/*
790+
* When CMD13 is sent from mmc_select_hs400es() after
791+
* switching to HS400ES mode, the bus is operating at
792+
* either MMC_HIGH_26_MAX_DTR or MMC_HIGH_52_MAX_DTR.
793+
* To meet Tegra SDHCI requirement at HS400ES mode, force SDHCI
794+
* interface clock to MMC_HS200_MAX_DTR (200 MHz) so that host
795+
* controller CAR clock and the interface clock are rate matched.
796+
*/
797+
tegra_sdhci_set_clock(host, MMC_HS200_MAX_DTR);
798+
} else {
799+
val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE;
800+
}
801+
802+
sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL);
803+
}
804+
796805
static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host)
797806
{
798807
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);

0 commit comments

Comments
 (0)