diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-25 17:29:46 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-25 17:29:46 -0700 |
| commit | c5c06e278019892391ef4d47933796cacfec29cb (patch) | |
| tree | 33291b9db7249779ec6cc3976654f47d568e4231 | |
| parent | eb8322d714ea98fdc620d682fb517b50ea282aa5 (diff) | |
| parent | 22a4455e75be443fb80784175bb70f40ba6d0c52 (diff) | |
Merge tag 'mmc-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Allow an invalid regulator in mmc_regulator_set_ocr()
- Log about empty non-removable slots
- Add helpers to enable/disable the vqmmc regulator
MMC host:
- mtk-sd: Add support for the mt8365 variant
- renesas_sdhi: Remove support for R-Car H3 ES1.* variants
- sdhci_am654: Add power management support
- sdhci-cadence: Add support for eMMC hardware reset
- sdhci-cadence: Add support for AMD Pensando Elba variant
- sdhci-msm: Add support for the IPQ5018 variant
- sdhci-msm: Add support for the QCM2290 variant
- sdhci-of-arasan: Skip setting clock delay for 400KHz
- sdhci-of-arasan: Add support for the Xilinx Versal Net variant
- sdhci-of-arasan: Remove Intel Thunder Bay SOC support
- sdhci-of-arasan: Add support to request the "gate" clock
- sdhci-of-dwcmshc: Properly determine max clock on Rockchip
- sdhci-of-esdhc: Fix quirk to ignore command inhibit for data
- sdhci-pci-o2micro: Fix SDR50 mode timing issue
MEMSTICK:
- r592: Fix use-after-free bug in r592_remove due to race condition"
* tag 'mmc-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (40 commits)
dt-bindings: mmc: sdhci-msm: Document the IPQ5018 compatible
mmc: vub300: remove unreachable code
mmc: sdhci-cadence: Support mmc hardware reset
mmc: sdhci-cadence: Add AMD Pensando Elba SoC support
mmc: sdhci-cadence: Support device specific init during probe
mmc: sdhci-cadence: Enable device specific override of writel()
dt-bindings: mmc: cdns: Add AMD Pensando Elba SoC
mmc: core: Remove unused macro mmc_req_rel_wr
mmc: sdhci-of-arasan: Skip setting clock delay for 400KHz
mmc: sdhci-of-arasan: Add support for eMMC5.1 on Xilinx Versal Net platform
dt-bindings: mmc: arasan,sdci: Add Xilinx Versal Net compatible
mmc: sdhci_am654: Add support for PM suspend/resume
mmc: core: remove unnecessary (void*) conversions
dt-bindings: mmc: fsl-imx-esdhc: ref sdhci-common.yaml
mmc: sdhci-of-esdhc: fix quirk to ignore command inhibit for data
mmc: core: Log about empty non-removable slots
dt-bindings: mmc: fujitsu: Add Socionext Synquacer
mmc: sdricoh_cs: remove unused sdricoh_readw function
dt-bindings: mmc: Remove bindings for Intel Thunder Bay SoC"
mmc: sdhci-of-arasan: Remove Intel Thunder Bay SOC support
...
38 files changed, 711 insertions, 205 deletions
diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml b/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml index 8296c34cfa00..a6c19a6cc99e 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.yaml @@ -27,6 +27,7 @@ allOf: enum: - xlnx,zynqmp-8.9a - xlnx,versal-8.9a + - xlnx,versal-net-emmc then: properties: clock-output-names: @@ -62,6 +63,10 @@ properties: description: For this device it is strongly suggested to include clock-output-names and '#clock-cells'. + - const: xlnx,versal-net-emmc # Versal Net eMMC PHY + description: + For this device it is strongly suggested to include + clock-output-names and '#clock-cells'. - items: - const: intel,lgm-sdhci-5.1-emmc # Intel LGM eMMC PHY - const: arasan,sdhci-5.1 @@ -88,12 +93,6 @@ properties: description: For this device it is strongly suggested to include arasan,soc-ctl-syscon. - - items: - - const: intel,thunderbay-sdhci-5.1 # Intel Thunder Bay eMMC PHY - - const: arasan,sdhci-5.1 - description: - For this device it is strongly suggested to include - clock-output-names and '#clock-cells'. reg: maxItems: 1 @@ -309,22 +308,3 @@ examples: <&scmi_clk KEEM_BAY_PSS_SD0>; arasan,soc-ctl-syscon = <&sd0_phy_syscon>; }; - - - | - #define EMMC_XIN_CLK - #define EMMC_AXI_CLK - #define TBH_PSS_EMMC_RST_N - mmc@80420000 { - compatible = "intel,thunderbay-sdhci-5.1", "arasan,sdhci-5.1"; - interrupts = <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>; - reg = <0x80420000 0x400>; - clocks = <&scmi_clk EMMC_XIN_CLK>, - <&scmi_clk EMMC_AXI_CLK>; - clock-names = "clk_xin", "clk_ahb"; - phys = <&emmc_phy>; - phy-names = "phy_arasan"; - assigned-clocks = <&scmi_clk EMMC_XIN_CLK>; - clock-output-names = "emmc_cardclock"; - resets = <&rst_pss1 TBH_PSS_EMMC_RST_N>; - #clock-cells = <0x0>; - }; diff --git a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml index adacd0535c14..6c40611405a0 100644 --- a/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml +++ b/Documentation/devicetree/bindings/mmc/cdns,sdhci.yaml @@ -9,19 +9,18 @@ title: Cadence SD/SDIO/eMMC Host Controller (SD4HC) maintainers: - Masahiro Yamada <yamada.masahiro@socionext.com> -allOf: - - $ref: mmc-controller.yaml - properties: compatible: items: - enum: + - amd,pensando-elba-sd4hc - microchip,mpfs-sd4hc - socionext,uniphier-sd4hc - const: cdns,sd4hc reg: - maxItems: 1 + minItems: 1 + maxItems: 2 interrupts: maxItems: 1 @@ -120,6 +119,26 @@ required: - interrupts - clocks +allOf: + - $ref: mmc-controller.yaml + - if: + properties: + compatible: + contains: + const: amd,pensando-elba-sd4hc + then: + properties: + reg: + items: + - description: Host controller registers + - description: Elba byte-lane enable register for writes + required: + - resets + else: + properties: + reg: + maxItems: 1 + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml index 7f721fbfb009..fbfd822b9270 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml @@ -10,7 +10,7 @@ maintainers: - Shawn Guo <shawnguo@kernel.org> allOf: - - $ref: mmc-controller.yaml + - $ref: sdhci-common.yaml# description: | The Enhanced Secure Digital Host Controller on Freescale i.MX family diff --git a/Documentation/devicetree/bindings/mmc/fujitsu,sdhci-fujitsu.yaml b/Documentation/devicetree/bindings/mmc/fujitsu,sdhci-fujitsu.yaml index 73d747e917f3..430b62899397 100644 --- a/Documentation/devicetree/bindings/mmc/fujitsu,sdhci-fujitsu.yaml +++ b/Documentation/devicetree/bindings/mmc/fujitsu,sdhci-fujitsu.yaml @@ -14,9 +14,13 @@ allOf: properties: compatible: - enum: - - fujitsu,mb86s70-sdhci-3.0 - - socionext,f-sdh30-e51-mmc + oneOf: + - items: + - const: socionext,synquacer-sdhci + - const: fujitsu,mb86s70-sdhci-3.0 + - enum: + - fujitsu,mb86s70-sdhci-3.0 + - socionext,f-sdh30-e51-mmc reg: maxItems: 1 @@ -29,6 +33,11 @@ properties: - const: iface - const: core + dma-coherent: true + + interrupts: + maxItems: 2 + resets: maxItems: 1 diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml index 7a649ebc688c..46eefdd19a2c 100644 --- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml @@ -34,6 +34,7 @@ properties: - mediatek,mt8188-mmc - mediatek,mt8192-mmc - mediatek,mt8195-mmc + - mediatek,mt8365-mmc - const: mediatek,mt8183-mmc reg: diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml index 64df6919abaf..4f2d9e8127dd 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.yaml @@ -34,8 +34,10 @@ properties: - const: qcom,sdhci-msm-v4 # for sdcc versions less than 5.0 - items: - enum: + - qcom,ipq5018-sdhci - qcom,ipq5332-sdhci - qcom,ipq9574-sdhci + - qcom,qcm2290-sdhci - qcom,qcs404-sdhci - qcom,sc7180-sdhci - qcom,sc7280-sdhci diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 1d35d147552d..42bfc46842b8 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -829,7 +829,7 @@ static void r592_remove(struct pci_dev *pdev) /* Stop the processing thread. That ensures that we won't take any more requests */ kthread_stop(dev->io_thread); - + del_timer_sync(&dev->detect_timer); r592_enable_device(dev, false); while (!error && dev->req) { diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 672ab90c4b2d..00c33edb9fb9 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -76,8 +76,6 @@ MODULE_ALIAS("mmc:block"); #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) #define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8) -#define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \ - (rq_data_dir(req) == WRITE)) static DEFINE_MUTEX(block_mutex); /* diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 426c7f66b349..3d3e0ca52614 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2257,6 +2257,11 @@ void mmc_rescan(struct work_struct *work) break; } + /* A non-removable card should have been detected by now. */ + if (!mmc_card_is_removable(host) && !host->bus_ops) + pr_info("%s: Failed to initialize a non-removable card", + mmc_hostname(host)); + /* * Ignore the command timeout errors observed during * the card init as those are excepted. diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index fe6808771bc7..2c97b94aab23 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c @@ -246,7 +246,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(mmc_err_state, mmc_err_state_get, NULL, "%llu\n"); static int mmc_err_stats_show(struct seq_file *file, void *data) { - struct mmc_host *host = (struct mmc_host *)file->private; + struct mmc_host *host = file->private; const char *desc[MMC_ERR_MAX] = { [MMC_ERR_CMD_TIMEOUT] = "Command Timeout Occurred", [MMC_ERR_CMD_CRC] = "Command CRC Errors Occurred", diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c index 156d34b2ed4d..0f6a563103fd 100644 --- a/drivers/mmc/core/mmc_test.c +++ b/drivers/mmc/core/mmc_test.c @@ -3045,7 +3045,7 @@ static LIST_HEAD(mmc_test_file_test); static int mtf_test_show(struct seq_file *sf, void *data) { - struct mmc_card *card = (struct mmc_card *)sf->private; + struct mmc_card *card = sf->private; struct mmc_test_general_result *gr; mutex_lock(&mmc_test_lock); @@ -3079,8 +3079,8 @@ static int mtf_test_open(struct inode *inode, struct file *file) static ssize_t mtf_test_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct seq_file *sf = (struct seq_file *)file->private_data; - struct mmc_card *card = (struct mmc_card *)sf->private; + struct seq_file *sf = file->private_data; + struct mmc_card *card = sf->private; struct mmc_test_card *test; long testcase; int ret; diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c index 609201a467ef..005247a49e51 100644 --- a/drivers/mmc/core/regulator.c +++ b/drivers/mmc/core/regulator.c @@ -110,6 +110,9 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc, int result = 0; int min_uV, max_uV; + if (IS_ERR(supply)) + return 0; + if (vdd_bit) { mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV); @@ -271,3 +274,44 @@ int mmc_regulator_get_supply(struct mmc_host *mmc) return 0; } EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); + +/** + * mmc_regulator_enable_vqmmc - enable VQMMC regulator for a host + * @mmc: the host to regulate + * + * Returns 0 or errno. Enables the regulator for vqmmc. + * Keeps track of the enable status for ensuring that calls to + * regulator_enable/disable are balanced. + */ +int mmc_regulator_enable_vqmmc(struct mmc_host *mmc) +{ + int ret = 0; + + if (!IS_ERR(mmc->supply.vqmmc) && !mmc->vqmmc_enabled) { + ret = regulator_enable(mmc->supply.vqmmc); + if (ret < 0) + dev_err(mmc_dev(mmc), "enabling vqmmc regulator failed\n"); + else + mmc->vqmmc_enabled = true; + } + + return ret; +} +EXPORT_SYMBOL_GPL(mmc_regulator_enable_vqmmc); + +/** + * mmc_regulator_disable_vqmmc - disable VQMMC regulator for a host + * @mmc: the host to regulate + * + * Returns 0 or errno. Disables the regulator for vqmmc. + * Keeps track of the enable status for ensuring that calls to + * regulator_enable/disable are balanced. + */ +void mmc_regulator_disable_vqmmc(struct mmc_host *mmc) +{ + if (!IS_ERR(mmc->supply.vqmmc) && mmc->vqmmc_enabled) { + regulator_disable(mmc->supply.vqmmc); + mmc->vqmmc_enabled = false; + } +} +EXPORT_SYMBOL_GPL(mmc_regulator_disable_vqmmc); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4745fe217ade..9f793892123c 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -255,6 +255,7 @@ config MMC_SDHCI_CADENCE tristate "SDHCI support for the Cadence SD/SDIO/eMMC controller" depends on MMC_SDHCI_PLTFM depends on OF + select MMC_SDHCI_IO_ACCESSORS help This selects the Cadence SD/SDIO/eMMC driver. diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 13e55cff8237..48b7da2b86b3 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -46,8 +46,7 @@ int dw_mci_pltfm_register(struct platform_device *pdev, host->irq_flags = 0; host->pdata = pdev->dev.platform_data; - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - host->regs = devm_ioremap_resource(&pdev->dev, regs); + host->regs = devm_platform_get_and_ioremap_resource(pdev, 0, ®s); if (IS_ERR(host->regs)) return PTR_ERR(host->regs); diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 698450afa7bb..1846a05210e3 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -1079,8 +1079,7 @@ static int jz4740_mmc_probe(struct platform_device* pdev) goto err_free_host; } - host->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - host->base = devm_ioremap_resource(&pdev->dev, host->mem_res); + host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &host->mem_res); if (IS_ERR(host->base)) { ret = PTR_ERR(host->base); goto err_free_host; diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 2b963a81c2ad..b8514d9d5e73 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -174,7 +174,6 @@ struct meson_host { int irq; - bool vqmmc_enabled; bool needs_pre_post_req; spinlock_t lock; @@ -604,32 +603,18 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) */ switch (ios->power_mode) { case MMC_POWER_OFF: - if (!IS_ERR(mmc->supply.vmmc)) - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); - - if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { - regulator_disable(mmc->supply.vqmmc); - host->vqmmc_enabled = false; - } + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + mmc_regulator_disable_vqmmc(mmc); break; case MMC_POWER_UP: - if (!IS_ERR(mmc->supply.vmmc)) - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd); break; case MMC_POWER_ON: - if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { - int ret = regulator_enable(mmc->supply.vqmmc); - - if (ret < 0) - dev_err(host->dev, - "failed to enable vqmmc regulator\n"); - else - host->vqmmc_enabled = true; - } + mmc_regulator_enable_vqmmc(mmc); break; } @@ -1181,7 +1166,6 @@ static int meson_mmc_probe(struct platform_device *pdev) "amlogic,dram-access-quirk"); /* Get regulators and the supported OCR mask */ - host->vqmmc_enabled = false; ret = mmc_regulator_get_supply(mmc); if (ret) return ret; diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b9e5dfe74e5c..f2b2e8b0574e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1962,28 +1962,28 @@ static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc) if (ret) return ret; - if (of_get_property(np, "st,sig-dir-dat0", NULL)) + if (of_property_read_bool(np, "st,sig-dir-dat0")) host->pwr_reg_add |= MCI_ST_DATA0DIREN; - if (of_get_property(np, "st,sig-dir-dat2", NULL)) + if (of_property_read_bool(np, "st,sig-dir-dat2")) host->pwr_reg_add |= MCI_ST_DATA2DIREN; - if (of_get_property(np, "st,sig-dir-dat31", NULL)) + if (of_property_read_bool(np, "st,sig-dir-dat31")) host->pwr_reg_add |= MCI_ST_DATA31DIREN; - if (of_get_property(np, "st,sig-dir-dat74", NULL)) + if (of_property_read_bool(np, "st,sig-dir-dat74")) host->pwr_reg_add |= MCI_ST_DATA74DIREN; - if (of_get_property(np, "st,sig-dir-cmd", NULL)) + if (of_property_read_bool(np, "st,sig-dir-cmd")) host->pwr_reg_add |= MCI_ST_CMDDIREN; - if (of_get_property(np, "st,sig-pin-fbclk", NULL)) + if (of_property_read_bool(np, "st,sig-pin-fbclk")) host->pwr_reg_add |= MCI_ST_FBCLKEN; - if (of_get_property(np, "st,sig-dir", NULL)) + if (of_property_read_bool(np, "st,sig-dir")) host->pwr_reg_add |= MCI_STM32_DIRPOL; - if (of_get_property(np, "st,neg-edge", NULL)) + if (of_property_read_bool(np, "st,neg-edge")) host->clk_reg_add |= MCI_STM32_CLK_NEGEDGE; - if (of_get_property(np, "st,use-ckin", NULL)) + if (of_property_read_bool(np, "st,use-ckin")) mmci_probe_level_translator(mmc); - if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL)) + if (of_property_read_bool(np, "mmc-cap-mmc-highspeed")) mmc->caps |= MMC_CAP_MMC_HIGHSPEED; - if (of_get_property(np, "mmc-cap-sd-highspeed", NULL)) + if (of_property_read_bool(np, "mmc-cap-sd-highspeed")) mmc->caps |= MMC_CAP_SD_HIGHSPEED; return 0; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 57d39283924d..ce78edfb402b 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1345,8 +1345,7 @@ static int mmc_omap_probe(struct platform_device *pdev) if (irq < 0) return -ENXIO; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - host->virt_base = devm_ioremap_resource(&pdev->dev, res); + host->virt_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(host->virt_base)) return PTR_ERR(host->virt_base); diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 4bd744755205..517dde777413 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1736,18 +1736,18 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev) if (legacy && legacy->name) pdata->name = legacy->name; - if (of_find_property(np, "ti,dual-volt", NULL)) + if (of_property_read_bool(np, "ti,dual-volt")) pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; - if (of_find_property(np, "ti,non-removable", NULL)) { + if (of_property_read_bool(np, "ti,non-removable")) { pdata->nonremovable = true; pdata->no_regulator_off_init = true; } - if (of_find_property(np, "ti,needs-special-reset", NULL)) + if (of_property_read_bool(np, "ti,needs-special-reset")) pdata->features |= HSMMC_HAS_UPDATED_RESET; - if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) + if (of_property_read_bool(np, "ti,needs-special-hs-handling")) pdata->features |= HSMMC_HAS_HSPE_SUPPORT; return pdata; diff --git a/drivers/mmc/host/owl-mmc.c b/drivers/mmc/host/owl-mmc.c index 3dc143b03939..6f9d31a886ba 100644 --- a/drivers/mmc/host/owl-mmc.c +++ b/drivers/mmc/host/owl-mmc.c @@ -578,8 +578,7 @@ static int owl_mmc_probe(struct platform_device *pdev) owl_host->mmc = mmc; spin_lock_init(&owl_host->lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - owl_host->base = devm_ioremap_resource(&pdev->dev, res); + owl_host->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(owl_host->base)) { ret = PTR_ERR(owl_host->base); goto err_free_host; diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index f38003f6b1ca..9ab813903b2c 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c @@ -72,11 +72,10 @@ enum renesas_sdhi_dma_cookie { static unsigned long global_flags; /* - * Workaround for avoiding to use RX DMAC by multiple channels. - * On R-Car H3 ES1.* and M3-W ES1.0, when multiple SDHI channels use - * RX DMAC simultaneously, sometimes hundreds of bytes data are not - * stored into the system memory even if the DMAC interrupt happened. - * So, this driver then uses one RX DMAC channel only. + * Workaround for avoiding to use RX DMAC by multiple channels. On R-Car M3-W + * ES1.0, when multiple SDHI channels use RX DMAC simultaneously, sometimes + * hundreds of data bytes are not stored into the system memory even if the + * DMAC interrupt happened. So, this driver then uses one RX DMAC channel only. */ #define SDHI_INTERNAL_DMAC_RX_IN_USE 0 @@ -222,7 +221,6 @@ static const struct renesas_sdhi_quirks sdhi_quirks_r9a09g011 = { */ 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_one_rx }, { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, { .soc_id = "r8a7796", .revision = "ES1.0", .data = &sdhi_quirks_4tap_nohs400_one_rx }, { .soc_id = "r8a7796", .revision = "ES1.[12]", .data = &sdhi_quirks_4tap_nohs400 }, diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 6f2de54a5987..b24aa27da50c 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c @@ -12,6 +12,7 @@ #include <linux/mmc/mmc.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/reset.h> #include "sdhci-pltfm.h" @@ -66,7 +67,11 @@ struct sdhci_cdns_phy_param { struct sdhci_cdns_priv { void __iomem *hrs_addr; + void __iomem *ctl_addr; /* write control */ + spinlock_t wrlock; /* write lock */ bool enhanced_strobe; + void (*priv_writel)(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg); + struct reset_control *rst_hw; unsigned int nr_phy_params; struct sdhci_cdns_phy_param phy_params[]; }; @@ -76,6 +81,11 @@ struct sdhci_cdns_phy_cfg { u8 addr; }; +struct sdhci_cdns_drv_data { + int (*init)(struct platform_device *pdev); + const struct sdhci_pltfm_data pltfm_data; +}; + static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = { { "cdns,phy-input-delay-sd-highspeed", SDHCI_CDNS_PHY_DLY_SD_HS, }, { "cdns,phy-input-delay-legacy", SDHCI_CDNS_PHY_DLY_SD_DEFAULT, }, @@ -90,6 +100,12 @@ static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = { { "cdns,phy-dll-delay-strobe", SDHCI_CDNS_PHY_DLY_STROBE, }, }; +static inline void cdns_writel(struct sdhci_cdns_priv *priv, u32 val, + void __iomem *reg) +{ + writel(val, reg); +} + static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, u8 addr, u8 data) { @@ -104,17 +120,17 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) | FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr); - writel(tmp, reg); + priv->priv_writel(priv, tmp, reg); tmp |= SDHCI_CDNS_HRS04_WR; - writel(tmp, reg); + priv->priv_writel(priv, tmp, reg); ret = readl_poll_timeout(reg, tmp, tmp & SDHCI_CDNS_HRS04_ACK, 0, 10); if (ret) return ret; tmp &= ~SDHCI_CDNS_HRS04_WR; - writel(tmp, reg); + priv->priv_writel(priv, tmp, reg); ret = readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS04_ACK), 0, 10); @@ -191,7 +207,7 @@ static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode) tmp = readl(priv->hrs_addr + SDHC |
