summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-10-30 11:00:07 +0000
committerMark Brown <broonie@kernel.org>2026-10-30 11:00:07 +0000
commit44c6c5b23e4ffb6fdb4a692e4e9fed5464cb572a (patch)
treec53f83c79202d04f4d1b83228a024c6f4e0f2f80
parentf5bf66bf7604efd02763f2fd1a83d5eb3b8cf068 (diff)
parentb626aeb4fa7e4fdfbbabc5e4ae186b8af23d1a0e (diff)
downloadlinux-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.c1
-rw-r--r--drivers/mmc/host/jz4740_mmc.c5
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c26
-rw-r--r--drivers/mmc/host/mmci.c4
-rw-r--r--drivers/mmc/host/omap.c4
-rw-r--r--drivers/mmc/host/sdhci-brcmstb.c11
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c17
-rw-r--r--drivers/mmc/host/sunxi-mmc.c24
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;
}