diff options
| author | Mark Brown <broonie@kernel.org> | 2026-10-30 11:00:07 +0000 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-10-30 11:00:07 +0000 |
| commit | 44c6c5b23e4ffb6fdb4a692e4e9fed5464cb572a (patch) | |
| tree | c53f83c79202d04f4d1b83228a024c6f4e0f2f80 | |
| parent | f5bf66bf7604efd02763f2fd1a83d5eb3b8cf068 (diff) | |
| parent | b626aeb4fa7e4fdfbbabc5e4ae186b8af23d1a0e (diff) | |
| download | linux-next-44c6c5b23e4ffb6fdb4a692e4e9fed5464cb572a.tar.gz linux-next-44c6c5b23e4ffb6fdb4a692e4e9fed5464cb572a.zip | |
Merge branch 'fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git
| -rw-r--r-- | drivers/memstick/core/memstick.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/jz4740_mmc.c | 5 | ||||
| -rw-r--r-- | drivers/mmc/host/meson-gx-mmc.c | 26 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/host/omap.c | 4 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-brcmstb.c | 11 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 17 | ||||
| -rw-r--r-- | drivers/mmc/host/sunxi-mmc.c | 24 |
8 files changed, 73 insertions, 19 deletions
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 0d15f48ef51d..6a80570ee01d 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -100,7 +100,6 @@ static void memstick_device_remove(struct device *dev) if (dev->driver && drv->remove) { drv->remove(card); - card->dev.driver = NULL; } put_device(dev); diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 6a3c26b7c82d..923cf1450de5 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -1151,12 +1151,13 @@ static void jz4740_mmc_remove(struct platform_device *pdev) { struct jz4740_mmc_host *host = platform_get_drvdata(pdev); + /* The card's driver may still send commands as it goes */ + mmc_remove_host(host->mmc); + timer_delete_sync(&host->timeout_timer); jz4740_mmc_set_irq_enabled(host, 0xff, false); jz4740_mmc_reset(host); - mmc_remove_host(host->mmc); - free_irq(host->irq, host); if (host->use_dma) diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 7ef16d7c03cb..49df33bbd8e5 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -125,6 +125,7 @@ #define SD_EMMC_CFG_RESP_TIMEOUT 256 /* in clock cycles */ #define SD_EMMC_CMD_TIMEOUT 1024 /* in ms */ #define SD_EMMC_CMD_TIMEOUT_DATA 4096 /* in ms */ +#define SD_EMMC_CMD_TIMEOUT_MAX 32768 /* in ms, 2^15: limit of CMD_CFG_TIMEOUT_MASK */ #define SD_EMMC_CFG_CMD_GAP 16 /* in clock cycles */ #define SD_EMMC_DESC_BUF_LEN PAGE_SIZE @@ -212,7 +213,21 @@ static unsigned int meson_mmc_get_timeout_msecs(struct mmc_data *data) timeout = roundup_pow_of_two(timeout); - return min(timeout, 32768U); /* max. 2^15 ms */ + return min_t(unsigned int, timeout, SD_EMMC_CMD_TIMEOUT_MAX); +} + +/* For R1b the controller waits for busy to be released within this timeout. */ +static unsigned int meson_mmc_get_cmd_timeout_msecs(struct mmc_command *cmd) +{ + unsigned int timeout = cmd->busy_timeout; + + if (!timeout) + return SD_EMMC_CMD_TIMEOUT; + + timeout = clamp_t(unsigned int, timeout, SD_EMMC_CMD_TIMEOUT, + SD_EMMC_CMD_TIMEOUT_MAX); + + return roundup_pow_of_two(timeout); } static struct mmc_command *meson_mmc_get_next_command(struct mmc_command *cmd) @@ -841,7 +856,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) cmd_data = host->bounce_dma_addr & CMD_DATA_MASK; } else { cmd_cfg |= FIELD_PREP(CMD_CFG_TIMEOUT_MASK, - ilog2(SD_EMMC_CMD_TIMEOUT)); + ilog2(meson_mmc_get_cmd_timeout_msecs(cmd))); } /* Last descriptor */ @@ -1080,8 +1095,8 @@ static int meson_mmc_card_busy(struct mmc_host *mmc) regval = readl(host->regs + SD_EMMC_STATUS); - /* We are only interrested in lines 0 to 3, so mask the other ones */ - return !(FIELD_GET(STATUS_DATI, regval) & 0xf); + /* The card signals busy on DAT0 alone. */ + return !(FIELD_GET(STATUS_DATI, regval) & BIT(0)); } static int meson_mmc_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) @@ -1168,6 +1183,9 @@ static int meson_mmc_probe(struct platform_device *pdev) mmc->caps |= MMC_CAP_CMD23; + /* The longest busy wait the CMD_CFG timeout field can hold. */ + mmc->max_busy_timeout = SD_EMMC_CMD_TIMEOUT_MAX; + if (mmc->caps & MMC_CAP_SDIO_IRQ) mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 416bdb184ed4..4db5c55b2700 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -2477,11 +2477,13 @@ static int mmci_probe(struct amba_device *dev, ret = mmc_add_host(mmc); if (ret) - goto clk_disable; + goto dma_release; pm_runtime_put(&dev->dev); return 0; +dma_release: + mmci_dma_release(host); clk_disable: clk_disable_unprepare(host->clk); return ret; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 527b89a5ed70..02d288e4e9dc 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -214,7 +214,7 @@ static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed) host->mmc = slot->mmc; spin_unlock_irqrestore(&host->slot_lock, flags); no_claim: - timer_delete(&host->clk_timer); + timer_delete_sync(&host->clk_timer); if (host->current_slot != slot || !claimed) mmc_omap_fclk_offdelay(host->current_slot); @@ -273,7 +273,7 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled) /* Keeps clock running for at least 8 cycles on valid freq */ mod_timer(&host->clk_timer, jiffies + HZ/10); else { - timer_delete(&host->clk_timer); + timer_delete_sync(&host->clk_timer); mmc_omap_fclk_offdelay(slot); mmc_omap_fclk_enable(host, 0); } diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c index 1de2f05fd958..7c17a3cd6a6c 100644 --- a/drivers/mmc/host/sdhci-brcmstb.c +++ b/drivers/mmc/host/sdhci-brcmstb.c @@ -491,6 +491,7 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) struct sdhci_brcmstb_priv *priv; u32 actual_clock_mhz; struct sdhci_host *host; + struct resource *boot_res; struct clk *clk; struct clk *base_clk = NULL; int res; @@ -534,9 +535,13 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev) /* map non-standard BOOT registers if present */ if (host->mmc->caps & MMC_CAP_NONREMOVABLE) { - priv->boot_regs = devm_platform_get_and_ioremap_resource(pdev, 2, NULL); - if (IS_ERR(priv->boot_regs)) - priv->boot_regs = NULL; + boot_res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (boot_res) { + priv->boot_regs = devm_ioremap_resource(&pdev->dev, + boot_res); + if (IS_ERR(priv->boot_regs)) + priv->boot_regs = NULL; + } } /* diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 6ab59d3e346f..931e383748a9 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -1142,6 +1142,20 @@ static void esdhc_reset_tuning(struct sdhci_host *host) } } +static void sdhci_esdhc_imx_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + /* + * This controller has no driver-type control: esdhc_writew_le() + * discards the driver-type field when writing SDHCI_HOST_CONTROL2. + * The programmed value is therefore irrelevant, but SDHCI rejects + * non-SD values such as 4 (eMMC 40 ohm, from fixed-emmc-driver-type). + * Force an always-valid Type B. + */ + ios->drv_type = MMC_SET_DRIVER_TYPE_B; + + sdhci_set_ios(mmc, ios); +} + static void usdhc_init_card(struct mmc_host *mmc, struct mmc_card *card) { struct sdhci_host *host = mmc_priv(mmc); @@ -1952,6 +1966,9 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) host->max_timeout_count = 0xF; } + /* No SDHCI driver type control */ + host->mmc_host_ops.set_ios = sdhci_esdhc_imx_set_ios; + if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) sdhci_esdhc_ops.platform_execute_tuning = esdhc_executing_tuning; diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index fe4c0f6d73f3..437fdadb5950 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -1354,8 +1354,13 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, goto error_disable_mmc; } - return devm_request_threaded_irq(&pdev->dev, host->irq, sunxi_mmc_irq, - sunxi_mmc_handle_manual_stop, 0, "sunxi-mmc", host); + ret = devm_request_threaded_irq(&pdev->dev, host->irq, sunxi_mmc_irq, + sunxi_mmc_handle_manual_stop, 0, + "sunxi-mmc", host); + if (ret) + goto error_disable_mmc; + + return 0; error_disable_mmc: sunxi_mmc_disable(host); @@ -1385,9 +1390,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev) host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); - if (!host->sg_cpu) - return dev_err_probe(&pdev->dev, -ENOMEM, - "Failed to allocate DMA descriptor mem\n"); + if (!host->sg_cpu) { + ret = dev_err_probe(&pdev->dev, -ENOMEM, + "Failed to allocate DMA descriptor mem\n"); + goto error_disable_mmc; + } if (host->cfg->ccu_has_timings_switch) { /* @@ -1467,7 +1474,7 @@ static int sunxi_mmc_probe(struct platform_device *pdev) ret = mmc_add_host(mmc); if (ret) - goto error_free_dma; + goto error_disable_rpm; dev_info(&pdev->dev, "initialized, max. request size: %u KB%s\n", mmc->max_req_size >> 10, @@ -1475,8 +1482,13 @@ static int sunxi_mmc_probe(struct platform_device *pdev) return 0; +error_disable_rpm: + pm_runtime_disable(&pdev->dev); error_free_dma: dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); +error_disable_mmc: + disable_irq(host->irq); + sunxi_mmc_disable(host); return ret; } |
