Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'mmc-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC updates from Ulf Hansson:
"MMC host:
- atmel-mci: Convert DT bindings to json schema
- dw_mmc: Add support for the Exynos7870 variant
- dw_mmc-rockchip: Add support for the RK3562/3528 variants
- omap: Fix potential memory leak in the probe error path
- renesas_sdhi: Add support for RZ/G3E variants
- sdhci: Disable SD card clock before changing parameters
- sdhci-esdhc-imx: Add support for the i.MX94 variant
- sdhci-of-dwcmshc: Add support for the RK3562/RK3528 variants
- sdhci-omap: Disable aggressive PM for eMMC/SD-cards
- sdhci-pci-core: Wait for VDD to settle on card power off
- sdhci-pxav3: Fix busy-signalling by using MMC_CAP_NEED_RSP_BUSY
- sunxi-mmc: Add support for the A523 variant

MEMSTICK:
- rtsx_usb_ms: Fix potential use-after-free during remove"

* tag 'mmc-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (27 commits)
mmc: core: Remove redundant null check
mmc: host: Wait for Vdd to settle on card power off
mmc: omap: Fix memory leak in mmc_omap_new_slot
memstick: rtsx_usb_ms: Fix slab-use-after-free in rtsx_usb_ms_drv_remove
mmc: renesas_sdhi: fix error code in renesas_sdhi_probe()
mmc: sdhci-pxav3: set NEED_RSP_BUSY capability
mmc: sdhci-omap: Disable MMC_CAP_AGGRESSIVE_PM for eMMC/SD
tty: mmc: sdio: use bool for cts and remove parentheses
dt-bindings: mmc: sunxi: add compatible strings for Allwinner A523
dt-bindings: mmc: sunxi: Simplify compatible string listing
dt-bindings: mmc: sdhci-of-dwcmhsc: Add compatible string for RK3528
dt-bindings: mmc: rockchip-dw-mshc: Add compatible string for RK3528
mmc: renesas_sdhi: Add support for RZ/G3E SoC
dt-bindings: mmc: renesas,sdhi: Document RZ/G3E support
dt-bindings: mmc: rockchip-dw-mshc: Add support for rk3562
dt-bindings: mmc: Add support for rk3562 eMMC
mmc: core: Trim trailing whitespace from card product names
dt-bindings: mmc: atmel,hsmci: Convert to json schema
dt-bindings: mmc: mmc-slot: Make compatible property optional
dt-bindings: mmc: fsl-imx-esdhc: Add i.MX94 support
...

+508 -184
+17 -21
Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
··· 30 30 - const: allwinner,sun50i-a100-emmc 31 31 - const: allwinner,sun50i-a100-mmc 32 32 - items: 33 - - const: allwinner,sun8i-a83t-mmc 33 + - enum: 34 + - allwinner,sun8i-a83t-mmc 35 + - allwinner,suniv-f1c100s-mmc 34 36 - const: allwinner,sun7i-a20-mmc 35 37 - items: 36 - - const: allwinner,sun8i-r40-emmc 38 + - enum: 39 + - allwinner,sun8i-r40-emmc 40 + - allwinner,sun50i-h5-emmc 41 + - allwinner,sun50i-h6-emmc 37 42 - const: allwinner,sun50i-a64-emmc 38 43 - items: 39 - - const: allwinner,sun8i-r40-mmc 44 + - enum: 45 + - allwinner,sun8i-r40-mmc 46 + - allwinner,sun50i-h5-mmc 47 + - allwinner,sun50i-h6-mmc 40 48 - const: allwinner,sun50i-a64-mmc 41 49 - items: 42 - - const: allwinner,sun50i-h5-emmc 43 - - const: allwinner,sun50i-a64-emmc 44 - - items: 45 - - const: allwinner,sun50i-h5-mmc 46 - - const: allwinner,sun50i-a64-mmc 47 - - items: 48 - - const: allwinner,sun50i-h6-emmc 49 - - const: allwinner,sun50i-a64-emmc 50 - - items: 51 - - const: allwinner,sun50i-h6-mmc 52 - - const: allwinner,sun50i-a64-mmc 53 - - items: 54 - - const: allwinner,sun20i-d1-emmc 55 - - const: allwinner,sun50i-a100-emmc 56 - - items: 57 - - const: allwinner,sun50i-h616-emmc 50 + - enum: 51 + - allwinner,sun20i-d1-emmc 52 + - allwinner,sun50i-h616-emmc 53 + - allwinner,sun55i-a523-emmc 58 54 - const: allwinner,sun50i-a100-emmc 59 55 - items: 60 56 - const: allwinner,sun50i-h616-mmc 61 57 - const: allwinner,sun50i-a100-mmc 62 58 - items: 63 - - const: allwinner,suniv-f1c100s-mmc 64 - - const: allwinner,sun7i-a20-mmc 59 + - const: allwinner,sun55i-a523-mmc 60 + - const: allwinner,sun20i-d1-mmc 65 61 66 62 reg: 67 63 maxItems: 1
+3
Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.yaml
··· 60 60 bus-width: 61 61 enum: [1, 4] 62 62 63 + required: 64 + - compatible 65 + 63 66 unevaluatedProperties: false 64 67 65 68 required:
+106
Documentation/devicetree/bindings/mmc/atmel,hsmci.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mmc/atmel,hsmci.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Atmel High-Speed MultiMedia Card Interface (HSMCI) 8 + 9 + description: 10 + The Atmel HSMCI controller provides an interface for MMC, SD, and SDIO memory 11 + cards. 12 + 13 + maintainers: 14 + - Nicolas Ferre <nicolas.ferre@microchip.com> 15 + - Aubin Constans <aubin.constans@microchip.com> 16 + 17 + allOf: 18 + - $ref: mmc-controller.yaml 19 + 20 + properties: 21 + compatible: 22 + const: atmel,hsmci 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + dmas: 31 + maxItems: 1 32 + 33 + dma-names: 34 + const: rxtx 35 + 36 + clocks: 37 + maxItems: 1 38 + 39 + clock-names: 40 + const: mci_clk 41 + 42 + "#address-cells": 43 + const: 1 44 + description: Used for slot IDs. 45 + 46 + "#size-cells": 47 + const: 0 48 + 49 + patternProperties: 50 + "slot@[0-2]$": 51 + $ref: mmc-slot.yaml 52 + description: A slot node representing an MMC, SD, or SDIO slot. 53 + 54 + properties: 55 + reg: 56 + enum: [0, 1] 57 + 58 + required: 59 + - reg 60 + - bus-width 61 + 62 + unevaluatedProperties: false 63 + 64 + required: 65 + - compatible 66 + - reg 67 + - interrupts 68 + - clocks 69 + - clock-names 70 + - "#address-cells" 71 + - "#size-cells" 72 + 73 + anyOf: 74 + - required: 75 + - slot@0 76 + - required: 77 + - slot@1 78 + 79 + unevaluatedProperties: false 80 + 81 + examples: 82 + - | 83 + #include <dt-bindings/interrupt-controller/irq.h> 84 + #include <dt-bindings/clock/at91.h> 85 + mmc@f0008000 { 86 + compatible = "atmel,hsmci"; 87 + reg = <0xf0008000 0x600>; 88 + interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; 89 + clocks = <&mci0_clk>; 90 + clock-names = "mci_clk"; 91 + #address-cells = <1>; 92 + #size-cells = <0>; 93 + 94 + slot@0 { 95 + reg = <0>; 96 + bus-width = <4>; 97 + cd-gpios = <&pioD 15 0>; 98 + cd-inverted; 99 + }; 100 + 101 + slot@1 { 102 + reg = <1>; 103 + bus-width = <4>; 104 + }; 105 + }; 106 + ...
-73
Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
··· 1 - * Atmel High Speed MultiMedia Card Interface 2 - 3 - This controller on atmel products provides an interface for MMC, SD and SDIO 4 - types of memory cards. 5 - 6 - This file documents differences between the core properties described 7 - by mmc.txt and the properties used by the atmel-mci driver. 8 - 9 - 1) MCI node 10 - 11 - Required properties: 12 - - compatible: should be "atmel,hsmci" 13 - - #address-cells: should be one. The cell is the slot id. 14 - - #size-cells: should be zero. 15 - - at least one slot node 16 - - clock-names: tuple listing input clock names. 17 - Required elements: "mci_clk" 18 - - clocks: phandles to input clocks. 19 - 20 - The node contains child nodes for each slot that the platform uses 21 - 22 - Example MCI node: 23 - 24 - mmc0: mmc@f0008000 { 25 - compatible = "atmel,hsmci"; 26 - reg = <0xf0008000 0x600>; 27 - interrupts = <12 4>; 28 - #address-cells = <1>; 29 - #size-cells = <0>; 30 - clock-names = "mci_clk"; 31 - clocks = <&mci0_clk>; 32 - 33 - [ child node definitions...] 34 - }; 35 - 36 - 2) slot nodes 37 - 38 - Required properties: 39 - - reg: should contain the slot id. 40 - - bus-width: number of data lines connected to the controller 41 - 42 - Optional properties: 43 - - cd-gpios: specify GPIOs for card detection 44 - - cd-inverted: invert the value of external card detect gpio line 45 - - wp-gpios: specify GPIOs for write protection 46 - 47 - Example slot node: 48 - 49 - slot@0 { 50 - reg = <0>; 51 - bus-width = <4>; 52 - cd-gpios = <&pioD 15 0> 53 - cd-inverted; 54 - }; 55 - 56 - Example full MCI node: 57 - mmc0: mmc@f0008000 { 58 - compatible = "atmel,hsmci"; 59 - reg = <0xf0008000 0x600>; 60 - interrupts = <12 4>; 61 - #address-cells = <1>; 62 - #size-cells = <0>; 63 - slot@0 { 64 - reg = <0>; 65 - bus-width = <4>; 66 - cd-gpios = <&pioD 15 0> 67 - cd-inverted; 68 - }; 69 - slot@1 { 70 - reg = <1>; 71 - bus-width = <4>; 72 - }; 73 - };
+1
Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
··· 57 57 - fsl,imx8mp-usdhc 58 58 - fsl,imx8ulp-usdhc 59 59 - fsl,imx93-usdhc 60 + - fsl,imx94-usdhc 60 61 - fsl,imx95-usdhc 61 62 - const: fsl,imx8mm-usdhc 62 63 - items:
+1 -1
Documentation/devicetree/bindings/mmc/mmc-controller.yaml
··· 24 24 $nodename: 25 25 pattern: "^mmc(@.*)?$" 26 26 27 - unevaluatedProperties: true 27 + additionalProperties: true 28 28 29 29 examples: 30 30 - |
-1
Documentation/devicetree/bindings/mmc/mmc-slot.yaml
··· 29 29 maxItems: 1 30 30 31 31 required: 32 - - compatible 33 32 - reg 34 33 35 34 unevaluatedProperties: false
+16
Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
··· 68 68 - renesas,sdhi-r9a08g045 # RZ/G3S 69 69 - renesas,sdhi-r9a09g011 # RZ/V2M 70 70 - const: renesas,rzg2l-sdhi 71 + - items: 72 + - const: renesas,sdhi-r9a09g047 # RZ/G3E 73 + - const: renesas,sdhi-r9a09g057 # RZ/V2H(P) 71 74 72 75 reg: 73 76 maxItems: 1 ··· 213 210 The internal card detection logic that exists in these controllers is 214 211 sectioned off to be run by a separate second clock source to allow 215 212 the main core clock to be turned off to save power. 213 + 214 + - if: 215 + properties: 216 + compatible: 217 + contains: 218 + const: renesas,sdhi-r9a09g057 219 + then: 220 + properties: 221 + vqmmc-regulator: 222 + type: object 223 + description: VQMMC SD regulator 224 + $ref: /schemas/regulator/regulator.yaml# 225 + unevaluatedProperties: false 216 226 217 227 required: 218 228 - compatible
+2
Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.yaml
··· 38 38 - rockchip,rk3328-dw-mshc 39 39 - rockchip,rk3368-dw-mshc 40 40 - rockchip,rk3399-dw-mshc 41 + - rockchip,rk3528-dw-mshc 42 + - rockchip,rk3562-dw-mshc 41 43 - rockchip,rk3568-dw-mshc 42 44 - rockchip,rk3588-dw-mshc 43 45 - rockchip,rv1108-dw-mshc
+2
Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml
··· 24 24 - samsung,exynos5420-dw-mshc-smu 25 25 - samsung,exynos7-dw-mshc 26 26 - samsung,exynos7-dw-mshc-smu 27 + - samsung,exynos7870-dw-mshc 28 + - samsung,exynos7870-dw-mshc-smu 27 29 - items: 28 30 - enum: 29 31 - samsung,exynos5433-dw-mshc-smu
+4 -1
Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml
··· 14 14 compatible: 15 15 oneOf: 16 16 - items: 17 - - const: rockchip,rk3576-dwcmshc 17 + - enum: 18 + - rockchip,rk3528-dwcmshc 19 + - rockchip,rk3562-dwcmshc 20 + - rockchip,rk3576-dwcmshc 18 21 - const: rockchip,rk3588-dwcmshc 19 22 - enum: 20 23 - rockchip,rk3568-dwcmshc
+1
drivers/memstick/host/rtsx_usb_ms.c
··· 813 813 814 814 host->eject = true; 815 815 cancel_work_sync(&host->handle_req); 816 + cancel_delayed_work_sync(&host->poll_card); 816 817 817 818 mutex_lock(&host->host_mutex); 818 819 if (host->req) {
+1 -1
drivers/mmc/core/core.c
··· 335 335 { 336 336 int err; 337 337 338 - if (mrq->cmd && mrq->cmd->has_ext_addr) 338 + if (mrq->cmd->has_ext_addr) 339 339 mmc_send_ext_addr(host, mrq->cmd->ext_addr); 340 340 341 341 init_completion(&mrq->cmd_completion);
+5 -1
drivers/mmc/core/mmc.c
··· 11 11 #include <linux/of.h> 12 12 #include <linux/slab.h> 13 13 #include <linux/stat.h> 14 + #include <linux/string.h> 14 15 #include <linux/pm_runtime.h> 15 16 #include <linux/random.h> 16 17 #include <linux/sysfs.h> ··· 67 66 68 67 /* 69 68 * The selection of the format here is based upon published 70 - * specs from sandisk and from what people have reported. 69 + * specs from SanDisk and from what people have reported. 71 70 */ 72 71 switch (card->csd.mmca_vsn) { 73 72 case 0: /* MMC v1.0 - v1.2 */ ··· 109 108 mmc_hostname(card->host), card->csd.mmca_vsn); 110 109 return -EINVAL; 111 110 } 111 + 112 + /* some product names include trailing whitespace */ 113 + strim(card->cid.prod_name); 112 114 113 115 return 0; 114 116 }
+4
drivers/mmc/core/sd.c
··· 11 11 #include <linux/sizes.h> 12 12 #include <linux/slab.h> 13 13 #include <linux/stat.h> 14 + #include <linux/string.h> 14 15 #include <linux/pm_runtime.h> 15 16 #include <linux/random.h> 16 17 #include <linux/scatterlist.h> ··· 96 95 card->cid.month = unstuff_bits(resp, 8, 4); 97 96 98 97 card->cid.year += 2000; /* SD cards year offset */ 98 + 99 + /* some product names may include trailing whitespace */ 100 + strim(card->cid.prod_name); 99 101 } 100 102 101 103 /*
+1 -1
drivers/mmc/core/sdio_uart.c
··· 471 471 port->icount.cts++; 472 472 tty = tty_port_tty_get(&port->port); 473 473 if (tty && C_CRTSCTS(tty)) { 474 - int cts = (status & UART_MSR_CTS); 474 + bool cts = status & UART_MSR_CTS; 475 475 if (tty->hw_stopped) { 476 476 if (cts) { 477 477 tty->hw_stopped = false;
-12
drivers/mmc/core/slot-gpio.c
··· 159 159 } 160 160 EXPORT_SYMBOL(mmc_gpio_set_cd_wake); 161 161 162 - /* Register an alternate interrupt service routine for 163 - * the card-detect GPIO. 164 - */ 165 - void mmc_gpio_set_cd_isr(struct mmc_host *host, irq_handler_t isr) 166 - { 167 - struct mmc_gpio *ctx = host->slot.handler_priv; 168 - 169 - WARN_ON(ctx->cd_gpio_isr); 170 - ctx->cd_gpio_isr = isr; 171 - } 172 - EXPORT_SYMBOL(mmc_gpio_set_cd_isr); 173 - 174 162 /** 175 163 * mmc_gpiod_request_cd - request a gpio descriptor for card-detection 176 164 * @host: mmc host
+40 -1
drivers/mmc/host/dw_mmc-exynos.c
··· 27 27 DW_MCI_TYPE_EXYNOS5420_SMU, 28 28 DW_MCI_TYPE_EXYNOS7, 29 29 DW_MCI_TYPE_EXYNOS7_SMU, 30 + DW_MCI_TYPE_EXYNOS7870, 31 + DW_MCI_TYPE_EXYNOS7870_SMU, 30 32 DW_MCI_TYPE_ARTPEC8, 31 33 }; 32 34 ··· 72 70 .compatible = "samsung,exynos7-dw-mshc-smu", 73 71 .ctrl_type = DW_MCI_TYPE_EXYNOS7_SMU, 74 72 }, { 73 + .compatible = "samsung,exynos7870-dw-mshc", 74 + .ctrl_type = DW_MCI_TYPE_EXYNOS7870, 75 + }, { 76 + .compatible = "samsung,exynos7870-dw-mshc-smu", 77 + .ctrl_type = DW_MCI_TYPE_EXYNOS7870_SMU, 78 + }, { 75 79 .compatible = "axis,artpec8-dw-mshc", 76 80 .ctrl_type = DW_MCI_TYPE_ARTPEC8, 77 81 }, ··· 93 85 return EXYNOS4210_FIXED_CIU_CLK_DIV; 94 86 else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 95 87 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 88 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 89 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 96 90 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 97 91 return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; 98 92 else ··· 110 100 * set for non-ecryption mode at this time. 111 101 */ 112 102 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU || 113 - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) { 103 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 104 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU) { 114 105 mci_writel(host, MPSBEGIN0, 0); 115 106 mci_writel(host, MPSEND0, SDMMC_ENDING_SEC_NR_MAX); 116 107 mci_writel(host, MPSCTRL0, SDMMC_MPSCTRL_SECURE_WRITE_BIT | ··· 137 126 DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); 138 127 } 139 128 129 + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 130 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU) { 131 + /* Quirk needed for certain Exynos SoCs */ 132 + host->quirks |= DW_MMC_QUIRK_FIFO64_32; 133 + } 134 + 140 135 if (priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) { 141 136 /* Quirk needed for the ARTPEC-8 SoC */ 142 137 host->quirks |= DW_MMC_QUIRK_EXTENDED_TMOUT; ··· 160 143 161 144 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 162 145 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 146 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 147 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 163 148 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 164 149 clksel = mci_readl(host, CLKSEL64); 165 150 else ··· 171 152 172 153 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 173 154 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 155 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 156 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 174 157 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 175 158 mci_writel(host, CLKSEL64, clksel); 176 159 else ··· 243 222 244 223 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 245 224 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 225 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 226 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 246 227 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 247 228 clksel = mci_readl(host, CLKSEL64); 248 229 else ··· 253 230 if (clksel & SDMMC_CLKSEL_WAKEUP_INT) { 254 231 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 255 232 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 233 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 234 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 256 235 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 257 236 mci_writel(host, CLKSEL64, clksel); 258 237 else ··· 434 409 435 410 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 436 411 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 412 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 413 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 437 414 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 438 415 return SDMMC_CLKSEL_CCLK_SAMPLE(mci_readl(host, CLKSEL64)); 439 416 else ··· 449 422 450 423 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 451 424 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 425 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 426 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 452 427 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 453 428 clksel = mci_readl(host, CLKSEL64); 454 429 else ··· 458 429 clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); 459 430 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 460 431 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 432 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 433 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 461 434 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 462 435 mci_writel(host, CLKSEL64, clksel); 463 436 else ··· 474 443 475 444 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 476 445 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 446 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 447 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 477 448 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 478 449 clksel = mci_readl(host, CLKSEL64); 479 450 else ··· 486 453 487 454 if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || 488 455 priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU || 456 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870 || 457 + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7870_SMU || 489 458 priv->ctrl_type == DW_MCI_TYPE_ARTPEC8) 490 459 mci_writel(host, CLKSEL64, clksel); 491 460 else ··· 666 631 { .compatible = "samsung,exynos7-dw-mshc", 667 632 .data = &exynos_drv_data, }, 668 633 { .compatible = "samsung,exynos7-dw-mshc-smu", 634 + .data = &exynos_drv_data, }, 635 + { .compatible = "samsung,exynos7870-dw-mshc", 636 + .data = &exynos_drv_data, }, 637 + { .compatible = "samsung,exynos7870-dw-mshc-smu", 669 638 .data = &exynos_drv_data, }, 670 639 { .compatible = "axis,artpec8-dw-mshc", 671 640 .data = &artpec_drv_data, },
+92 -2
drivers/mmc/host/dw_mmc.c
··· 2578 2578 } 2579 2579 } 2580 2580 2581 + static void dw_mci_push_data64_32(struct dw_mci *host, void *buf, int cnt) 2582 + { 2583 + struct mmc_data *data = host->data; 2584 + int init_cnt = cnt; 2585 + 2586 + /* try and push anything in the part_buf */ 2587 + if (unlikely(host->part_buf_count)) { 2588 + int len = dw_mci_push_part_bytes(host, buf, cnt); 2589 + 2590 + buf += len; 2591 + cnt -= len; 2592 + 2593 + if (host->part_buf_count == 8) { 2594 + mci_fifo_l_writeq(host->fifo_reg, host->part_buf); 2595 + host->part_buf_count = 0; 2596 + } 2597 + } 2598 + #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 2599 + if (unlikely((unsigned long)buf & 0x7)) { 2600 + while (cnt >= 8) { 2601 + u64 aligned_buf[16]; 2602 + int len = min(cnt & -8, (int)sizeof(aligned_buf)); 2603 + int items = len >> 3; 2604 + int i; 2605 + /* memcpy from input buffer into aligned buffer */ 2606 + memcpy(aligned_buf, buf, len); 2607 + buf += len; 2608 + cnt -= len; 2609 + /* push data from aligned buffer into fifo */ 2610 + for (i = 0; i < items; ++i) 2611 + mci_fifo_l_writeq(host->fifo_reg, aligned_buf[i]); 2612 + } 2613 + } else 2614 + #endif 2615 + { 2616 + u64 *pdata = buf; 2617 + 2618 + for (; cnt >= 8; cnt -= 8) 2619 + mci_fifo_l_writeq(host->fifo_reg, *pdata++); 2620 + buf = pdata; 2621 + } 2622 + /* put anything remaining in the part_buf */ 2623 + if (cnt) { 2624 + dw_mci_set_part_bytes(host, buf, cnt); 2625 + /* Push data if we have reached the expected data length */ 2626 + if ((data->bytes_xfered + init_cnt) == 2627 + (data->blksz * data->blocks)) 2628 + mci_fifo_l_writeq(host->fifo_reg, host->part_buf); 2629 + } 2630 + } 2631 + 2632 + static void dw_mci_pull_data64_32(struct dw_mci *host, void *buf, int cnt) 2633 + { 2634 + #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 2635 + if (unlikely((unsigned long)buf & 0x7)) { 2636 + while (cnt >= 8) { 2637 + /* pull data from fifo into aligned buffer */ 2638 + u64 aligned_buf[16]; 2639 + int len = min(cnt & -8, (int)sizeof(aligned_buf)); 2640 + int items = len >> 3; 2641 + int i; 2642 + 2643 + for (i = 0; i < items; ++i) 2644 + aligned_buf[i] = mci_fifo_l_readq(host->fifo_reg); 2645 + 2646 + /* memcpy from aligned buffer into output buffer */ 2647 + memcpy(buf, aligned_buf, len); 2648 + buf += len; 2649 + cnt -= len; 2650 + } 2651 + } else 2652 + #endif 2653 + { 2654 + u64 *pdata = buf; 2655 + 2656 + for (; cnt >= 8; cnt -= 8) 2657 + *pdata++ = mci_fifo_l_readq(host->fifo_reg); 2658 + buf = pdata; 2659 + } 2660 + if (cnt) { 2661 + host->part_buf = mci_fifo_l_readq(host->fifo_reg); 2662 + dw_mci_pull_final_bytes(host, buf, cnt); 2663 + } 2664 + } 2665 + 2581 2666 static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) 2582 2667 { 2583 2668 int len; ··· 3463 3378 width = 16; 3464 3379 host->data_shift = 1; 3465 3380 } else if (i == 2) { 3466 - host->push_data = dw_mci_push_data64; 3467 - host->pull_data = dw_mci_pull_data64; 3381 + if ((host->quirks & DW_MMC_QUIRK_FIFO64_32)) { 3382 + host->push_data = dw_mci_push_data64_32; 3383 + host->pull_data = dw_mci_pull_data64_32; 3384 + } else { 3385 + host->push_data = dw_mci_push_data64; 3386 + host->pull_data = dw_mci_pull_data64; 3387 + } 3468 3388 width = 64; 3469 3389 host->data_shift = 3; 3470 3390 } else {
+27
drivers/mmc/host/dw_mmc.h
··· 281 281 282 282 /* Support for longer data read timeout */ 283 283 #define DW_MMC_QUIRK_EXTENDED_TMOUT BIT(0) 284 + /* Force 32-bit access to the FIFO */ 285 + #define DW_MMC_QUIRK_FIFO64_32 BIT(1) 284 286 285 287 #define DW_MMC_240A 0x240a 286 288 #define DW_MMC_280A 0x280a ··· 473 471 #define mci_fifo_writew(__value, __reg) __raw_writew(__reg, __value) 474 472 #define mci_fifo_writel(__value, __reg) __raw_writel(__reg, __value) 475 473 #define mci_fifo_writeq(__value, __reg) __raw_writeq(__reg, __value) 474 + 475 + /* 476 + * Some dw_mmc devices have 64-bit FIFOs, but expect them to be 477 + * accessed using two 32-bit accesses. If such controller is used 478 + * with a 64-bit kernel, this has to be done explicitly. 479 + */ 480 + static inline u64 mci_fifo_l_readq(void __iomem *addr) 481 + { 482 + u64 ans; 483 + u32 proxy[2]; 484 + 485 + proxy[0] = mci_fifo_readl(addr); 486 + proxy[1] = mci_fifo_readl(addr + 4); 487 + memcpy(&ans, proxy, 8); 488 + return ans; 489 + } 490 + 491 + static inline void mci_fifo_l_writeq(void __iomem *addr, u64 value) 492 + { 493 + u32 proxy[2]; 494 + 495 + memcpy(proxy, &value, 8); 496 + mci_fifo_writel(addr, proxy[0]); 497 + mci_fifo_writel(addr + 4, proxy[1]); 498 + } 476 499 477 500 /* Register access macros */ 478 501 #define mci_readl(dev, reg) \
+13 -6
drivers/mmc/host/omap.c
··· 1272 1272 /* Check for some optional GPIO controls */ 1273 1273 slot->vsd = devm_gpiod_get_index_optional(host->dev, "vsd", 1274 1274 id, GPIOD_OUT_LOW); 1275 - if (IS_ERR(slot->vsd)) 1276 - return dev_err_probe(host->dev, PTR_ERR(slot->vsd), 1275 + if (IS_ERR(slot->vsd)) { 1276 + r = dev_err_probe(host->dev, PTR_ERR(slot->vsd), 1277 1277 "error looking up VSD GPIO\n"); 1278 + goto err_free_host; 1279 + } 1278 1280 slot->vio = devm_gpiod_get_index_optional(host->dev, "vio", 1279 1281 id, GPIOD_OUT_LOW); 1280 - if (IS_ERR(slot->vio)) 1281 - return dev_err_probe(host->dev, PTR_ERR(slot->vio), 1282 + if (IS_ERR(slot->vio)) { 1283 + r = dev_err_probe(host->dev, PTR_ERR(slot->vio), 1282 1284 "error looking up VIO GPIO\n"); 1285 + goto err_free_host; 1286 + } 1283 1287 slot->cover = devm_gpiod_get_index_optional(host->dev, "cover", 1284 1288 id, GPIOD_IN); 1285 - if (IS_ERR(slot->cover)) 1286 - return dev_err_probe(host->dev, PTR_ERR(slot->cover), 1289 + if (IS_ERR(slot->cover)) { 1290 + r = dev_err_probe(host->dev, PTR_ERR(slot->cover), 1287 1291 "error looking up cover switch GPIO\n"); 1292 + goto err_free_host; 1293 + } 1288 1294 1289 1295 host->slots[id] = slot; 1290 1296 ··· 1350 1344 device_remove_file(&mmc->class_dev, &dev_attr_slot_name); 1351 1345 err_remove_host: 1352 1346 mmc_remove_host(mmc); 1347 + err_free_host: 1353 1348 mmc_free_host(mmc); 1354 1349 return r; 1355 1350 }
+1
drivers/mmc/host/renesas_sdhi.h
··· 95 95 96 96 struct reset_control *rstc; 97 97 struct tmio_mmc_host *host; 98 + struct regulator_dev *rdev; 98 99 }; 99 100 100 101 #define host_to_priv(host) \
+131
drivers/mmc/host/renesas_sdhi_core.c
··· 32 32 #include <linux/platform_device.h> 33 33 #include <linux/pm_domain.h> 34 34 #include <linux/regulator/consumer.h> 35 + #include <linux/regulator/driver.h> 36 + #include <linux/regulator/of_regulator.h> 35 37 #include <linux/reset.h> 36 38 #include <linux/sh_dma.h> 37 39 #include <linux/slab.h> ··· 583 581 584 582 if (!preserve) { 585 583 if (priv->rstc) { 584 + u32 sd_status; 585 + /* 586 + * HW reset might have toggled the regulator state in 587 + * HW which regulator core might be unaware of so save 588 + * and restore the regulator state during HW reset. 589 + */ 590 + if (priv->rdev) 591 + sd_status = sd_ctrl_read32(host, CTL_SD_STATUS); 592 + 586 593 reset_control_reset(priv->rstc); 587 594 /* Unknown why but without polling reset status, it will hang */ 588 595 read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100, 589 596 false, priv->rstc); 590 597 /* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */ 591 598 sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); 599 + if (priv->rdev) 600 + sd_ctrl_write32(host, CTL_SD_STATUS, sd_status); 601 + 592 602 priv->needs_adjust_hs400 = false; 593 603 renesas_sdhi_set_clock(host, host->clk_cache); 594 604 ··· 918 904 renesas_sdhi_sdbuf_width(host, enable ? width : 16); 919 905 } 920 906 907 + static const unsigned int renesas_sdhi_vqmmc_voltages[] = { 908 + 3300000, 1800000 909 + }; 910 + 911 + static int renesas_sdhi_regulator_disable(struct regulator_dev *rdev) 912 + { 913 + struct tmio_mmc_host *host = rdev_get_drvdata(rdev); 914 + u32 sd_status; 915 + 916 + sd_status = sd_ctrl_read32(host, CTL_SD_STATUS); 917 + sd_status &= ~SD_STATUS_PWEN; 918 + sd_ctrl_write32(host, CTL_SD_STATUS, sd_status); 919 + 920 + return 0; 921 + } 922 + 923 + static int renesas_sdhi_regulator_enable(struct regulator_dev *rdev) 924 + { 925 + struct tmio_mmc_host *host = rdev_get_drvdata(rdev); 926 + u32 sd_status; 927 + 928 + sd_status = sd_ctrl_read32(host, CTL_SD_STATUS); 929 + sd_status |= SD_STATUS_PWEN; 930 + sd_ctrl_write32(host, CTL_SD_STATUS, sd_status); 931 + 932 + return 0; 933 + } 934 + 935 + static int renesas_sdhi_regulator_is_enabled(struct regulator_dev *rdev) 936 + { 937 + struct tmio_mmc_host *host = rdev_get_drvdata(rdev); 938 + u32 sd_status; 939 + 940 + sd_status = sd_ctrl_read32(host, CTL_SD_STATUS); 941 + 942 + return (sd_status & SD_STATUS_PWEN) ? 1 : 0; 943 + } 944 + 945 + static int renesas_sdhi_regulator_get_voltage(struct regulator_dev *rdev) 946 + { 947 + struct tmio_mmc_host *host = rdev_get_drvdata(rdev); 948 + u32 sd_status; 949 + 950 + sd_status = sd_ctrl_read32(host, CTL_SD_STATUS); 951 + 952 + return (sd_status & SD_STATUS_IOVS) ? 1800000 : 3300000; 953 + } 954 + 955 + static int renesas_sdhi_regulator_set_voltage(struct regulator_dev *rdev, 956 + int min_uV, int max_uV, 957 + unsigned int *selector) 958 + { 959 + struct tmio_mmc_host *host = rdev_get_drvdata(rdev); 960 + u32 sd_status; 961 + 962 + sd_status = sd_ctrl_read32(host, CTL_SD_STATUS); 963 + if (min_uV >= 1700000 && max_uV <= 1950000) { 964 + sd_status |= SD_STATUS_IOVS; 965 + *selector = 1; 966 + } else { 967 + sd_status &= ~SD_STATUS_IOVS; 968 + *selector = 0; 969 + } 970 + sd_ctrl_write32(host, CTL_SD_STATUS, sd_status); 971 + 972 + return 0; 973 + } 974 + 975 + static int renesas_sdhi_regulator_list_voltage(struct regulator_dev *rdev, 976 + unsigned int selector) 977 + { 978 + if (selector >= ARRAY_SIZE(renesas_sdhi_vqmmc_voltages)) 979 + return -EINVAL; 980 + 981 + return renesas_sdhi_vqmmc_voltages[selector]; 982 + } 983 + 984 + static const struct regulator_ops renesas_sdhi_regulator_voltage_ops = { 985 + .enable = renesas_sdhi_regulator_enable, 986 + .disable = renesas_sdhi_regulator_disable, 987 + .is_enabled = renesas_sdhi_regulator_is_enabled, 988 + .list_voltage = renesas_sdhi_regulator_list_voltage, 989 + .get_voltage = renesas_sdhi_regulator_get_voltage, 990 + .set_voltage = renesas_sdhi_regulator_set_voltage, 991 + }; 992 + 993 + static const struct regulator_desc renesas_sdhi_vqmmc_regulator = { 994 + .name = "sdhi-vqmmc-regulator", 995 + .of_match = of_match_ptr("vqmmc-regulator"), 996 + .type = REGULATOR_VOLTAGE, 997 + .owner = THIS_MODULE, 998 + .ops = &renesas_sdhi_regulator_voltage_ops, 999 + .volt_table = renesas_sdhi_vqmmc_voltages, 1000 + .n_voltages = ARRAY_SIZE(renesas_sdhi_vqmmc_voltages), 1001 + }; 1002 + 921 1003 int renesas_sdhi_probe(struct platform_device *pdev, 922 1004 const struct tmio_mmc_dma_ops *dma_ops, 923 1005 const struct renesas_sdhi_of_data *of_data, ··· 1021 911 { 1022 912 struct tmio_mmc_data *mmd = pdev->dev.platform_data; 1023 913 struct tmio_mmc_data *mmc_data; 914 + struct regulator_config rcfg = { .dev = &pdev->dev, }; 915 + struct regulator_dev *rdev; 1024 916 struct renesas_sdhi_dma *dma_priv; 917 + struct device *dev = &pdev->dev; 1025 918 struct tmio_mmc_host *host; 1026 919 struct renesas_sdhi *priv; 1027 920 int num_irqs, irq, ret, i; ··· 1165 1052 ret = renesas_sdhi_clk_enable(host); 1166 1053 if (ret) 1167 1054 goto efree; 1055 + 1056 + rcfg.of_node = of_get_child_by_name(dev->of_node, "vqmmc-regulator"); 1057 + if (!of_device_is_available(rcfg.of_node)) { 1058 + of_node_put(rcfg.of_node); 1059 + rcfg.of_node = NULL; 1060 + } 1061 + 1062 + if (rcfg.of_node) { 1063 + rcfg.driver_data = priv->host; 1064 + rdev = devm_regulator_register(dev, &renesas_sdhi_vqmmc_regulator, &rcfg); 1065 + of_node_put(rcfg.of_node); 1066 + if (IS_ERR(rdev)) { 1067 + dev_err(dev, "regulator register failed err=%ld", PTR_ERR(rdev)); 1068 + ret = PTR_ERR(rdev); 1069 + goto efree; 1070 + } 1071 + priv->rdev = rdev; 1072 + } 1168 1073 1169 1074 ver = sd_ctrl_read16(host, CTL_VERSION); 1170 1075 /* GEN2_SDR104 is first known SDHI to use 32bit block count */
+15 -57
drivers/mmc/host/sdhci-of-dwcmshc.c
··· 328 328 sdhci_request(mmc, mrq); 329 329 } 330 330 331 - static void dwcmshc_phy_1_8v_init(struct sdhci_host *host) 331 + static void dwcmshc_phy_init(struct sdhci_host *host) 332 332 { 333 333 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 334 334 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); 335 + u32 rxsel = PHY_PAD_RXSEL_3V3; 335 336 u32 val; 337 + 338 + if (priv->flags & FLAG_IO_FIXED_1V8 || 339 + host->mmc->ios.timing & MMC_SIGNAL_VOLTAGE_180) 340 + rxsel = PHY_PAD_RXSEL_1V8; 336 341 337 342 /* deassert phy reset & set tx drive strength */ 338 343 val = PHY_CNFG_RSTN_DEASSERT; ··· 358 353 sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R); 359 354 360 355 /* configure phy pads */ 361 - val = PHY_PAD_RXSEL_1V8; 356 + val = rxsel; 362 357 val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLUP); 363 358 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); 364 359 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N); ··· 370 365 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N); 371 366 sdhci_writew(host, val, PHY_CLKPAD_CNFG_R); 372 367 373 - val = PHY_PAD_RXSEL_1V8; 368 + val = rxsel; 374 369 val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLDOWN); 375 370 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); 376 371 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N); 377 372 sdhci_writew(host, val, PHY_STBPAD_CNFG_R); 378 373 379 374 /* enable data strobe mode */ 380 - sdhci_writeb(host, FIELD_PREP(PHY_DLLDL_CNFG_SLV_INPSEL_MASK, PHY_DLLDL_CNFG_SLV_INPSEL), 381 - PHY_DLLDL_CNFG_R); 375 + if (rxsel == PHY_PAD_RXSEL_1V8) { 376 + u8 sel = FIELD_PREP(PHY_DLLDL_CNFG_SLV_INPSEL_MASK, PHY_DLLDL_CNFG_SLV_INPSEL); 377 + 378 + sdhci_writeb(host, sel, PHY_DLLDL_CNFG_R); 379 + } 382 380 383 381 /* enable phy dll */ 384 382 sdhci_writeb(host, PHY_DLL_CTRL_ENABLE, PHY_DLL_CTRL_R); 385 - } 386 383 387 - static void dwcmshc_phy_3_3v_init(struct sdhci_host *host) 388 - { 389 - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); 390 - struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host); 391 - u32 val; 392 - 393 - /* deassert phy reset & set tx drive strength */ 394 - val = PHY_CNFG_RSTN_DEASSERT; 395 - val |= FIELD_PREP(PHY_CNFG_PAD_SP_MASK, PHY_CNFG_PAD_SP); 396 - val |= FIELD_PREP(PHY_CNFG_PAD_SN_MASK, PHY_CNFG_PAD_SN); 397 - sdhci_writel(host, val, PHY_CNFG_R); 398 - 399 - /* disable delay line */ 400 - sdhci_writeb(host, PHY_SDCLKDL_CNFG_UPDATE, PHY_SDCLKDL_CNFG_R); 401 - 402 - /* set delay line */ 403 - sdhci_writeb(host, priv->delay_line, PHY_SDCLKDL_DC_R); 404 - sdhci_writeb(host, PHY_DLL_CNFG2_JUMPSTEP, PHY_DLL_CNFG2_R); 405 - 406 - /* enable delay lane */ 407 - val = sdhci_readb(host, PHY_SDCLKDL_CNFG_R); 408 - val &= ~(PHY_SDCLKDL_CNFG_UPDATE); 409 - sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R); 410 - 411 - /* configure phy pads */ 412 - val = PHY_PAD_RXSEL_3V3; 413 - val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLUP); 414 - val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); 415 - val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N); 416 - sdhci_writew(host, val, PHY_CMDPAD_CNFG_R); 417 - sdhci_writew(host, val, PHY_DATAPAD_CNFG_R); 418 - sdhci_writew(host, val, PHY_RSTNPAD_CNFG_R); 419 - 420 - val = FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); 421 - val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N); 422 - sdhci_writew(host, val, PHY_CLKPAD_CNFG_R); 423 - 424 - val = PHY_PAD_RXSEL_3V3; 425 - val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLDOWN); 426 - val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P); 427 - val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N); 428 - sdhci_writew(host, val, PHY_STBPAD_CNFG_R); 429 - 430 - /* enable phy dll */ 431 - sdhci_writeb(host, PHY_DLL_CTRL_ENABLE, PHY_DLL_CTRL_R); 432 384 } 433 385 434 386 static void th1520_sdhci_set_phy(struct sdhci_host *host) ··· 395 433 u32 emmc_caps = MMC_CAP2_NO_SD | MMC_CAP2_NO_SDIO; 396 434 u16 emmc_ctrl; 397 435 398 - /* Before power on, set PHY configs */ 399 - if (priv->flags & FLAG_IO_FIXED_1V8) 400 - dwcmshc_phy_1_8v_init(host); 401 - else 402 - dwcmshc_phy_3_3v_init(host); 436 + dwcmshc_phy_init(host); 403 437 404 438 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) { 405 439 emmc_ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL); ··· 1121 1163 .get_max_clock = dwcmshc_get_max_clock, 1122 1164 .reset = th1520_sdhci_reset, 1123 1165 .adma_write_desc = dwcmshc_adma_write_desc, 1124 - .voltage_switch = dwcmshc_phy_1_8v_init, 1166 + .voltage_switch = dwcmshc_phy_init, 1125 1167 .platform_execute_tuning = th1520_execute_tuning, 1126 1168 }; 1127 1169
+2 -2
drivers/mmc/host/sdhci-omap.c
··· 1339 1339 /* R1B responses is required to properly manage HW busy detection. */ 1340 1340 mmc->caps |= MMC_CAP_NEED_RSP_BUSY; 1341 1341 1342 - /* Allow card power off and runtime PM for eMMC/SD card devices */ 1343 - mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_AGGRESSIVE_PM; 1342 + /* Enable SDIO card power off. */ 1343 + mmc->caps |= MMC_CAP_POWER_OFF_CARD; 1344 1344 1345 1345 ret = sdhci_setup_host(host); 1346 1346 if (ret)
+5 -1
drivers/mmc/host/sdhci-pci-core.c
··· 610 610 611 611 sdhci_set_power(host, mode, vdd); 612 612 613 - if (mode == MMC_POWER_OFF) 613 + if (mode == MMC_POWER_OFF) { 614 + if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD || 615 + slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_SD) 616 + usleep_range(15000, 17500); 614 617 return; 618 + } 615 619 616 620 /* 617 621 * Bus power might not enable after D3 -> D0 transition due to the
+1
drivers/mmc/host/sdhci-pxav3.c
··· 399 399 if (!IS_ERR(pxa->clk_core)) 400 400 clk_prepare_enable(pxa->clk_core); 401 401 402 + host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; 402 403 /* enable 1/8V DDR capable */ 403 404 host->mmc->caps |= MMC_CAP_1_8V_DDR; 404 405
+7 -2
drivers/mmc/host/sdhci.c
··· 2065 2065 2066 2066 host->mmc->actual_clock = 0; 2067 2067 2068 - sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); 2068 + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 2069 + if (clk & SDHCI_CLOCK_CARD_EN) 2070 + sdhci_writew(host, clk & ~SDHCI_CLOCK_CARD_EN, 2071 + SDHCI_CLOCK_CONTROL); 2069 2072 2070 - if (clock == 0) 2073 + if (clock == 0) { 2074 + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); 2071 2075 return; 2076 + } 2072 2077 2073 2078 clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); 2074 2079 sdhci_enable_clk(host, clk);
+10
drivers/mmc/host/tmio_mmc.h
··· 44 44 #define CTL_RESET_SD 0xe0 45 45 #define CTL_VERSION 0xe2 46 46 #define CTL_SDIF_MODE 0xe6 /* only known on R-Car 2+ */ 47 + #define CTL_SD_STATUS 0xf2 /* only known on RZ/{G2L,G3E,V2H} */ 47 48 48 49 /* Definitions for values the CTL_STOP_INTERNAL_ACTION register can take */ 49 50 #define TMIO_STOP_STP BIT(0) ··· 103 102 104 103 /* Definitions for values the CTL_SDIF_MODE register can take */ 105 104 #define SDIF_MODE_HS400 BIT(0) /* only known on R-Car 2+ */ 105 + 106 + /* Definitions for values the CTL_SD_STATUS register can take */ 107 + #define SD_STATUS_PWEN BIT(0) /* only known on RZ/{G3E,V2H} */ 108 + #define SD_STATUS_IOVS BIT(16) /* only known on RZ/{G3E,V2H} */ 106 109 107 110 /* Define some IRQ masks */ 108 111 /* This is the mask used at reset by the chip */ ··· 229 224 { 230 225 return ioread16(host->ctl + (addr << host->bus_shift)) | 231 226 ioread16(host->ctl + ((addr + 2) << host->bus_shift)) << 16; 227 + } 228 + 229 + static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr) 230 + { 231 + return ioread32(host->ctl + (addr << host->bus_shift)); 232 232 } 233 233 234 234 static inline void sd_ctrl_read32_rep(struct tmio_mmc_host *host, int addr,
-1
include/linux/mmc/slot-gpio.h
··· 22 22 int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, 23 23 unsigned int idx, unsigned int debounce); 24 24 int mmc_gpiod_set_cd_config(struct mmc_host *host, unsigned long config); 25 - void mmc_gpio_set_cd_isr(struct mmc_host *host, irq_handler_t isr); 26 25 int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on); 27 26 void mmc_gpiod_request_cd_irq(struct mmc_host *host); 28 27 bool mmc_can_gpio_cd(struct mmc_host *host);