* [PATCH 01/13] mmc: dw_mmc: Remove unused struct dma_pdata
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 02/13] mmc: dw_mmc: add dw_mci_prepare_desc() for both of 32bit and 64bit DMA Shawn Lin
` (13 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.h | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 648b4a5..b4ceca0 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -255,8 +255,6 @@ struct dw_mci_dma_ops {
void (*exit)(struct dw_mci *host);
};
-struct dma_pdata;
-
/* Board platform data */
struct dw_mci_board {
unsigned int bus_hz; /* Clock speed at the cclk_in pad */
@@ -276,7 +274,6 @@ struct dw_mci_board {
struct reset_control *rstc;
struct dw_mci_dma_ops *dma_ops;
- struct dma_pdata *data;
};
/* Support for longer data read timeout */
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 02/13] mmc: dw_mmc: add dw_mci_prepare_desc() for both of 32bit and 64bit DMA
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
2025-11-20 10:29 ` [PATCH 01/13] mmc: dw_mmc: Remove unused struct dma_pdata Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 03/13] mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci Shawn Lin
` (12 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
dw_mci_prepare_desc64() and dw_mci_prepare_desc32() duplicate a lot of
code, add a new dw_mci_prepare_desc() to save the bits.
No functional change intended.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 147 ++++++++++++++--------------------------------
1 file changed, 43 insertions(+), 104 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 9e74b67..80d3851 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -575,16 +575,19 @@ static int dw_mci_idmac_init(struct dw_mci *host)
return 0;
}
-static inline int dw_mci_prepare_desc64(struct dw_mci *host,
- struct mmc_data *data,
- unsigned int sg_len)
+static inline int dw_mci_prepare_desc(struct dw_mci *host, struct mmc_data *data,
+ unsigned int sg_len, bool is_64bit)
{
unsigned int desc_len;
- struct idmac_desc_64addr *desc_first, *desc_last, *desc;
- u32 val;
+ struct idmac_desc *desc_first, *desc_last, *desc;
+ struct idmac_desc_64addr *desc64_first, *desc64_last, *desc64;
+ u32 val, des0;
int i;
- desc_first = desc_last = desc = host->sg_cpu;
+ if (is_64bit)
+ desc64_first = desc64_last = desc64 = host->sg_cpu;
+ else
+ desc_first = desc_last = desc = host->sg_cpu;
for (i = 0; i < sg_len; i++) {
unsigned int length = sg_dma_len(&data->sg[i]);
@@ -603,113 +606,52 @@ static inline int dw_mci_prepare_desc64(struct dw_mci *host,
* isn't still owned by IDMAC as IDMAC's write
* ops and CPU's read ops are asynchronous.
*/
- if (readl_poll_timeout_atomic(&desc->des0, val,
- !(val & IDMAC_DES0_OWN),
- 10, 100 * USEC_PER_MSEC))
+ if (readl_poll_timeout_atomic(is_64bit ? &desc64->des0 : &desc->des0,
+ val, IDMAC_OWN_CLR64(val), 10, 100 * USEC_PER_MSEC))
goto err_own_bit;
- /*
- * Set the OWN bit and disable interrupts
- * for this descriptor
- */
- desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC |
- IDMAC_DES0_CH;
-
- /* Buffer length */
- IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len);
-
- /* Physical address to DMA to/from */
- desc->des4 = mem_addr & 0xffffffff;
- desc->des5 = mem_addr >> 32;
-
- /* Update physical address for the next desc */
- mem_addr += desc_len;
-
- /* Save pointer to the last descriptor */
- desc_last = desc;
- }
- }
-
- /* Set first descriptor */
- desc_first->des0 |= IDMAC_DES0_FD;
-
- /* Set last descriptor */
- desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC);
- desc_last->des0 |= IDMAC_DES0_LD;
-
- return 0;
-err_own_bit:
- /* restore the descriptor chain as it's polluted */
- dev_dbg(host->dev, "descriptor is still owned by IDMAC.\n");
- memset(host->sg_cpu, 0, DESC_RING_BUF_SZ);
- dw_mci_idmac_init(host);
- return -EINVAL;
-}
-
-
-static inline int dw_mci_prepare_desc32(struct dw_mci *host,
- struct mmc_data *data,
- unsigned int sg_len)
-{
- unsigned int desc_len;
- struct idmac_desc *desc_first, *desc_last, *desc;
- u32 val;
- int i;
-
- desc_first = desc_last = desc = host->sg_cpu;
-
- for (i = 0; i < sg_len; i++) {
- unsigned int length = sg_dma_len(&data->sg[i]);
-
- u32 mem_addr = sg_dma_address(&data->sg[i]);
-
- for ( ; length ; desc++) {
- desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ?
- length : DW_MCI_DESC_DATA_LENGTH;
-
- length -= desc_len;
-
- /*
- * Wait for the former clear OWN bit operation
- * of IDMAC to make sure that this descriptor
- * isn't still owned by IDMAC as IDMAC's write
- * ops and CPU's read ops are asynchronous.
- */
- if (readl_poll_timeout_atomic(&desc->des0, val,
- IDMAC_OWN_CLR64(val),
- 10,
- 100 * USEC_PER_MSEC))
- goto err_own_bit;
+ des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | IDMAC_DES0_CH;
+ if (is_64bit)
+ desc64->des0 = des0;
+ else
+ desc->des0 = cpu_to_le32(des0);
/*
- * Set the OWN bit and disable interrupts
- * for this descriptor
+ * 1. Set OWN bit and disable interrupts for this descriptor
+ * 2. Set Buffer length
+ * Set physical address to DMA to/from
*/
- desc->des0 = cpu_to_le32(IDMAC_DES0_OWN |
- IDMAC_DES0_DIC |
- IDMAC_DES0_CH);
-
- /* Buffer length */
- IDMAC_SET_BUFFER1_SIZE(desc, desc_len);
-
- /* Physical address to DMA to/from */
- desc->des2 = cpu_to_le32(mem_addr);
+ if (is_64bit) {
+ desc64->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | IDMAC_DES0_CH;
+ IDMAC_64ADDR_SET_BUFFER1_SIZE(desc64, desc_len);
+ desc64->des4 = mem_addr & 0xffffffff;
+ desc64->des5 = mem_addr >> 32;
+ } else {
+ IDMAC_SET_BUFFER1_SIZE(desc, desc_len);
+ desc->des2 = cpu_to_le32(mem_addr);
+ }
/* Update physical address for the next desc */
mem_addr += desc_len;
/* Save pointer to the last descriptor */
- desc_last = desc;
+ if (is_64bit)
+ desc64_last = desc64;
+ else
+ desc_last = desc;
}
}
- /* Set first descriptor */
- desc_first->des0 |= cpu_to_le32(IDMAC_DES0_FD);
-
- /* Set last descriptor */
- desc_last->des0 &= cpu_to_le32(~(IDMAC_DES0_CH |
- IDMAC_DES0_DIC));
- desc_last->des0 |= cpu_to_le32(IDMAC_DES0_LD);
+ /* Set the first descriptor and the last descriptor */
+ if (is_64bit) {
+ desc64_first->des0 |= IDMAC_DES0_FD;
+ desc64_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC);
+ desc64_last->des0 |= IDMAC_DES0_LD;
+ } else {
+ desc_first->des0 |= cpu_to_le32(IDMAC_DES0_FD);
+ desc_last->des0 &= cpu_to_le32(~(IDMAC_DES0_CH | IDMAC_DES0_DIC));
+ desc_last->des0 |= cpu_to_le32(IDMAC_DES0_LD);
+ }
return 0;
err_own_bit:
@@ -725,10 +667,7 @@ static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
u32 temp;
int ret;
- if (host->dma_64bit_address == 1)
- ret = dw_mci_prepare_desc64(host, host->data, sg_len);
- else
- ret = dw_mci_prepare_desc32(host, host->data, sg_len);
+ ret = dw_mci_prepare_desc(host, host->data, sg_len, host->dma_64bit_address);
if (ret)
goto out;
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 03/13] mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
2025-11-20 10:29 ` [PATCH 01/13] mmc: dw_mmc: Remove unused struct dma_pdata Shawn Lin
2025-11-20 10:29 ` [PATCH 02/13] mmc: dw_mmc: add dw_mci_prepare_desc() for both of 32bit and 64bit DMA Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-25 12:23 ` Ulf Hansson
2025-11-20 10:29 ` [PATCH 04/13] mmc: dw_mmc: Remove unused header files and keep alphabetical order Shawn Lin
` (11 subsequent siblings)
14 siblings, 1 reply; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
commit 51da2240906c ("mmc: dw_mmc: use mmc_regulator_get_supply to handle regulators")
introduced tracking of vqmmc_enabled. Currently, dw_mmc properly maintains power sequence
according to MMC_POWER_* from mmc core, which should be enough. There is nothing special
I could see here to still keep tracking of vqmmc status. Hence, remove it.
This patch is tested on RK3588s EVB1 with TF cards with both vqmmc present or not.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 28 ++++++++--------------------
drivers/mmc/host/dw_mmc.h | 2 --
2 files changed, 8 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 80d3851..ebbf1a6 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1436,25 +1436,12 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
mci_writel(slot->host, PWREN, regs);
break;
case MMC_POWER_ON:
- if (!slot->host->vqmmc_enabled) {
- if (!IS_ERR(mmc->supply.vqmmc)) {
- ret = regulator_enable(mmc->supply.vqmmc);
- if (ret < 0)
- dev_err(slot->host->dev,
- "failed to enable vqmmc\n");
- else
- slot->host->vqmmc_enabled = true;
-
- } else {
- /* Keep track so we don't reset again */
- slot->host->vqmmc_enabled = true;
- }
-
- /* Reset our state machine after powering on */
- dw_mci_ctrl_reset(slot->host,
- SDMMC_CTRL_ALL_RESET_FLAGS);
+ if (!IS_ERR(mmc->supply.vqmmc)) {
+ ret = regulator_enable(mmc->supply.vqmmc);
+ if (ret < 0)
+ dev_err(slot->host->dev,
+ "failed to enable vqmmc\n");
}
-
/* Adjust clock / bus width after power is up */
dw_mci_setup_bus(slot, false);
@@ -1466,13 +1453,14 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (!IS_ERR(mmc->supply.vmmc))
mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
- if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled)
+ if (!IS_ERR(mmc->supply.vqmmc))
regulator_disable(mmc->supply.vqmmc);
- slot->host->vqmmc_enabled = false;
regs = mci_readl(slot->host, PWREN);
regs &= ~(1 << slot->id);
mci_writel(slot->host, PWREN, regs);
+ /* Reset our state machine after powering off */
+ dw_mci_ctrl_reset(slot->host, SDMMC_CTRL_ALL_RESET_FLAGS);
break;
default:
break;
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index b4ceca0..6faa63b 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -121,7 +121,6 @@ struct dw_mci_dma_slave {
* @push_data: Pointer to FIFO push function.
* @pull_data: Pointer to FIFO pull function.
* @quirks: Set of quirks that apply to specific versions of the IP.
- * @vqmmc_enabled: Status of vqmmc, should be true or false.
* @irq_flags: The flags to be passed to request_irq.
* @irq: The irq value to be passed to request_irq.
* @sdio_id0: Number of slot0 in the SDIO interrupt registers.
@@ -228,7 +227,6 @@ struct dw_mci {
void (*pull_data)(struct dw_mci *host, void *buf, int cnt);
u32 quirks;
- bool vqmmc_enabled;
unsigned long irq_flags; /* IRQ flags */
int irq;
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 03/13] mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci
2025-11-20 10:29 ` [PATCH 03/13] mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci Shawn Lin
@ 2025-11-25 12:23 ` Ulf Hansson
0 siblings, 0 replies; 21+ messages in thread
From: Ulf Hansson @ 2025-11-25 12:23 UTC (permalink / raw)
To: Shawn Lin; +Cc: linux-mmc, Jaehoon Chung
On Thu, 20 Nov 2025 at 11:30, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>
> commit 51da2240906c ("mmc: dw_mmc: use mmc_regulator_get_supply to handle regulators")
> introduced tracking of vqmmc_enabled. Currently, dw_mmc properly maintains power sequence
> according to MMC_POWER_* from mmc core, which should be enough. There is nothing special
> I could see here to still keep tracking of vqmmc status. Hence, remove it.
>
> This patch is tested on RK3588s EVB1 with TF cards with both vqmmc present or not.
>
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> ---
>
> drivers/mmc/host/dw_mmc.c | 28 ++++++++--------------------
> drivers/mmc/host/dw_mmc.h | 2 --
> 2 files changed, 8 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 80d3851..ebbf1a6 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1436,25 +1436,12 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> mci_writel(slot->host, PWREN, regs);
> break;
> case MMC_POWER_ON:
The mmc core may call the ->set_ios() callback with MMC_POWER_ON
several times during initialization. For example, to change the clock
rate. Hence the below is needed to keep the reference counting of the
regulator correctly balanced.
Although, we have added mmc_regulator_enable_vqmmc() which should be
able to replace the below code.
> - if (!slot->host->vqmmc_enabled) {
> - if (!IS_ERR(mmc->supply.vqmmc)) {
> - ret = regulator_enable(mmc->supply.vqmmc);
> - if (ret < 0)
> - dev_err(slot->host->dev,
> - "failed to enable vqmmc\n");
> - else
> - slot->host->vqmmc_enabled = true;
> -
> - } else {
> - /* Keep track so we don't reset again */
> - slot->host->vqmmc_enabled = true;
> - }
> -
> - /* Reset our state machine after powering on */
> - dw_mci_ctrl_reset(slot->host,
> - SDMMC_CTRL_ALL_RESET_FLAGS);
> + if (!IS_ERR(mmc->supply.vqmmc)) {
> + ret = regulator_enable(mmc->supply.vqmmc);
> + if (ret < 0)
> + dev_err(slot->host->dev,
> + "failed to enable vqmmc\n");
> }
> -
> /* Adjust clock / bus width after power is up */
> dw_mci_setup_bus(slot, false);
>
> @@ -1466,13 +1453,14 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> if (!IS_ERR(mmc->supply.vmmc))
> mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
>
> - if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled)
> + if (!IS_ERR(mmc->supply.vqmmc))
> regulator_disable(mmc->supply.vqmmc);
> - slot->host->vqmmc_enabled = false;
>
> regs = mci_readl(slot->host, PWREN);
> regs &= ~(1 << slot->id);
> mci_writel(slot->host, PWREN, regs);
> + /* Reset our state machine after powering off */
> + dw_mci_ctrl_reset(slot->host, SDMMC_CTRL_ALL_RESET_FLAGS);
> break;
> default:
> break;
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index b4ceca0..6faa63b 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -121,7 +121,6 @@ struct dw_mci_dma_slave {
> * @push_data: Pointer to FIFO push function.
> * @pull_data: Pointer to FIFO pull function.
> * @quirks: Set of quirks that apply to specific versions of the IP.
> - * @vqmmc_enabled: Status of vqmmc, should be true or false.
> * @irq_flags: The flags to be passed to request_irq.
> * @irq: The irq value to be passed to request_irq.
> * @sdio_id0: Number of slot0 in the SDIO interrupt registers.
> @@ -228,7 +227,6 @@ struct dw_mci {
> void (*pull_data)(struct dw_mci *host, void *buf, int cnt);
>
> u32 quirks;
> - bool vqmmc_enabled;
> unsigned long irq_flags; /* IRQ flags */
> int irq;
>
> --
> 2.7.4
>
Kind regards
Uffe
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 04/13] mmc: dw_mmc: Remove unused header files and keep alphabetical order
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (2 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 03/13] mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 05/13] mmc: dw_mmc: Move struct mmc_host from struct dw_mci_slot to struct dw_mci Shawn Lin
` (10 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index ebbf1a6..2e2d492 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -7,35 +7,28 @@
* Copyright (C) 2009, 2010 Imagination Technologies Ltd.
*/
-#include <linux/blkdev.h>
+#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
+#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
-#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
-#include <linux/ioport.h>
-#include <linux/ktime.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/prandom.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/delay.h>
#include <linux/irq.h>
+#include <linux/ktime.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sd.h>
#include <linux/mmc/sdio.h>
-#include <linux/bitops.h>
-#include <linux/regulator/consumer.h>
-#include <linux/of.h>
#include <linux/mmc/slot-gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
#include "dw_mmc.h"
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 05/13] mmc: dw_mmc: Move struct mmc_host from struct dw_mci_slot to struct dw_mci
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (3 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 04/13] mmc: dw_mmc: Remove unused header files and keep alphabetical order Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 06/13] mmc: dw_mmc: Let glue drivers to use struct dw_mci as possible Shawn Lin
` (9 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
No functional change intended.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc-exynos.c | 2 +-
drivers/mmc/host/dw_mmc-hi3798cv200.c | 2 +-
drivers/mmc/host/dw_mmc-hi3798mv200.c | 2 +-
drivers/mmc/host/dw_mmc-k3.c | 2 +-
drivers/mmc/host/dw_mmc-rockchip.c | 2 +-
drivers/mmc/host/dw_mmc-starfive.c | 2 +-
drivers/mmc/host/dw_mmc.c | 62 +++++++++++++++++------------------
drivers/mmc/host/dw_mmc.h | 4 +--
8 files changed, 38 insertions(+), 40 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 3846096..067569b 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -534,7 +534,7 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
{
struct dw_mci *host = slot->host;
struct dw_mci_exynos_priv_data *priv = host->priv;
- struct mmc_host *mmc = slot->mmc;
+ struct mmc_host *mmc = host->mmc;
u8 start_smpl, smpl, candidates = 0;
s8 found;
int ret = 0;
diff --git a/drivers/mmc/host/dw_mmc-hi3798cv200.c b/drivers/mmc/host/dw_mmc-hi3798cv200.c
index 0ccfae1..03f7ed8 100644
--- a/drivers/mmc/host/dw_mmc-hi3798cv200.c
+++ b/drivers/mmc/host/dw_mmc-hi3798cv200.c
@@ -72,7 +72,7 @@ static int dw_mci_hi3798cv200_execute_tuning(struct dw_mci_slot *slot,
clk_set_phase(priv->sample_clk, degrees[i]);
mci_writel(host, RINTSTS, ALL_INT_CLR);
- err = mmc_send_tuning(slot->mmc, opcode, NULL);
+ err = mmc_send_tuning(host->mmc, opcode, NULL);
if (!err)
found = 1;
diff --git a/drivers/mmc/host/dw_mmc-hi3798mv200.c b/drivers/mmc/host/dw_mmc-hi3798mv200.c
index 5791a97..3cc4bc2 100644
--- a/drivers/mmc/host/dw_mmc-hi3798mv200.c
+++ b/drivers/mmc/host/dw_mmc-hi3798mv200.c
@@ -115,7 +115,7 @@ static int dw_mci_hi3798mv200_execute_tuning_mix_mode(struct dw_mci_slot *slot,
*
* Treat edge(flip) found as an error too.
*/
- err = mmc_send_tuning(slot->mmc, opcode, NULL);
+ err = mmc_send_tuning(host->mmc, opcode, NULL);
regval = mci_readl(host, TUNING_CTRL);
if (err || (regval & SDMMC_TUNING_FIND_EDGE))
err = 1;
diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c
index ad6aa1a..4ef99c0 100644
--- a/drivers/mmc/host/dw_mmc-k3.c
+++ b/drivers/mmc/host/dw_mmc-k3.c
@@ -368,7 +368,7 @@ static int dw_mci_hi3660_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
{
int i = 0;
struct dw_mci *host = slot->host;
- struct mmc_host *mmc = slot->mmc;
+ struct mmc_host *mmc = host->mmc;
int smpl_phase = 0;
u32 tuning_sample_flag = 0;
int best_clksmpl = 0;
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 62c68cd..ffffbf59 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -286,7 +286,7 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
{
struct dw_mci *host = slot->host;
struct dw_mci_rockchip_priv_data *priv = host->priv;
- struct mmc_host *mmc = slot->mmc;
+ struct mmc_host *mmc = host->mmc;
int ret = 0;
int i;
bool v, prev_v = 0, first_v;
diff --git a/drivers/mmc/host/dw_mmc-starfive.c b/drivers/mmc/host/dw_mmc-starfive.c
index 34964b0..d4ea289 100644
--- a/drivers/mmc/host/dw_mmc-starfive.c
+++ b/drivers/mmc/host/dw_mmc-starfive.c
@@ -65,7 +65,7 @@ static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
dw_mci_starfive_set_sample_phase(host, smpl_phase);
mci_writel(host, RINTSTS, ALL_INT_CLR);
- ret = mmc_send_tuning(slot->mmc, opcode, NULL);
+ ret = mmc_send_tuning(host->mmc, opcode, NULL);
if (!ret && smpl_raise < 0) {
smpl_raise = smpl_phase;
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 2e2d492..26db1ef 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -160,8 +160,8 @@ DEFINE_SHOW_ATTRIBUTE(dw_mci_regs);
static void dw_mci_init_debugfs(struct dw_mci_slot *slot)
{
- struct mmc_host *mmc = slot->mmc;
struct dw_mci *host = slot->host;
+ struct mmc_host *mmc = host->mmc;
struct dentry *root;
root = mmc->debugfs_root;
@@ -237,7 +237,7 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
if (readl_poll_timeout_atomic(host->regs + SDMMC_CMD, cmd_status,
!(cmd_status & SDMMC_CMD_START),
1, 500 * USEC_PER_MSEC))
- dev_err(&slot->mmc->class_dev,
+ dev_err(&host->mmc->class_dev,
"Timeout sending command (cmd %#x arg %#x status %#x)\n",
cmd, arg, cmd_status);
}
@@ -473,7 +473,7 @@ static void dw_mci_dmac_complete_dma(void *arg)
if ((host->use_dma == TRANS_MODE_EDMAC) &&
data && (data->flags & MMC_DATA_READ))
/* Invalidate cache after read */
- dma_sync_sg_for_cpu(mmc_dev(host->slot->mmc),
+ dma_sync_sg_for_cpu(mmc_dev(host->mmc),
data->sg,
data->sg_len,
DMA_FROM_DEVICE);
@@ -755,7 +755,7 @@ static int dw_mci_edmac_start_dma(struct dw_mci *host,
/* Flush cache before write */
if (host->data->flags & MMC_DATA_WRITE)
- dma_sync_sg_for_device(mmc_dev(host->slot->mmc), sgl,
+ dma_sync_sg_for_device(mmc_dev(host->mmc), sgl,
sg_elems, DMA_TO_DEVICE);
dma_async_issue_pending(host->dms->ch);
@@ -1144,7 +1144,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
if (host->state == STATE_WAITING_CMD11_DONE)
sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
- slot->mmc->actual_clock = 0;
+ host->mmc->actual_clock = 0;
if (!clock) {
mci_writel(host, CLKENA, 0);
@@ -1165,7 +1165,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
force_clkinit) {
/* Silent the verbose log if calling from PM context */
if (!force_clkinit)
- dev_info(&slot->mmc->class_dev,
+ dev_info(&host->mmc->class_dev,
"Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n",
slot->id, host->bus_hz, clock,
div ? ((host->bus_hz / div) >> 1) :
@@ -1175,8 +1175,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
* If card is polling, display the message only
* one time at boot time.
*/
- if (slot->mmc->caps & MMC_CAP_NEEDS_POLL &&
- slot->mmc->f_min == clock)
+ if (host->mmc->caps & MMC_CAP_NEEDS_POLL &&
+ host->mmc->f_min == clock)
set_bit(DW_MMC_CARD_NEEDS_POLL, &slot->flags);
}
@@ -1204,7 +1204,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
/* keep the last clock value that was requested from core */
slot->__clk_old = clock;
- slot->mmc->actual_clock = div ? ((host->bus_hz / div) >> 1) :
+ host->mmc->actual_clock = div ? ((host->bus_hz / div) >> 1) :
host->bus_hz;
}
@@ -1270,7 +1270,7 @@ static void __dw_mci_start_request(struct dw_mci *host,
mci_writel(host, BLKSIZ, data->blksz);
}
- cmdflags = dw_mci_prepare_command(slot->mmc, cmd);
+ cmdflags = dw_mci_prepare_command(host->mmc, cmd);
/* this is the first command, send the initialization clock */
if (test_and_clear_bit(DW_MMC_CARD_NEED_INIT, &slot->flags))
@@ -1320,13 +1320,13 @@ static void dw_mci_start_request(struct dw_mci *host,
static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
struct mmc_request *mrq)
{
- dev_vdbg(&slot->mmc->class_dev, "queue request: state=%d\n",
+ dev_vdbg(&host->mmc->class_dev, "queue request: state=%d\n",
host->state);
slot->mrq = mrq;
if (host->state == STATE_WAITING_CMD11_DONE) {
- dev_warn(&slot->mmc->class_dev,
+ dev_warn(&host->mmc->class_dev,
"Voltage change didn't complete\n");
/*
* this case isn't expected to happen, so we can
@@ -1816,7 +1816,7 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
__acquires(&host->lock)
{
struct dw_mci_slot *slot;
- struct mmc_host *prev_mmc = host->slot->mmc;
+ struct mmc_host *prev_mmc = host->mmc;
WARN_ON(host->cmd || host->data);
@@ -1827,7 +1827,7 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
struct dw_mci_slot, queue_node);
list_del(&slot->queue_node);
dev_vdbg(host->dev, "list not empty: %s is next\n",
- mmc_hostname(slot->mmc));
+ mmc_hostname(host->mmc));
host->state = STATE_SENDING_CMD;
dw_mci_start_request(host, slot);
} else {
@@ -2723,9 +2723,7 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status)
static void dw_mci_handle_cd(struct dw_mci *host)
{
- struct dw_mci_slot *slot = host->slot;
-
- mmc_detect_change(slot->mmc,
+ mmc_detect_change(host->mmc,
msecs_to_jiffies(host->pdata->detect_delay_ms));
}
@@ -2838,7 +2836,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
mci_writel(host, RINTSTS,
SDMMC_INT_SDIO(slot->sdio_id));
__dw_mci_enable_sdio_irq(slot, 0);
- sdio_signal_irq(slot->mmc);
+ sdio_signal_irq(host->mmc);
}
}
@@ -2874,7 +2872,7 @@ static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)
{
struct dw_mci *host = slot->host;
const struct dw_mci_drv_data *drv_data = host->drv_data;
- struct mmc_host *mmc = slot->mmc;
+ struct mmc_host *mmc = host->mmc;
int ctrl_id;
if (host->pdata->caps)
@@ -2935,7 +2933,7 @@ static int dw_mci_init_slot(struct dw_mci *host)
slot = mmc_priv(mmc);
slot->id = 0;
slot->sdio_id = host->sdio_id0 + slot->id;
- slot->mmc = mmc;
+ host->mmc = mmc;
slot->host = host;
host->slot = slot;
@@ -2997,7 +2995,7 @@ static int dw_mci_init_slot(struct dw_mci *host)
static void dw_mci_cleanup_slot(struct dw_mci_slot *slot)
{
/* Debugfs stuff is cleaned up by mmc core */
- mmc_remove_host(slot->mmc);
+ mmc_remove_host(slot->host->mmc);
slot->host->slot = NULL;
}
@@ -3269,10 +3267,10 @@ static void dw_mci_enable_cd(struct dw_mci *host)
* No need for CD if all slots have a non-error GPIO
* as well as broken card detection is found.
*/
- if (host->slot->mmc->caps & MMC_CAP_NEEDS_POLL)
+ if (host->mmc->caps & MMC_CAP_NEEDS_POLL)
return;
- if (mmc_gpio_get_cd(host->slot->mmc) < 0) {
+ if (mmc_gpio_get_cd(host->mmc) < 0) {
spin_lock_irqsave(&host->irq_lock, irqflags);
temp = mci_readl(host, INTMASK);
temp |= SDMMC_INT_CD;
@@ -3536,8 +3534,8 @@ int dw_mci_runtime_suspend(struct device *dev)
clk_disable_unprepare(host->ciu_clk);
if (host->slot &&
- (mmc_host_can_gpio_cd(host->slot->mmc) ||
- !mmc_card_is_removable(host->slot->mmc)))
+ (mmc_host_can_gpio_cd(host->mmc) ||
+ !mmc_card_is_removable(host->mmc)))
clk_disable_unprepare(host->biu_clk);
return 0;
@@ -3550,8 +3548,8 @@ int dw_mci_runtime_resume(struct device *dev)
struct dw_mci *host = dev_get_drvdata(dev);
if (host->slot &&
- (mmc_host_can_gpio_cd(host->slot->mmc) ||
- !mmc_card_is_removable(host->slot->mmc))) {
+ (mmc_host_can_gpio_cd(host->mmc) ||
+ !mmc_card_is_removable(host->mmc))) {
ret = clk_prepare_enable(host->biu_clk);
if (ret)
return ret;
@@ -3587,14 +3585,14 @@ int dw_mci_runtime_resume(struct device *dev)
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
- if (host->slot && host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER)
- dw_mci_set_ios(host->slot->mmc, &host->slot->mmc->ios);
+ if (host->slot && host->mmc->pm_flags & MMC_PM_KEEP_POWER)
+ dw_mci_set_ios(host->mmc, &host->mmc->ios);
/* Force setup bus to guarantee available clock output */
dw_mci_setup_bus(host->slot, true);
/* Re-enable SDIO interrupts. */
- if (sdio_irq_claimed(host->slot->mmc))
+ if (sdio_irq_claimed(host->mmc))
__dw_mci_enable_sdio_irq(host->slot, 1);
/* Now that slots are all setup, we can enable card detect */
@@ -3604,8 +3602,8 @@ int dw_mci_runtime_resume(struct device *dev)
err:
if (host->slot &&
- (mmc_host_can_gpio_cd(host->slot->mmc) ||
- !mmc_card_is_removable(host->slot->mmc)))
+ (mmc_host_can_gpio_cd(host->mmc) ||
+ !mmc_card_is_removable(host->mmc)))
clk_disable_unprepare(host->biu_clk);
return ret;
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 6faa63b..b4efc58 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -127,6 +127,7 @@ struct dw_mci_dma_slave {
* @cmd11_timer: Timer for SD3.0 voltage switch over scheme.
* @cto_timer: Timer for broken command transfer over scheme.
* @dto_timer: Timer for broken data transfer over scheme.
+ * @mmc: The mmc_host representing this dw_mci.
*
* Locking
* =======
@@ -240,6 +241,7 @@ struct dw_mci {
struct fault_attr fail_data_crc;
struct hrtimer fault_timer;
#endif
+ struct mmc_host *mmc;
};
/* DMA ops for Internal/External DMAC interface */
@@ -543,7 +545,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
/**
* struct dw_mci_slot - MMC slot state
- * @mmc: The mmc_host representing this slot.
* @host: The MMC controller this slot is using.
* @ctype: Card type for this slot.
* @mrq: mmc_request currently being processed or waiting to be
@@ -558,7 +559,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
* @sdio_id: Number of this slot in the SDIO interrupt registers.
*/
struct dw_mci_slot {
- struct mmc_host *mmc;
struct dw_mci *host;
u32 ctype;
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 06/13] mmc: dw_mmc: Let glue drivers to use struct dw_mci as possible
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (4 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 05/13] mmc: dw_mmc: Move struct mmc_host from struct dw_mci_slot to struct dw_mci Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 07/13] mmc: dw_mmc: Move flags from struct dw_mci_slot to struct dw_mci Shawn Lin
` (8 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
This patch changes the callbacks of switch_voltage() and execute_tuning()
in order for glue drivers to avoid accessing to struct dw_mci_slot.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc-exynos.c | 3 +--
drivers/mmc/host/dw_mmc-hi3798cv200.c | 4 +---
drivers/mmc/host/dw_mmc-hi3798mv200.c | 15 +++++++--------
drivers/mmc/host/dw_mmc-k3.c | 19 +++++++------------
drivers/mmc/host/dw_mmc-rockchip.c | 3 +--
drivers/mmc/host/dw_mmc-starfive.c | 3 +--
drivers/mmc/host/dw_mmc.c | 4 ++--
drivers/mmc/host/dw_mmc.h | 4 ++--
8 files changed, 22 insertions(+), 33 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 067569b..4106985 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -530,9 +530,8 @@ static s8 dw_mci_exynos_get_best_clksmpl(u8 candidates)
return loc;
}
-static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
+static int dw_mci_exynos_execute_tuning(struct dw_mci *host, u32 opcode)
{
- struct dw_mci *host = slot->host;
struct dw_mci_exynos_priv_data *priv = host->priv;
struct mmc_host *mmc = host->mmc;
u8 start_smpl, smpl, candidates = 0;
diff --git a/drivers/mmc/host/dw_mmc-hi3798cv200.c b/drivers/mmc/host/dw_mmc-hi3798cv200.c
index 03f7ed8..4b723ed 100644
--- a/drivers/mmc/host/dw_mmc-hi3798cv200.c
+++ b/drivers/mmc/host/dw_mmc-hi3798cv200.c
@@ -57,11 +57,9 @@ static void dw_mci_hi3798cv200_set_ios(struct dw_mci *host, struct mmc_ios *ios)
clk_set_phase(priv->drive_clk, 135);
}
-static int dw_mci_hi3798cv200_execute_tuning(struct dw_mci_slot *slot,
- u32 opcode)
+static int dw_mci_hi3798cv200_execute_tuning(struct dw_mci *host, u32 opcode)
{
static const int degrees[] = { 0, 45, 90, 135, 180, 225, 270, 315 };
- struct dw_mci *host = slot->host;
struct hi3798cv200_priv *priv = host->priv;
int raise_point = -1, fall_point = -1;
int err, prev_err = -1;
diff --git a/drivers/mmc/host/dw_mmc-hi3798mv200.c b/drivers/mmc/host/dw_mmc-hi3798mv200.c
index 3cc4bc2..a64907e 100644
--- a/drivers/mmc/host/dw_mmc-hi3798mv200.c
+++ b/drivers/mmc/host/dw_mmc-hi3798mv200.c
@@ -74,25 +74,24 @@ static void dw_mci_hi3798mv200_set_ios(struct dw_mci *host, struct mmc_ios *ios)
}
}
-static inline int dw_mci_hi3798mv200_enable_tuning(struct dw_mci_slot *slot)
+static inline int dw_mci_hi3798mv200_enable_tuning(struct dw_mci *host)
{
- struct dw_mci_hi3798mv200_priv *priv = slot->host->priv;
+ struct dw_mci_hi3798mv200_priv *priv = host->priv;
return regmap_clear_bits(priv->crg_reg, priv->sap_dll_offset, SAP_DLL_CTRL_DLLMODE);
}
-static inline int dw_mci_hi3798mv200_disable_tuning(struct dw_mci_slot *slot)
+static inline int dw_mci_hi3798mv200_disable_tuning(struct dw_mci *host)
{
- struct dw_mci_hi3798mv200_priv *priv = slot->host->priv;
+ struct dw_mci_hi3798mv200_priv *priv = host->priv;
return regmap_set_bits(priv->crg_reg, priv->sap_dll_offset, SAP_DLL_CTRL_DLLMODE);
}
-static int dw_mci_hi3798mv200_execute_tuning_mix_mode(struct dw_mci_slot *slot,
+static int dw_mci_hi3798mv200_execute_tuning_mix_mode(struct dw_mci *host,
u32 opcode)
{
static const int degrees[] = { 0, 45, 90, 135, 180, 225, 270, 315 };
- struct dw_mci *host = slot->host;
struct dw_mci_hi3798mv200_priv *priv = host->priv;
int raise_point = -1, fall_point = -1, mid;
int err, prev_err = -1;
@@ -101,7 +100,7 @@ static int dw_mci_hi3798mv200_execute_tuning_mix_mode(struct dw_mci_slot *slot,
int i;
int ret;
- ret = dw_mci_hi3798mv200_enable_tuning(slot);
+ ret = dw_mci_hi3798mv200_enable_tuning(host);
if (ret < 0)
return ret;
@@ -136,7 +135,7 @@ static int dw_mci_hi3798mv200_execute_tuning_mix_mode(struct dw_mci_slot *slot,
}
tuning_out:
- ret = dw_mci_hi3798mv200_disable_tuning(slot);
+ ret = dw_mci_hi3798mv200_disable_tuning(host);
if (ret < 0)
return ret;
diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c
index 4ef99c0..23c3031 100644
--- a/drivers/mmc/host/dw_mmc-k3.c
+++ b/drivers/mmc/host/dw_mmc-k3.c
@@ -138,15 +138,13 @@ static int dw_mci_hi6220_parse_dt(struct dw_mci *host)
return 0;
}
-static int dw_mci_hi6220_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
+static int dw_mci_hi6220_switch_voltage(struct dw_mci *host, struct mmc_ios *ios)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
struct k3_priv *priv;
- struct dw_mci *host;
+ struct mmc_host *mmc = host->mmc;
int min_uv, max_uv;
int ret;
- host = slot->host;
priv = host->priv;
if (!priv || !priv->reg)
@@ -199,7 +197,7 @@ static void dw_mci_hi6220_set_ios(struct dw_mci *host, struct mmc_ios *ios)
host->bus_hz = clk_get_rate(host->biu_clk);
}
-static int dw_mci_hi6220_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
+static int dw_mci_hi6220_execute_tuning(struct dw_mci *host, u32 opcode)
{
return 0;
}
@@ -364,10 +362,9 @@ static int dw_mci_get_best_clksmpl(unsigned int sample_flag)
return middle_range;
}
-static int dw_mci_hi3660_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
+static int dw_mci_hi3660_execute_tuning(struct dw_mci *host, u32 opcode)
{
int i = 0;
- struct dw_mci *host = slot->host;
struct mmc_host *mmc = host->mmc;
int smpl_phase = 0;
u32 tuning_sample_flag = 0;
@@ -398,15 +395,13 @@ static int dw_mci_hi3660_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
return 0;
}
-static int dw_mci_hi3660_switch_voltage(struct mmc_host *mmc,
+static int dw_mci_hi3660_switch_voltage(struct dw_mci *host,
struct mmc_ios *ios)
{
- int ret = 0;
- struct dw_mci_slot *slot = mmc_priv(mmc);
struct k3_priv *priv;
- struct dw_mci *host;
+ struct mmc_host *mmc = host->mmc;
+ int ret = 0;
- host = slot->host;
priv = host->priv;
if (!priv || !priv->reg)
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index ffffbf59..743864b 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -282,9 +282,8 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
#define TUNING_ITERATION_TO_PHASE(i, num_phases) \
(DIV_ROUND_UP((i) * 360, num_phases))
-static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
+static int dw_mci_rk3288_execute_tuning(struct dw_mci *host, u32 opcode)
{
- struct dw_mci *host = slot->host;
struct dw_mci_rockchip_priv_data *priv = host->priv;
struct mmc_host *mmc = host->mmc;
int ret = 0;
diff --git a/drivers/mmc/host/dw_mmc-starfive.c b/drivers/mmc/host/dw_mmc-starfive.c
index d4ea289..11472a6 100644
--- a/drivers/mmc/host/dw_mmc-starfive.c
+++ b/drivers/mmc/host/dw_mmc-starfive.c
@@ -53,11 +53,10 @@ static void dw_mci_starfive_set_sample_phase(struct dw_mci *host, u32 smpl_phase
mdelay(1);
}
-static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
+static int dw_mci_starfive_execute_tuning(struct dw_mci *host,
u32 opcode)
{
static const int grade = MAX_DELAY_CHAIN;
- struct dw_mci *host = slot->host;
int smpl_phase, smpl_raise = -1, smpl_fall = -1;
int ret;
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 26db1ef..c2c4ac6 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1487,7 +1487,7 @@ static int dw_mci_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
int ret;
if (drv_data && drv_data->switch_voltage)
- return drv_data->switch_voltage(mmc, ios);
+ return drv_data->switch_voltage(host, ios);
/*
* Program the voltage. Note that some instances of dw_mmc may use
@@ -1645,7 +1645,7 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
int err = -EINVAL;
if (drv_data && drv_data->execute_tuning)
- err = drv_data->execute_tuning(slot, opcode);
+ err = drv_data->execute_tuning(host, opcode);
return err;
}
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index b4efc58..594c8f7 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -604,10 +604,10 @@ struct dw_mci_drv_data {
int (*init)(struct dw_mci *host);
void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
int (*parse_dt)(struct dw_mci *host);
- int (*execute_tuning)(struct dw_mci_slot *slot, u32 opcode);
+ int (*execute_tuning)(struct dw_mci *host, u32 opcode);
int (*prepare_hs400_tuning)(struct dw_mci *host,
struct mmc_ios *ios);
- int (*switch_voltage)(struct mmc_host *mmc,
+ int (*switch_voltage)(struct dw_mci *host,
struct mmc_ios *ios);
void (*set_data_timeout)(struct dw_mci *host,
unsigned int timeout_ns);
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 07/13] mmc: dw_mmc: Move flags from struct dw_mci_slot to struct dw_mci
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (5 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 06/13] mmc: dw_mmc: Let glue drivers to use struct dw_mci as possible Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 08/13] mmc: dw_mmc: Remove id from dw_mci_slot Shawn Lin
` (7 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
With this, dw_mmc-exynos.c will not need to access slot.
BTW, the host->slot is always present when calling
dw_mci_exynos_set_clksel_timing(), so remove it together.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc-exynos.c | 4 ++--
drivers/mmc/host/dw_mmc.c | 26 +++++++++++++-------------
drivers/mmc/host/dw_mmc.h | 14 +++++++-------
3 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 4106985..261344d 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -185,8 +185,8 @@ static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
* HOLD register should be bypassed in case there is no phase shift
* applied on CMD/DATA that is sent to the card.
*/
- if (!SDMMC_CLKSEL_GET_DRV_WD3(clksel) && host->slot)
- set_bit(DW_MMC_CARD_NO_USE_HOLD, &host->slot->flags);
+ if (!SDMMC_CLKSEL_GET_DRV_WD3(clksel))
+ set_bit(DW_MMC_CARD_NO_USE_HOLD, &host->flags);
}
static int dw_mci_exynos_runtime_resume(struct device *dev)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index c2c4ac6..3dc816e 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -304,7 +304,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
cmdr |= SDMMC_CMD_DAT_WR;
}
- if (!test_bit(DW_MMC_CARD_NO_USE_HOLD, &slot->flags))
+ if (!test_bit(DW_MMC_CARD_NO_USE_HOLD, &host->flags))
cmdr |= SDMMC_CMD_USE_HOLD_REG;
return cmdr;
@@ -343,7 +343,7 @@ static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd)
cmdr = stop->opcode | SDMMC_CMD_STOP |
SDMMC_CMD_RESP_CRC | SDMMC_CMD_RESP_EXP;
- if (!test_bit(DW_MMC_CARD_NO_USE_HOLD, &host->slot->flags))
+ if (!test_bit(DW_MMC_CARD_NO_USE_HOLD, &host->flags))
cmdr |= SDMMC_CMD_USE_HOLD_REG;
return cmdr;
@@ -889,7 +889,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
|| !mmc_card_is_removable(mmc))) {
present = 1;
- if (!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)) {
+ if (!test_bit(DW_MMC_CARD_PRESENT, &host->flags)) {
if (mmc->caps & MMC_CAP_NEEDS_POLL) {
dev_info(&mmc->class_dev,
"card is polling.\n");
@@ -897,7 +897,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
dev_info(&mmc->class_dev,
"card is non-removable.\n");
}
- set_bit(DW_MMC_CARD_PRESENT, &slot->flags);
+ set_bit(DW_MMC_CARD_PRESENT, &host->flags);
}
return present;
@@ -908,10 +908,10 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
== 0 ? 1 : 0;
spin_lock_bh(&host->lock);
- if (present && !test_and_set_bit(DW_MMC_CARD_PRESENT, &slot->flags))
+ if (present && !test_and_set_bit(DW_MMC_CARD_PRESENT, &host->flags))
dev_dbg(&mmc->class_dev, "card is present\n");
else if (!present &&
- !test_and_clear_bit(DW_MMC_CARD_PRESENT, &slot->flags))
+ !test_and_clear_bit(DW_MMC_CARD_PRESENT, &host->flags))
dev_dbg(&mmc->class_dev, "card is not present\n");
spin_unlock_bh(&host->lock);
@@ -1161,7 +1161,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
div = (host->bus_hz != clock) ? DIV_ROUND_UP(div, 2) : 0;
if ((clock != slot->__clk_old &&
- !test_bit(DW_MMC_CARD_NEEDS_POLL, &slot->flags)) ||
+ !test_bit(DW_MMC_CARD_NEEDS_POLL, &host->flags)) ||
force_clkinit) {
/* Silent the verbose log if calling from PM context */
if (!force_clkinit)
@@ -1177,7 +1177,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
*/
if (host->mmc->caps & MMC_CAP_NEEDS_POLL &&
host->mmc->f_min == clock)
- set_bit(DW_MMC_CARD_NEEDS_POLL, &slot->flags);
+ set_bit(DW_MMC_CARD_NEEDS_POLL, &host->flags);
}
/* disable clock */
@@ -1195,7 +1195,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
/* enable clock; only low power if no SDIO */
clk_en_a = SDMMC_CLKEN_ENABLE << slot->id;
- if (!test_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags))
+ if (!test_bit(DW_MMC_CARD_NO_LOW_PWR, &host->flags))
clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id;
mci_writel(host, CLKENA, clk_en_a);
@@ -1273,7 +1273,7 @@ static void __dw_mci_start_request(struct dw_mci *host,
cmdflags = dw_mci_prepare_command(host->mmc, cmd);
/* this is the first command, send the initialization clock */
- if (test_and_clear_bit(DW_MMC_CARD_NEED_INIT, &slot->flags))
+ if (test_and_clear_bit(DW_MMC_CARD_NEED_INIT, &host->flags))
cmdflags |= SDMMC_CMD_INIT;
if (data) {
@@ -1423,7 +1423,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
return;
}
}
- set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
+ set_bit(DW_MMC_CARD_NEED_INIT, &slot->host->flags);
regs = mci_readl(slot->host, PWREN);
regs |= (1 << slot->id);
mci_writel(slot->host, PWREN, regs);
@@ -1582,10 +1582,10 @@ static void dw_mci_prepare_sdio_irq(struct dw_mci_slot *slot, bool prepare)
clk_en_a_old = mci_readl(host, CLKENA);
if (prepare) {
- set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
+ set_bit(DW_MMC_CARD_NO_LOW_PWR, &host->flags);
clk_en_a = clk_en_a_old & ~clken_low_pwr;
} else {
- clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
+ clear_bit(DW_MMC_CARD_NO_LOW_PWR, &host->flags);
clk_en_a = clk_en_a_old | clken_low_pwr;
}
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 594c8f7..933d0a37 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -128,6 +128,7 @@ struct dw_mci_dma_slave {
* @cto_timer: Timer for broken command transfer over scheme.
* @dto_timer: Timer for broken data transfer over scheme.
* @mmc: The mmc_host representing this dw_mci.
+ * @flags: Random state bits associated with the host.
*
* Locking
* =======
@@ -242,6 +243,12 @@ struct dw_mci {
struct hrtimer fault_timer;
#endif
struct mmc_host *mmc;
+ unsigned long flags;
+#define DW_MMC_CARD_PRESENT 0
+#define DW_MMC_CARD_NEED_INIT 1
+#define DW_MMC_CARD_NO_LOW_PWR 2
+#define DW_MMC_CARD_NO_USE_HOLD 3
+#define DW_MMC_CARD_NEEDS_POLL 4
};
/* DMA ops for Internal/External DMAC interface */
@@ -554,7 +561,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
* @clock: Clock rate configured by set_ios(). Protected by host->lock.
* @__clk_old: The last clock value that was requested from core.
* Keeping track of this helps us to avoid spamming the console.
- * @flags: Random state bits associated with the slot.
* @id: Number of this slot.
* @sdio_id: Number of this slot in the SDIO interrupt registers.
*/
@@ -569,12 +575,6 @@ struct dw_mci_slot {
unsigned int clock;
unsigned int __clk_old;
- unsigned long flags;
-#define DW_MMC_CARD_PRESENT 0
-#define DW_MMC_CARD_NEED_INIT 1
-#define DW_MMC_CARD_NO_LOW_PWR 2
-#define DW_MMC_CARD_NO_USE_HOLD 3
-#define DW_MMC_CARD_NEEDS_POLL 4
int id;
int sdio_id;
};
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 08/13] mmc: dw_mmc: Remove id from dw_mci_slot
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (6 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 07/13] mmc: dw_mmc: Move flags from struct dw_mci_slot to struct dw_mci Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 09/13] mmc: dw_mmc: Remove sdio_id from struct dw_mci_slot Shawn Lin
` (6 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
There is only one slot support, id should be zero. So no need
to keep it in track.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 41 ++++++++++++++++++++---------------------
drivers/mmc/host/dw_mmc.h | 7 ++-----
2 files changed, 22 insertions(+), 26 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3dc816e..83f213c 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -282,7 +282,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
* until the voltage change is all done.
*/
clk_en_a = mci_readl(host, CLKENA);
- clk_en_a &= ~(SDMMC_CLKEN_LOW_PWR << slot->id);
+ clk_en_a &= ~SDMMC_CLKEN_LOW_PWR;
mci_writel(host, CLKENA, clk_en_a);
mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
SDMMC_CMD_PRV_DAT_WAIT, 0);
@@ -904,7 +904,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
} else if (gpio_cd >= 0)
present = gpio_cd;
else
- present = (mci_readl(slot->host, CDETECT) & (1 << slot->id))
+ present = (mci_readl(slot->host, CDETECT) & BIT(0))
== 0 ? 1 : 0;
spin_lock_bh(&host->lock);
@@ -1166,8 +1166,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
/* Silent the verbose log if calling from PM context */
if (!force_clkinit)
dev_info(&host->mmc->class_dev,
- "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n",
- slot->id, host->bus_hz, clock,
+ "Bus speed = %dHz (slot req %dHz, actual %dHZ div = %d)\n",
+ host->bus_hz, clock,
div ? ((host->bus_hz / div) >> 1) :
host->bus_hz, div);
@@ -1194,9 +1194,9 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
mci_send_cmd(slot, sdmmc_cmd_bits, 0);
/* enable clock; only low power if no SDIO */
- clk_en_a = SDMMC_CLKEN_ENABLE << slot->id;
+ clk_en_a = SDMMC_CLKEN_ENABLE;
if (!test_bit(DW_MMC_CARD_NO_LOW_PWR, &host->flags))
- clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id;
+ clk_en_a |= SDMMC_CLKEN_LOW_PWR;
mci_writel(host, CLKENA, clk_en_a);
/* inform CIU */
@@ -1211,7 +1211,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
host->current_speed = clock;
/* Set the current slot bus width */
- mci_writel(host, CTYPE, (slot->ctype << slot->id));
+ mci_writel(host, CTYPE, host->ctype);
}
static void dw_mci_set_data_timeout(struct dw_mci *host,
@@ -1379,14 +1379,14 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
switch (ios->bus_width) {
case MMC_BUS_WIDTH_4:
- slot->ctype = SDMMC_CTYPE_4BIT;
+ slot->host->ctype = SDMMC_CTYPE_4BIT;
break;
case MMC_BUS_WIDTH_8:
- slot->ctype = SDMMC_CTYPE_8BIT;
+ slot->host->ctype = SDMMC_CTYPE_8BIT;
break;
default:
/* set default 1 bit mode */
- slot->ctype = SDMMC_CTYPE_1BIT;
+ slot->host->ctype = SDMMC_CTYPE_1BIT;
}
regs = mci_readl(slot->host, UHS_REG);
@@ -1395,9 +1395,9 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (ios->timing == MMC_TIMING_MMC_DDR52 ||
ios->timing == MMC_TIMING_UHS_DDR50 ||
ios->timing == MMC_TIMING_MMC_HS400)
- regs |= ((0x1 << slot->id) << 16);
+ regs |= BIT(16);
else
- regs &= ~((0x1 << slot->id) << 16);
+ regs &= ~BIT(16);
mci_writel(slot->host, UHS_REG, regs);
slot->host->timing = ios->timing;
@@ -1425,7 +1425,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
}
set_bit(DW_MMC_CARD_NEED_INIT, &slot->host->flags);
regs = mci_readl(slot->host, PWREN);
- regs |= (1 << slot->id);
+ regs |= BIT(0);
mci_writel(slot->host, PWREN, regs);
break;
case MMC_POWER_ON:
@@ -1450,7 +1450,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
regulator_disable(mmc->supply.vqmmc);
regs = mci_readl(slot->host, PWREN);
- regs &= ~(1 << slot->id);
+ regs &= ~BIT(0);
mci_writel(slot->host, PWREN, regs);
/* Reset our state machine after powering off */
dw_mci_ctrl_reset(slot->host, SDMMC_CTRL_ALL_RESET_FLAGS);
@@ -1483,7 +1483,7 @@ static int dw_mci_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
struct dw_mci *host = slot->host;
const struct dw_mci_drv_data *drv_data = host->drv_data;
u32 uhs;
- u32 v18 = SDMMC_UHS_18V << slot->id;
+ u32 v18 = SDMMC_UHS_18V;
int ret;
if (drv_data && drv_data->switch_voltage)
@@ -1525,7 +1525,7 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
read_only = gpio_ro;
else
read_only =
- mci_readl(slot->host, WRTPRT) & (1 << slot->id) ? 1 : 0;
+ mci_readl(slot->host, WRTPRT) & BIT(0) ? 1 : 0;
dev_dbg(&mmc->class_dev, "card is %s\n",
read_only ? "read-only" : "read-write");
@@ -1559,10 +1559,10 @@ static void dw_mci_hw_reset(struct mmc_host *mmc)
* tRSTH >= 1us: RST_n high period
*/
reset = mci_readl(host, RST_N);
- reset &= ~(SDMMC_RST_HWACTIVE << slot->id);
+ reset &= ~SDMMC_RST_HWACTIVE;
mci_writel(host, RST_N, reset);
usleep_range(1, 2);
- reset |= SDMMC_RST_HWACTIVE << slot->id;
+ reset |= SDMMC_RST_HWACTIVE;
mci_writel(host, RST_N, reset);
usleep_range(200, 300);
}
@@ -1570,7 +1570,7 @@ static void dw_mci_hw_reset(struct mmc_host *mmc)
static void dw_mci_prepare_sdio_irq(struct dw_mci_slot *slot, bool prepare)
{
struct dw_mci *host = slot->host;
- const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
+ const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR;
u32 clk_en_a_old;
u32 clk_en_a;
@@ -2931,8 +2931,7 @@ static int dw_mci_init_slot(struct dw_mci *host)
return -ENOMEM;
slot = mmc_priv(mmc);
- slot->id = 0;
- slot->sdio_id = host->sdio_id0 + slot->id;
+ slot->sdio_id = host->sdio_id0;
host->mmc = mmc;
slot->host = host;
host->slot = slot;
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 933d0a37..7f6efb6 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -129,6 +129,7 @@ struct dw_mci_dma_slave {
* @dto_timer: Timer for broken data transfer over scheme.
* @mmc: The mmc_host representing this dw_mci.
* @flags: Random state bits associated with the host.
+ * @ctype: Card type for this host.
*
* Locking
* =======
@@ -249,6 +250,7 @@ struct dw_mci {
#define DW_MMC_CARD_NO_LOW_PWR 2
#define DW_MMC_CARD_NO_USE_HOLD 3
#define DW_MMC_CARD_NEEDS_POLL 4
+ u32 ctype;
};
/* DMA ops for Internal/External DMAC interface */
@@ -553,7 +555,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
/**
* struct dw_mci_slot - MMC slot state
* @host: The MMC controller this slot is using.
- * @ctype: Card type for this slot.
* @mrq: mmc_request currently being processed or waiting to be
* processed, or NULL when the slot is idle.
* @queue_node: List node for placing this node in the @queue list of
@@ -561,21 +562,17 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
* @clock: Clock rate configured by set_ios(). Protected by host->lock.
* @__clk_old: The last clock value that was requested from core.
* Keeping track of this helps us to avoid spamming the console.
- * @id: Number of this slot.
* @sdio_id: Number of this slot in the SDIO interrupt registers.
*/
struct dw_mci_slot {
struct dw_mci *host;
- u32 ctype;
-
struct mmc_request *mrq;
struct list_head queue_node;
unsigned int clock;
unsigned int __clk_old;
- int id;
int sdio_id;
};
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 09/13] mmc: dw_mmc: Remove sdio_id from struct dw_mci_slot
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (7 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 08/13] mmc: dw_mmc: Remove id from dw_mci_slot Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 10/13] mmc: dw_mmc: Move clock rate stuff from struct dw_mci_slot to struct dw_mci Shawn Lin
` (5 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
There is only one slot support, the sdio_id is used to indicate the SDIO slot
and where is the irq located. So it's pointless now, remove it. Given sdio_id0
is only used by Rockchip to inform dwc core the irq is located with a offset,
rename sdio_id0 to sdio_irq to reflect the fact.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc-rockchip.c | 4 ++--
drivers/mmc/host/dw_mmc.c | 9 ++++-----
drivers/mmc/host/dw_mmc.h | 7 ++-----
3 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 743864b..879188f 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -474,8 +474,8 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
struct dw_mci_rockchip_priv_data *priv = host->priv;
int ret, i;
- /* It is slot 8 on Rockchip SoCs */
- host->sdio_id0 = 8;
+ /* SDIO irq is the 8th on Rockchip SoCs */
+ host->sdio_irq = 8;
if (of_device_is_compatible(host->dev->of_node, "rockchip,rk3288-dw-mshc")) {
host->bus_hz /= RK3288_CLKGEN_DIV;
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 83f213c..afcb556e 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1607,9 +1607,9 @@ static void __dw_mci_enable_sdio_irq(struct dw_mci_slot *slot, int enb)
/* Enable/disable Slot Specific SDIO interrupt */
int_mask = mci_readl(host, INTMASK);
if (enb)
- int_mask |= SDMMC_INT_SDIO(slot->sdio_id);
+ int_mask |= SDMMC_INT_SDIO(host->sdio_irq);
else
- int_mask &= ~SDMMC_INT_SDIO(slot->sdio_id);
+ int_mask &= ~SDMMC_INT_SDIO(host->sdio_irq);
mci_writel(host, INTMASK, int_mask);
spin_unlock_irqrestore(&host->irq_lock, irqflags);
@@ -2832,9 +2832,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
dw_mci_handle_cd(host);
}
- if (pending & SDMMC_INT_SDIO(slot->sdio_id)) {
+ if (pending & SDMMC_INT_SDIO(host->sdio_irq)) {
mci_writel(host, RINTSTS,
- SDMMC_INT_SDIO(slot->sdio_id));
+ SDMMC_INT_SDIO(host->sdio_irq));
__dw_mci_enable_sdio_irq(slot, 0);
sdio_signal_irq(host->mmc);
}
@@ -2931,7 +2931,6 @@ static int dw_mci_init_slot(struct dw_mci *host)
return -ENOMEM;
slot = mmc_priv(mmc);
- slot->sdio_id = host->sdio_id0;
host->mmc = mmc;
slot->host = host;
host->slot = slot;
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 7f6efb6..3a2e1a0 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -123,7 +123,7 @@ struct dw_mci_dma_slave {
* @quirks: Set of quirks that apply to specific versions of the IP.
* @irq_flags: The flags to be passed to request_irq.
* @irq: The irq value to be passed to request_irq.
- * @sdio_id0: Number of slot0 in the SDIO interrupt registers.
+ * @sdio_irq: SDIO interrupt bit in interrupt registers.
* @cmd11_timer: Timer for SD3.0 voltage switch over scheme.
* @cto_timer: Timer for broken command transfer over scheme.
* @dto_timer: Timer for broken data transfer over scheme.
@@ -233,7 +233,7 @@ struct dw_mci {
unsigned long irq_flags; /* IRQ flags */
int irq;
- int sdio_id0;
+ int sdio_irq;
struct timer_list cmd11_timer;
struct timer_list cto_timer;
@@ -562,7 +562,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
* @clock: Clock rate configured by set_ios(). Protected by host->lock.
* @__clk_old: The last clock value that was requested from core.
* Keeping track of this helps us to avoid spamming the console.
- * @sdio_id: Number of this slot in the SDIO interrupt registers.
*/
struct dw_mci_slot {
struct dw_mci *host;
@@ -572,8 +571,6 @@ struct dw_mci_slot {
unsigned int clock;
unsigned int __clk_old;
-
- int sdio_id;
};
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 10/13] mmc: dw_mmc: Move clock rate stuff from struct dw_mci_slot to struct dw_mci
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (8 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 09/13] mmc: dw_mmc: Remove sdio_id from struct dw_mci_slot Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 11/13] mmc: dw_mmc: Remove mrq from struct dw_mci_slot Shawn Lin
` (4 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
Except for moving them, this patch also renames __clk_old to clk_old.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 8 ++++----
drivers/mmc/host/dw_mmc.h | 9 ++++-----
2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index afcb556e..98c9aaa 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1135,7 +1135,7 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
{
struct dw_mci *host = slot->host;
- unsigned int clock = slot->clock;
+ unsigned int clock = host->clock;
u32 div;
u32 clk_en_a;
u32 sdmmc_cmd_bits = SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT;
@@ -1160,7 +1160,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
div = (host->bus_hz != clock) ? DIV_ROUND_UP(div, 2) : 0;
- if ((clock != slot->__clk_old &&
+ if ((clock != host->clk_old &&
!test_bit(DW_MMC_CARD_NEEDS_POLL, &host->flags)) ||
force_clkinit) {
/* Silent the verbose log if calling from PM context */
@@ -1203,7 +1203,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
mci_send_cmd(slot, sdmmc_cmd_bits, 0);
/* keep the last clock value that was requested from core */
- slot->__clk_old = clock;
+ host->clk_old = clock;
host->mmc->actual_clock = div ? ((host->bus_hz / div) >> 1) :
host->bus_hz;
}
@@ -1406,7 +1406,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
* Use mirror of ios->clock to prevent race with mmc
* core ios update when finding the minimum.
*/
- slot->clock = ios->clock;
+ slot->host->clock = ios->clock;
if (drv_data && drv_data->set_ios)
drv_data->set_ios(slot->host, ios);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 3a2e1a0..99a69da 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -130,6 +130,8 @@ struct dw_mci_dma_slave {
* @mmc: The mmc_host representing this dw_mci.
* @flags: Random state bits associated with the host.
* @ctype: Card type for this host.
+ * @clock: Clock rate configured by set_ios(). Protected by host->lock.
+ * @clk_old: The last clock value that was requested from core.
*
* Locking
* =======
@@ -251,6 +253,8 @@ struct dw_mci {
#define DW_MMC_CARD_NO_USE_HOLD 3
#define DW_MMC_CARD_NEEDS_POLL 4
u32 ctype;
+ unsigned int clock;
+ unsigned int clk_old;
};
/* DMA ops for Internal/External DMAC interface */
@@ -559,8 +563,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
* processed, or NULL when the slot is idle.
* @queue_node: List node for placing this node in the @queue list of
* &struct dw_mci.
- * @clock: Clock rate configured by set_ios(). Protected by host->lock.
- * @__clk_old: The last clock value that was requested from core.
* Keeping track of this helps us to avoid spamming the console.
*/
struct dw_mci_slot {
@@ -568,9 +570,6 @@ struct dw_mci_slot {
struct mmc_request *mrq;
struct list_head queue_node;
-
- unsigned int clock;
- unsigned int __clk_old;
};
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 11/13] mmc: dw_mmc: Remove mrq from struct dw_mci_slot
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (9 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 10/13] mmc: dw_mmc: Move clock rate stuff from struct dw_mci_slot to struct dw_mci Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 12/13] mmc: dw_mmc: Remove queue from dw_mci Shawn Lin
` (3 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
struct dw_mci has already keep mrq.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 11 +++++------
drivers/mmc/host/dw_mmc.h | 4 +---
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 98c9aaa..0b352df 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -108,7 +108,7 @@ static int dw_mci_req_show(struct seq_file *s, void *v)
/* Make sure we get a consistent snapshot */
spin_lock_bh(&slot->host->lock);
- mrq = slot->mrq;
+ mrq = slot->host->mrq;
if (mrq) {
cmd = mrq->cmd;
@@ -1253,7 +1253,7 @@ static void __dw_mci_start_request(struct dw_mci *host,
struct mmc_data *data;
u32 cmdflags;
- mrq = slot->mrq;
+ mrq = host->mrq;
host->mrq = mrq;
@@ -1309,7 +1309,7 @@ static void __dw_mci_start_request(struct dw_mci *host,
static void dw_mci_start_request(struct dw_mci *host,
struct dw_mci_slot *slot)
{
- struct mmc_request *mrq = slot->mrq;
+ struct mmc_request *mrq = host->mrq;
struct mmc_command *cmd;
cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
@@ -1323,7 +1323,7 @@ static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
dev_vdbg(&host->mmc->class_dev, "queue request: state=%d\n",
host->state);
- slot->mrq = mrq;
+ host->mrq = mrq;
if (host->state == STATE_WAITING_CMD11_DONE) {
dev_warn(&host->mmc->class_dev,
@@ -1349,7 +1349,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
struct dw_mci_slot *slot = mmc_priv(mmc);
struct dw_mci *host = slot->host;
- WARN_ON(slot->mrq);
+ WARN_ON(host->mrq);
/*
* The check for card presence and queueing of the request must be
@@ -1820,7 +1820,6 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
WARN_ON(host->cmd || host->data);
- host->slot->mrq = NULL;
host->mrq = NULL;
if (!list_empty(&host->queue)) {
slot = list_entry(host->queue.next,
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 99a69da..f91f5fc 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -64,7 +64,7 @@ struct dw_mci_dma_slave {
* @fifo_reg: Pointer to MMIO registers for data FIFO
* @sg: Scatterlist entry currently being processed by PIO code, if any.
* @sg_miter: PIO mapping scatterlist iterator.
- * @mrq: The request currently being processed on @slot,
+ * @mrq: The request currently being processed on @host,
* or NULL if the controller is idle.
* @cmd: The command currently being sent to the card, or NULL.
* @data: The data currently being transferred, or NULL if no data
@@ -559,7 +559,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
/**
* struct dw_mci_slot - MMC slot state
* @host: The MMC controller this slot is using.
- * @mrq: mmc_request currently being processed or waiting to be
* processed, or NULL when the slot is idle.
* @queue_node: List node for placing this node in the @queue list of
* &struct dw_mci.
@@ -568,7 +567,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
struct dw_mci_slot {
struct dw_mci *host;
- struct mmc_request *mrq;
struct list_head queue_node;
};
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 12/13] mmc: dw_mmc: Remove queue from dw_mci
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (10 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 11/13] mmc: dw_mmc: Remove mrq from struct dw_mci_slot Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-20 10:29 ` [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot Shawn Lin
` (2 subsequent siblings)
14 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
It's pointless to use a queue if only one slot is supported.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc.c | 24 +++++-------------------
drivers/mmc/host/dw_mmc.h | 9 ++-------
2 files changed, 7 insertions(+), 26 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 0b352df..6253bc6 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1339,8 +1339,6 @@ static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
if (host->state == STATE_IDLE) {
host->state = STATE_SENDING_CMD;
dw_mci_start_request(host, slot);
- } else {
- list_add_tail(&slot->queue_node, &host->queue);
}
}
@@ -1815,28 +1813,17 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
__releases(&host->lock)
__acquires(&host->lock)
{
- struct dw_mci_slot *slot;
+ //struct dw_mci_slot *slot;
struct mmc_host *prev_mmc = host->mmc;
WARN_ON(host->cmd || host->data);
host->mrq = NULL;
- if (!list_empty(&host->queue)) {
- slot = list_entry(host->queue.next,
- struct dw_mci_slot, queue_node);
- list_del(&slot->queue_node);
- dev_vdbg(host->dev, "list not empty: %s is next\n",
- mmc_hostname(host->mmc));
- host->state = STATE_SENDING_CMD;
- dw_mci_start_request(host, slot);
- } else {
- dev_vdbg(host->dev, "list empty\n");
- if (host->state == STATE_SENDING_CMD11)
- host->state = STATE_WAITING_CMD11_DONE;
- else
- host->state = STATE_IDLE;
- }
+ if (host->state == STATE_SENDING_CMD11)
+ host->state = STATE_WAITING_CMD11_DONE;
+ else
+ host->state = STATE_IDLE;
spin_unlock(&host->lock);
mmc_request_done(prev_mmc, mrq);
@@ -3357,7 +3344,6 @@ int dw_mci_probe(struct dw_mci *host)
spin_lock_init(&host->lock);
spin_lock_init(&host->irq_lock);
- INIT_LIST_HEAD(&host->queue);
dw_mci_init_fault(host);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index f91f5fc..d5e4e6d 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -96,7 +96,6 @@ struct dw_mci_dma_slave {
* @completed_events: Bitmask of events which the state machine has
* processed.
* @state: BH work state.
- * @queue: List of slots waiting for access to the controller.
* @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus
* rate and timeout calculations.
* @current_speed: Configured rate of the controller.
@@ -136,12 +135,12 @@ struct dw_mci_dma_slave {
* Locking
* =======
*
- * @lock is a softirq-safe spinlock protecting @queue as well as
+ * @lock is a softirq-safe spinlock protecting as well as
* @slot, @mrq and @state. These must always be updated
* at the same time while holding @lock.
* The @mrq field of struct dw_mci_slot is also protected by @lock,
* and must always be written at the same time as the slot is added to
- * @queue.
+ * @host.
*
* @irq_lock is an irq-safe spinlock protecting the INTMASK register
* to allow the interrupt handler to modify it directly. Held for only long
@@ -203,7 +202,6 @@ struct dw_mci {
unsigned long pending_events;
unsigned long completed_events;
enum dw_mci_state state;
- struct list_head queue;
u32 bus_hz;
u32 current_speed;
@@ -560,14 +558,11 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
* struct dw_mci_slot - MMC slot state
* @host: The MMC controller this slot is using.
* processed, or NULL when the slot is idle.
- * @queue_node: List node for placing this node in the @queue list of
* &struct dw_mci.
* Keeping track of this helps us to avoid spamming the console.
*/
struct dw_mci_slot {
struct dw_mci *host;
-
- struct list_head queue_node;
};
/**
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (11 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 12/13] mmc: dw_mmc: Remove queue from dw_mci Shawn Lin
@ 2025-11-20 10:29 ` Shawn Lin
2025-11-22 18:40 ` kernel test robot
2025-11-22 19:54 ` kernel test robot
2025-11-20 11:10 ` [PATCH 0/13] dw_mmc cleanup Ulf Hansson
2025-11-25 12:33 ` Ulf Hansson
14 siblings, 2 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 10:29 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc, Jaehoon Chung, Shawn Lin
This patch sets struct dw_mci as mmc_host's private data by
copying struct dw_mci passing to dw_mci_probe() in order to
achieve with mminimal changes. Then we remove slot everywhere.
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---
drivers/mmc/host/dw_mmc-pltfm.c | 2 +-
drivers/mmc/host/dw_mmc.c | 257 ++++++++++++++++++----------------------
drivers/mmc/host/dw_mmc.h | 22 +---
3 files changed, 123 insertions(+), 158 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index de820ff..af947e1 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -45,6 +45,7 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
host->dev = &pdev->dev;
host->irq_flags = 0;
host->pdata = pdev->dev.platform_data;
+ host->pdev = pdev;
host->regs = devm_platform_get_and_ioremap_resource(pdev, 0, ®s);
if (IS_ERR(host->regs))
@@ -53,7 +54,6 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
/* Get registers' physical base address */
host->phy_regs = regs->start;
- platform_set_drvdata(pdev, host);
return dw_mci_probe(host);
}
EXPORT_SYMBOL_GPL(dw_mci_pltfm_register);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 6253bc6..74cc240 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -100,15 +100,15 @@ struct idmac_desc {
#if defined(CONFIG_DEBUG_FS)
static int dw_mci_req_show(struct seq_file *s, void *v)
{
- struct dw_mci_slot *slot = s->private;
+ struct dw_mci *host = s->private;
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_command *stop;
struct mmc_data *data;
/* Make sure we get a consistent snapshot */
- spin_lock_bh(&slot->host->lock);
- mrq = slot->host->mrq;
+ spin_lock_bh(&host->lock);
+ mrq = host->mrq;
if (mrq) {
cmd = mrq->cmd;
@@ -133,7 +133,7 @@ static int dw_mci_req_show(struct seq_file *s, void *v)
stop->resp[2], stop->error);
}
- spin_unlock_bh(&slot->host->lock);
+ spin_unlock_bh(&host->lock);
return 0;
}
@@ -158,9 +158,8 @@ static int dw_mci_regs_show(struct seq_file *s, void *v)
}
DEFINE_SHOW_ATTRIBUTE(dw_mci_regs);
-static void dw_mci_init_debugfs(struct dw_mci_slot *slot)
+static void dw_mci_init_debugfs(struct dw_mci *host)
{
- struct dw_mci *host = slot->host;
struct mmc_host *mmc = host->mmc;
struct dentry *root;
@@ -169,7 +168,6 @@ static void dw_mci_init_debugfs(struct dw_mci_slot *slot)
return;
debugfs_create_file("regs", 0400, root, host, &dw_mci_regs_fops);
- debugfs_create_file("req", 0400, root, slot, &dw_mci_req_fops);
debugfs_create_u32("state", 0400, root, &host->state);
debugfs_create_xul("pending_events", 0400, root,
&host->pending_events);
@@ -224,9 +222,8 @@ static void dw_mci_wait_while_busy(struct dw_mci *host, u32 cmd_flags)
}
}
-static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
+static void mci_send_cmd(struct dw_mci *host, u32 cmd, u32 arg)
{
- struct dw_mci *host = slot->host;
unsigned int cmd_status = 0;
mci_writel(host, CMDARG, arg);
@@ -244,8 +241,7 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
u32 cmdr;
cmd->error = -EINPROGRESS;
@@ -267,8 +263,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
cmdr |= SDMMC_CMD_VOLT_SWITCH;
/* Change state to continue to handle CMD11 weirdness */
- WARN_ON(slot->host->state != STATE_SENDING_CMD);
- slot->host->state = STATE_SENDING_CMD11;
+ WARN_ON(host->state != STATE_SENDING_CMD);
+ host->state = STATE_SENDING_CMD11;
/*
* We need to disable low power mode (automatic clock stop)
@@ -284,7 +280,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
clk_en_a = mci_readl(host, CLKENA);
clk_en_a &= ~SDMMC_CLKEN_LOW_PWR;
mci_writel(host, CLKENA, clk_en_a);
- mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
+ mci_send_cmd(host, SDMMC_CMD_UPD_CLK |
SDMMC_CMD_PRV_DAT_WAIT, 0);
}
@@ -845,16 +841,16 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host,
static void dw_mci_pre_req(struct mmc_host *mmc,
struct mmc_request *mrq)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct dw_mci *host = mmc_priv(mmc);
struct mmc_data *data = mrq->data;
- if (!slot->host->use_dma || !data)
+ if (!host->use_dma || !data)
return;
/* This data might be unmapped at this time */
data->host_cookie = COOKIE_UNMAPPED;
- if (dw_mci_pre_dma_transfer(slot->host, mrq->data,
+ if (dw_mci_pre_dma_transfer(host, mrq->data,
COOKIE_PRE_MAPPED) < 0)
data->host_cookie = COOKIE_UNMAPPED;
}
@@ -863,14 +859,14 @@ static void dw_mci_post_req(struct mmc_host *mmc,
struct mmc_request *mrq,
int err)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct dw_mci *host = mmc_priv(mmc);
struct mmc_data *data = mrq->data;
- if (!slot->host->use_dma || !data)
+ if (!host->use_dma || !data)
return;
if (data->host_cookie != COOKIE_UNMAPPED)
- dma_unmap_sg(slot->host->dev,
+ dma_unmap_sg(host->dev,
data->sg,
data->sg_len,
mmc_get_dma_dir(data));
@@ -880,8 +876,7 @@ static void dw_mci_post_req(struct mmc_host *mmc,
static int dw_mci_get_cd(struct mmc_host *mmc)
{
int present;
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
int gpio_cd = mmc_gpio_get_cd(mmc);
/* Use platform get_cd function, else try onboard card detect */
@@ -904,7 +899,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
} else if (gpio_cd >= 0)
present = gpio_cd;
else
- present = (mci_readl(slot->host, CDETECT) & BIT(0))
+ present = (mci_readl(host, CDETECT) & BIT(0))
== 0 ? 1 : 0;
spin_lock_bh(&host->lock);
@@ -1132,9 +1127,8 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
}
}
-static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
+static void dw_mci_setup_bus(struct dw_mci *host, bool force_clkinit)
{
- struct dw_mci *host = slot->host;
unsigned int clock = host->clock;
u32 div;
u32 clk_en_a;
@@ -1148,7 +1142,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
if (!clock) {
mci_writel(host, CLKENA, 0);
- mci_send_cmd(slot, sdmmc_cmd_bits, 0);
+ mci_send_cmd(host, sdmmc_cmd_bits, 0);
} else if (clock != host->current_speed || force_clkinit) {
div = host->bus_hz / clock;
if (host->bus_hz % clock && host->bus_hz > clock)
@@ -1166,7 +1160,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
/* Silent the verbose log if calling from PM context */
if (!force_clkinit)
dev_info(&host->mmc->class_dev,
- "Bus speed = %dHz (slot req %dHz, actual %dHZ div = %d)\n",
+ "Bus speed = %dHz (req %dHz, actual %dHZ div = %d)\n",
host->bus_hz, clock,
div ? ((host->bus_hz / div) >> 1) :
host->bus_hz, div);
@@ -1185,13 +1179,13 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
mci_writel(host, CLKSRC, 0);
/* inform CIU */
- mci_send_cmd(slot, sdmmc_cmd_bits, 0);
+ mci_send_cmd(host, sdmmc_cmd_bits, 0);
/* set clock to desired speed */
mci_writel(host, CLKDIV, div);
/* inform CIU */
- mci_send_cmd(slot, sdmmc_cmd_bits, 0);
+ mci_send_cmd(host, sdmmc_cmd_bits, 0);
/* enable clock; only low power if no SDIO */
clk_en_a = SDMMC_CLKEN_ENABLE;
@@ -1200,7 +1194,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
mci_writel(host, CLKENA, clk_en_a);
/* inform CIU */
- mci_send_cmd(slot, sdmmc_cmd_bits, 0);
+ mci_send_cmd(host, sdmmc_cmd_bits, 0);
/* keep the last clock value that was requested from core */
host->clk_old = clock;
@@ -1210,7 +1204,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
host->current_speed = clock;
- /* Set the current slot bus width */
+ /* Set bus width */
mci_writel(host, CTYPE, host->ctype);
}
@@ -1246,7 +1240,6 @@ static void dw_mci_set_data_timeout(struct dw_mci *host,
}
static void __dw_mci_start_request(struct dw_mci *host,
- struct dw_mci_slot *slot,
struct mmc_command *cmd)
{
struct mmc_request *mrq;
@@ -1306,19 +1299,17 @@ static void __dw_mci_start_request(struct dw_mci *host,
host->stop_cmdr = dw_mci_prep_stop_abort(host, cmd);
}
-static void dw_mci_start_request(struct dw_mci *host,
- struct dw_mci_slot *slot)
+static void dw_mci_start_request(struct dw_mci *host)
{
struct mmc_request *mrq = host->mrq;
struct mmc_command *cmd;
cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
- __dw_mci_start_request(host, slot, cmd);
+ __dw_mci_start_request(host, cmd);
}
/* must be called with host->lock held */
-static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
- struct mmc_request *mrq)
+static void dw_mci_queue_request(struct dw_mci *host, struct mmc_request *mrq)
{
dev_vdbg(&host->mmc->class_dev, "queue request: state=%d\n",
host->state);
@@ -1338,14 +1329,13 @@ static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
if (host->state == STATE_IDLE) {
host->state = STATE_SENDING_CMD;
- dw_mci_start_request(host, slot);
+ dw_mci_start_request(host);
}
}
static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
WARN_ON(host->mrq);
@@ -1363,31 +1353,31 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
spin_lock_bh(&host->lock);
- dw_mci_queue_request(host, slot, mrq);
+ dw_mci_queue_request(host, mrq);
spin_unlock_bh(&host->lock);
}
static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- const struct dw_mci_drv_data *drv_data = slot->host->drv_data;
+ struct dw_mci *host = mmc_priv(mmc);
+ const struct dw_mci_drv_data *drv_data = host->drv_data;
u32 regs;
int ret;
switch (ios->bus_width) {
case MMC_BUS_WIDTH_4:
- slot->host->ctype = SDMMC_CTYPE_4BIT;
+ host->ctype = SDMMC_CTYPE_4BIT;
break;
case MMC_BUS_WIDTH_8:
- slot->host->ctype = SDMMC_CTYPE_8BIT;
+ host->ctype = SDMMC_CTYPE_8BIT;
break;
default:
/* set default 1 bit mode */
- slot->host->ctype = SDMMC_CTYPE_1BIT;
+ host->ctype = SDMMC_CTYPE_1BIT;
}
- regs = mci_readl(slot->host, UHS_REG);
+ regs = mci_readl(host, UHS_REG);
/* DDR mode set */
if (ios->timing == MMC_TIMING_MMC_DDR52 ||
@@ -1397,17 +1387,17 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
regs &= ~BIT(16);
- mci_writel(slot->host, UHS_REG, regs);
- slot->host->timing = ios->timing;
+ mci_writel(host, UHS_REG, regs);
+ host->timing = ios->timing;
/*
* Use mirror of ios->clock to prevent race with mmc
* core ios update when finding the minimum.
*/
- slot->host->clock = ios->clock;
+ host->clock = ios->clock;
if (drv_data && drv_data->set_ios)
- drv_data->set_ios(slot->host, ios);
+ drv_data->set_ios(host, ios);
switch (ios->power_mode) {
case MMC_POWER_UP:
@@ -1415,31 +1405,31 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
ios->vdd);
if (ret) {
- dev_err(slot->host->dev,
+ dev_err(host->dev,
"failed to enable vmmc regulator\n");
/*return, if failed turn on vmmc*/
return;
}
}
- set_bit(DW_MMC_CARD_NEED_INIT, &slot->host->flags);
- regs = mci_readl(slot->host, PWREN);
+ set_bit(DW_MMC_CARD_NEED_INIT, &host->flags);
+ regs = mci_readl(host, PWREN);
regs |= BIT(0);
- mci_writel(slot->host, PWREN, regs);
+ mci_writel(host, PWREN, regs);
break;
case MMC_POWER_ON:
if (!IS_ERR(mmc->supply.vqmmc)) {
ret = regulator_enable(mmc->supply.vqmmc);
if (ret < 0)
- dev_err(slot->host->dev,
+ dev_err(host->dev,
"failed to enable vqmmc\n");
}
/* Adjust clock / bus width after power is up */
- dw_mci_setup_bus(slot, false);
+ dw_mci_setup_bus(host, false);
break;
case MMC_POWER_OFF:
/* Turn clock off before power goes down */
- dw_mci_setup_bus(slot, false);
+ dw_mci_setup_bus(host, false);
if (!IS_ERR(mmc->supply.vmmc))
mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
@@ -1447,38 +1437,37 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (!IS_ERR(mmc->supply.vqmmc))
regulator_disable(mmc->supply.vqmmc);
- regs = mci_readl(slot->host, PWREN);
+ regs = mci_readl(host, PWREN);
regs &= ~BIT(0);
- mci_writel(slot->host, PWREN, regs);
+ mci_writel(host, PWREN, regs);
/* Reset our state machine after powering off */
- dw_mci_ctrl_reset(slot->host, SDMMC_CTRL_ALL_RESET_FLAGS);
+ dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
break;
default:
break;
}
- if (slot->host->state == STATE_WAITING_CMD11_DONE && ios->clock != 0)
- slot->host->state = STATE_IDLE;
+ if (host->state == STATE_WAITING_CMD11_DONE && ios->clock != 0)
+ host->state = STATE_IDLE;
}
static int dw_mci_card_busy(struct mmc_host *mmc)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct dw_mci *host = mmc_priv(mmc);
u32 status;
/*
* Check the busy bit which is low when DAT[3:0]
* (the data lines) are 0000
*/
- status = mci_readl(slot->host, STATUS);
+ status = mci_readl(host, STATUS);
return !!(status & SDMMC_STATUS_BUSY);
}
static int dw_mci_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
const struct dw_mci_drv_data *drv_data = host->drv_data;
u32 uhs;
u32 v18 = SDMMC_UHS_18V;
@@ -1515,7 +1504,7 @@ static int dw_mci_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
static int dw_mci_get_ro(struct mmc_host *mmc)
{
int read_only;
- struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct dw_mci *host = mmc_priv(mmc);
int gpio_ro = mmc_gpio_get_ro(mmc);
/* Use platform get_ro function, else try on board write protect */
@@ -1523,7 +1512,7 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
read_only = gpio_ro;
else
read_only =
- mci_readl(slot->host, WRTPRT) & BIT(0) ? 1 : 0;
+ mci_readl(host, WRTPRT) & BIT(0) ? 1 : 0;
dev_dbg(&mmc->class_dev, "card is %s\n",
read_only ? "read-only" : "read-write");
@@ -1533,8 +1522,7 @@ static int dw_mci_get_ro(struct mmc_host *mmc)
static void dw_mci_hw_reset(struct mmc_host *mmc)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
const struct dw_mci_drv_data *drv_data = host->drv_data;
int reset;
@@ -1565,9 +1553,8 @@ static void dw_mci_hw_reset(struct mmc_host *mmc)
usleep_range(200, 300);
}
-static void dw_mci_prepare_sdio_irq(struct dw_mci_slot *slot, bool prepare)
+static void dw_mci_prepare_sdio_irq(struct dw_mci *host, bool prepare)
{
- struct dw_mci *host = slot->host;
const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR;
u32 clk_en_a_old;
u32 clk_en_a;
@@ -1589,14 +1576,13 @@ static void dw_mci_prepare_sdio_irq(struct dw_mci_slot *slot, bool prepare)
if (clk_en_a != clk_en_a_old) {
mci_writel(host, CLKENA, clk_en_a);
- mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT,
+ mci_send_cmd(host, SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT,
0);
}
}
-static void __dw_mci_enable_sdio_irq(struct dw_mci_slot *slot, int enb)
+static void __dw_mci_enable_sdio_irq(struct dw_mci *host, int enb)
{
- struct dw_mci *host = slot->host;
unsigned long irqflags;
u32 int_mask;
@@ -1615,11 +1601,10 @@ static void __dw_mci_enable_sdio_irq(struct dw_mci_slot *slot, int enb)
static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
- dw_mci_prepare_sdio_irq(slot, enb);
- __dw_mci_enable_sdio_irq(slot, enb);
+ dw_mci_prepare_sdio_irq(host, enb);
+ __dw_mci_enable_sdio_irq(host, enb);
/* Avoid runtime suspending the device when SDIO IRQ is enabled */
if (enb)
@@ -1630,15 +1615,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
static void dw_mci_ack_sdio_irq(struct mmc_host *mmc)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
+ struct dw_mci *host = mmc_priv(mmc);
- __dw_mci_enable_sdio_irq(slot, 1);
+ __dw_mci_enable_sdio_irq(host, 1);
}
static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
const struct dw_mci_drv_data *drv_data = host->drv_data;
int err = -EINVAL;
@@ -1650,8 +1634,7 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
static int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc,
struct mmc_ios *ios)
{
- struct dw_mci_slot *slot = mmc_priv(mmc);
- struct dw_mci *host = slot->host;
+ struct dw_mci *host = mmc_priv(mmc);
const struct dw_mci_drv_data *drv_data = host->drv_data;
if (drv_data && drv_data->prepare_hs400_tuning)
@@ -1722,7 +1705,7 @@ static bool dw_mci_reset(struct dw_mci *host)
ciu_out:
/* After a CTRL reset we need to have CIU set clock registers */
- mci_send_cmd(host->slot, SDMMC_CMD_UPD_CLK, 0);
+ mci_send_cmd(host, SDMMC_CMD_UPD_CLK, 0);
return ret;
}
@@ -1813,7 +1796,6 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
__releases(&host->lock)
__acquires(&host->lock)
{
- //struct dw_mci_slot *slot;
struct mmc_host *prev_mmc = host->mmc;
WARN_ON(host->cmd || host->data);
@@ -2001,8 +1983,7 @@ static void dw_mci_work_func(struct work_struct *t)
set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
err = dw_mci_command_complete(host, cmd);
if (cmd == mrq->sbc && !err) {
- __dw_mci_start_request(host, host->slot,
- mrq->cmd);
+ __dw_mci_start_request(host, mrq->cmd);
goto unlock;
}
@@ -2717,7 +2698,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
{
struct dw_mci *host = dev_id;
u32 pending;
- struct dw_mci_slot *slot = host->slot;
pending = mci_readl(host, MINTSTS); /* read-only mask reg */
@@ -2821,7 +2801,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
if (pending & SDMMC_INT_SDIO(host->sdio_irq)) {
mci_writel(host, RINTSTS,
SDMMC_INT_SDIO(host->sdio_irq));
- __dw_mci_enable_sdio_irq(slot, 0);
+ __dw_mci_enable_sdio_irq(host, 0);
sdio_signal_irq(host->mmc);
}
@@ -2854,9 +2834,8 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)
+static int dw_mci_init_host_caps(struct dw_mci *host)
{
- struct dw_mci *host = slot->host;
const struct dw_mci_drv_data *drv_data = host->drv_data;
struct mmc_host *mmc = host->mmc;
int ctrl_id;
@@ -2906,38 +2885,40 @@ static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)
return 0;
}
-static int dw_mci_init_slot(struct dw_mci *host)
+static struct dw_mci *dw_mci_init_host(struct dw_mci *host)
{
struct mmc_host *mmc;
- struct dw_mci_slot *slot;
+ struct dw_mci *local_host;
int ret;
- mmc = devm_mmc_alloc_host(host->dev, sizeof(*slot));
+ mmc = devm_mmc_alloc_host(host->dev, sizeof(*host));
if (!mmc)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
+
+ local_host = mmc_priv(mmc);
+ memcpy(local_host, host, sizeof(*host));
+ local_host->mmc = mmc;
- slot = mmc_priv(mmc);
- host->mmc = mmc;
- slot->host = host;
- host->slot = slot;
+ if (host->pdev)
+ platform_set_drvdata(host->pdev, local_host);
mmc->ops = &dw_mci_ops;
/*if there are external regulators, get them*/
ret = mmc_regulator_get_supply(mmc);
if (ret)
- return ret;
+ return ERR_PTR(ret);
if (!mmc->ocr_avail)
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
ret = mmc_of_parse(mmc);
if (ret)
- return ret;
+ return ERR_PTR(ret);
- ret = dw_mci_init_slot_caps(slot);
+ ret = dw_mci_init_host_caps(local_host);
if (ret)
- return ret;
+ return ERR_PTR(ret);
/* Useful defaults if platform data is unset. */
if (host->use_dma == TRANS_MODE_IDMAC) {
@@ -2967,20 +2948,19 @@ static int dw_mci_init_slot(struct dw_mci *host)
ret = mmc_add_host(mmc);
if (ret)
- return ret;
+ return ERR_PTR(ret);
#if defined(CONFIG_DEBUG_FS)
- dw_mci_init_debugfs(slot);
+ dw_mci_init_debugfs(local_host);
#endif
- return 0;
+ return local_host;
}
-static void dw_mci_cleanup_slot(struct dw_mci_slot *slot)
+static void dw_mci_cleanup_host(struct dw_mci *host)
{
/* Debugfs stuff is cleaned up by mmc core */
- mmc_remove_host(slot->host->mmc);
- slot->host->slot = NULL;
+ mmc_remove_host(host->mmc);
}
static void dw_mci_init_dma(struct dw_mci *host)
@@ -3022,8 +3002,9 @@ static void dw_mci_init_dma(struct dw_mci *host)
host->dma_64bit_address = 1;
dev_info(host->dev,
"IDMAC supports 64-bit address mode.\n");
- if (dma_set_mask_and_coherent(host->dev, DMA_BIT_MASK(64)))
- dev_info(host->dev, "Fail to set 64-bit DMA mask");
+ if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
+ dma_set_coherent_mask(host->dev,
+ DMA_BIT_MASK(64));
} else {
/* host supports IDMAC in 32-bit address mode */
host->dma_64bit_address = 0;
@@ -3248,7 +3229,7 @@ static void dw_mci_enable_cd(struct dw_mci *host)
u32 temp;
/*
- * No need for CD if all slots have a non-error GPIO
+ * No need for CD if host has a non-error GPIO
* as well as broken card detection is found.
*/
if (host->mmc->caps & MMC_CAP_NEEDS_POLL)
@@ -3266,6 +3247,7 @@ static void dw_mci_enable_cd(struct dw_mci *host)
int dw_mci_probe(struct dw_mci *host)
{
const struct dw_mci_drv_data *drv_data = host->drv_data;
+ struct dw_mci *local_host;
int width, i, ret = 0;
u32 fifo_size;
@@ -3433,12 +3415,6 @@ int dw_mci_probe(struct dw_mci *host)
else
host->fifo_reg = host->regs + DATA_240A_OFFSET;
- INIT_WORK(&host->bh_work, dw_mci_work_func);
- ret = devm_request_irq(host->dev, host->irq, dw_mci_interrupt,
- host->irq_flags, "dw-mci", host);
- if (ret)
- goto err_dmaunmap;
-
/*
* Enable interrupts for command done, data over, data empty,
* receive ready and error such as transmit, receive timeout, crc error
@@ -3453,15 +3429,20 @@ int dw_mci_probe(struct dw_mci *host)
"DW MMC controller at irq %d,%d bit host data width,%u deep fifo\n",
host->irq, width, fifo_size);
- /* We need at least one slot to succeed */
- ret = dw_mci_init_slot(host);
- if (ret) {
- dev_dbg(host->dev, "slot %d init failed\n", i);
+ local_host = dw_mci_init_host(host);
+ if (IS_ERR(local_host)) {
+ dev_dbg(host->dev, "host init failed\n");
goto err_dmaunmap;
}
- /* Now that slots are all setup, we can enable card detect */
- dw_mci_enable_cd(host);
+ INIT_WORK(&local_host->bh_work, dw_mci_work_func);
+ ret = devm_request_irq(local_host->dev, local_host->irq, dw_mci_interrupt,
+ local_host->irq_flags, "dw-mci", local_host);
+ if (ret)
+ goto err_dmaunmap;
+
+ /* Now that host is all setup, we can enable card detect */
+ dw_mci_enable_cd(local_host);
return 0;
@@ -3483,9 +3464,9 @@ EXPORT_SYMBOL(dw_mci_probe);
void dw_mci_remove(struct dw_mci *host)
{
- dev_dbg(host->dev, "remove slot\n");
- if (host->slot)
- dw_mci_cleanup_slot(host->slot);
+ dev_dbg(host->dev, "remove host\n");
+ if (host)
+ dw_mci_cleanup_host(host);
mci_writel(host, RINTSTS, 0xFFFFFFFF);
mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */
@@ -3504,8 +3485,6 @@ void dw_mci_remove(struct dw_mci *host)
}
EXPORT_SYMBOL(dw_mci_remove);
-
-
#ifdef CONFIG_PM
int dw_mci_runtime_suspend(struct device *dev)
{
@@ -3516,7 +3495,7 @@ int dw_mci_runtime_suspend(struct device *dev)
clk_disable_unprepare(host->ciu_clk);
- if (host->slot &&
+ if (host &&
(mmc_host_can_gpio_cd(host->mmc) ||
!mmc_card_is_removable(host->mmc)))
clk_disable_unprepare(host->biu_clk);
@@ -3530,7 +3509,7 @@ int dw_mci_runtime_resume(struct device *dev)
int ret = 0;
struct dw_mci *host = dev_get_drvdata(dev);
- if (host->slot &&
+ if (host &&
(mmc_host_can_gpio_cd(host->mmc) ||
!mmc_card_is_removable(host->mmc))) {
ret = clk_prepare_enable(host->biu_clk);
@@ -3568,23 +3547,23 @@ int dw_mci_runtime_resume(struct device *dev)
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
- if (host->slot && host->mmc->pm_flags & MMC_PM_KEEP_POWER)
+ if (host && host->mmc->pm_flags & MMC_PM_KEEP_POWER)
dw_mci_set_ios(host->mmc, &host->mmc->ios);
/* Force setup bus to guarantee available clock output */
- dw_mci_setup_bus(host->slot, true);
+ dw_mci_setup_bus(host, true);
/* Re-enable SDIO interrupts. */
if (sdio_irq_claimed(host->mmc))
- __dw_mci_enable_sdio_irq(host->slot, 1);
+ __dw_mci_enable_sdio_irq(host, 1);
- /* Now that slots are all setup, we can enable card detect */
+ /* Now that host is setup, we can enable card detect */
dw_mci_enable_cd(host);
return 0;
err:
- if (host->slot &&
+ if (host &&
(mmc_host_can_gpio_cd(host->mmc) ||
!mmc_card_is_removable(host->mmc)))
clk_disable_unprepare(host->biu_clk);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index d5e4e6d..66f6402 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -57,7 +57,7 @@ struct dw_mci_dma_slave {
};
/**
- * struct dw_mci - MMC controller state shared between all slots
+ * struct dw_mci - MMC controller state
* @lock: Spinlock protecting the queue and associated data.
* @irq_lock: Spinlock protecting the INTMASK setting.
* @regs: Pointer to MMIO registers.
@@ -108,7 +108,6 @@ struct dw_mci_dma_slave {
* @priv: Implementation defined private data.
* @biu_clk: Pointer to bus interface unit clock instance.
* @ciu_clk: Pointer to card interface unit clock instance.
- * @slot: Slots sharing this MMC controller.
* @fifo_depth: depth of FIFO.
* @data_addr_override: override fifo reg offset with this value.
* @wm_aligned: force fifo watermark equal with data length in PIO mode.
@@ -131,16 +130,14 @@ struct dw_mci_dma_slave {
* @ctype: Card type for this host.
* @clock: Clock rate configured by set_ios(). Protected by host->lock.
* @clk_old: The last clock value that was requested from core.
+ * @pdev: platform_device registered
*
* Locking
* =======
*
* @lock is a softirq-safe spinlock protecting as well as
- * @slot, @mrq and @state. These must always be updated
+ * @mrq and @state. These must always be updated
* at the same time while holding @lock.
- * The @mrq field of struct dw_mci_slot is also protected by @lock,
- * and must always be written at the same time as the slot is added to
- * @host.
*
* @irq_lock is an irq-safe spinlock protecting the INTMASK register
* to allow the interrupt handler to modify it directly. Held for only long
@@ -214,7 +211,6 @@ struct dw_mci {
void *priv;
struct clk *biu_clk;
struct clk *ciu_clk;
- struct dw_mci_slot *slot;
/* FIFO push and pull */
int fifo_depth;
@@ -253,6 +249,7 @@ struct dw_mci {
u32 ctype;
unsigned int clock;
unsigned int clk_old;
+ struct platform_device *pdev;
};
/* DMA ops for Internal/External DMAC interface */
@@ -555,17 +552,6 @@ static inline int dw_mci_runtime_resume(struct device *device) { return -EOPNOTS
#endif
/**
- * struct dw_mci_slot - MMC slot state
- * @host: The MMC controller this slot is using.
- * processed, or NULL when the slot is idle.
- * &struct dw_mci.
- * Keeping track of this helps us to avoid spamming the console.
- */
-struct dw_mci_slot {
- struct dw_mci *host;
-};
-
-/**
* dw_mci driver data - dw-mshc implementation specific driver data.
* @caps: mmc subsystem specified capabilities of the controller(s).
* @num_caps: number of capabilities specified by @caps.
--
2.7.4
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot
2025-11-20 10:29 ` [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot Shawn Lin
@ 2025-11-22 18:40 ` kernel test robot
2025-11-22 19:54 ` kernel test robot
1 sibling, 0 replies; 21+ messages in thread
From: kernel test robot @ 2025-11-22 18:40 UTC (permalink / raw)
To: Shawn Lin, Ulf Hansson; +Cc: oe-kbuild-all, linux-mmc, Jaehoon Chung, Shawn Lin
Hi Shawn,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20251120]
[cannot apply to krzk/for-next rockchip/for-next linus/master ulf-hansson-mmc-mirror/next v6.18-rc6 v6.18-rc5 v6.18-rc4 v6.18-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Shawn-Lin/mmc-dw_mmc-Remove-unused-struct-dma_pdata/20251120-205522
base: next-20251120
patch link: https://lore.kernel.org/r/1763634565-183891-14-git-send-email-shawn.lin%40rock-chips.com
patch subject: [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot
config: arc-randconfig-002-20251123 (https://download.01.org/0day-ci/archive/20251123/202511230231.JzqFjaBp-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 12.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251123/202511230231.JzqFjaBp-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511230231.JzqFjaBp-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/debugfs.h:16,
from drivers/mmc/host/dw_mmc.c:12:
>> drivers/mmc/host/dw_mmc.c:140:23: warning: 'dw_mci_req_fops' defined but not used [-Wunused-const-variable=]
140 | DEFINE_SHOW_ATTRIBUTE(dw_mci_req);
| ^~~~~~~~~~
include/linux/seq_file.h:213:37: note: in definition of macro 'DEFINE_SHOW_ATTRIBUTE'
213 | static const struct file_operations __name ## _fops = { \
| ^~~~~~
vim +/dw_mci_req_fops +140 drivers/mmc/host/dw_mmc.c
f95f3850f7a9e1 Will Newton 2011-01-02 99
f95f3850f7a9e1 Will Newton 2011-01-02 100 #if defined(CONFIG_DEBUG_FS)
f95f3850f7a9e1 Will Newton 2011-01-02 101 static int dw_mci_req_show(struct seq_file *s, void *v)
f95f3850f7a9e1 Will Newton 2011-01-02 102 {
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 103 struct dw_mci *host = s->private;
f95f3850f7a9e1 Will Newton 2011-01-02 104 struct mmc_request *mrq;
f95f3850f7a9e1 Will Newton 2011-01-02 105 struct mmc_command *cmd;
f95f3850f7a9e1 Will Newton 2011-01-02 106 struct mmc_command *stop;
f95f3850f7a9e1 Will Newton 2011-01-02 107 struct mmc_data *data;
f95f3850f7a9e1 Will Newton 2011-01-02 108
f95f3850f7a9e1 Will Newton 2011-01-02 109 /* Make sure we get a consistent snapshot */
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 110 spin_lock_bh(&host->lock);
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 111 mrq = host->mrq;
f95f3850f7a9e1 Will Newton 2011-01-02 112
f95f3850f7a9e1 Will Newton 2011-01-02 113 if (mrq) {
f95f3850f7a9e1 Will Newton 2011-01-02 114 cmd = mrq->cmd;
f95f3850f7a9e1 Will Newton 2011-01-02 115 data = mrq->data;
f95f3850f7a9e1 Will Newton 2011-01-02 116 stop = mrq->stop;
f95f3850f7a9e1 Will Newton 2011-01-02 117
f95f3850f7a9e1 Will Newton 2011-01-02 118 if (cmd)
f95f3850f7a9e1 Will Newton 2011-01-02 119 seq_printf(s,
f95f3850f7a9e1 Will Newton 2011-01-02 120 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
f95f3850f7a9e1 Will Newton 2011-01-02 121 cmd->opcode, cmd->arg, cmd->flags,
f95f3850f7a9e1 Will Newton 2011-01-02 122 cmd->resp[0], cmd->resp[1], cmd->resp[2],
f95f3850f7a9e1 Will Newton 2011-01-02 123 cmd->resp[2], cmd->error);
f95f3850f7a9e1 Will Newton 2011-01-02 124 if (data)
f95f3850f7a9e1 Will Newton 2011-01-02 125 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
f95f3850f7a9e1 Will Newton 2011-01-02 126 data->bytes_xfered, data->blocks,
f95f3850f7a9e1 Will Newton 2011-01-02 127 data->blksz, data->flags, data->error);
f95f3850f7a9e1 Will Newton 2011-01-02 128 if (stop)
f95f3850f7a9e1 Will Newton 2011-01-02 129 seq_printf(s,
f95f3850f7a9e1 Will Newton 2011-01-02 130 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
f95f3850f7a9e1 Will Newton 2011-01-02 131 stop->opcode, stop->arg, stop->flags,
f95f3850f7a9e1 Will Newton 2011-01-02 132 stop->resp[0], stop->resp[1], stop->resp[2],
f95f3850f7a9e1 Will Newton 2011-01-02 133 stop->resp[2], stop->error);
f95f3850f7a9e1 Will Newton 2011-01-02 134 }
f95f3850f7a9e1 Will Newton 2011-01-02 135
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 136 spin_unlock_bh(&host->lock);
f95f3850f7a9e1 Will Newton 2011-01-02 137
f95f3850f7a9e1 Will Newton 2011-01-02 138 return 0;
f95f3850f7a9e1 Will Newton 2011-01-02 139 }
64c1412b77d08d Shawn Lin 2018-02-23 @140 DEFINE_SHOW_ATTRIBUTE(dw_mci_req);
f95f3850f7a9e1 Will Newton 2011-01-02 141
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot
2025-11-20 10:29 ` [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot Shawn Lin
2025-11-22 18:40 ` kernel test robot
@ 2025-11-22 19:54 ` kernel test robot
1 sibling, 0 replies; 21+ messages in thread
From: kernel test robot @ 2025-11-22 19:54 UTC (permalink / raw)
To: Shawn Lin, Ulf Hansson
Cc: llvm, oe-kbuild-all, linux-mmc, Jaehoon Chung, Shawn Lin
Hi Shawn,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20251120]
[cannot apply to krzk/for-next rockchip/for-next linus/master ulf-hansson-mmc-mirror/next v6.18-rc6 v6.18-rc5 v6.18-rc4 v6.18-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Shawn-Lin/mmc-dw_mmc-Remove-unused-struct-dma_pdata/20251120-205522
base: next-20251120
patch link: https://lore.kernel.org/r/1763634565-183891-14-git-send-email-shawn.lin%40rock-chips.com
patch subject: [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot
config: loongarch-randconfig-002-20251123 (https://download.01.org/0day-ci/archive/20251123/202511230347.DmGrS3Dd-lkp@intel.com/config)
compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251123/202511230347.DmGrS3Dd-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511230347.DmGrS3Dd-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/mmc/host/dw_mmc.c:140:1: warning: unused variable 'dw_mci_req_fops' [-Wunused-const-variable]
140 | DEFINE_SHOW_ATTRIBUTE(dw_mci_req);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/seq_file.h:213:37: note: expanded from macro 'DEFINE_SHOW_ATTRIBUTE'
213 | static const struct file_operations __name ## _fops = { \
| ^~~~~~~~~~~~~~~
<scratch space>:23:1: note: expanded from here
23 | dw_mci_req_fops
| ^~~~~~~~~~~~~~~
1 warning generated.
vim +/dw_mci_req_fops +140 drivers/mmc/host/dw_mmc.c
f95f3850f7a9e1 Will Newton 2011-01-02 99
f95f3850f7a9e1 Will Newton 2011-01-02 100 #if defined(CONFIG_DEBUG_FS)
f95f3850f7a9e1 Will Newton 2011-01-02 101 static int dw_mci_req_show(struct seq_file *s, void *v)
f95f3850f7a9e1 Will Newton 2011-01-02 102 {
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 103 struct dw_mci *host = s->private;
f95f3850f7a9e1 Will Newton 2011-01-02 104 struct mmc_request *mrq;
f95f3850f7a9e1 Will Newton 2011-01-02 105 struct mmc_command *cmd;
f95f3850f7a9e1 Will Newton 2011-01-02 106 struct mmc_command *stop;
f95f3850f7a9e1 Will Newton 2011-01-02 107 struct mmc_data *data;
f95f3850f7a9e1 Will Newton 2011-01-02 108
f95f3850f7a9e1 Will Newton 2011-01-02 109 /* Make sure we get a consistent snapshot */
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 110 spin_lock_bh(&host->lock);
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 111 mrq = host->mrq;
f95f3850f7a9e1 Will Newton 2011-01-02 112
f95f3850f7a9e1 Will Newton 2011-01-02 113 if (mrq) {
f95f3850f7a9e1 Will Newton 2011-01-02 114 cmd = mrq->cmd;
f95f3850f7a9e1 Will Newton 2011-01-02 115 data = mrq->data;
f95f3850f7a9e1 Will Newton 2011-01-02 116 stop = mrq->stop;
f95f3850f7a9e1 Will Newton 2011-01-02 117
f95f3850f7a9e1 Will Newton 2011-01-02 118 if (cmd)
f95f3850f7a9e1 Will Newton 2011-01-02 119 seq_printf(s,
f95f3850f7a9e1 Will Newton 2011-01-02 120 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
f95f3850f7a9e1 Will Newton 2011-01-02 121 cmd->opcode, cmd->arg, cmd->flags,
f95f3850f7a9e1 Will Newton 2011-01-02 122 cmd->resp[0], cmd->resp[1], cmd->resp[2],
f95f3850f7a9e1 Will Newton 2011-01-02 123 cmd->resp[2], cmd->error);
f95f3850f7a9e1 Will Newton 2011-01-02 124 if (data)
f95f3850f7a9e1 Will Newton 2011-01-02 125 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
f95f3850f7a9e1 Will Newton 2011-01-02 126 data->bytes_xfered, data->blocks,
f95f3850f7a9e1 Will Newton 2011-01-02 127 data->blksz, data->flags, data->error);
f95f3850f7a9e1 Will Newton 2011-01-02 128 if (stop)
f95f3850f7a9e1 Will Newton 2011-01-02 129 seq_printf(s,
f95f3850f7a9e1 Will Newton 2011-01-02 130 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
f95f3850f7a9e1 Will Newton 2011-01-02 131 stop->opcode, stop->arg, stop->flags,
f95f3850f7a9e1 Will Newton 2011-01-02 132 stop->resp[0], stop->resp[1], stop->resp[2],
f95f3850f7a9e1 Will Newton 2011-01-02 133 stop->resp[2], stop->error);
f95f3850f7a9e1 Will Newton 2011-01-02 134 }
f95f3850f7a9e1 Will Newton 2011-01-02 135
93ac9a7f4a2ac9 Shawn Lin 2025-11-20 136 spin_unlock_bh(&host->lock);
f95f3850f7a9e1 Will Newton 2011-01-02 137
f95f3850f7a9e1 Will Newton 2011-01-02 138 return 0;
f95f3850f7a9e1 Will Newton 2011-01-02 139 }
64c1412b77d08d Shawn Lin 2018-02-23 @140 DEFINE_SHOW_ATTRIBUTE(dw_mci_req);
f95f3850f7a9e1 Will Newton 2011-01-02 141
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/13] dw_mmc cleanup
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (12 preceding siblings ...)
2025-11-20 10:29 ` [PATCH 13/13] mmc: dw_mmc: Remove struct dw_mci_slot Shawn Lin
@ 2025-11-20 11:10 ` Ulf Hansson
2025-11-20 12:51 ` Shawn Lin
2025-11-25 12:33 ` Ulf Hansson
14 siblings, 1 reply; 21+ messages in thread
From: Ulf Hansson @ 2025-11-20 11:10 UTC (permalink / raw)
To: Shawn Lin; +Cc: linux-mmc, Jaehoon Chung
On Thu, 20 Nov 2025 at 11:29, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>
> Hi Ulf & Jaehoon
>
> As you can see, dw_mmc is likely one of the most complex and difficult-to-read
> host driver at present. It maintains various states and bottom-half scheduling,
> containing a significant amount of redundant code—including a multi-slot mechanism
> that has been unsupported for over a decade.
>
> Jaehoon attempted to remove cur_slot more than ten years ago, but the driver still
> retains the slot structure and the associated queue mechanism designed to support
> multiple slots. This has made the already complex code even harder to read and maintain.
>
> The first four patches aim to eliminate some of the redundant code, while the remaining
> patches are intended to ultimately remove the dw_mci_slot variable. To facilitate review
> and minimize the risk of regression, each patch is designed to accomplish a single,
> clear objective.
>
> This series have been tested on the RK3588S EVB1 platform.
Thanks for working on this! I had something similar on my todo list
for dw_mmc for years, but never reached to actually work on it.
Anyway, I will review the code shortly.
That said, would it be possible for you to step in and help Jaehoon
with the maintenance going forward?
Kind regards
Uffe
>
>
>
> Shawn Lin (13):
> mmc: dw_mmc: Remove unused struct dma_pdata
> mmc: dw_mmc: add dw_mci_prepare_desc() for both of 32bit and 64bit DMA
> mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci
> mmc: dw_mmc: Remove unused header files and keep alphabetical order
> mmc: dw_mmc: Move struct mmc_host from struct dw_mci_slot to struct
> dw_mci
> mmc: dw_mmc: Let glue drivers to use struct dw_mci as possible
> mmc: dw_mmc: Move flags from struct dw_mci_slot to struct dw_mci
> mmc: dw_mmc: Remove id from dw_mci_slot
> mmc: dw_mmc: Remove sdio_id from struct dw_mci_slot
> mmc: dw_mmc: Move clock rate stuff from struct dw_mci_slot to struct
> dw_mci
> mmc: dw_mmc: Remove mrq from struct dw_mci_slot
> mmc: dw_mmc: Remove queue from dw_mci
> mmc: dw_mmc: Remove struct dw_mci_slot
>
> drivers/mmc/host/dw_mmc-exynos.c | 9 +-
> drivers/mmc/host/dw_mmc-hi3798cv200.c | 6 +-
> drivers/mmc/host/dw_mmc-hi3798mv200.c | 17 +-
> drivers/mmc/host/dw_mmc-k3.c | 21 +-
> drivers/mmc/host/dw_mmc-pltfm.c | 2 +-
> drivers/mmc/host/dw_mmc-rockchip.c | 9 +-
> drivers/mmc/host/dw_mmc-starfive.c | 5 +-
> drivers/mmc/host/dw_mmc.c | 606 ++++++++++++++--------------------
> drivers/mmc/host/dw_mmc.h | 83 ++---
> 9 files changed, 297 insertions(+), 461 deletions(-)
>
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 0/13] dw_mmc cleanup
2025-11-20 11:10 ` [PATCH 0/13] dw_mmc cleanup Ulf Hansson
@ 2025-11-20 12:51 ` Shawn Lin
0 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-20 12:51 UTC (permalink / raw)
To: Ulf Hansson; +Cc: shawn.lin, linux-mmc, Jaehoon Chung
在 2025/11/20 星期四 19:10, Ulf Hansson 写道:
> On Thu, 20 Nov 2025 at 11:29, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>>
>> Hi Ulf & Jaehoon
>>
>> As you can see, dw_mmc is likely one of the most complex and difficult-to-read
>> host driver at present. It maintains various states and bottom-half scheduling,
>> containing a significant amount of redundant code—including a multi-slot mechanism
>> that has been unsupported for over a decade.
>>
>> Jaehoon attempted to remove cur_slot more than ten years ago, but the driver still
>> retains the slot structure and the associated queue mechanism designed to support
>> multiple slots. This has made the already complex code even harder to read and maintain.
>>
>> The first four patches aim to eliminate some of the redundant code, while the remaining
>> patches are intended to ultimately remove the dw_mci_slot variable. To facilitate review
>> and minimize the risk of regression, each patch is designed to accomplish a single,
>> clear objective.
>>
>> This series have been tested on the RK3588S EVB1 platform.
>
> Thanks for working on this! I had something similar on my todo list
> for dw_mmc for years, but never reached to actually work on it.
> Anyway, I will review the code shortly.
Thanks for helping review it. I found patch 8,12 and 13 need to be
improved a bit after another round of self-reviewing, but they are
trival formatting issues. Will update onced get reviewed.
>
> That said, would it be possible for you to step in and help Jaehoon
> with the maintenance going forward?
>
As I do have other follow-up patches to improve this driver, it would be
good for me to keep an eye on changes of dw_mmc. So yes, I am OK
to step in and help review dw_mmc patches.
> Kind regards
> Uffe
>
>>
>>
>>
>> Shawn Lin (13):
>> mmc: dw_mmc: Remove unused struct dma_pdata
>> mmc: dw_mmc: add dw_mci_prepare_desc() for both of 32bit and 64bit DMA
>> mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci
>> mmc: dw_mmc: Remove unused header files and keep alphabetical order
>> mmc: dw_mmc: Move struct mmc_host from struct dw_mci_slot to struct
>> dw_mci
>> mmc: dw_mmc: Let glue drivers to use struct dw_mci as possible
>> mmc: dw_mmc: Move flags from struct dw_mci_slot to struct dw_mci
>> mmc: dw_mmc: Remove id from dw_mci_slot
>> mmc: dw_mmc: Remove sdio_id from struct dw_mci_slot
>> mmc: dw_mmc: Move clock rate stuff from struct dw_mci_slot to struct
>> dw_mci
>> mmc: dw_mmc: Remove mrq from struct dw_mci_slot
>> mmc: dw_mmc: Remove queue from dw_mci
>> mmc: dw_mmc: Remove struct dw_mci_slot
>>
>> drivers/mmc/host/dw_mmc-exynos.c | 9 +-
>> drivers/mmc/host/dw_mmc-hi3798cv200.c | 6 +-
>> drivers/mmc/host/dw_mmc-hi3798mv200.c | 17 +-
>> drivers/mmc/host/dw_mmc-k3.c | 21 +-
>> drivers/mmc/host/dw_mmc-pltfm.c | 2 +-
>> drivers/mmc/host/dw_mmc-rockchip.c | 9 +-
>> drivers/mmc/host/dw_mmc-starfive.c | 5 +-
>> drivers/mmc/host/dw_mmc.c | 606 ++++++++++++++--------------------
>> drivers/mmc/host/dw_mmc.h | 83 ++---
>> 9 files changed, 297 insertions(+), 461 deletions(-)
>>
>> --
>> 2.7.4
>>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/13] dw_mmc cleanup
2025-11-20 10:29 [PATCH 0/13] dw_mmc cleanup Shawn Lin
` (13 preceding siblings ...)
2025-11-20 11:10 ` [PATCH 0/13] dw_mmc cleanup Ulf Hansson
@ 2025-11-25 12:33 ` Ulf Hansson
2025-11-25 14:00 ` Shawn Lin
14 siblings, 1 reply; 21+ messages in thread
From: Ulf Hansson @ 2025-11-25 12:33 UTC (permalink / raw)
To: Shawn Lin; +Cc: linux-mmc, Jaehoon Chung
On Thu, 20 Nov 2025 at 11:29, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>
> Hi Ulf & Jaehoon
>
> As you can see, dw_mmc is likely one of the most complex and difficult-to-read
> host driver at present. It maintains various states and bottom-half scheduling,
> containing a significant amount of redundant code—including a multi-slot mechanism
> that has been unsupported for over a decade.
>
> Jaehoon attempted to remove cur_slot more than ten years ago, but the driver still
> retains the slot structure and the associated queue mechanism designed to support
> multiple slots. This has made the already complex code even harder to read and maintain.
>
> The first four patches aim to eliminate some of the redundant code, while the remaining
> patches are intended to ultimately remove the dw_mci_slot variable. To facilitate review
> and minimize the risk of regression, each patch is designed to accomplish a single,
> clear objective.
>
> This series have been tested on the RK3588S EVB1 platform.
>
>
>
> Shawn Lin (13):
> mmc: dw_mmc: Remove unused struct dma_pdata
> mmc: dw_mmc: add dw_mci_prepare_desc() for both of 32bit and 64bit DMA
> mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci
> mmc: dw_mmc: Remove unused header files and keep alphabetical order
> mmc: dw_mmc: Move struct mmc_host from struct dw_mci_slot to struct
> dw_mci
> mmc: dw_mmc: Let glue drivers to use struct dw_mci as possible
> mmc: dw_mmc: Move flags from struct dw_mci_slot to struct dw_mci
> mmc: dw_mmc: Remove id from dw_mci_slot
> mmc: dw_mmc: Remove sdio_id from struct dw_mci_slot
> mmc: dw_mmc: Move clock rate stuff from struct dw_mci_slot to struct
> dw_mci
> mmc: dw_mmc: Remove mrq from struct dw_mci_slot
> mmc: dw_mmc: Remove queue from dw_mci
> mmc: dw_mmc: Remove struct dw_mci_slot
>
> drivers/mmc/host/dw_mmc-exynos.c | 9 +-
> drivers/mmc/host/dw_mmc-hi3798cv200.c | 6 +-
> drivers/mmc/host/dw_mmc-hi3798mv200.c | 17 +-
> drivers/mmc/host/dw_mmc-k3.c | 21 +-
> drivers/mmc/host/dw_mmc-pltfm.c | 2 +-
> drivers/mmc/host/dw_mmc-rockchip.c | 9 +-
> drivers/mmc/host/dw_mmc-starfive.c | 5 +-
> drivers/mmc/host/dw_mmc.c | 606 ++++++++++++++--------------------
> drivers/mmc/host/dw_mmc.h | 83 ++---
> 9 files changed, 297 insertions(+), 461 deletions(-)
>
> --
> 2.7.4
>
I have walked through the series and overall this looks good to me,
besides the comments on patch 3 and the obvious reported build
problems.
Moreover, I would appreciate it if you could work a bit on the commit
messages. No empty commit messages please - and try to describe a bit
more on why/what each patch does.
Kind regards
Uffe
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH 0/13] dw_mmc cleanup
2025-11-25 12:33 ` Ulf Hansson
@ 2025-11-25 14:00 ` Shawn Lin
0 siblings, 0 replies; 21+ messages in thread
From: Shawn Lin @ 2025-11-25 14:00 UTC (permalink / raw)
To: Ulf Hansson; +Cc: shawn.lin, linux-mmc, Jaehoon Chung
在 2025/11/25 星期二 20:33, Ulf Hansson 写道:
> On Thu, 20 Nov 2025 at 11:29, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>>
>> Hi Ulf & Jaehoon
>>
>> As you can see, dw_mmc is likely one of the most complex and difficult-to-read
>> host driver at present. It maintains various states and bottom-half scheduling,
>> containing a significant amount of redundant code—including a multi-slot mechanism
>> that has been unsupported for over a decade.
>>
>> Jaehoon attempted to remove cur_slot more than ten years ago, but the driver still
>> retains the slot structure and the associated queue mechanism designed to support
>> multiple slots. This has made the already complex code even harder to read and maintain.
>>
>> The first four patches aim to eliminate some of the redundant code, while the remaining
>> patches are intended to ultimately remove the dw_mci_slot variable. To facilitate review
>> and minimize the risk of regression, each patch is designed to accomplish a single,
>> clear objective.
>>
>> This series have been tested on the RK3588S EVB1 platform.
>>
>>
>>
>> Shawn Lin (13):
>> mmc: dw_mmc: Remove unused struct dma_pdata
>> mmc: dw_mmc: add dw_mci_prepare_desc() for both of 32bit and 64bit DMA
>> mmc: dw_mmc: Remove vqmmc_enabled from struct dw_mci
>> mmc: dw_mmc: Remove unused header files and keep alphabetical order
>> mmc: dw_mmc: Move struct mmc_host from struct dw_mci_slot to struct
>> dw_mci
>> mmc: dw_mmc: Let glue drivers to use struct dw_mci as possible
>> mmc: dw_mmc: Move flags from struct dw_mci_slot to struct dw_mci
>> mmc: dw_mmc: Remove id from dw_mci_slot
>> mmc: dw_mmc: Remove sdio_id from struct dw_mci_slot
>> mmc: dw_mmc: Move clock rate stuff from struct dw_mci_slot to struct
>> dw_mci
>> mmc: dw_mmc: Remove mrq from struct dw_mci_slot
>> mmc: dw_mmc: Remove queue from dw_mci
>> mmc: dw_mmc: Remove struct dw_mci_slot
>>
>> drivers/mmc/host/dw_mmc-exynos.c | 9 +-
>> drivers/mmc/host/dw_mmc-hi3798cv200.c | 6 +-
>> drivers/mmc/host/dw_mmc-hi3798mv200.c | 17 +-
>> drivers/mmc/host/dw_mmc-k3.c | 21 +-
>> drivers/mmc/host/dw_mmc-pltfm.c | 2 +-
>> drivers/mmc/host/dw_mmc-rockchip.c | 9 +-
>> drivers/mmc/host/dw_mmc-starfive.c | 5 +-
>> drivers/mmc/host/dw_mmc.c | 606 ++++++++++++++--------------------
>> drivers/mmc/host/dw_mmc.h | 83 ++---
>> 9 files changed, 297 insertions(+), 461 deletions(-)
>>
>> --
>> 2.7.4
>>
>
> I have walked through the series and overall this looks good to me,
> besides the comments on patch 3 and the obvious reported build
> problems.
Yes, I have fixed them locally and will look more into your comment on
patch 3.
>
> Moreover, I would appreciate it if you could work a bit on the commit
> messages. No empty commit messages please - and try to describe a bit
> more on why/what each patch does.
Sure, will do.
>
> Kind regards
> Uffe
>
^ permalink raw reply [flat|nested] 21+ messages in thread