MMC core:

- Fix path when releasing the host by canceling the delayed work
  - Fix pause retune on all RPMB partitions
 
 MMC host:
  - meson-mx-sdhc: Fix HW hang during card initialization
  - sdhci-sprd: Fix eMMC init failure after HW reset
 -----BEGIN PGP SIGNATURE-----
 
 iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmWXzxQXHHVsZi5oYW5z
 c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCnUiA/+Nirp2Jemjr/UqAvs4+yh++Ib
 wRaUtvPaZbGxB1JTPoGG5s5S8WZfz1neSax8xS++/A/PVFtpSDnNtUiY6YIZ4TPm
 E2PkhsCPDkgYfPtikMmzJbRvrh60EhdaWfd4A8BT/SsZnJxJHAwpvc5a3ayxbYxj
 TreNbnzK0JidJxaEtZQpjZ9fSxViMQ8OB04QpiWG2c5tXlgEJDX8R76nv5/4pdTK
 3y3jcy1FztUz0vAkAbQ0qvaP32PlJZ1Yei5mToHLOE0cYgwdtSfgYt89jT1GeePZ
 fiBS6ODURh5npZeS55DWq8lgQRbEzJxuDQcZgYoa85ZO5MDRFOlYdGdyvDB458s4
 HqUvZyO5aMIMwREXDXixynZj4WVde1XYDUGRoWu3N/pjfB/qVIMry+cTSNeGobhk
 yHvS3WCROXG3/wy4Nb5QN7r6UogaIoxITINP5vCgHpxUW8c1tYes/NmL05joeHUT
 61dxsXrIGMGMQaTeUuC6CTqbzhG/xOYLo51K8jVnAKshJsZlGdPj3tIyND4Xo4Mm
 MuVfCtEr7vyMwBjkOF2nDTdj5Kn67jmuNXY9zf6NNN+bgYcWC3zvrRk+OiVzz8mF
 MkjbIadWLJ2J5gpQtjYFpKs4oAUPth0wHiVI9c5mXhVR3qapA9v7kOTXycWUVrfu
 mO5oaJvuBzM3DSlwTJw=
 =SfSL
 -----END PGP SIGNATURE-----

Merge tag 'mmc-v6.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "MMC core:
   - Fix releasing the host by canceling the delayed work
   - Fix pause retune on all RPMB partitions

  MMC host:
   - meson-mx-sdhc: Fix HW hang during card initialization
   - sdhci-sprd: Fix eMMC init failure after HW reset"

* tag 'mmc-v6.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci-sprd: Fix eMMC init failure after hw reset
  mmc: core: Cancel delayed work before releasing host
  mmc: rpmb: fixes pause retune on all RPMB partitions.
  mmc: meson-mx-sdhc: Fix initialization frozen issue
This commit is contained in:
Linus Torvalds 2024-01-05 12:12:33 -08:00
commit 6c23529c08
4 changed files with 17 additions and 27 deletions

View File

@ -851,9 +851,10 @@ static const struct block_device_operations mmc_bdops = {
static int mmc_blk_part_switch_pre(struct mmc_card *card,
unsigned int part_type)
{
const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
int ret = 0;
if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
if ((part_type & mask) == mask) {
if (card->ext_csd.cmdq_en) {
ret = mmc_cmdq_disable(card);
if (ret)
@ -868,9 +869,10 @@ static int mmc_blk_part_switch_pre(struct mmc_card *card,
static int mmc_blk_part_switch_post(struct mmc_card *card,
unsigned int part_type)
{
const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
int ret = 0;
if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) {
if ((part_type & mask) == mask) {
mmc_retune_unpause(card->host);
if (card->reenable_cmdq && !card->ext_csd.cmdq_en)
ret = mmc_cmdq_enable(card);
@ -3145,4 +3147,3 @@ module_exit(mmc_blk_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");

View File

@ -692,6 +692,7 @@ EXPORT_SYMBOL(mmc_remove_host);
*/
void mmc_free_host(struct mmc_host *host)
{
cancel_delayed_work_sync(&host->detect);
mmc_pwrseq_free(host);
put_device(&host->class_dev);
}

View File

@ -269,7 +269,7 @@ static int meson_mx_sdhc_enable_clks(struct mmc_host *mmc)
static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct meson_mx_sdhc_host *host = mmc_priv(mmc);
u32 rx_clk_phase;
u32 val, rx_clk_phase;
int ret;
meson_mx_sdhc_disable_clks(mmc);
@ -290,27 +290,11 @@ static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios)
mmc->actual_clock = clk_get_rate(host->sd_clk);
/*
* according to Amlogic the following latching points are
* selected with empirical values, there is no (known) formula
* to calculate these.
* Phase 90 should work in most cases. For data transmission,
* meson_mx_sdhc_execute_tuning() will find a accurate value
*/
if (mmc->actual_clock > 100000000) {
rx_clk_phase = 1;
} else if (mmc->actual_clock > 45000000) {
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
rx_clk_phase = 15;
else
rx_clk_phase = 11;
} else if (mmc->actual_clock >= 25000000) {
rx_clk_phase = 15;
} else if (mmc->actual_clock > 5000000) {
rx_clk_phase = 23;
} else if (mmc->actual_clock > 1000000) {
rx_clk_phase = 55;
} else {
rx_clk_phase = 1061;
}
regmap_read(host->regmap, MESON_SDHC_CLKC, &val);
rx_clk_phase = FIELD_GET(MESON_SDHC_CLKC_CLK_DIV, val) / 4;
regmap_update_bits(host->regmap, MESON_SDHC_CLK2,
MESON_SDHC_CLK2_RX_CLK_PHASE,
FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE,

View File

@ -239,15 +239,19 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host,
div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
sdhci_enable_clk(host, div);
val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
/* Enable CLK_AUTO when the clock is greater than 400K. */
if (clk > 400000) {
val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
if (mask != (val & mask)) {
val |= mask;
sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
}
} else {
if (val & mask) {
val &= ~mask;
sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
}
}
}