Skip to content

Commit 2df2adc

Browse files
committed
Merge tag 'mmc-v6.1-rc5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fixes from Ulf Hansson: "MMC core: - Fix ambiguous TRIM and DISCARD args - Fix removal of debugfs file for mmc_test MMC host: - mtk-sd: Add missing clk_disable_unprepare() in an error path - sdhci: Fix I/O voltage switch delay for UHS-I SD cards - sdhci-esdhc-imx: Fix CQHCI exit halt state check - sdhci-sprd: Fix voltage switch" * tag 'mmc-v6.1-rc5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: sdhci-sprd: Fix no reset data and command after voltage switch mmc: sdhci: Fix voltage switch delay mmc: mtk-sd: Fix missing clk_disable_unprepare in msdc_of_clock_parse() mmc: mmc_test: Fix removal of debugfs file mmc: sdhci-esdhc-imx: correct CQHCI exit halt state check mmc: core: Fix ambiguous TRIM and DISCARD arg
2 parents f66f62f + dd30dcf commit 2df2adc

File tree

8 files changed

+72
-17
lines changed

8 files changed

+72
-17
lines changed

drivers/mmc/core/core.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,6 +1484,11 @@ void mmc_init_erase(struct mmc_card *card)
14841484
card->pref_erase = 0;
14851485
}
14861486

1487+
static bool is_trim_arg(unsigned int arg)
1488+
{
1489+
return (arg & MMC_TRIM_OR_DISCARD_ARGS) && arg != MMC_DISCARD_ARG;
1490+
}
1491+
14871492
static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
14881493
unsigned int arg, unsigned int qty)
14891494
{
@@ -1766,7 +1771,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
17661771
!(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN))
17671772
return -EOPNOTSUPP;
17681773

1769-
if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) &&
1774+
if (mmc_card_mmc(card) && is_trim_arg(arg) &&
17701775
!(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN))
17711776
return -EOPNOTSUPP;
17721777

@@ -1796,7 +1801,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
17961801
* identified by the card->eg_boundary flag.
17971802
*/
17981803
rem = card->erase_size - (from % card->erase_size);
1799-
if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) {
1804+
if ((arg & MMC_TRIM_OR_DISCARD_ARGS) && card->eg_boundary && nr > rem) {
18001805
err = mmc_do_erase(card, from, from + rem - 1, arg);
18011806
from += rem;
18021807
if ((err) || (to <= from))

drivers/mmc/core/mmc_test.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3179,7 +3179,8 @@ static int __mmc_test_register_dbgfs_file(struct mmc_card *card,
31793179
struct mmc_test_dbgfs_file *df;
31803180

31813181
if (card->debugfs_root)
3182-
debugfs_create_file(name, mode, card->debugfs_root, card, fops);
3182+
file = debugfs_create_file(name, mode, card->debugfs_root,
3183+
card, fops);
31833184

31843185
df = kmalloc(sizeof(*df), GFP_KERNEL);
31853186
if (!df) {

drivers/mmc/host/mtk-sd.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,13 +2588,11 @@ static int msdc_of_clock_parse(struct platform_device *pdev,
25882588
return PTR_ERR(host->src_clk_cg);
25892589
}
25902590

2591-
host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg");
2591+
/* If present, always enable for this clock gate */
2592+
host->sys_clk_cg = devm_clk_get_optional_enabled(&pdev->dev, "sys_cg");
25922593
if (IS_ERR(host->sys_clk_cg))
25932594
host->sys_clk_cg = NULL;
25942595

2595-
/* If present, always enable for this clock gate */
2596-
clk_prepare_enable(host->sys_clk_cg);
2597-
25982596
host->bulk_clks[0].id = "pclk_cg";
25992597
host->bulk_clks[1].id = "axi_cg";
26002598
host->bulk_clks[2].id = "ahb_cg";

drivers/mmc/host/sdhci-esdhc-imx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,7 @@ static void esdhc_cqe_enable(struct mmc_host *mmc)
15121512
* system resume back.
15131513
*/
15141514
cqhci_writel(cq_host, 0, CQHCI_CTL);
1515-
if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT)
1515+
if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT)
15161516
dev_err(mmc_dev(host->mmc),
15171517
"failed to exit halt state when enable CQE\n");
15181518

drivers/mmc/host/sdhci-sprd.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
470470
}
471471

472472
if (IS_ERR(sprd_host->pinctrl))
473-
return 0;
473+
goto reset;
474474

475475
switch (ios->signal_voltage) {
476476
case MMC_SIGNAL_VOLTAGE_180:
@@ -498,6 +498,8 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
498498

499499
/* Wait for 300 ~ 500 us for pin state stable */
500500
usleep_range(300, 500);
501+
502+
reset:
501503
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
502504

503505
return 0;

drivers/mmc/host/sdhci.c

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ static void sdhci_init(struct sdhci_host *host, int soft)
373373
if (soft) {
374374
/* force clock reconfiguration */
375375
host->clock = 0;
376+
host->reinit_uhs = true;
376377
mmc->ops->set_ios(mmc, &mmc->ios);
377378
}
378379
}
@@ -2293,11 +2294,46 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
22932294
}
22942295
EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling);
22952296

2297+
static bool sdhci_timing_has_preset(unsigned char timing)
2298+
{
2299+
switch (timing) {
2300+
case MMC_TIMING_UHS_SDR12:
2301+
case MMC_TIMING_UHS_SDR25:
2302+
case MMC_TIMING_UHS_SDR50:
2303+
case MMC_TIMING_UHS_SDR104:
2304+
case MMC_TIMING_UHS_DDR50:
2305+
case MMC_TIMING_MMC_DDR52:
2306+
return true;
2307+
};
2308+
return false;
2309+
}
2310+
2311+
static bool sdhci_preset_needed(struct sdhci_host *host, unsigned char timing)
2312+
{
2313+
return !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
2314+
sdhci_timing_has_preset(timing);
2315+
}
2316+
2317+
static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_ios *ios)
2318+
{
2319+
/*
2320+
* Preset Values are: Driver Strength, Clock Generator and SDCLK/RCLK
2321+
* Frequency. Check if preset values need to be enabled, or the Driver
2322+
* Strength needs updating. Note, clock changes are handled separately.
2323+
*/
2324+
return !host->preset_enabled &&
2325+
(sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type);
2326+
}
2327+
22962328
void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
22972329
{
22982330
struct sdhci_host *host = mmc_priv(mmc);
2331+
bool reinit_uhs = host->reinit_uhs;
2332+
bool turning_on_clk = false;
22992333
u8 ctrl;
23002334

2335+
host->reinit_uhs = false;
2336+
23012337
if (ios->power_mode == MMC_POWER_UNDEFINED)
23022338
return;
23032339

@@ -2323,6 +2359,8 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
23232359
sdhci_enable_preset_value(host, false);
23242360

23252361
if (!ios->clock || ios->clock != host->clock) {
2362+
turning_on_clk = ios->clock && !host->clock;
2363+
23262364
host->ops->set_clock(host, ios->clock);
23272365
host->clock = ios->clock;
23282366

@@ -2349,6 +2387,17 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
23492387

23502388
host->ops->set_bus_width(host, ios->bus_width);
23512389

2390+
/*
2391+
* Special case to avoid multiple clock changes during voltage
2392+
* switching.
2393+
*/
2394+
if (!reinit_uhs &&
2395+
turning_on_clk &&
2396+
host->timing == ios->timing &&
2397+
host->version >= SDHCI_SPEC_300 &&
2398+
!sdhci_presetable_values_change(host, ios))
2399+
return;
2400+
23522401
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
23532402

23542403
if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) {
@@ -2392,6 +2441,7 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
23922441
}
23932442

23942443
sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
2444+
host->drv_type = ios->drv_type;
23952445
} else {
23962446
/*
23972447
* According to SDHC Spec v3.00, if the Preset Value
@@ -2419,19 +2469,14 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
24192469
host->ops->set_uhs_signaling(host, ios->timing);
24202470
host->timing = ios->timing;
24212471

2422-
if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) &&
2423-
((ios->timing == MMC_TIMING_UHS_SDR12) ||
2424-
(ios->timing == MMC_TIMING_UHS_SDR25) ||
2425-
(ios->timing == MMC_TIMING_UHS_SDR50) ||
2426-
(ios->timing == MMC_TIMING_UHS_SDR104) ||
2427-
(ios->timing == MMC_TIMING_UHS_DDR50) ||
2428-
(ios->timing == MMC_TIMING_MMC_DDR52))) {
2472+
if (sdhci_preset_needed(host, ios->timing)) {
24292473
u16 preset;
24302474

24312475
sdhci_enable_preset_value(host, true);
24322476
preset = sdhci_get_preset_value(host);
24332477
ios->drv_type = FIELD_GET(SDHCI_PRESET_DRV_MASK,
24342478
preset);
2479+
host->drv_type = ios->drv_type;
24352480
}
24362481

24372482
/* Re-enable SD Clock */
@@ -3768,6 +3813,7 @@ int sdhci_resume_host(struct sdhci_host *host)
37683813
sdhci_init(host, 0);
37693814
host->pwr = 0;
37703815
host->clock = 0;
3816+
host->reinit_uhs = true;
37713817
mmc->ops->set_ios(mmc, &mmc->ios);
37723818
} else {
37733819
sdhci_init(host, (mmc->pm_flags & MMC_PM_KEEP_POWER));
@@ -3830,6 +3876,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset)
38303876
/* Force clock and power re-program */
38313877
host->pwr = 0;
38323878
host->clock = 0;
3879+
host->reinit_uhs = true;
38333880
mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
38343881
mmc->ops->set_ios(mmc, &mmc->ios);
38353882

drivers/mmc/host/sdhci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,8 @@ struct sdhci_host {
524524

525525
unsigned int clock; /* Current clock (MHz) */
526526
u8 pwr; /* Current voltage */
527+
u8 drv_type; /* Current UHS-I driver type */
528+
bool reinit_uhs; /* Force UHS-related re-initialization */
527529

528530
bool runtime_suspended; /* Host is runtime suspended */
529531
bool bus_on; /* Bus power prevents runtime suspend */

include/linux/mmc/mmc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ static inline bool mmc_ready_for_data(u32 status)
451451
#define MMC_SECURE_TRIM1_ARG 0x80000001
452452
#define MMC_SECURE_TRIM2_ARG 0x80008000
453453
#define MMC_SECURE_ARGS 0x80000000
454-
#define MMC_TRIM_ARGS 0x00008001
454+
#define MMC_TRIM_OR_DISCARD_ARGS 0x00008003
455455

456456
#define mmc_driver_type_mask(n) (1 << (n))
457457

0 commit comments

Comments
 (0)