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-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

+17 -27
+4 -3
drivers/mmc/core/block.c
··· 851 851 static int mmc_blk_part_switch_pre(struct mmc_card *card, 852 852 unsigned int part_type) 853 853 { 854 + const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB; 854 855 int ret = 0; 855 856 856 - if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { 857 + if ((part_type & mask) == mask) { 857 858 if (card->ext_csd.cmdq_en) { 858 859 ret = mmc_cmdq_disable(card); 859 860 if (ret) ··· 869 868 static int mmc_blk_part_switch_post(struct mmc_card *card, 870 869 unsigned int part_type) 871 870 { 871 + const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB; 872 872 int ret = 0; 873 873 874 - if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { 874 + if ((part_type & mask) == mask) { 875 875 mmc_retune_unpause(card->host); 876 876 if (card->reenable_cmdq && !card->ext_csd.cmdq_en) 877 877 ret = mmc_cmdq_enable(card); ··· 3147 3145 3148 3146 MODULE_LICENSE("GPL"); 3149 3147 MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); 3150 -
+1
drivers/mmc/core/host.c
··· 692 692 */ 693 693 void mmc_free_host(struct mmc_host *host) 694 694 { 695 + cancel_delayed_work_sync(&host->detect); 695 696 mmc_pwrseq_free(host); 696 697 put_device(&host->class_dev); 697 698 }
+5 -21
drivers/mmc/host/meson-mx-sdhc-mmc.c
··· 269 269 static int meson_mx_sdhc_set_clk(struct mmc_host *mmc, struct mmc_ios *ios) 270 270 { 271 271 struct meson_mx_sdhc_host *host = mmc_priv(mmc); 272 - u32 rx_clk_phase; 272 + u32 val, rx_clk_phase; 273 273 int ret; 274 274 275 275 meson_mx_sdhc_disable_clks(mmc); ··· 290 290 mmc->actual_clock = clk_get_rate(host->sd_clk); 291 291 292 292 /* 293 - * according to Amlogic the following latching points are 294 - * selected with empirical values, there is no (known) formula 295 - * to calculate these. 293 + * Phase 90 should work in most cases. For data transmission, 294 + * meson_mx_sdhc_execute_tuning() will find a accurate value 296 295 */ 297 - if (mmc->actual_clock > 100000000) { 298 - rx_clk_phase = 1; 299 - } else if (mmc->actual_clock > 45000000) { 300 - if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) 301 - rx_clk_phase = 15; 302 - else 303 - rx_clk_phase = 11; 304 - } else if (mmc->actual_clock >= 25000000) { 305 - rx_clk_phase = 15; 306 - } else if (mmc->actual_clock > 5000000) { 307 - rx_clk_phase = 23; 308 - } else if (mmc->actual_clock > 1000000) { 309 - rx_clk_phase = 55; 310 - } else { 311 - rx_clk_phase = 1061; 312 - } 313 - 296 + regmap_read(host->regmap, MESON_SDHC_CLKC, &val); 297 + rx_clk_phase = FIELD_GET(MESON_SDHC_CLKC_CLK_DIV, val) / 4; 314 298 regmap_update_bits(host->regmap, MESON_SDHC_CLK2, 315 299 MESON_SDHC_CLK2_RX_CLK_PHASE, 316 300 FIELD_PREP(MESON_SDHC_CLK2_RX_CLK_PHASE,
+7 -3
drivers/mmc/host/sdhci-sprd.c
··· 239 239 div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8); 240 240 sdhci_enable_clk(host, div); 241 241 242 + val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); 243 + mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; 242 244 /* Enable CLK_AUTO when the clock is greater than 400K. */ 243 245 if (clk > 400000) { 244 - val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); 245 - mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | 246 - SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; 247 246 if (mask != (val & mask)) { 248 247 val |= mask; 248 + sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); 249 + } 250 + } else { 251 + if (val & mask) { 252 + val &= ~mask; 249 253 sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); 250 254 } 251 255 }