From 68249abd7ae8de55e59844436bcd3c8f51bdd252 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 24 Jun 2021 17:16:15 +0200 Subject: mmc: host: add kdoc for mmc_retune_{en|dis}able I wanted to use it in a wrong way, so document the intended way. Signed-off-by: Wolfram Sang Acked-by: Adrian Hunter Reviewed-by: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20210624151616.38770-3-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/host.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 0475d96047c4..913fd62c01cd 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -96,6 +96,10 @@ void mmc_unregister_host_class(void) class_unregister(&mmc_host_class); } +/** + * mmc_retune_enable() - enter a transfer mode that requires retuning + * @host: host which should retune now + */ void mmc_retune_enable(struct mmc_host *host) { host->can_retune = 1; @@ -127,6 +131,12 @@ void mmc_retune_unpause(struct mmc_host *host) } EXPORT_SYMBOL(mmc_retune_unpause); +/** + * mmc_retune_disable() - exit a transfer mode that requires retuning + * @host: host which should not retune anymore + * + * It is not meant for temporarily preventing retuning! + */ void mmc_retune_disable(struct mmc_host *host) { mmc_retune_unpause(host); -- cgit v1.2.3-70-g09d2 From 8ffb2611a752e1067c18fba39968080469394206 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 24 Jun 2021 17:16:16 +0200 Subject: mmc: host: factor out clearing the retune state We have this in two places, so let's have a dedicated function. It is also more readable. Signed-off-by: Wolfram Sang Acked-by: Adrian Hunter Reviewed-by: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20210624151616.38770-4-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/core.c | 3 +-- drivers/mmc/core/host.c | 3 +-- drivers/mmc/core/host.h | 6 ++++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 95fedcf56e4a..84f39a59a28e 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -941,8 +941,7 @@ int mmc_execute_tuning(struct mmc_card *card) pr_err("%s: tuning execution failed: %d\n", mmc_hostname(host), err); } else { - host->retune_now = 0; - host->need_retune = 0; + mmc_retune_clear(host); mmc_retune_enable(host); } diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 913fd62c01cd..d4683b1d263f 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -142,8 +142,7 @@ void mmc_retune_disable(struct mmc_host *host) mmc_retune_unpause(host); host->can_retune = 0; del_timer_sync(&host->retune_timer); - host->retune_now = 0; - host->need_retune = 0; + mmc_retune_clear(host); } void mmc_retune_timer_stop(struct mmc_host *host) diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index ba407617ed23..48c4952512a5 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -21,6 +21,12 @@ int mmc_retune(struct mmc_host *host); void mmc_retune_pause(struct mmc_host *host); void mmc_retune_unpause(struct mmc_host *host); +static inline void mmc_retune_clear(struct mmc_host *host) +{ + host->retune_now = 0; + host->need_retune = 0; +} + static inline void mmc_retune_hold_now(struct mmc_host *host) { host->retune_now = 0; -- cgit v1.2.3-70-g09d2 From c0b4e411a9b09748466ee06d2ae6772effa64dfb Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Tue, 15 Jun 2021 16:13:51 +0530 Subject: mmc: sdhci-of-arasan: Modified SD default speed to 19MHz for ZynqMP SD standard speed timing was met only at 19MHz and not 25 MHz, that's why changing driver to 19MHz. The reason for this is when a level shifter is used on the board, timing was met for standard speed only at 19MHz. Since this level shifter is commonly required for high speed modes, the driver is modified to use standard speed of 19Mhz. Signed-off-by: Manish Narani Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1623753837-21035-2-git-send-email-manish.narani@xilinx.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 0e7c07ed9690..03c80c9bb7e3 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -159,6 +159,12 @@ struct sdhci_arasan_data { /* Controller immediately reports SDHCI_CLOCK_INT_STABLE after enabling the * internal clock even when the clock isn't stable */ #define SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE BIT(1) +/* + * Some of the Arasan variations might not have timing requirements + * met at 25MHz for Default Speed mode, those controllers work at + * 19MHz instead + */ +#define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2) }; struct sdhci_arasan_of_data { @@ -290,6 +296,16 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) sdhci_arasan->is_phy_on = false; } + if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN) { + /* + * Some of the Arasan variations might not have timing + * requirements met at 25MHz for Default Speed mode, + * those controllers work at 19MHz instead. + */ + if (clock == DEFAULT_SPEED_MAX_DTR) + clock = (DEFAULT_SPEED_MAX_DTR * 19) / 25; + } + /* Set the Input and Output Clock Phase Delays */ if (clk_data->set_clk_delays) clk_data->set_clk_delays(host); @@ -1608,6 +1624,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev) if (of_device_is_compatible(np, "xlnx,zynqmp-8.9a")) { host->mmc_host_ops.execute_tuning = arasan_zynqmp_execute_tuning; + + sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN; } arasan_dt_parse_clk_phases(dev, &sdhci_arasan->clk_data); -- cgit v1.2.3-70-g09d2 From 25a916645e02123ca4d0ee8a053c198033d8e61c Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Tue, 15 Jun 2021 16:13:52 +0530 Subject: mmc: sdhci-of-arasan: Add "SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12" quirk. Arasan controller supports AUTO CMD12, this patch adds "SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12" quirk to enable auto cmd12 feature. By using auto cmd12 we can also avoid following error message "Got data interrupt even though no data operation in progress" Signed-off-by: Manish Narani Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1623753837-21035-3-git-send-email-manish.narani@xilinx.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 03c80c9bb7e3..e61dbe0cf9fe 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -1626,6 +1626,7 @@ static int sdhci_arasan_probe(struct platform_device *pdev) arasan_zynqmp_execute_tuning; sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN; + host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; } arasan_dt_parse_clk_phases(dev, &sdhci_arasan->clk_data); -- cgit v1.2.3-70-g09d2 From 256e4e4e836ce2452f6874a1612dc3e29f512143 Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Tue, 15 Jun 2021 16:13:53 +0530 Subject: mmc: sdhci-of-arasan: Skip Auto tuning for DDR50 mode in ZynqMP platform ZynqMP platform does not perform auto tuning in DDR50 mode. Skip the same while the card is operating in DDR50 mode. Signed-off-by: Manish Narani Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1623753837-21035-4-git-send-email-manish.narani@xilinx.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index e61dbe0cf9fe..0f6ef4f45825 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -894,6 +894,10 @@ static int arasan_zynqmp_execute_tuning(struct mmc_host *mmc, u32 opcode) NODE_SD_1; int err; + /* ZynqMP SD controller does not perform auto tuning in DDR50 mode */ + if (mmc->ios.timing == MMC_TIMING_UHS_DDR50) + return 0; + arasan_zynqmp_dll_reset(host, device_id); err = sdhci_execute_tuning(mmc, opcode); -- cgit v1.2.3-70-g09d2 From 66bad6ed2204fdb78a0a8fb89d824397106a5471 Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Tue, 15 Jun 2021 16:13:54 +0530 Subject: mmc: sdhci-of-arasan: Check return value of non-void funtions At a couple of places, the return values of the non-void functions were not getting checked. This was reported by the coverity tool. Modify the code to check the return values of the same. Addresses-Coverity: ("check_return") Signed-off-by: Manish Narani Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1623753837-21035-5-git-send-email-manish.narani@xilinx.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 0f6ef4f45825..ec49207ad768 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -273,7 +273,12 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) * through low speeds without power cycling. */ sdhci_set_clock(host, host->max_clk); - phy_power_on(sdhci_arasan->phy); + if (phy_power_on(sdhci_arasan->phy)) { + pr_err("%s: Cannot power on phy.\n", + mmc_hostname(host->mmc)); + return; + } + sdhci_arasan->is_phy_on = true; /* @@ -323,7 +328,12 @@ static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) msleep(20); if (ctrl_phy) { - phy_power_on(sdhci_arasan->phy); + if (phy_power_on(sdhci_arasan->phy)) { + pr_err("%s: Cannot power on phy.\n", + mmc_hostname(host->mmc)); + return; + } + sdhci_arasan->is_phy_on = true; } } @@ -479,7 +489,9 @@ static int sdhci_arasan_suspend(struct device *dev) ret = phy_power_off(sdhci_arasan->phy); if (ret) { dev_err(dev, "Cannot power off phy.\n"); - sdhci_resume_host(host); + if (sdhci_resume_host(host)) + dev_err(dev, "Cannot resume host.\n"); + return ret; } sdhci_arasan->is_phy_on = false; -- cgit v1.2.3-70-g09d2 From 462f58fdb8c0277a49c01831bf4dc8405c37ddaf Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Tue, 15 Jun 2021 16:13:55 +0530 Subject: mmc: sdhci-of-arasan: Use appropriate type of division macro The division macro DIV_ROUND_CLOSEST takes int values as the argument. However the code here uses unsigned int values for this, which is causing the values comparison with 0 as always true. We can use DIV_ROUND_CLOSEST_ULL instead for the same. Addresses-coverity: ("result_independent_of_operands") Signed-off-by: Manish Narani Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1623753837-21035-6-git-send-email-manish.narani@xilinx.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index ec49207ad768..fbcb9b070351 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -984,7 +984,7 @@ static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host) struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); const struct sdhci_arasan_soc_ctl_map *soc_ctl_map = sdhci_arasan->soc_ctl_map; - u32 mhz = DIV_ROUND_CLOSEST(clk_get_rate(pltfm_host->clk), 1000000); + u32 mhz = DIV_ROUND_CLOSEST_ULL(clk_get_rate(pltfm_host->clk), 1000000); /* Having a map is optional */ if (!soc_ctl_map) -- cgit v1.2.3-70-g09d2 From 4dd7080a78925ff293f1ded598b2010bd4ed3729 Mon Sep 17 00:00:00 2001 From: Manish Narani Date: Tue, 15 Jun 2021 16:13:56 +0530 Subject: mmc: sdhci-of-arasan: Modify data type of the clk_phase array Modify the data type of the clk_phase array to u32 to make it compatible with the argument requirement of "of_property_read_variable_u32_array". Addresses-coverity: ("incompatible_param") Signed-off-by: Manish Narani Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1623753837-21035-7-git-send-email-manish.narani@xilinx.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index fbcb9b070351..ba425b9563bf 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -1018,7 +1018,7 @@ static void arasan_dt_read_clk_phase(struct device *dev, { struct device_node *np = dev->of_node; - int clk_phase[2] = {0}; + u32 clk_phase[2] = {0}; /* * Read Tap Delay values from DT, if the DT does not contain the -- cgit v1.2.3-70-g09d2 From 5c7e468ab17fe9cc9ce94a6fdef635d5289a8095 Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Tue, 15 Jun 2021 16:13:57 +0530 Subject: mmc: arasan: Fix the issue in reading tap values from DT 'of_property_read_variable_u32_array' function returns number of elements read on success. This patch updates the condition check in the driver to overwrite the tap values from DT if exist. Signed-off-by: Sai Krishna Potthuri Signed-off-by: Manish Narani Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1623753837-21035-8-git-send-email-manish.narani@xilinx.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-arasan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index ba425b9563bf..737e2bfdedc2 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -1019,13 +1019,15 @@ static void arasan_dt_read_clk_phase(struct device *dev, struct device_node *np = dev->of_node; u32 clk_phase[2] = {0}; + int ret; /* * Read Tap Delay values from DT, if the DT does not contain the * Tap Values then use the pre-defined values. */ - if (of_property_read_variable_u32_array(np, prop, &clk_phase[0], - 2, 0)) { + ret = of_property_read_variable_u32_array(np, prop, &clk_phase[0], + 2, 0); + if (ret < 0) { dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n", prop, clk_data->clk_phase_in[timing], clk_data->clk_phase_out[timing]); -- cgit v1.2.3-70-g09d2 From 1a769fb66420289d3787272ca39ea6c204b58f5d Mon Sep 17 00:00:00 2001 From: Shaik Sajida Bhanu Date: Wed, 16 Jun 2021 14:50:07 +0530 Subject: dt-bindings: mmc: sdhci-msm: Add compatible string for sc7280 Add sc7280 SoC specific compatible strings for qcom-sdhci controller. Signed-off-by: Shaik Sajida Bhanu Acked-by: Rob Herring Link: https://lore.kernel.org/r/1623835207-29462-1-git-send-email-sbhanu@codeaurora.org Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/sdhci-msm.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt index 4c7fa6a4ed15..365c3fc122ea 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt @@ -19,6 +19,7 @@ Required properties: "qcom,msm8996-sdhci", "qcom,sdhci-msm-v4" "qcom,qcs404-sdhci", "qcom,sdhci-msm-v5" "qcom,sc7180-sdhci", "qcom,sdhci-msm-v5"; + "qcom,sc7280-sdhci", "qcom,sdhci-msm-v5"; "qcom,sdm845-sdhci", "qcom,sdhci-msm-v5" "qcom,sdx55-sdhci", "qcom,sdhci-msm-v5"; "qcom,sm8250-sdhci", "qcom,sdhci-msm-v5" -- cgit v1.2.3-70-g09d2 From 2fc2628a450901069f552ccbe170e6bc56d0458d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Jun 2021 11:57:31 +0200 Subject: mmc: renesas_sdhi_sys_dmac: use proper DMAENGINE API for termination dmaengine_terminate_all() is deprecated in favor of explicitly saying if it should be sync or async. Here, we want dmaengine_terminate_sync() because there is no other synchronization code in the driver to handle an async case. Signed-off-by: Wolfram Sang Link: https://lore.kernel.org/r/20210623095734.3046-2-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/renesas_sdhi_sys_dmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c index ffa64211f4de..6956b83469c8 100644 --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c @@ -108,9 +108,9 @@ static void renesas_sdhi_sys_dmac_abort_dma(struct tmio_mmc_host *host) renesas_sdhi_sys_dmac_enable_dma(host, false); if (host->chan_rx) - dmaengine_terminate_all(host->chan_rx); + dmaengine_terminate_sync(host->chan_rx); if (host->chan_tx) - dmaengine_terminate_all(host->chan_tx); + dmaengine_terminate_sync(host->chan_tx); renesas_sdhi_sys_dmac_enable_dma(host, true); } -- cgit v1.2.3-70-g09d2 From 492200f2479d08ac4dddd8a9d59a28b9227a0310 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Jun 2021 11:57:32 +0200 Subject: mmc: sh_mmcif: use proper DMAENGINE API for termination dmaengine_terminate_all() is deprecated in favor of explicitly saying if it should be sync or async. Here, we want dmaengine_terminate_sync() because there is no other synchronization code in the driver to handle an async case. Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20210623095734.3046-3-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sh_mmcif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index e5e457037235..bcc595c70a9f 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -1164,9 +1164,9 @@ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host) data->bytes_xfered = 0; /* Abort DMA */ if (data->flags & MMC_DATA_READ) - dmaengine_terminate_all(host->chan_rx); + dmaengine_terminate_sync(host->chan_rx); else - dmaengine_terminate_all(host->chan_tx); + dmaengine_terminate_sync(host->chan_tx); } return false; -- cgit v1.2.3-70-g09d2 From 29cef6d47b67c5408d816a6268763bf4dafcac4e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 23 Jun 2021 11:57:33 +0200 Subject: mmc: usdhi6rol0: use proper DMAENGINE API for termination dmaengine_terminate_all() is deprecated in favor of explicitly saying if it should be sync or async. Here, we want dmaengine_terminate_sync() because there is no other synchronization code in the driver to handle an async case. Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20210623095734.3046-4-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/usdhi6rol0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index b9b79b1089a0..e34a5e6d69a2 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c @@ -631,9 +631,9 @@ static void usdhi6_dma_kill(struct usdhi6_host *host) __func__, data->sg_len, data->blocks, data->blksz); /* Abort DMA */ if (data->flags & MMC_DATA_READ) - dmaengine_terminate_all(host->chan_rx); + dmaengine_terminate_sync(host->chan_rx); else - dmaengine_terminate_all(host->chan_tx); + dmaengine_terminate_sync(host->chan_tx); } static void usdhi6_dma_check_error(struct usdhi6_host *host) -- cgit v1.2.3-70-g09d2 From 575cf1046923690c1821cd33c55dc641937404cf Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 30 Jun 2021 12:24:08 +0200 Subject: mmc: mmci: De-assert reset on probe If we find a reset handle when probing the MMCI block, make sure the reset is de-asserted. It could happen that a hardware has reset asserted at boot. Cc: Russell King Cc: Yann Gautier Cc: Ludovic Barre Signed-off-by: Linus Walleij Tested-by: Yann Gautier Link: https://lore.kernel.org/r/20210630102408.3543024-1-linus.walleij@linaro.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/mmci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 984d35055156..3765e2f4ad98 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -2126,6 +2126,9 @@ static int mmci_probe(struct amba_device *dev, ret = PTR_ERR(host->rst); goto clk_disable; } + ret = reset_control_deassert(host->rst); + if (ret) + dev_err(mmc_dev(mmc), "failed to de-assert reset\n"); /* Get regulators and the supported OCR mask */ ret = mmc_regulator_get_supply(mmc); -- cgit v1.2.3-70-g09d2 From 696068470e38e4bd710c1dea5f0a2a835daf9388 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 23 Jun 2021 13:17:31 +0300 Subject: mmc: mmc_spi: Simplify busy loop in mmc_spi_skip() Infinite loops are hard to read and understand because of hidden main loop condition. Simplify such one in mmc_spi_skip(). Using schedule() to schedule (and be friendly to others) is discouraged and cond_resched() should be used instead. Hence, replace schedule() with cond_resched() at the same time. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210623101731.87885-1-andriy.shevchenko@linux.intel.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/mmc_spi.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 65c65bb5737f..a1bcde3395a6 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -180,7 +180,7 @@ static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout, u8 *cp = host->data->status; unsigned long start = jiffies; - while (1) { + do { int status; unsigned i; @@ -193,16 +193,9 @@ static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout, return cp[i]; } - if (time_is_before_jiffies(start + timeout)) - break; - - /* If we need long timeouts, we may release the CPU. - * We use jiffies here because we want to have a relation - * between elapsed time and the blocking of the scheduler. - */ - if (time_is_before_jiffies(start + 1)) - schedule(); - } + /* If we need long timeouts, we may release the CPU */ + cond_resched(); + } while (time_is_after_jiffies(start + timeout)); return -ETIMEDOUT; } -- cgit v1.2.3-70-g09d2 From 2b8ac062f33781edbefb482c6abebfde6b373eed Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Thu, 1 Jul 2021 10:05:34 +0200 Subject: mmc: dw_mmc: Add data CRC error injection This driver has had problems when handling data errors. Add fault injection support so that the abort handling can be easily triggered and regression-tested. A hrtimer is used to indicate a data CRC error at various points during the data transfer. Note that for the recent problem with hangs in the case of some data CRC errors, a udelay(10) inserted at the start of send_stop_abort() greatly helped in triggering the error, but I've not included this as part of the fault injection support since it seemed too specific. Signed-off-by: Vincent Whitchurch Reviewed-by: Jaehoon Chung Link: https://lore.kernel.org/r/20210701080534.23138-1-vincent.whitchurch@axis.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/dw_mmc.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/dw_mmc.h | 7 +++++ 2 files changed, 80 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index c3229d8c7041..29c848e25df6 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -17,9 +17,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -181,6 +183,9 @@ static void dw_mci_init_debugfs(struct dw_mci_slot *slot) &host->pending_events); debugfs_create_xul("completed_events", S_IRUSR, root, &host->completed_events); +#ifdef CONFIG_FAULT_INJECTION + fault_create_debugfs_attr("fail_data_crc", root, &host->fail_data_crc); +#endif } #endif /* defined(CONFIG_DEBUG_FS) */ @@ -1788,6 +1793,68 @@ static const struct mmc_host_ops dw_mci_ops = { .prepare_hs400_tuning = dw_mci_prepare_hs400_tuning, }; +#ifdef CONFIG_FAULT_INJECTION +static enum hrtimer_restart dw_mci_fault_timer(struct hrtimer *t) +{ + struct dw_mci *host = container_of(t, struct dw_mci, fault_timer); + unsigned long flags; + + spin_lock_irqsave(&host->irq_lock, flags); + + if (!host->data_status) + host->data_status = SDMMC_INT_DCRC; + set_bit(EVENT_DATA_ERROR, &host->pending_events); + tasklet_schedule(&host->tasklet); + + spin_unlock_irqrestore(&host->irq_lock, flags); + + return HRTIMER_NORESTART; +} + +static void dw_mci_start_fault_timer(struct dw_mci *host) +{ + struct mmc_data *data = host->data; + + if (!data || data->blocks <= 1) + return; + + if (!should_fail(&host->fail_data_crc, 1)) + return; + + /* + * Try to inject the error at random points during the data transfer. + */ + hrtimer_start(&host->fault_timer, + ms_to_ktime(prandom_u32() % 25), + HRTIMER_MODE_REL); +} + +static void dw_mci_stop_fault_timer(struct dw_mci *host) +{ + hrtimer_cancel(&host->fault_timer); +} + +static void dw_mci_init_fault(struct dw_mci *host) +{ + host->fail_data_crc = (struct fault_attr) FAULT_ATTR_INITIALIZER; + + hrtimer_init(&host->fault_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + host->fault_timer.function = dw_mci_fault_timer; +} +#else +static void dw_mci_init_fault(struct dw_mci *host) +{ +} + +static void dw_mci_start_fault_timer(struct dw_mci *host) +{ +} + +static void dw_mci_stop_fault_timer(struct dw_mci *host) +{ +} +#endif + static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) __releases(&host->lock) __acquires(&host->lock) @@ -2102,6 +2169,7 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t) break; } + dw_mci_stop_fault_timer(host); host->data = NULL; set_bit(EVENT_DATA_COMPLETE, &host->completed_events); err = dw_mci_data_complete(host, data); @@ -2151,6 +2219,7 @@ static void dw_mci_tasklet_func(struct tasklet_struct *t) if (mrq->cmd->error && mrq->data) dw_mci_reset(host); + dw_mci_stop_fault_timer(host); host->cmd = NULL; host->data = NULL; @@ -2600,6 +2669,8 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) set_bit(EVENT_CMD_COMPLETE, &host->pending_events); tasklet_schedule(&host->tasklet); + + dw_mci_start_fault_timer(host); } static void dw_mci_handle_cd(struct dw_mci *host) @@ -3223,6 +3294,8 @@ int dw_mci_probe(struct dw_mci *host) spin_lock_init(&host->irq_lock); INIT_LIST_HEAD(&host->queue); + dw_mci_init_fault(host); + /* * Get the host data width - this assumes that HCON has been set with * the correct values. diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index da5923a92e60..ce05d81477d9 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include enum dw_mci_state { @@ -230,6 +232,11 @@ struct dw_mci { struct timer_list cmd11_timer; struct timer_list cto_timer; struct timer_list dto_timer; + +#ifdef CONFIG_FAULT_INJECTION + struct fault_attr fail_data_crc; + struct hrtimer fault_timer; +#endif }; /* DMA ops for Internal/External DMAC interface */ -- cgit v1.2.3-70-g09d2 From 972d5084831dc9ae30f1a4b66cb4a19fb7ba6f09 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 2 Jul 2021 15:42:27 +0200 Subject: mmc: core: Avoid hogging the CPU while polling for busy in the I/O err path When mmc_blk_fix_state() sends a CMD12 to try to move the card into the transfer state, it calls card_busy_detect() to poll for the card's state with CMD13. This is done without any delays in between the commands being sent. Rather than fixing card_busy_detect() in this regards, let's instead convert into using the common mmc_poll_for_busy(), which also helps us to avoid open-coding. Signed-off-by: Ulf Hansson Reviewed-by: Shawn Lin Link: https://lore.kernel.org/r/20210702134229.357717-2-ulf.hansson@linaro.org --- drivers/mmc/core/block.c | 2 +- drivers/mmc/core/mmc_ops.c | 4 +++- drivers/mmc/core/mmc_ops.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index ce8aed562929..170343411f53 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1636,7 +1636,7 @@ static int mmc_blk_fix_state(struct mmc_card *card, struct request *req) mmc_blk_send_stop(card, timeout); - err = card_busy_detect(card, timeout, NULL); + err = mmc_poll_for_busy(card, timeout, false, MMC_BUSY_IO); mmc_retune_release(card->host); diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 973756ed4016..e2c431c0ce5d 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -435,7 +435,7 @@ static int mmc_busy_cb(void *cb_data, bool *busy) u32 status = 0; int err; - if (host->ops->card_busy) { + if (data->busy_cmd != MMC_BUSY_IO && host->ops->card_busy) { *busy = host->ops->card_busy(host); return 0; } @@ -457,6 +457,7 @@ static int mmc_busy_cb(void *cb_data, bool *busy) break; case MMC_BUSY_HPI: case MMC_BUSY_EXTR_SINGLE: + case MMC_BUSY_IO: break; default: err = -EINVAL; @@ -521,6 +522,7 @@ int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, return __mmc_poll_for_busy(card, timeout_ms, &mmc_busy_cb, &cb_data); } +EXPORT_SYMBOL_GPL(mmc_poll_for_busy); bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd, unsigned int timeout_ms) diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 41ab4f573a31..ae25ffc2e870 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h @@ -15,6 +15,7 @@ enum mmc_busy_cmd { MMC_BUSY_ERASE, MMC_BUSY_HPI, MMC_BUSY_EXTR_SINGLE, + MMC_BUSY_IO, }; struct mmc_host; -- cgit v1.2.3-70-g09d2 From 468108155b0f89cc08189cc33f9bacfe9da8a125 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 2 Jul 2021 15:42:28 +0200 Subject: mmc: core: Avoid hogging the CPU while polling for busy for mmc ioctls When __mmc_blk_ioctl_cmd() calls card_busy_detect() to verify that the card's states moves back into transfer state, the polling with CMD13 is done without any delays in between the commands being sent. Rather than fixing card_busy_detect() in this regards, let's instead convert into using the common mmc_poll_for_busy(), which also helps us to avoid open-coding. Signed-off-by: Ulf Hansson Reviewed-by: Shawn Lin Link: https://lore.kernel.org/r/20210702134229.357717-3-ulf.hansson@linaro.org --- drivers/mmc/core/block.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 170343411f53..c30d0ab15539 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -605,7 +605,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, * Ensure RPMB/R1B command has completed by polling CMD13 * "Send Status". */ - err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, NULL); + err = mmc_poll_for_busy(card, MMC_BLK_TIMEOUT_MS, false, + MMC_BUSY_IO); } return err; -- cgit v1.2.3-70-g09d2 From 6966e6094c6d594044ef1b740dd827e05881331c Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 2 Jul 2021 15:42:29 +0200 Subject: mmc: core: Avoid hogging the CPU while polling for busy after I/O writes When mmc_blk_card_busy() calls card_busy_detect() to poll for the card's state with CMD13, this is done without any delays in between the commands being sent. Rather than fixing card_busy_detect() in this regards, let's instead convert into using the common __mmc_poll_for_busy(), which also helps us to avoid open-coding. Signed-off-by: Ulf Hansson Reviewed-by: Shawn Lin Link: https://lore.kernel.org/r/20210702134229.357717-4-ulf.hansson@linaro.org --- drivers/mmc/core/block.c | 69 +++++++++++++++++++--------------------------- drivers/mmc/core/mmc_ops.c | 1 + 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index c30d0ab15539..a9ad9f5fa949 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -98,6 +98,11 @@ static int max_devices; static DEFINE_IDA(mmc_blk_ida); static DEFINE_IDA(mmc_rpmb_ida); +struct mmc_blk_busy_data { + struct mmc_card *card; + u32 status; +}; + /* * There is one mmc_blk_data per slot. */ @@ -417,42 +422,6 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr, return 0; } -static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, - u32 *resp_errs) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); - int err = 0; - u32 status; - - do { - bool done = time_after(jiffies, timeout); - - err = __mmc_send_status(card, &status, 5); - if (err) { - dev_err(mmc_dev(card->host), - "error %d requesting status\n", err); - return err; - } - - /* Accumulate any response error bits seen */ - if (resp_errs) - *resp_errs |= status; - - /* - * Timeout if the device never becomes ready for data and never - * leaves the program state. - */ - if (done) { - dev_err(mmc_dev(card->host), - "Card stuck in wrong state! %s status: %#x\n", - __func__, status); - return -ETIMEDOUT; - } - } while (!mmc_ready_for_data(status)); - - return err; -} - static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, struct mmc_blk_ioc_data *idata) { @@ -1852,28 +1821,48 @@ static inline bool mmc_blk_rq_error(struct mmc_blk_request *brq) brq->data.error || brq->cmd.resp[0] & CMD_ERRORS; } +static int mmc_blk_busy_cb(void *cb_data, bool *busy) +{ + struct mmc_blk_busy_data *data = cb_data; + u32 status = 0; + int err; + + err = mmc_send_status(data->card, &status); + if (err) + return err; + + /* Accumulate response error bits. */ + data->status |= status; + + *busy = !mmc_ready_for_data(status); + return 0; +} + static int mmc_blk_card_busy(struct mmc_card *card, struct request *req) { struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req); - u32 status = 0; + struct mmc_blk_busy_data cb_data; int err; if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ) return 0; - err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, &status); + cb_data.card = card; + cb_data.status = 0; + err = __mmc_poll_for_busy(card, MMC_BLK_TIMEOUT_MS, &mmc_blk_busy_cb, + &cb_data); /* * Do not assume data transferred correctly if there are any error bits * set. */ - if (status & mmc_blk_stop_err_bits(&mqrq->brq)) { + if (cb_data.status & mmc_blk_stop_err_bits(&mqrq->brq)) { mqrq->brq.data.bytes_xfered = 0; err = err ? err : -EIO; } /* Copy the exception bit so it will be seen later on */ - if (mmc_card_mmc(card) && status & R1_EXCEPTION_EVENT) + if (mmc_card_mmc(card) && cb_data.status & R1_EXCEPTION_EVENT) mqrq->brq.cmd.resp[0] |= R1_EXCEPTION_EVENT; return err; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index e2c431c0ce5d..90d213a2203f 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -510,6 +510,7 @@ int __mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, return 0; } +EXPORT_SYMBOL_GPL(__mmc_poll_for_busy); int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, bool retry_crc_err, enum mmc_busy_cmd busy_cmd) -- cgit v1.2.3-70-g09d2 From 4a11cc647d7c07388ef00f231fb07c9b01b1db5b Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 19 Jul 2021 16:34:13 -0300 Subject: mmc: sdhci-esdhc-imx: Remove unneeded mmc-esdhc-imx.h header After the i.MX conversion to a DT-only platform, the mmc-esdhc-imx.h header file is no longer used outside the driver, so move its content to the sdhci-esdhc-imx driver and remove the header. Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210719193413.3792615-1-festevam@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-esdhc-imx.c | 33 ++++++++++++++++++++++- include/linux/platform_data/mmc-esdhc-imx.h | 42 ----------------------------- 2 files changed, 32 insertions(+), 43 deletions(-) delete mode 100644 include/linux/platform_data/mmc-esdhc-imx.h diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 72c0bf0c1887..57b19ca1ad6d 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" @@ -191,6 +190,38 @@ */ #define ESDHC_FLAG_BROKEN_AUTO_CMD23 BIT(16) +enum wp_types { + ESDHC_WP_NONE, /* no WP, neither controller nor gpio */ + ESDHC_WP_CONTROLLER, /* mmc controller internal WP */ + ESDHC_WP_GPIO, /* external gpio pin for WP */ +}; + +enum cd_types { + ESDHC_CD_NONE, /* no CD, neither controller nor gpio */ + ESDHC_CD_CONTROLLER, /* mmc controller internal CD */ + ESDHC_CD_GPIO, /* external gpio pin for CD */ + ESDHC_CD_PERMANENT, /* no CD, card permanently wired to host */ +}; + +/* + * struct esdhc_platform_data - platform data for esdhc on i.MX + * + * ESDHC_WP(CD)_CONTROLLER type is not available on i.MX25/35. + * + * @wp_type: type of write_protect method (see wp_types enum above) + * @cd_type: type of card_detect method (see cd_types enum above) + */ + +struct esdhc_platform_data { + enum wp_types wp_type; + enum cd_types cd_type; + int max_bus_width; + unsigned int delay_line; + unsigned int tuning_step; /* The delay cell steps in tuning procedure */ + unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */ + unsigned int strobe_dll_delay_target; /* The delay cell for strobe pad (read clock) */ +}; + struct esdhc_soc_data { u32 flags; }; diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h deleted file mode 100644 index cba1184b364c..000000000000 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2010 Wolfram Sang - */ - -#ifndef __ASM_ARCH_IMX_ESDHC_H -#define __ASM_ARCH_IMX_ESDHC_H - -#include - -enum wp_types { - ESDHC_WP_NONE, /* no WP, neither controller nor gpio */ - ESDHC_WP_CONTROLLER, /* mmc controller internal WP */ - ESDHC_WP_GPIO, /* external gpio pin for WP */ -}; - -enum cd_types { - ESDHC_CD_NONE, /* no CD, neither controller nor gpio */ - ESDHC_CD_CONTROLLER, /* mmc controller internal CD */ - ESDHC_CD_GPIO, /* external gpio pin for CD */ - ESDHC_CD_PERMANENT, /* no CD, card permanently wired to host */ -}; - -/** - * struct esdhc_platform_data - platform data for esdhc on i.MX - * - * ESDHC_WP(CD)_CONTROLLER type is not available on i.MX25/35. - * - * @wp_type: type of write_protect method (see wp_types enum above) - * @cd_type: type of card_detect method (see cd_types enum above) - */ - -struct esdhc_platform_data { - enum wp_types wp_type; - enum cd_types cd_type; - int max_bus_width; - unsigned int delay_line; - unsigned int tuning_step; /* The delay cell steps in tuning procedure */ - unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */ - unsigned int strobe_dll_delay_target; /* The delay cell for strobe pad (read clock) */ -}; -#endif /* __ASM_ARCH_IMX_ESDHC_H */ -- cgit v1.2.3-70-g09d2 From 86c639ce08266ed521974038f0592739fec1c11a Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 21 Jul 2021 08:47:38 -0700 Subject: mmc: core: Store pointer to bio_crypt_ctx in mmc_request Make 'struct mmc_request' contain a pointer to the request's 'struct bio_crypt_ctx' directly, instead of extracting a 32-bit DUN from it which is a cqhci-crypto specific detail. This keeps the cqhci crypto specific details in the cqhci module, and it makes mmc_core and mmc_block ready for MMC crypto hardware that accepts the DUN and/or key in a way that is more flexible than that which will be specified by the eMMC v5.2 standard. Exynos SoCs are an example of such hardware, as their inline encryption hardware takes keys directly (it has no concept of keyslots) and supports 128-bit DUNs. Note that the 32-bit DUN length specified by the standard is very restrictive, so it is likely that more hardware will support longer DUNs despite it not following the standard. Thus, limiting the scope of the 32-bit DUN assumption to the place that actually needs it is warranted. Signed-off-by: Eric Biggers Link: https://lore.kernel.org/r/20210721154738.3966463-1-ebiggers@kernel.org Signed-off-by: Ulf Hansson --- drivers/mmc/core/crypto.c | 15 ++++----------- drivers/mmc/host/cqhci-crypto.h | 7 +++++-- include/linux/mmc/core.h | 3 +-- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/core/crypto.c b/drivers/mmc/core/crypto.c index 419a368f8402..67557808cada 100644 --- a/drivers/mmc/core/crypto.c +++ b/drivers/mmc/core/crypto.c @@ -31,18 +31,11 @@ void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq) struct request *req = mmc_queue_req_to_req(mqrq); struct mmc_request *mrq = &mqrq->brq.mrq; - if (!req->crypt_keyslot) + if (!req->crypt_ctx) return; - mrq->crypto_enabled = true; - mrq->crypto_key_slot = blk_ksm_get_slot_idx(req->crypt_keyslot); - - /* - * For now we assume that all MMC drivers set max_dun_bytes_supported=4, - * which is the limit for CQHCI crypto. So all DUNs should be 32-bit. - */ - WARN_ON_ONCE(req->crypt_ctx->bc_dun[0] > U32_MAX); - - mrq->data_unit_num = req->crypt_ctx->bc_dun[0]; + mrq->crypto_ctx = req->crypt_ctx; + if (req->crypt_keyslot) + mrq->crypto_key_slot = blk_ksm_get_slot_idx(req->crypt_keyslot); } EXPORT_SYMBOL_GPL(mmc_crypto_prepare_req); diff --git a/drivers/mmc/host/cqhci-crypto.h b/drivers/mmc/host/cqhci-crypto.h index 60b58ee0e625..d7fb084f563b 100644 --- a/drivers/mmc/host/cqhci-crypto.h +++ b/drivers/mmc/host/cqhci-crypto.h @@ -22,12 +22,15 @@ int cqhci_crypto_init(struct cqhci_host *host); */ static inline u64 cqhci_crypto_prep_task_desc(struct mmc_request *mrq) { - if (!mrq->crypto_enabled) + if (!mrq->crypto_ctx) return 0; + /* We set max_dun_bytes_supported=4, so all DUNs should be 32-bit. */ + WARN_ON_ONCE(mrq->crypto_ctx->bc_dun[0] > U32_MAX); + return CQHCI_CRYPTO_ENABLE_BIT | CQHCI_CRYPTO_KEYSLOT(mrq->crypto_key_slot) | - mrq->data_unit_num; + mrq->crypto_ctx->bc_dun[0]; } #else /* CONFIG_MMC_CRYPTO */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index ab19245e9945..71101d1ec825 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -164,9 +164,8 @@ struct mmc_request { int tag; #ifdef CONFIG_MMC_CRYPTO - bool crypto_enabled; + const struct bio_crypt_ctx *crypto_ctx; int crypto_key_slot; - u32 data_unit_num; #endif }; -- cgit v1.2.3-70-g09d2 From 8335928849729f8e5f10c1497c67260742f7a8cb Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 30 Jun 2021 06:16:58 +0200 Subject: mmc: core: Only print retune error when we don't check for card removal Skip printing a retune error when we scan for a removed card because we then expect a failed command. Signed-off-by: Wolfram Sang Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20210630041658.7574-1-wsa+renesas@sang-engineering.com [Ulf: Rebased patch] Signed-off-by: Ulf Hansson --- drivers/mmc/core/core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 84f39a59a28e..6249c83d616f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -936,15 +936,17 @@ int mmc_execute_tuning(struct mmc_card *card) opcode = MMC_SEND_TUNING_BLOCK; err = host->ops->execute_tuning(host, opcode); - - if (err) { - pr_err("%s: tuning execution failed: %d\n", - mmc_hostname(host), err); - } else { + if (!err) { mmc_retune_clear(host); mmc_retune_enable(host); + return 0; } + /* Only print error when we don't check for card removal */ + if (!host->detect_change) + pr_err("%s: tuning execution failed: %d\n", + mmc_hostname(host), err); + return err; } -- cgit v1.2.3-70-g09d2 From 60885bfb2a478ceb3b1b766be550eb364a595074 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 28 Jul 2021 11:32:54 +0100 Subject: memstick: ms_block: Fix spelling contraction "cant" -> "can't" There is a spelling mistake in a pr_err message. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20210728103254.171546-1-colin.king@canonical.com Signed-off-by: Ulf Hansson --- drivers/memstick/core/ms_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index 4a4573fa7b0f..acf36676e388 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c @@ -1105,7 +1105,7 @@ static u16 msb_get_free_block(struct msb_data *msb, int zone) dbg_verbose("result of the free blocks scan: pba %d", pba); if (pba == msb->block_count || (msb_get_zone_from_pba(pba)) != zone) { - pr_err("BUG: cant get a free block"); + pr_err("BUG: can't get a free block"); msb->read_only = true; return MS_BLOCK_INVALID; } -- cgit v1.2.3-70-g09d2 From 4b5e37b8fd6491b4a782cbbb8a98e5031b0bc981 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 26 Jul 2021 12:36:52 -0400 Subject: mmc: sdio: Don't warn about vendor CIS tuples CIS tuples in the range 0x80-0x8F are reserved for vendors. Some devices have tuples in this range which get warned about every boot. Since this is normal behavior, don't print these tuples unless debug is enabled. Unfortunately, we cannot use a variable for the format string since it gets pasted by pr_*_ratelimited. Signed-off-by: Sean Anderson Link: https://lore.kernel.org/r/20210726163654.1110969-1-sean.anderson@seco.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/sdio_cis.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index b23773583179..7518b27bcef2 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -330,13 +330,23 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) prev = &this->next; if (ret == -ENOENT) { + if (time_after(jiffies, timeout)) break; - /* warn about unknown tuples */ - pr_warn_ratelimited("%s: queuing unknown" - " CIS tuple 0x%02x (%u bytes)\n", - mmc_hostname(card->host), - tpl_code, tpl_link); + +#define FMT(type) "%s: queuing " type " CIS tuple 0x%02x (%u bytes)\n" + /* + * Tuples in this range are reserved for + * vendors, so don't warn about them + */ + if (tpl_code >= 0x80 && tpl_code <= 0x8f) + pr_debug_ratelimited(FMT("vendor"), + mmc_hostname(card->host), + tpl_code, tpl_link); + else + pr_warn_ratelimited(FMT("unknown"), + mmc_hostname(card->host), + tpl_code, tpl_link); } /* keep on analyzing tuples */ -- cgit v1.2.3-70-g09d2 From e285b3e064647c6b4b822ade9acb0f3ffd6b1317 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Mon, 26 Jul 2021 12:36:53 -0400 Subject: mmc: sdio: Print contents of unknown CIS tuples Print out the contents of the offending tuples when we do print them. This can make it easier to debug, since these tuples are not exposed to userspace anywhere else. We are limited to 64 bytes, so keep printing out the full length in case the tuple is truncated. Signed-off-by: Sean Anderson Link: https://lore.kernel.org/r/20210726163654.1110969-2-sean.anderson@seco.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/sdio_cis.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index 7518b27bcef2..a705ba6eff5b 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c @@ -334,7 +334,7 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) if (time_after(jiffies, timeout)) break; -#define FMT(type) "%s: queuing " type " CIS tuple 0x%02x (%u bytes)\n" +#define FMT(type) "%s: queuing " type " CIS tuple 0x%02x [%*ph] (%u bytes)\n" /* * Tuples in this range are reserved for * vendors, so don't warn about them @@ -342,11 +342,13 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func) if (tpl_code >= 0x80 && tpl_code <= 0x8f) pr_debug_ratelimited(FMT("vendor"), mmc_hostname(card->host), - tpl_code, tpl_link); + tpl_code, tpl_link, this->data, + tpl_link); else pr_warn_ratelimited(FMT("unknown"), mmc_hostname(card->host), - tpl_code, tpl_link); + tpl_code, tpl_link, this->data, + tpl_link); } /* keep on analyzing tuples */ -- cgit v1.2.3-70-g09d2 From 3ac5e45291f3f0d699a721357380d4593bc2dcb3 Mon Sep 17 00:00:00 2001 From: Thomas Hebb Date: Sun, 1 Aug 2021 04:46:14 -0700 Subject: mmc: rtsx_pci: Fix long reads when clock is prescaled For unexplained reasons, the prescaler register for this device needs to be cleared (set to 1) while performing a data read or else the command will hang. This does not appear to affect the real clock rate sent out on the bus, so I assume it's purely to work around a hardware bug. During normal operation, the prescaler is already set to 1, so nothing needs to be done. However, in "initial mode" (which is used for sub-MHz clock speeds, like the core sets while enumerating cards), it's set to 128 and so we need to reset it during data reads. We currently fail to do this for long reads. This has no functional affect on the driver's operation currently written, as the MMC core always sets a clock above 1MHz before attempting any long reads. However, the core could conceivably set any clock speed at any time and the driver should still work, so I think this fix is worthwhile. I personally encountered this issue while performing data recovery on an external chip. My connections had poor signal integrity, so I modified the core code to reduce the clock speed. Without this change, I saw the card enumerate but was unable to actually read any data. Writes don't seem to work in the situation described above even with this change (and even if the workaround is extended to encompass data write commands). I was not able to find a way to get them working. Signed-off-by: Thomas Hebb Link: https://lore.kernel.org/r/2fef280d8409ab0100c26c6ac7050227defd098d.1627818365.git.tommyhebb@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/rtsx_pci_sdmmc.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 4ca937415734..58cfaffa3c2d 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -542,9 +542,22 @@ static int sd_write_long_data(struct realtek_pci_sdmmc *host, return 0; } +static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); +} + +static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); +} + static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) { struct mmc_data *data = mrq->data; + int err; if (host->sg_count < 0) { data->error = host->sg_count; @@ -553,22 +566,19 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) return data->error; } - if (data->flags & MMC_DATA_READ) - return sd_read_long_data(host, mrq); + if (data->flags & MMC_DATA_READ) { + if (host->initial_mode) + sd_disable_initial_mode(host); - return sd_write_long_data(host, mrq); -} + err = sd_read_long_data(host, mrq); -static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); -} + if (host->initial_mode) + sd_enable_initial_mode(host); -static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); + return err; + } + + return sd_write_long_data(host, mrq); } static void sd_normal_rw(struct realtek_pci_sdmmc *host, -- cgit v1.2.3-70-g09d2 From e30314f255117f37412d41e918f941a9ae0835f3 Mon Sep 17 00:00:00 2001 From: Sarthak Garg Date: Fri, 6 Aug 2021 12:24:59 +0530 Subject: mmc: sdhci: Introduce max_timeout_count variable in sdhci_host Introduce max_timeout_count variable in the sdhci_host structure and use in timeout calculation. By default its set to 0xE (max timeout register value as per SDHC spec). But at the same time vendors drivers can update it if they support different max timeout register value than 0xE. Signed-off-by: Sarthak Garg Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1628232901-30897-2-git-send-email-sartgarg@codeaurora.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 16 +++++++++------- drivers/mmc/host/sdhci.h | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index aba6e10b8605..613e1ab6cac4 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -934,21 +934,21 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd, /* * If the host controller provides us with an incorrect timeout - * value, just skip the check and use 0xE. The hardware may take + * value, just skip the check and use the maximum. The hardware may take * longer to time out, but that's much better than having a too-short * timeout value. */ if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) - return 0xE; + return host->max_timeout_count; /* Unspecified command, asume max */ if (cmd == NULL) - return 0xE; + return host->max_timeout_count; data = cmd->data; /* Unspecified timeout, assume max */ if (!data && !cmd->busy_timeout) - return 0xE; + return host->max_timeout_count; /* timeout in us */ target_timeout = sdhci_target_timeout(host, cmd, data); @@ -968,15 +968,15 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd, while (current_timeout < target_timeout) { count++; current_timeout <<= 1; - if (count >= 0xF) + if (count > host->max_timeout_count) break; } - if (count >= 0xF) { + if (count > host->max_timeout_count) { if (!(host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT)) DBG("Too large timeout 0x%x requested for CMD%d!\n", count, cmd->opcode); - count = 0xE; + count = host->max_timeout_count; } else { *too_big = false; } @@ -3940,6 +3940,8 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, */ host->adma_table_cnt = SDHCI_MAX_SEGS * 2 + 1; + host->max_timeout_count = 0xE; + return host; } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 074dc182b184..e8d04e42a5af 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -517,6 +517,7 @@ struct sdhci_host { unsigned int max_clk; /* Max possible freq (MHz) */ unsigned int timeout_clk; /* Timeout freq (KHz) */ + u8 max_timeout_count; /* Vendor specific max timeout count */ unsigned int clk_mul; /* Clock Muliplier value */ unsigned int clock; /* Current clock (MHz) */ -- cgit v1.2.3-70-g09d2 From ed78a03d4128ac90f73332d7ac992f952916573c Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Fri, 6 Aug 2021 12:25:00 +0530 Subject: mmc: sdhci-msm: Use maximum possible data timeout value The Qcom SD controller defines the usage of 0xF in data timeout counter register (0x2E) which is actually a reserved bit as per specification. This would result in maximum of 21.26 secs timeout value. Some SDcard taking more time than 2.67secs (timeout value corresponding to 0xE) and with that observed data timeout errors. So increasing the timeout value to max possible timeout. Signed-off-by: Sahitya Tummala Signed-off-by: Sarthak Garg Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1628232901-30897-3-git-send-email-sartgarg@codeaurora.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-msm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 290a14cdc1cf..50c71e0ba5e4 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2714,6 +2714,9 @@ static int sdhci_msm_probe(struct platform_device *pdev) msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; + /* Set the timeout value to max possible */ + host->max_timeout_count = 0xF; + pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); -- cgit v1.2.3-70-g09d2 From 522654d534d315d540710124c57b49ca22ac5f72 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 10 Aug 2021 11:16:42 +0300 Subject: mmc: sdhci: Fix issue with uninitialized dma_slave_config Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures at least if external TI SDMA is ever configured for sdhci. For other external DMA cases, this is probably not currently an issue but is still good to fix though. Fixes: 18e762e3b7a7 ("mmc: sdhci: add support for using external DMA devices") Cc: Adrian Hunter Cc: Chunyan Zhang Cc: Faiz Abbas Cc: Peter Ujfalusi Cc: Vinod Koul Signed-off-by: Tony Lindgren Acked-by: Adrian Hunter Reviewed-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20210810081644.19353-1-tony@atomide.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 613e1ab6cac4..36f15f81a6af 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1222,6 +1222,7 @@ static int sdhci_external_dma_setup(struct sdhci_host *host, if (!host->mapbase) return -EINVAL; + memset(&cfg, 0, sizeof(cfg)); cfg.src_addr = host->mapbase + SDHCI_BUFFER; cfg.dst_addr = host->mapbase + SDHCI_BUFFER; cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -- cgit v1.2.3-70-g09d2 From c3ff0189d3bc9c03845fe37472c140f0fefd0c79 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 10 Aug 2021 11:16:43 +0300 Subject: mmc: dw_mmc: Fix issue with uninitialized dma_slave_config Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures. For dw_mmc, this is probably not currently an issue but is still good to fix though. Fixes: 3fc7eaef44db ("mmc: dw_mmc: Add external dma interface support") Cc: Shawn Lin Cc: Jaehoon Chung Cc: Peter Ujfalusi Cc: Vinod Koul Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210810081644.19353-2-tony@atomide.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/dw_mmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 29c848e25df6..6578cc64ae9e 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -787,6 +787,7 @@ static int dw_mci_edmac_start_dma(struct dw_mci *host, int ret = 0; /* Set external dma config: burst size, burst width */ + memset(&cfg, 0, sizeof(cfg)); cfg.dst_addr = host->phy_regs + fifo_offset; cfg.src_addr = cfg.dst_addr; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -- cgit v1.2.3-70-g09d2 From ee5165354d498e5bceb0b386e480ac84c5f8c28c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 10 Aug 2021 11:16:44 +0300 Subject: mmc: moxart: Fix issue with uninitialized dma_slave_config Depending on the DMA driver being used, the struct dma_slave_config may need to be initialized to zero for the unused data. For example, we have three DMA drivers using src_port_window_size and dst_port_window_size. If these are left uninitialized, it can cause DMA failures. For moxart, this is probably not currently an issue but is still good to fix though. Fixes: 1b66e94e6b99 ("mmc: moxart: Add MOXA ART SD/MMC driver") Cc: Jonas Jensen Cc: Vinod Koul Cc: Peter Ujfalusi Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210810081644.19353-3-tony@atomide.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/moxart-mmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index bde298887579..6c9d38132f74 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.c @@ -628,6 +628,7 @@ static int moxart_probe(struct platform_device *pdev) host->dma_chan_tx, host->dma_chan_rx); host->have_dma = true; + memset(&cfg, 0, sizeof(cfg)); cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -- cgit v1.2.3-70-g09d2 From 71b7597c63d2ddf6d7e5eb01319f9611af437a7b Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 29 Jul 2021 19:32:34 +0900 Subject: mmc: renesas_sdhi: Refactor renesas_sdhi_probe() Refactor renesas_sdhi_probe() to avoid increasing numbers of sdhi_quirks_match[] entry when we add other stable SoCs like r8a779m*. Note that the sdhi_quirks_match[] is only needed on renesas_sdhi_internal_dmac.c so that of_data of renesas_sdhi_sys_dmac.c keeps as-is. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang Tested-by: Wolfram Sang Link: https://lore.kernel.org/r/20210729103234.480743-1-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/renesas_sdhi.h | 9 +- drivers/mmc/host/renesas_sdhi_core.c | 90 +---------------- drivers/mmc/host/renesas_sdhi_internal_dmac.c | 135 ++++++++++++++++++++++++-- drivers/mmc/host/renesas_sdhi_sys_dmac.c | 3 +- 4 files changed, 141 insertions(+), 96 deletions(-) diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h index 53eded81a53e..0c45e82ff0de 100644 --- a/drivers/mmc/host/renesas_sdhi.h +++ b/drivers/mmc/host/renesas_sdhi.h @@ -42,6 +42,11 @@ struct renesas_sdhi_quirks { const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX]; }; +struct renesas_sdhi_of_data_with_quirks { + const struct renesas_sdhi_of_data *of_data; + const struct renesas_sdhi_quirks *quirks; +}; + struct tmio_mmc_dma { enum dma_slave_buswidth dma_buswidth; bool (*filter)(struct dma_chan *chan, void *arg); @@ -78,6 +83,8 @@ struct renesas_sdhi { container_of((host)->pdata, struct renesas_sdhi, mmc_data) int renesas_sdhi_probe(struct platform_device *pdev, - const struct tmio_mmc_dma_ops *dma_ops); + const struct tmio_mmc_dma_ops *dma_ops, + const struct renesas_sdhi_of_data *of_data, + const struct renesas_sdhi_quirks *quirks); int renesas_sdhi_remove(struct platform_device *pdev); #endif diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index e49ca0f7fe9a..6fc4cf3c9dce 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -305,27 +305,6 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc, #define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK 0x1f #define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE BIT(7) -static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = { - { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15, - 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11, - 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 } -}; - -static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = { - { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 }, - { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 } -}; - -static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10, - 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 } -}; - static inline u32 sd_scc_read32(struct tmio_mmc_host *host, struct renesas_sdhi *priv, int addr) { @@ -895,69 +874,12 @@ static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable) renesas_sdhi_sdbuf_width(host, enable ? width : 16); } -static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = { - .hs400_disabled = true, - .hs400_4taps = true, -}; - -static const struct renesas_sdhi_quirks sdhi_quirks_4tap = { - .hs400_4taps = true, - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), -}; - -static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = { - .hs400_disabled = true, -}; - -static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = { - .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7), -}; - -static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = { - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), -}; - -static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = { - .hs400_4taps = true, - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), - .hs400_calib_table = r8a7796_es13_calib_table, -}; - -static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = { - .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), - .hs400_calib_table = r8a77965_calib_table, -}; - -static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = { - .hs400_calib_table = r8a77990_calib_table, -}; - -/* - * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now. - * So, we want to treat them equally and only have a match for ES1.2 to enforce - * this if there ever will be a way to distinguish ES1.2. - */ -static const struct soc_device_attribute sdhi_quirks_match[] = { - { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, - { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 }, - { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, - { .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 }, - { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, - { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 }, - { .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 }, - { .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 }, - { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 }, - { .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 }, - { /* Sentinel. */ }, -}; - int renesas_sdhi_probe(struct platform_device *pdev, - const struct tmio_mmc_dma_ops *dma_ops) + const struct tmio_mmc_dma_ops *dma_ops, + const struct renesas_sdhi_of_data *of_data, + const struct renesas_sdhi_quirks *quirks) { struct tmio_mmc_data *mmd = pdev->dev.platform_data; - const struct renesas_sdhi_quirks *quirks = NULL; - const struct renesas_sdhi_of_data *of_data; - const struct soc_device_attribute *attr; struct tmio_mmc_data *mmc_data; struct tmio_mmc_dma *dma_priv; struct tmio_mmc_host *host; @@ -966,12 +888,6 @@ int renesas_sdhi_probe(struct platform_device *pdev, struct resource *res; u16 ver; - of_data = of_device_get_match_data(&pdev->dev); - - attr = soc_device_match(sdhi_quirks_match); - if (attr) - quirks = attr->data; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -EINVAL; diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index e8f4863d8f1a..7660f7ea74dd 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -92,7 +93,7 @@ static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = { }, }; -static const struct renesas_sdhi_of_data of_rza2_compatible = { +static const struct renesas_sdhi_of_data of_data_rza2 = { .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL | TMIO_MMC_HAVE_CBSY, .tmio_ocr_mask = MMC_VDD_32_33, @@ -107,7 +108,11 @@ static const struct renesas_sdhi_of_data of_rza2_compatible = { .max_segs = 1, }; -static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { +static const struct renesas_sdhi_of_data_with_quirks of_rza2_compatible = { + .of_data = &of_data_rza2, +}; + +static const struct renesas_sdhi_of_data of_data_rcar_gen3 = { .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | @@ -122,11 +127,116 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { .max_segs = 1, }; +static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = { + { 3, 3, 3, 3, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 15, + 16, 16, 16, 16, 16, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 11, + 12, 17, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, 22, 23, 25, 25 } +}; + +static const u8 r8a77965_calib_table[2][SDHI_CALIB_TABLE_MAX] = { + { 1, 2, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31 }, + { 2, 3, 4, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 17, 17, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 31, 31, 31 } +}; + +static const u8 r8a77990_calib_table[2][SDHI_CALIB_TABLE_MAX] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 1, 2, 3, 3, 4, 4, 4, 5, 5, 6, 8, 9, 10, + 11, 12, 13, 15, 16, 17, 17, 18, 18, 19, 20, 22, 24, 25, 26, 26 } +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400 = { + .hs400_disabled = true, + .hs400_4taps = true, +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_4tap = { + .hs400_4taps = true, + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = { + .hs400_disabled = true, +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps1357 = { + .hs400_bad_taps = BIT(1) | BIT(3) | BIT(5) | BIT(7), +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_bad_taps2367 = { + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_r8a7796_es13 = { + .hs400_4taps = true, + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), + .hs400_calib_table = r8a7796_es13_calib_table, +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_r8a77965 = { + .hs400_bad_taps = BIT(2) | BIT(3) | BIT(6) | BIT(7), + .hs400_calib_table = r8a77965_calib_table, +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_r8a77990 = { + .hs400_calib_table = r8a77990_calib_table, +}; + +/* + * Note for r8a7796 / r8a774a1: we can't distinguish ES1.1 and 1.2 as of now. + * So, we want to treat them equally and only have a match for ES1.2 to enforce + * this if there ever will be a way to distinguish ES1.2. + */ +static const struct soc_device_attribute sdhi_quirks_match[] = { + { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, + { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 }, + { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, + { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, + { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 }, + { /* Sentinel. */ }, +}; + +static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = { + .of_data = &of_data_rcar_gen3, + .quirks = &sdhi_quirks_bad_taps2367, +}; + +static const struct renesas_sdhi_of_data_with_quirks of_r8a77961_compatible = { + .of_data = &of_data_rcar_gen3, + .quirks = &sdhi_quirks_bad_taps1357, +}; + +static const struct renesas_sdhi_of_data_with_quirks of_r8a77965_compatible = { + .of_data = &of_data_rcar_gen3, + .quirks = &sdhi_quirks_r8a77965, +}; + +static const struct renesas_sdhi_of_data_with_quirks of_r8a77980_compatible = { + .of_data = &of_data_rcar_gen3, + .quirks = &sdhi_quirks_nohs400, +}; + +static const struct renesas_sdhi_of_data_with_quirks of_r8a77990_compatible = { + .of_data = &of_data_rcar_gen3, + .quirks = &sdhi_quirks_r8a77990, +}; + +static const struct renesas_sdhi_of_data_with_quirks of_rcar_gen3_compatible = { + .of_data = &of_data_rcar_gen3, +}; + static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = { { .compatible = "renesas,sdhi-r7s9210", .data = &of_rza2_compatible, }, { .compatible = "renesas,sdhi-mmc-r8a77470", .data = &of_rcar_gen3_compatible, }, - { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, }, + { .compatible = "renesas,sdhi-r8a7795", .data = &of_r8a7795_compatible, }, { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, }, + { .compatible = "renesas,sdhi-r8a77961", .data = &of_r8a77961_compatible, }, + { .compatible = "renesas,sdhi-r8a77965", .data = &of_r8a77965_compatible, }, + { .compatible = "renesas,sdhi-r8a77980", .data = &of_r8a77980_compatible, }, + { .compatible = "renesas,sdhi-r8a77990", .data = &of_r8a77990_compatible, }, { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, }, {}, }; @@ -405,16 +515,27 @@ static const struct soc_device_attribute soc_dma_quirks[] = { static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev) { - const struct soc_device_attribute *soc = soc_device_match(soc_dma_quirks); + const struct soc_device_attribute *attr; + const struct renesas_sdhi_of_data_with_quirks *of_data_quirks; + const struct renesas_sdhi_quirks *quirks; struct device *dev = &pdev->dev; - if (soc) - global_flags |= (unsigned long)soc->data; + of_data_quirks = of_device_get_match_data(&pdev->dev); + quirks = of_data_quirks->quirks; + + attr = soc_device_match(soc_dma_quirks); + if (attr) + global_flags |= (unsigned long)attr->data; + + attr = soc_device_match(sdhi_quirks_match); + if (attr) + quirks = attr->data; /* value is max of SD_SECCNT. Confirmed by HW engineers */ dma_set_max_seg_size(dev, 0xffffffff); - return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops); + return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops, + of_data_quirks->of_data, quirks); } static const struct dev_pm_ops renesas_sdhi_internal_dmac_dev_pm_ops = { diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c index 6956b83469c8..99e3426df702 100644 --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c @@ -451,7 +451,8 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_sys_dmac_dma_ops = { static int renesas_sdhi_sys_dmac_probe(struct platform_device *pdev) { - return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops); + return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops, + of_device_get_match_data(&pdev->dev), NULL); } static const struct dev_pm_ops renesas_sdhi_sys_dmac_dev_pm_ops = { -- cgit v1.2.3-70-g09d2 From f4ff24f8a7c144e6d2107a2f2d16bcd9e2b2578f Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Fri, 13 Aug 2021 20:34:01 +0800 Subject: mmc: sdhci: Correct the tuning command handle for PIO mode If sdhci use PIO mode, and use mmc_send_tuning() to send the tuning command, system will stuck because of the storm irq of sdhci. For PIO mode, use mmc_send_tuning(), it will trigger buffer_read_ready interrupt and data transfer complete interrupt. In current code logic, it will directly return in sdhci_data_irq, can not call the sdhci_transfer_pio(). So the buffer_read_ready interrupt storm happen. So for standard tuning method, need to exclude this case. Signed-off-by: Haibo Chen Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1628858041-1911-1-git-send-email-haibo.chen@nxp.com [Ulf: Dropped redundant parenthesis in an expression] Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 36f15f81a6af..8eefa7d5fe85 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3279,8 +3279,14 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) { u32 command; - /* CMD19 generates _only_ Buffer Read Ready interrupt */ - if (intmask & SDHCI_INT_DATA_AVAIL) { + /* + * CMD19 generates _only_ Buffer Read Ready interrupt if + * use sdhci_send_tuning. + * Need to exclude this case: PIO mode and use mmc_send_tuning, + * If not, sdhci_transfer_pio will never be called, make the + * SDHCI_INT_DATA_AVAIL always there, stuck in irq storm. + */ + if (intmask & SDHCI_INT_DATA_AVAIL && !host->data) { command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)); if (command == MMC_SEND_TUNING_BLOCK || command == MMC_SEND_TUNING_BLOCK_HS200) { -- cgit v1.2.3-70-g09d2 From 4850c225dd0e82c8aff8fe4bddc183c37551ede9 Mon Sep 17 00:00:00 2001 From: Mårten Lindahl Date: Mon, 16 Aug 2021 16:23:14 +0200 Subject: mmc: usdhi6rol0: Implement card_busy function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When switching card voltage to UHS voltage the mmc framework tries to check the card busy signal, meaning the card pulling DAT0 line low, before the switch is made. Drivers that does not implement the card_busy function will manage to do the switch anyway, but the framework will print a warning about not being able to verify the voltage signal. Implement card_busy function. Signed-off-by: Mårten Lindahl Link: https://lore.kernel.org/r/20210816142314.1168-1-marten.lindahl@axis.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/usdhi6rol0.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index e34a5e6d69a2..99515be6e5e5 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c @@ -1186,6 +1186,15 @@ static int usdhi6_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) return ret; } +static int usdhi6_card_busy(struct mmc_host *mmc) +{ + struct usdhi6_host *host = mmc_priv(mmc); + u32 tmp = usdhi6_read(host, USDHI6_SD_INFO2); + + /* Card is busy if it is pulling dat[0] low */ + return !(tmp & USDHI6_SD_INFO2_SDDAT0); +} + static const struct mmc_host_ops usdhi6_ops = { .request = usdhi6_request, .set_ios = usdhi6_set_ios, @@ -1193,6 +1202,7 @@ static const struct mmc_host_ops usdhi6_ops = { .get_ro = usdhi6_get_ro, .enable_sdio_irq = usdhi6_enable_sdio_irq, .start_signal_voltage_switch = usdhi6_sig_volt_switch, + .card_busy = usdhi6_card_busy, }; /* State machine handlers */ -- cgit v1.2.3-70-g09d2 From 291ee9d5da535f8c72408850a413074c4719c8d3 Mon Sep 17 00:00:00 2001 From: Mårten Lindahl Date: Mon, 16 Aug 2021 17:30:54 +0200 Subject: mmc: core: Update ->card_busy() callback comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to SD specification checking state of DAT0 only, is enough while polling for card busy completion. Let's update the comment in the header file to correct this, as the comment says DAT[0:3]. Signed-off-by: Mårten Lindahl Link: https://lore.kernel.org/r/20210816153054.24082-1-marten.lindahl@axis.com Signed-off-by: Ulf Hansson --- include/linux/mmc/host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0abd47e9ef9b..ff1a251bb0bc 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -153,7 +153,7 @@ struct mmc_host_ops { int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios); - /* Check if the card is pulling dat[0:3] low */ + /* Check if the card is pulling dat[0] low */ int (*card_busy)(struct mmc_host *host); /* The tuning command opcode value is different for SD and eMMC cards */ -- cgit v1.2.3-70-g09d2 From 4aba5dc71eae041aa1a9240de10ad2e30e9f32dd Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 17 Aug 2021 10:03:12 +0100 Subject: dt-bindings: mmc: renesas,sdhi: Fix dtbs-check warning Fix dtbs-check warning pinctrl-names:0:'default' was expected for r8a77470-iwg23s-sbc.dts file. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210817090313.31858-2-biju.das.jz@bp.renesas.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/renesas,sdhi.yaml | 60 +++++++++++++--------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml index 677989bc5924..43584f4f4c7e 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml +++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml @@ -9,9 +9,6 @@ title: Renesas SDHI SD/MMC controller maintainers: - Wolfram Sang -allOf: - - $ref: "mmc-controller.yaml" - properties: compatible: oneOf: @@ -104,14 +101,46 @@ properties: pinctrl-1: maxItems: 1 - pinctrl-names: - minItems: 1 - items: - - const: default - - const: state_uhs + pinctrl-names: true max-frequency: true +allOf: + - $ref: "mmc-controller.yaml" + + - if: + properties: + compatible: + contains: + const: renesas,sdhi-mmc-r8a77470 + then: + properties: + pinctrl-names: + items: + - const: state_uhs + else: + properties: + pinctrl-names: + minItems: 1 + items: + - const: default + - const: state_uhs + + - if: + properties: + compatible: + contains: + enum: + - renesas,sdhi-r7s72100 + - renesas,sdhi-r7s9210 + then: + required: + - clock-names + description: + The internal card detection logic that exists in these controllers is + sectioned off to be run by a separate second clock source to allow + the main core clock to be turned off to save power. + required: - compatible - reg @@ -119,21 +148,6 @@ required: - clocks - power-domains -if: - properties: - compatible: - contains: - enum: - - renesas,sdhi-r7s72100 - - renesas,sdhi-r7s9210 -then: - required: - - clock-names - description: - The internal card detection logic that exists in these controllers is - sectioned off to be run by a separate second clock source to allow - the main core clock to be turned off to save power. - unevaluatedProperties: false examples: -- cgit v1.2.3-70-g09d2 From bfadee4554c3782bfbc5943866bd2ad44d631e50 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 17 Aug 2021 10:03:13 +0100 Subject: dt-bindings: mmc: renesas,sdhi: Document RZ/G2L bindings Document RZ/G2L SDHI controller bindings. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210817090313.31858-3-biju.das.jz@bp.renesas.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/renesas,sdhi.yaml | 73 +++++++++++++++------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml index 43584f4f4c7e..9f1e7092cf44 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml +++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml @@ -44,19 +44,20 @@ properties: - const: renesas,sdhi-mmc-r8a77470 # RZ/G1C (SDHI/MMC IP) - items: - enum: - - renesas,sdhi-r8a774a1 # RZ/G2M - - renesas,sdhi-r8a774b1 # RZ/G2N - - renesas,sdhi-r8a774c0 # RZ/G2E - - renesas,sdhi-r8a774e1 # RZ/G2H - - renesas,sdhi-r8a7795 # R-Car H3 - - renesas,sdhi-r8a7796 # R-Car M3-W - - renesas,sdhi-r8a77961 # R-Car M3-W+ - - renesas,sdhi-r8a77965 # R-Car M3-N - - renesas,sdhi-r8a77970 # R-Car V3M - - renesas,sdhi-r8a77980 # R-Car V3H - - renesas,sdhi-r8a77990 # R-Car E3 - - renesas,sdhi-r8a77995 # R-Car D3 - - renesas,sdhi-r8a779a0 # R-Car V3U + - renesas,sdhi-r8a774a1 # RZ/G2M + - renesas,sdhi-r8a774b1 # RZ/G2N + - renesas,sdhi-r8a774c0 # RZ/G2E + - renesas,sdhi-r8a774e1 # RZ/G2H + - renesas,sdhi-r8a7795 # R-Car H3 + - renesas,sdhi-r8a7796 # R-Car M3-W + - renesas,sdhi-r8a77961 # R-Car M3-W+ + - renesas,sdhi-r8a77965 # R-Car M3-N + - renesas,sdhi-r8a77970 # R-Car V3M + - renesas,sdhi-r8a77980 # R-Car V3H + - renesas,sdhi-r8a77990 # R-Car E3 + - renesas,sdhi-r8a77995 # R-Car D3 + - renesas,sdhi-r8a779a0 # R-Car V3U + - renesas,sdhi-r9a07g044 # RZ/G2{L,LC} - const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2 reg: @@ -66,15 +67,9 @@ properties: minItems: 1 maxItems: 3 - clocks: - minItems: 1 - maxItems: 2 + clocks: true - clock-names: - minItems: 1 - items: - - const: core - - const: cd + clock-names: true dmas: minItems: 4 @@ -108,6 +103,42 @@ properties: allOf: - $ref: "mmc-controller.yaml" + - if: + properties: + compatible: + contains: + const: renesas,sdhi-r9a07g044 + then: + properties: + clocks: + items: + - description: IMCLK, SDHI channel main clock1. + - description: IMCLK2, SDHI channel main clock2. When this clock is + turned off, external SD card detection cannot be + detected. + - description: CLK_HS, SDHI channel High speed clock which operates + 4 times that of SDHI channel main clock1. + - description: ACLK, SDHI channel bus clock. + clock-names: + items: + - const: imclk + - const: imclk2 + - const: clk_hs + - const: aclk + required: + - clock-names + - resets + else: + properties: + clocks: + minItems: 1 + maxItems: 2 + clock-names: + minItems: 1 + items: + - const: core + - const: cd + - if: properties: compatible: -- cgit v1.2.3-70-g09d2 From 3f6e276270de935296caea6fb10a545f7388478b Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Wed, 18 Aug 2021 17:17:57 +0800 Subject: dt-bindings: mmc: fsl-imx-esdhc: add a new compatible string Lack a compatible string "fsl,imx6sll-usdhc", so add it here. Signed-off-by: Haibo Chen Acked-by: Rob Herring Link: https://lore.kernel.org/r/1629278277-7313-1-git-send-email-haibo.chen@nxp.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml index b5baf439fbac..17086f60f8a3 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml @@ -29,6 +29,7 @@ properties: - fsl,imx53-esdhc - fsl,imx6q-usdhc - fsl,imx6sl-usdhc + - fsl,imx6sll-usdhc - fsl,imx6sx-usdhc - fsl,imx6ull-usdhc - fsl,imx7d-usdhc -- cgit v1.2.3-70-g09d2 From 4bdda3db47db079b9b487ea05fd6ca7dbd71c4e7 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Thu, 19 Aug 2021 19:52:18 +0800 Subject: dt-bindings: mmc: fsl-imx-esdhc: change the pinctrl-names rule Change the pinctrl-names rule to cover all cases. Signed-off-by: Haibo Chen Acked-by: Rob Herring Link: https://lore.kernel.org/r/1629373938-9226-1-git-send-email-haibo.chen@nxp.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml index 17086f60f8a3..a3412f221104 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml @@ -116,12 +116,17 @@ properties: - const: per pinctrl-names: - minItems: 1 - items: - - const: default - - const: state_100mhz - - const: state_200mhz - - const: sleep + oneOf: + - minItems: 3 + items: + - const: default + - const: state_100mhz + - const: state_200mhz + - const: sleep + - minItems: 1 + items: + - const: default + - const: sleep required: - compatible -- cgit v1.2.3-70-g09d2 From 2c2eaf882f7b4d8bb9a68856eae9cb0b7d77f371 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 20 Aug 2021 12:28:00 +0300 Subject: dt-bindings: mmc: Extend pwrseq-sd8787 binding for wilc1000 Extend the DT bindings to support wilc1000 devices. Signed-off-by: Claudiu Beznea Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210820092803.78523-2-claudiu.beznea@microchip.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml index e0169a285aa2..9e2396751030 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.yaml @@ -11,7 +11,9 @@ maintainers: properties: compatible: - const: mmc-pwrseq-sd8787 + enum: + - mmc-pwrseq-sd8787 + - mmc-pwrseq-wilc1000 powerdown-gpios: minItems: 1 -- cgit v1.2.3-70-g09d2 From b2832b96fcf50270d69dae3f95bf14949ff638e4 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 20 Aug 2021 12:28:01 +0300 Subject: mmc: pwrseq: sd8787: add support for wilc1000 Add new compatible for wilc1000 devices and specify the delay in .data member of struct of_device_id. WILC1000, WILC3000 devices needs a minimum of 5ms delay b/w reset and power lines. Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20210820092803.78523-3-claudiu.beznea@microchip.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/pwrseq_sd8787.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c index 68a826f1c0a1..264e48067af2 100644 --- a/drivers/mmc/core/pwrseq_sd8787.c +++ b/drivers/mmc/core/pwrseq_sd8787.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ struct mmc_pwrseq_sd8787 { struct mmc_pwrseq pwrseq; struct gpio_desc *reset_gpio; struct gpio_desc *pwrdn_gpio; + u32 reset_pwrdwn_delay_ms; }; #define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq) @@ -37,7 +39,7 @@ static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host) gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); - msleep(300); + msleep(pwrseq->reset_pwrdwn_delay_ms); gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1); } @@ -55,7 +57,8 @@ static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = { }; static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = { - { .compatible = "mmc-pwrseq-sd8787",}, + { .compatible = "mmc-pwrseq-sd8787", .data = (void *)300 }, + { .compatible = "mmc-pwrseq-wilc1000", .data = (void *)5 }, {/* sentinel */}, }; MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match); @@ -64,11 +67,15 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev) { struct mmc_pwrseq_sd8787 *pwrseq; struct device *dev = &pdev->dev; + const struct of_device_id *match; pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); if (!pwrseq) return -ENOMEM; + match = of_match_node(mmc_pwrseq_sd8787_of_match, pdev->dev.of_node); + pwrseq->reset_pwrdwn_delay_ms = (u32)match->data; + pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); if (IS_ERR(pwrseq->pwrdn_gpio)) return PTR_ERR(pwrseq->pwrdn_gpio); -- cgit v1.2.3-70-g09d2 From 09cedbd8dbc057c07885cfacdcdb09ef4880c5cb Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Fri, 20 Aug 2021 12:28:02 +0300 Subject: mmc: pwrseq: add wilc1000_sdio dependency for pwrseq_sd8787 pwseq_sd8787 could also be used with wilc1000_sdio driver. Add a dependency for this. Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20210820092803.78523-4-claudiu.beznea@microchip.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index ae8b69aee619..6f25c34e4fec 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -15,7 +15,7 @@ config PWRSEQ_EMMC config PWRSEQ_SD8787 tristate "HW reset support for SD8787 BT + Wifi module" - depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO) + depends on OF && (MWIFIEX || BT_MRVL_SDIO || LIBERTAS_SDIO || WILC1000_SDIO) help This selects hardware reset support for the SD8787 BT + Wifi module. By default this option is set to n. -- cgit v1.2.3-70-g09d2 From 2b50c81fb7284d9122b98e8227cd8c6495238bd6 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 21 Aug 2021 23:17:15 +0200 Subject: memstick: r592: Change the name of the 'pci_driver' structure to be consistent This driver is all about r592. Axe the reference to r852 in the 'pci_driver' structure name. This is likely a copy/paste typo left as is when the driver has been created. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/258f76acc73d5c448b9cb5dab4c39d80d517c7a9.1629580585.git.christophe.jaillet@wanadoo.fr Signed-off-by: Ulf Hansson --- drivers/memstick/host/r592.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 615a83782e55..3515246dfd12 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -877,7 +877,7 @@ static SIMPLE_DEV_PM_OPS(r592_pm_ops, r592_suspend, r592_resume); MODULE_DEVICE_TABLE(pci, r592_pci_id_tbl); -static struct pci_driver r852_pci_driver = { +static struct pci_driver r592_pci_driver = { .name = DRV_NAME, .id_table = r592_pci_id_tbl, .probe = r592_probe, @@ -885,7 +885,7 @@ static struct pci_driver r852_pci_driver = { .driver.pm = &r592_pm_ops, }; -module_pci_driver(r852_pci_driver); +module_pci_driver(r592_pci_driver); module_param_named(enable_dma, r592_enable_dma, bool, S_IRUGO); MODULE_PARM_DESC(enable_dma, "Enable usage of the DMA (default)"); -- cgit v1.2.3-70-g09d2 From 89d74b30f44371c2fc388f7fb172a583977ef0d8 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 21 Aug 2021 23:13:07 +0200 Subject: memstick: switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below. It has been compile tested. No memory allocation in involved in this patch, so no GFP_ tweak is needed. @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/f6fe24f2372c8c627a08ace7187bfe60d35788b6.1629580314.git.christophe.jaillet@wanadoo.fr Signed-off-by: Ulf Hansson --- drivers/memstick/host/r592.c | 5 ++--- drivers/memstick/host/tifm_ms.c | 12 ++++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 3515246dfd12..e79a0218c492 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -293,7 +293,7 @@ static int r592_transfer_fifo_dma(struct r592_device *dev) /* TODO: hidden assumption about nenth beeing always 1 */ sg_count = dma_map_sg(&dev->pci_dev->dev, &dev->req->sg, 1, is_write ? - PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + DMA_TO_DEVICE : DMA_FROM_DEVICE); if (sg_count != 1 || sg_dma_len(&dev->req->sg) < R592_LFIFO_SIZE) { message("problem in dma_map_sg"); @@ -310,8 +310,7 @@ static int r592_transfer_fifo_dma(struct r592_device *dev) } dma_unmap_sg(&dev->pci_dev->dev, &dev->req->sg, 1, is_write ? - PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - + DMA_TO_DEVICE : DMA_FROM_DEVICE); return dev->dma_error; } diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 57145374f6ac..c272453670be 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c @@ -279,8 +279,8 @@ static int tifm_ms_issue_cmd(struct tifm_ms *host) if (host->use_dma) { if (1 != tifm_map_sg(sock, &host->req->sg, 1, host->req->data_dir == READ - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE)) { + ? DMA_FROM_DEVICE + : DMA_TO_DEVICE)) { host->req->error = -ENOMEM; return host->req->error; } @@ -350,8 +350,8 @@ static void tifm_ms_complete_cmd(struct tifm_ms *host) if (host->use_dma) { tifm_unmap_sg(sock, &host->req->sg, 1, host->req->data_dir == READ - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE); + ? DMA_FROM_DEVICE + : DMA_TO_DEVICE); } writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), @@ -607,8 +607,8 @@ static void tifm_ms_remove(struct tifm_dev *sock) if (host->use_dma) tifm_unmap_sg(sock, &host->req->sg, 1, host->req->data_dir == READ - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); host->req->error = -ETIME; do { -- cgit v1.2.3-70-g09d2 From b048457c54e4dcf3e326ddd4974d5e3d2a74d03b Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 22 Aug 2021 15:48:37 +0200 Subject: mmc: switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below. It has been compile tested. @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/b617f284e2ab8b6b48fff150eba1638641646edd.1629640046.git.christophe.jaillet@wanadoo.fr Signed-off-by: Ulf Hansson --- drivers/mmc/host/tifm_sd.c | 16 ++++++++-------- drivers/mmc/host/via-sdmmc.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 9fdf7ea06e3f..63917070b1a7 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c @@ -669,8 +669,8 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) if(1 != tifm_map_sg(sock, &host->bounce_buf, 1, r_data->flags & MMC_DATA_WRITE - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE)) { + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE)) { pr_err("%s : scatterlist map failed\n", dev_name(&sock->dev)); mrq->cmd->error = -ENOMEM; @@ -680,15 +680,15 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) r_data->sg_len, r_data->flags & MMC_DATA_WRITE - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); if (host->sg_len < 1) { pr_err("%s : scatterlist map failed\n", dev_name(&sock->dev)); tifm_unmap_sg(sock, &host->bounce_buf, 1, r_data->flags & MMC_DATA_WRITE - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); mrq->cmd->error = -ENOMEM; goto err_out; } @@ -762,10 +762,10 @@ static void tifm_sd_end_cmd(struct tasklet_struct *t) } else { tifm_unmap_sg(sock, &host->bounce_buf, 1, (r_data->flags & MMC_DATA_WRITE) - ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + ? DMA_TO_DEVICE : DMA_FROM_DEVICE); tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, (r_data->flags & MMC_DATA_WRITE) - ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + ? DMA_TO_DEVICE : DMA_FROM_DEVICE); } r_data->bytes_xfered = r_data->blocks diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index c32df5530b94..88662a90ed96 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c @@ -491,7 +491,7 @@ static void via_sdc_preparedata(struct via_crdr_mmc_host *host, count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, ((data->flags & MMC_DATA_READ) ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE)); + DMA_FROM_DEVICE : DMA_TO_DEVICE)); BUG_ON(count != 1); via_set_ddma(host, sg_dma_address(data->sg), sg_dma_len(data->sg), @@ -638,7 +638,7 @@ static void via_sdc_finish_data(struct via_crdr_mmc_host *host) dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, ((data->flags & MMC_DATA_READ) ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE)); + DMA_FROM_DEVICE : DMA_TO_DEVICE)); if (data->stop) via_sdc_send_command(host, data->stop); -- cgit v1.2.3-70-g09d2 From f6f607070aa6f0c730c5ca38e888c88f34bea7d6 Mon Sep 17 00:00:00 2001 From: ChanWoo Lee Date: Tue, 24 Aug 2021 16:39:34 +0900 Subject: mmc: queue: Match the data type of max_segments Each function has a different data type for max_segments, Modify to match unsigned short(host->max_segs). * unsigned short max_segs; /* see blk_queue_max_segments */ 1) Return type : unsigned int static unsigned int mmc_get_max_segments(struct mmc_host *host) { return host->can_dma_map_merge ? MMC_DMA_MAP_MERGE_SEGMENTS : host->max_segs; } 2) Parameter type : int mmc_alloc_sg(mmc_get_max_segments(host), gfp); -> static struct scatterlist *mmc_alloc_sg(int sg_len, gfp_t gfp) 3) Parameter type : unsigned short blk_queue_max_segments(mq->queue, mmc_get_max_segments(host)); -> void blk_queue_max_segments(struct request_queue *q, unsigned short max_segments) Signed-off-by: ChanWoo Lee Acked-by: Coly Li Link: https://lore.kernel.org/r/20210824073934.19727-1-cw9316.lee@samsung.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index cc3261777637..48304bcf963c 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -163,7 +163,7 @@ static void mmc_mq_recovery_handler(struct work_struct *work) blk_mq_run_hw_queues(q, true); } -static struct scatterlist *mmc_alloc_sg(int sg_len, gfp_t gfp) +static struct scatterlist *mmc_alloc_sg(unsigned short sg_len, gfp_t gfp) { struct scatterlist *sg; @@ -193,7 +193,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, blk_queue_flag_set(QUEUE_FLAG_SECERASE, q); } -static unsigned int mmc_get_max_segments(struct mmc_host *host) +static unsigned short mmc_get_max_segments(struct mmc_host *host) { return host->can_dma_map_merge ? MMC_DMA_MAP_MERGE_SEGMENTS : host->max_segs; -- cgit v1.2.3-70-g09d2 From fe72d08a961f9e09a7b04c15904a98f7c8cd537e Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 18 Aug 2021 00:42:07 +0200 Subject: mmc: core: Issue HPI in case the BKOPS timed out If the BKOPS timed out, the card is probably still busy in the R1_STATE_PRG. Rather than continue as nothing has happened and hitting and error for the next command being sent, let's try to abort the running BKOPS by sending a HPI command to get back into R1_STATE_TRAN. Signed-off-by: Bean Huo Link: https://lore.kernel.org/r/20210817224208.153652-2-huobean@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/mmc_ops.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 90d213a2203f..0c54858e89c0 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -959,8 +959,15 @@ void mmc_run_bkops(struct mmc_card *card) */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_START, 1, MMC_BKOPS_TIMEOUT_MS); - if (err) - pr_warn("%s: Error %d starting bkops\n", + /* + * If the BKOPS timed out, the card is probably still busy in the + * R1_STATE_PRG. Rather than continue to wait, let's try to abort + * it with a HPI command to get back into R1_STATE_TRAN. + */ + if (err == -ETIMEDOUT && !mmc_interrupt_hpi(card)) + pr_warn("%s: BKOPS aborted\n", mmc_hostname(card->host)); + else if (err) + pr_warn("%s: Error %d running bkops\n", mmc_hostname(card->host), err); mmc_retune_release(card->host); -- cgit v1.2.3-70-g09d2 From a0dbbdc2036e7406bf937912f7997c0b34042464 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Wed, 18 Aug 2021 19:16:50 +0800 Subject: mmc: sdhci-esdhc-imx: Remove redundant code for manual tuning For manual tuning method, already call esdhc_prepare_tuning() config the necessary registers, so remove the redundant code in esdhc_writew_le() for SDHCI_HOST_CONTROL2. Signed-off-by: Haibo Chen Link: https://lore.kernel.org/r/1629285415-7495-1-git-send-email-haibo.chen@nxp.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-esdhc-imx.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 57b19ca1ad6d..a49fac719fca 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -628,17 +628,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) else new_val &= ~ESDHC_VENDOR_SPEC_VSELECT; writel(new_val, host->ioaddr + ESDHC_VENDOR_SPEC); - if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { - new_val = readl(host->ioaddr + ESDHC_MIX_CTRL); - if (val & SDHCI_CTRL_TUNED_CLK) { - new_val |= ESDHC_MIX_CTRL_SMPCLK_SEL; - new_val |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; - } else { - new_val &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; - new_val &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN; - } - writel(new_val , host->ioaddr + ESDHC_MIX_CTRL); - } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { + if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { u32 v = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); if (val & SDHCI_CTRL_TUNED_CLK) { -- cgit v1.2.3-70-g09d2 From 45334ee13858de4c8c8c781b3b0f94b7b81e9e69 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Wed, 18 Aug 2021 19:16:51 +0800 Subject: mmc: sdhci-esdhc-imx: Select the correct mode for auto tuning USDHC hardware auto tuning circuit support check 1/4/8 data lines and cmd line. Out of reset uSDHC, it default select check 4 data lines and do not check cmd line. This is incorrect if we use 8 data lines. So need to config the auto tuning mode according to current bus width. Signed-off-by: Haibo Chen Link: https://lore.kernel.org/r/1629285415-7495-2-git-send-email-haibo.chen@nxp.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-esdhc-imx.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index a49fac719fca..f18d169bc8ff 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -94,6 +94,11 @@ #define ESDHC_VEND_SPEC2 0xc8 #define ESDHC_VEND_SPEC2_EN_BUSY_IRQ (1 << 8) +#define ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN (1 << 4) +#define ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN (0 << 4) +#define ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN (2 << 4) +#define ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN (1 << 6) +#define ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK (7 << 4) #define ESDHC_TUNING_CTRL 0xcc #define ESDHC_STD_TUNING_EN (1 << 24) @@ -114,6 +119,7 @@ #define ESDHC_CTRL_4BITBUS (0x1 << 1) #define ESDHC_CTRL_8BITBUS (0x2 << 1) #define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1) +#define USDHC_GET_BUSWIDTH(c) (c & ESDHC_CTRL_BUSWIDTH_MASK) /* * There is an INT DMA ERR mismatch between eSDHC and STD SDHC SPEC: @@ -407,6 +413,30 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host) dev_warn(mmc_dev(host->mmc), "%s: card clock still not gate off in 100us!.\n", __func__); } +/* Enable the auto tuning circuit to check the CMD line and BUS line */ +static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host) +{ + u32 buswidth, auto_tune_buswidth; + + buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); + + switch (buswidth) { + case ESDHC_CTRL_8BITBUS: + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN; + break; + case ESDHC_CTRL_4BITBUS: + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN; + break; + default: /* 1BITBUS */ + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; + break; + } + + esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, + auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, + ESDHC_VEND_SPEC2); +} + static u32 esdhc_readl_le(struct sdhci_host *host, int reg) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -643,6 +673,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) v |= ESDHC_MIX_CTRL_EXE_TUNE; m |= ESDHC_MIX_CTRL_FBCLK_SEL; m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; + usdhc_auto_tuning_mode_sel(host); } else { v &= ~ESDHC_MIX_CTRL_EXE_TUNE; } @@ -1012,6 +1043,8 @@ static void esdhc_post_tuning(struct sdhci_host *host) { u32 reg; + usdhc_auto_tuning_mode_sel(host); + reg = readl(host->ioaddr + ESDHC_MIX_CTRL); reg &= ~ESDHC_MIX_CTRL_EXE_TUNE; reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; -- cgit v1.2.3-70-g09d2 From e72a55f2e5ddcfb3dce0701caf925ce435b87682 Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Wed, 25 Aug 2021 00:47:26 +0530 Subject: mmc: core: Return correct emmc response in case of ioctl error When a read/write command is sent via ioctl to the kernel, and the command fails, the actual error response of the emmc is not sent to the user. IOCTL read/write tests are carried out using commands 17 (Single BLock Read), 24 (Single Block Write), 18 (Multi Block Read), 25 (Multi Block Write) The tests are carried out on a 64Gb emmc device. All of these tests try to access an "out of range" sector address (0x09B2FFFF). It is seen that without the patch the response received by the user is not OUT_OF_RANGE error (R1 response 31st bit is not set) as per JEDEC specification. After applying the patch proper response is seen. This is because the function returns without copying the response to the user in case of failure. This patch fixes the issue. Hence, this memcpy is required whether we get an error response or not. Therefor it is moved up from the current position up to immediately after we have called mmc_wait_for_req(). The test code and the output of only the CMD17 is included in the commit to limit the message length. CMD17 (Test Code Snippet): ========================== printf("Forming CMD%d\n", opt_idx); /* single block read */ cmd.blksz = 512; cmd.blocks = 1; cmd.write_flag = 0; cmd.opcode = 17; //cmd.arg = atoi(argv[3]); cmd.arg = 0x09B2FFFF; /* Expecting response R1B */ cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; memset(data, 0, sizeof(__u8) * 512); mmc_ioc_cmd_set_data(cmd, data); printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg); if(ioctl(fd, MMC_IOC_CMD, &cmd)) perror("Error"); printf("\nResponse: %08x\n", cmd.response[0]); CMD17 (Output without patch): ============================= test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4 Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 0x09B2FFF] Forming CMD17 Sending CMD17: ARG[0x09b2ffff] Error: Connection timed out Response: 00000000 (Incorrect response) CMD17 (Output with patch): ========================== test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 [sudo] password for test: Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4 Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 09B2FFFF] Forming CMD17 Sending CMD17: ARG[0x09b2ffff] Error: Connection timed out Response: 80000900 (Correct OUT_OF_ERROR response as per JEDEC specification) Signed-off-by: Nishad Kamdar Reviewed-by: Avri Altman Link: https://lore.kernel.org/r/20210824191726.8296-1-nishadkamdar@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/block.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index a9ad9f5fa949..c3ecec3f6ddc 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -518,6 +518,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, return mmc_sanitize(card, idata->ic.cmd_timeout_ms); mmc_wait_for_req(card->host, &mrq); + memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp)); if (cmd.error) { dev_err(mmc_dev(card->host), "%s: cmd error %d\n", @@ -567,8 +568,6 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, if (idata->ic.postsleep_min_us) usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); - memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); - if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { /* * Ensure RPMB/R1B command has completed by polling CMD13 -- cgit v1.2.3-70-g09d2 From dba914b248845492080162c0b604a5e25e52dc7b Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 25 Aug 2021 11:19:31 +0300 Subject: mmc: pwrseq: sd8787: fix compilation warning Fixed compilation warning "cast from pointer to integer of different size [-Wpointer-to-int-cast]" Fixes: b2832b96fcf5 ("mmc: pwrseq: sd8787: add support for wilc1000") Reported-by: kernel test robot Reported-by: Stephen Rothwell Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20210825081931.598934-1-claudiu.beznea@microchip.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/pwrseq_sd8787.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c index 264e48067af2..2e120ad83020 100644 --- a/drivers/mmc/core/pwrseq_sd8787.c +++ b/drivers/mmc/core/pwrseq_sd8787.c @@ -56,9 +56,12 @@ static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = { .power_off = mmc_pwrseq_sd8787_power_off, }; +static const u32 sd8787_delay_ms = 300; +static const u32 wilc1000_delay_ms = 5; + static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = { - { .compatible = "mmc-pwrseq-sd8787", .data = (void *)300 }, - { .compatible = "mmc-pwrseq-wilc1000", .data = (void *)5 }, + { .compatible = "mmc-pwrseq-sd8787", .data = &sd8787_delay_ms }, + { .compatible = "mmc-pwrseq-wilc1000", .data = &wilc1000_delay_ms }, {/* sentinel */}, }; MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match); @@ -74,7 +77,7 @@ static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev) return -ENOMEM; match = of_match_node(mmc_pwrseq_sd8787_of_match, pdev->dev.of_node); - pwrseq->reset_pwrdwn_delay_ms = (u32)match->data; + pwrseq->reset_pwrdwn_delay_ms = *(u32 *)match->data; pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); if (IS_ERR(pwrseq->pwrdn_gpio)) -- cgit v1.2.3-70-g09d2 From f80c8e6864eb14b71f58c1a159654e4f379673a6 Mon Sep 17 00:00:00 2001 From: ChanWoo Lee Date: Wed, 25 Aug 2021 16:46:01 +0900 Subject: mmc: queue: Remove unused parameters(request_queue) In function mmc_exit_request, the request_queue structure(*q) is not used. I remove the unnecessary code related to the request_queue structure. Signed-off-by: ChanWoo Lee Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20210825074601.8881-1-cw9316.lee@samsung.com Signed-off-by: Ulf Hansson --- drivers/mmc/core/queue.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 48304bcf963c..b15c034b42fb 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -199,27 +199,23 @@ static unsigned short mmc_get_max_segments(struct mmc_host *host) host->max_segs; } -/** - * mmc_init_request() - initialize the MMC-specific per-request data - * @mq: the request queue - * @req: the request - * @gfp: memory allocation policy - */ -static int __mmc_init_request(struct mmc_queue *mq, struct request *req, - gfp_t gfp) +static int mmc_mq_init_request(struct blk_mq_tag_set *set, struct request *req, + unsigned int hctx_idx, unsigned int numa_node) { struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req); + struct mmc_queue *mq = set->driver_data; struct mmc_card *card = mq->card; struct mmc_host *host = card->host; - mq_rq->sg = mmc_alloc_sg(mmc_get_max_segments(host), gfp); + mq_rq->sg = mmc_alloc_sg(mmc_get_max_segments(host), GFP_KERNEL); if (!mq_rq->sg) return -ENOMEM; return 0; } -static void mmc_exit_request(struct request_queue *q, struct request *req) +static void mmc_mq_exit_request(struct blk_mq_tag_set *set, struct request *req, + unsigned int hctx_idx) { struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req); @@ -227,20 +223,6 @@ static void mmc_exit_request(struct request_queue *q, struct request *req) mq_rq->sg = NULL; } -static int mmc_mq_init_request(struct blk_mq_tag_set *set, struct request *req, - unsigned int hctx_idx, unsigned int numa_node) -{ - return __mmc_init_request(set->driver_data, req, GFP_KERNEL); -} - -static void mmc_mq_exit_request(struct blk_mq_tag_set *set, struct request *req, - unsigned int hctx_idx) -{ - struct mmc_queue *mq = set->driver_data; - - mmc_exit_request(mq->queue, req); -} - static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { -- cgit v1.2.3-70-g09d2