diff options
66 files changed, 1382 insertions, 431 deletions
diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt index 50bf611a4d2c..13e70409e8ac 100644 --- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt | |||
| @@ -12,6 +12,7 @@ Required properties: | |||
| 12 | - "amlogic,meson-gxbb-mmc" | 12 | - "amlogic,meson-gxbb-mmc" |
| 13 | - "amlogic,meson-gxl-mmc" | 13 | - "amlogic,meson-gxl-mmc" |
| 14 | - "amlogic,meson-gxm-mmc" | 14 | - "amlogic,meson-gxm-mmc" |
| 15 | - "amlogic,meson-axg-mmc" | ||
| 15 | - clocks : A list of phandle + clock-specifier pairs for the clocks listed in clock-names. | 16 | - clocks : A list of phandle + clock-specifier pairs for the clocks listed in clock-names. |
| 16 | - clock-names: Should contain the following: | 17 | - clock-names: Should contain the following: |
| 17 | "core" - Main peripheral bus clock | 18 | "core" - Main peripheral bus clock |
| @@ -19,6 +20,7 @@ Required properties: | |||
| 19 | "clkin1" - Other parent clock of internal mux | 20 | "clkin1" - Other parent clock of internal mux |
| 20 | The driver has an internal mux clock which switches between clkin0 and clkin1 depending on the | 21 | The driver has an internal mux clock which switches between clkin0 and clkin1 depending on the |
| 21 | clock rate requested by the MMC core. | 22 | clock rate requested by the MMC core. |
| 23 | - resets : phandle of the internal reset line | ||
| 22 | 24 | ||
| 23 | Example: | 25 | Example: |
| 24 | 26 | ||
| @@ -29,4 +31,5 @@ Example: | |||
| 29 | clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, <&clkc CLKID_FCLK_DIV2>; | 31 | clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, <&clkc CLKID_FCLK_DIV2>; |
| 30 | clock-names = "core", "clkin0", "clkin1"; | 32 | clock-names = "core", "clkin0", "clkin1"; |
| 31 | pinctrl-0 = <&emmc_pins>; | 33 | pinctrl-0 = <&emmc_pins>; |
| 34 | resets = <&reset RESET_SD_EMMC_A>; | ||
| 32 | }; | 35 | }; |
diff --git a/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt new file mode 100644 index 000000000000..b0f0999ea1a9 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/bluefield-dw-mshc.txt | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | * Mellanox Bluefield SoC specific extensions to the Synopsys Designware | ||
| 2 | Mobile Storage Host Controller | ||
| 3 | |||
| 4 | Read synopsys-dw-mshc.txt for more details | ||
| 5 | |||
| 6 | The Synopsys designware mobile storage host controller is used to interface | ||
| 7 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents | ||
| 8 | differences between the core Synopsys dw mshc controller properties described | ||
| 9 | by synopsys-dw-mshc.txt and the properties used by the Mellanox Bluefield SoC | ||
| 10 | specific extensions to the Synopsys Designware Mobile Storage Host Controller. | ||
| 11 | |||
| 12 | Required Properties: | ||
| 13 | |||
| 14 | * compatible: should be one of the following. | ||
| 15 | - "mellanox,bluefield-dw-mshc": for controllers with Mellanox Bluefield SoC | ||
| 16 | specific extensions. | ||
| 17 | |||
| 18 | Example: | ||
| 19 | |||
| 20 | /* Mellanox Bluefield SoC MMC */ | ||
| 21 | mmc@6008000 { | ||
| 22 | compatible = "mellanox,bluefield-dw-mshc"; | ||
| 23 | reg = <0x6008000 0x400>; | ||
| 24 | interrupts = <32>; | ||
| 25 | fifo-depth = <0x100>; | ||
| 26 | clock-frequency = <24000000>; | ||
| 27 | bus-width = <8>; | ||
| 28 | cap-mmc-highspeed; | ||
| 29 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/jz4740.txt b/Documentation/devicetree/bindings/mmc/jz4740.txt new file mode 100644 index 000000000000..7cd8c432d7c8 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/jz4740.txt | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | * Ingenic JZ47xx MMC controllers | ||
| 2 | |||
| 3 | This file documents the device tree properties used for the MMC controller in | ||
| 4 | Ingenic JZ4740/JZ4780 SoCs. These are in addition to the core MMC properties | ||
| 5 | described in mmc.txt. | ||
| 6 | |||
| 7 | Required properties: | ||
| 8 | - compatible: Should be one of the following: | ||
| 9 | - "ingenic,jz4740-mmc" for the JZ4740 | ||
| 10 | - "ingenic,jz4780-mmc" for the JZ4780 | ||
| 11 | - reg: Should contain the MMC controller registers location and length. | ||
| 12 | - interrupts: Should contain the interrupt specifier of the MMC controller. | ||
| 13 | - clocks: Clock for the MMC controller. | ||
| 14 | |||
| 15 | Optional properties: | ||
| 16 | - dmas: List of DMA specifiers with the controller specific format | ||
| 17 | as described in the generic DMA client binding. A tx and rx | ||
| 18 | specifier is required. | ||
| 19 | - dma-names: RX and TX DMA request names. | ||
| 20 | Should be "rx" and "tx", in that order. | ||
| 21 | |||
| 22 | For additional details on DMA client bindings see ../dma/dma.txt. | ||
| 23 | |||
| 24 | Example: | ||
| 25 | |||
| 26 | mmc0: mmc@13450000 { | ||
| 27 | compatible = "ingenic,jz4780-mmc"; | ||
| 28 | reg = <0x13450000 0x1000>; | ||
| 29 | |||
| 30 | interrupt-parent = <&intc>; | ||
| 31 | interrupts = <37>; | ||
| 32 | |||
| 33 | clocks = <&cgu JZ4780_CLK_MSC0>; | ||
| 34 | clock-names = "mmc"; | ||
| 35 | |||
| 36 | dmas = <&dma JZ4780_DMA_MSC0_RX 0xffffffff>, <&dma JZ4780_DMA_MSC0_TX 0xffffffff>; | ||
| 37 | dma-names = "rx", "tx"; | ||
| 38 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index 467cd7b147ce..f5a0923b34ca 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt | |||
| @@ -19,6 +19,8 @@ Optional properties: | |||
| 19 | - wp-gpios: Specify GPIOs for write protection, see gpio binding | 19 | - wp-gpios: Specify GPIOs for write protection, see gpio binding |
| 20 | - cd-inverted: when present, polarity on the CD line is inverted. See the note | 20 | - cd-inverted: when present, polarity on the CD line is inverted. See the note |
| 21 | below for the case, when a GPIO is used for the CD line | 21 | below for the case, when a GPIO is used for the CD line |
| 22 | - cd-debounce-delay-ms: Set delay time before detecting card after card insert interrupt. | ||
| 23 | It's only valid when cd-gpios is present. | ||
| 22 | - wp-inverted: when present, polarity on the WP line is inverted. See the note | 24 | - wp-inverted: when present, polarity on the WP line is inverted. See the note |
| 23 | below for the case, when a GPIO is used for the WP line | 25 | below for the case, when a GPIO is used for the WP line |
| 24 | - disable-wp: When set no physical WP line is present. This property should | 26 | - disable-wp: When set no physical WP line is present. This property should |
| @@ -56,6 +58,10 @@ Optional properties: | |||
| 56 | - fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type. | 58 | - fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type. |
| 57 | The value <n> is the driver type as specified in the eMMC specification | 59 | The value <n> is the driver type as specified in the eMMC specification |
| 58 | (table 206 in spec version 5.1). | 60 | (table 206 in spec version 5.1). |
| 61 | - post-power-on-delay-ms : It was invented for MMC pwrseq-simple which could | ||
| 62 | be referred to mmc-pwrseq-simple.txt. But now it's reused as a tunable delay | ||
| 63 | waiting for I/O signalling and card power supply to be stable, regardless of | ||
| 64 | whether pwrseq-simple is used. Default to 10ms if no available. | ||
| 59 | 65 | ||
| 60 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line | 66 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line |
| 61 | polarity properties, we have to fix the meaning of the "normal" and "inverted" | 67 | polarity properties, we have to fix the meaning of the "normal" and "inverted" |
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt index 51775a372c06..393848c2138e 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt | |||
| @@ -4,7 +4,14 @@ Refer to mmc.txt for standard MMC bindings. | |||
| 4 | 4 | ||
| 5 | Required properties: | 5 | Required properties: |
| 6 | - compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers | 6 | - compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers |
| 7 | Should be "ti,k2g-sdhci" for K2G | ||
| 7 | - ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1 | 8 | - ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1 |
| 9 | (Not required for K2G). | ||
| 10 | - pinctrl-names: Should be subset of "default", "hs", "sdr12", "sdr25", "sdr50", | ||
| 11 | "ddr50-rev11", "sdr104-rev11", "ddr50", "sdr104", | ||
| 12 | "ddr_1_8v-rev11", "ddr_1_8v" or "ddr_3_3v", "hs200_1_8v-rev11", | ||
| 13 | "hs200_1_8v", | ||
| 14 | - pinctrl-<n> : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt | ||
| 8 | 15 | ||
| 9 | Example: | 16 | Example: |
| 10 | mmc1: mmc@4809c000 { | 17 | mmc1: mmc@4809c000 { |
diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index 2d5287eeed95..ee978c95189d 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt | |||
| @@ -26,6 +26,8 @@ Required properties: | |||
| 26 | "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC | 26 | "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC |
| 27 | "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC | 27 | "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC |
| 28 | "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC | 28 | "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC |
| 29 | "renesas,sdhi-r8a77965" - SDHI IP on R8A77965 SoC | ||
| 30 | "renesas,sdhi-r8a77980" - SDHI IP on R8A77980 SoC | ||
| 29 | "renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC | 31 | "renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC |
| 30 | "renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller | 32 | "renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller |
| 31 | "renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller | 33 | "renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller |
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index 38078594cf97..50cff3cbcc6d 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts | |||
| @@ -36,6 +36,28 @@ | |||
| 36 | clock-frequency = <48000000>; | 36 | clock-frequency = <48000000>; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | &mmc0 { | ||
| 40 | status = "okay"; | ||
| 41 | |||
| 42 | bus-width = <4>; | ||
| 43 | max-frequency = <50000000>; | ||
| 44 | |||
| 45 | pinctrl-names = "default"; | ||
| 46 | pinctrl-0 = <&pins_mmc0>; | ||
| 47 | |||
| 48 | cd-gpios = <&gpf 20 GPIO_ACTIVE_LOW>; | ||
| 49 | }; | ||
| 50 | |||
| 51 | &mmc1 { | ||
| 52 | status = "okay"; | ||
| 53 | |||
| 54 | bus-width = <4>; | ||
| 55 | max-frequency = <50000000>; | ||
| 56 | |||
| 57 | pinctrl-names = "default"; | ||
| 58 | pinctrl-0 = <&pins_mmc1>; | ||
| 59 | }; | ||
| 60 | |||
| 39 | &uart0 { | 61 | &uart0 { |
| 40 | status = "okay"; | 62 | status = "okay"; |
| 41 | 63 | ||
| @@ -203,4 +225,16 @@ | |||
| 203 | groups = "nemc-cs6"; | 225 | groups = "nemc-cs6"; |
| 204 | bias-disable; | 226 | bias-disable; |
| 205 | }; | 227 | }; |
| 228 | |||
| 229 | pins_mmc0: mmc0 { | ||
| 230 | function = "mmc0"; | ||
| 231 | groups = "mmc0-1bit-e", "mmc0-4bit-e"; | ||
| 232 | bias-disable; | ||
| 233 | }; | ||
| 234 | |||
| 235 | pins_mmc1: mmc1 { | ||
| 236 | function = "mmc1"; | ||
| 237 | groups = "mmc1-1bit-d", "mmc1-4bit-d"; | ||
| 238 | bias-disable; | ||
| 239 | }; | ||
| 206 | }; | 240 | }; |
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index 9b5794667aee..b72e53bb7292 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <dt-bindings/clock/jz4780-cgu.h> | 2 | #include <dt-bindings/clock/jz4780-cgu.h> |
| 3 | #include <dt-bindings/dma/jz4780-dma.h> | ||
| 3 | 4 | ||
| 4 | / { | 5 | / { |
| 5 | #address-cells = <1>; | 6 | #address-cells = <1>; |
| @@ -241,6 +242,57 @@ | |||
| 241 | status = "disabled"; | 242 | status = "disabled"; |
| 242 | }; | 243 | }; |
| 243 | 244 | ||
| 245 | dma: dma@13420000 { | ||
| 246 | compatible = "ingenic,jz4780-dma"; | ||
| 247 | reg = <0x13420000 0x10000>; | ||
| 248 | #dma-cells = <2>; | ||
| 249 | |||
| 250 | interrupt-parent = <&intc>; | ||
| 251 | interrupts = <10>; | ||
| 252 | |||
| 253 | clocks = <&cgu JZ4780_CLK_PDMA>; | ||
| 254 | }; | ||
| 255 | |||
| 256 | mmc0: mmc@13450000 { | ||
| 257 | compatible = "ingenic,jz4780-mmc"; | ||
| 258 | reg = <0x13450000 0x1000>; | ||
| 259 | |||
| 260 | interrupt-parent = <&intc>; | ||
| 261 | interrupts = <37>; | ||
| 262 | |||
| 263 | clocks = <&cgu JZ4780_CLK_MSC0>; | ||
| 264 | clock-names = "mmc"; | ||
| 265 | |||
| 266 | cap-sd-highspeed; | ||
| 267 | cap-mmc-highspeed; | ||
| 268 | cap-sdio-irq; | ||
| 269 | dmas = <&dma JZ4780_DMA_MSC0_RX 0xffffffff>, | ||
| 270 | <&dma JZ4780_DMA_MSC0_TX 0xffffffff>; | ||
| 271 | dma-names = "rx", "tx"; | ||
| 272 | |||
| 273 | status = "disabled"; | ||
| 274 | }; | ||
| 275 | |||
| 276 | mmc1: mmc@13460000 { | ||
| 277 | compatible = "ingenic,jz4780-mmc"; | ||
| 278 | reg = <0x13460000 0x1000>; | ||
| 279 | |||
| 280 | interrupt-parent = <&intc>; | ||
| 281 | interrupts = <36>; | ||
| 282 | |||
| 283 | clocks = <&cgu JZ4780_CLK_MSC1>; | ||
| 284 | clock-names = "mmc"; | ||
| 285 | |||
| 286 | cap-sd-highspeed; | ||
| 287 | cap-mmc-highspeed; | ||
| 288 | cap-sdio-irq; | ||
| 289 | dmas = <&dma JZ4780_DMA_MSC1_RX 0xffffffff>, | ||
| 290 | <&dma JZ4780_DMA_MSC1_TX 0xffffffff>; | ||
| 291 | dma-names = "rx", "tx"; | ||
| 292 | |||
| 293 | status = "disabled"; | ||
| 294 | }; | ||
| 295 | |||
| 244 | bch: bch@134d0000 { | 296 | bch: bch@134d0000 { |
| 245 | compatible = "ingenic,jz4780-bch"; | 297 | compatible = "ingenic,jz4780-bch"; |
| 246 | reg = <0x134d0000 0x10000>; | 298 | reg = <0x134d0000 0x10000>; |
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index b5f4ad8f2c45..be23fd25eeaa 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig | |||
| @@ -104,10 +104,14 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y | |||
| 104 | # CONFIG_HID is not set | 104 | # CONFIG_HID is not set |
| 105 | # CONFIG_USB_SUPPORT is not set | 105 | # CONFIG_USB_SUPPORT is not set |
| 106 | CONFIG_MMC=y | 106 | CONFIG_MMC=y |
| 107 | CONFIG_MMC_JZ4740=y | ||
| 107 | CONFIG_RTC_CLASS=y | 108 | CONFIG_RTC_CLASS=y |
| 108 | CONFIG_RTC_DRV_JZ4740=y | 109 | CONFIG_RTC_DRV_JZ4740=y |
| 110 | CONFIG_DMADEVICES=y | ||
| 111 | CONFIG_DMA_JZ4780=y | ||
| 109 | # CONFIG_IOMMU_SUPPORT is not set | 112 | # CONFIG_IOMMU_SUPPORT is not set |
| 110 | CONFIG_MEMORY=y | 113 | CONFIG_MEMORY=y |
| 114 | CONFIG_EXT4_FS=y | ||
| 111 | # CONFIG_DNOTIFY is not set | 115 | # CONFIG_DNOTIFY is not set |
| 112 | CONFIG_PROC_KCORE=y | 116 | CONFIG_PROC_KCORE=y |
| 113 | # CONFIG_PROC_PAGE_MONITOR is not set | 117 | # CONFIG_PROC_PAGE_MONITOR is not set |
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index d89e17829527..a0b9102c4c6e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c | |||
| @@ -2351,7 +2351,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
| 2351 | set_disk_ro(md->disk, md->read_only || default_ro); | 2351 | set_disk_ro(md->disk, md->read_only || default_ro); |
| 2352 | md->disk->flags = GENHD_FL_EXT_DEVT; | 2352 | md->disk->flags = GENHD_FL_EXT_DEVT; |
| 2353 | if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) | 2353 | if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) |
| 2354 | md->disk->flags |= GENHD_FL_NO_PART_SCAN; | 2354 | md->disk->flags |= GENHD_FL_NO_PART_SCAN |
| 2355 | | GENHD_FL_SUPPRESS_PARTITION_INFO; | ||
| 2355 | 2356 | ||
| 2356 | /* | 2357 | /* |
| 2357 | * As discussed on lkml, GENHD_FL_REMOVABLE should: | 2358 | * As discussed on lkml, GENHD_FL_REMOVABLE should: |
| @@ -2965,9 +2966,11 @@ static void mmc_blk_remove(struct mmc_card *card) | |||
| 2965 | mmc_blk_remove_debugfs(card, md); | 2966 | mmc_blk_remove_debugfs(card, md); |
| 2966 | mmc_blk_remove_parts(card, md); | 2967 | mmc_blk_remove_parts(card, md); |
| 2967 | pm_runtime_get_sync(&card->dev); | 2968 | pm_runtime_get_sync(&card->dev); |
| 2968 | mmc_claim_host(card->host); | 2969 | if (md->part_curr != md->part_type) { |
| 2969 | mmc_blk_part_switch(card, md->part_type); | 2970 | mmc_claim_host(card->host); |
| 2970 | mmc_release_host(card->host); | 2971 | mmc_blk_part_switch(card, md->part_type); |
| 2972 | mmc_release_host(card->host); | ||
| 2973 | } | ||
| 2971 | if (card->type != MMC_TYPE_SD_COMBO) | 2974 | if (card->type != MMC_TYPE_SD_COMBO) |
| 2972 | pm_runtime_disable(&card->dev); | 2975 | pm_runtime_disable(&card->dev); |
| 2973 | pm_runtime_put_noidle(&card->dev); | 2976 | pm_runtime_put_noidle(&card->dev); |
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h index 9c821eedd156..1170feb8f969 100644 --- a/drivers/mmc/core/card.h +++ b/drivers/mmc/core/card.h | |||
| @@ -149,6 +149,12 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) | |||
| 149 | card->quirks &= ~data; | 149 | card->quirks &= ~data; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | static inline void __maybe_unused add_limit_rate_quirk(struct mmc_card *card, | ||
| 153 | int data) | ||
| 154 | { | ||
| 155 | card->quirk_max_rate = data; | ||
| 156 | } | ||
| 157 | |||
| 152 | /* | 158 | /* |
| 153 | * Quirk add/remove for MMC products. | 159 | * Quirk add/remove for MMC products. |
| 154 | */ | 160 | */ |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 121ce50b6d5e..281826d1fcca 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -50,9 +50,6 @@ | |||
| 50 | #include "sd_ops.h" | 50 | #include "sd_ops.h" |
| 51 | #include "sdio_ops.h" | 51 | #include "sdio_ops.h" |
| 52 | 52 | ||
| 53 | /* If the device is not responding */ | ||
| 54 | #define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ | ||
| 55 | |||
| 56 | /* The max erase timeout, used when host->max_busy_timeout isn't specified */ | 53 | /* The max erase timeout, used when host->max_busy_timeout isn't specified */ |
| 57 | #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ | 54 | #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ |
| 58 | 55 | ||
| @@ -1484,6 +1481,17 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) | |||
| 1484 | 1481 | ||
| 1485 | } | 1482 | } |
| 1486 | 1483 | ||
| 1484 | void mmc_set_initial_signal_voltage(struct mmc_host *host) | ||
| 1485 | { | ||
| 1486 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ | ||
| 1487 | if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330)) | ||
| 1488 | dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); | ||
| 1489 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) | ||
| 1490 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); | ||
| 1491 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120)) | ||
| 1492 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); | ||
| 1493 | } | ||
| 1494 | |||
| 1487 | int mmc_host_set_uhs_voltage(struct mmc_host *host) | 1495 | int mmc_host_set_uhs_voltage(struct mmc_host *host) |
| 1488 | { | 1496 | { |
| 1489 | u32 clock; | 1497 | u32 clock; |
| @@ -1646,19 +1654,13 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
| 1646 | /* Set initial state and call mmc_set_ios */ | 1654 | /* Set initial state and call mmc_set_ios */ |
| 1647 | mmc_set_initial_state(host); | 1655 | mmc_set_initial_state(host); |
| 1648 | 1656 | ||
| 1649 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ | 1657 | mmc_set_initial_signal_voltage(host); |
| 1650 | if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330)) | ||
| 1651 | dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); | ||
| 1652 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) | ||
| 1653 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); | ||
| 1654 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120)) | ||
| 1655 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); | ||
| 1656 | 1658 | ||
| 1657 | /* | 1659 | /* |
| 1658 | * This delay should be sufficient to allow the power supply | 1660 | * This delay should be sufficient to allow the power supply |
| 1659 | * to reach the minimum voltage. | 1661 | * to reach the minimum voltage. |
| 1660 | */ | 1662 | */ |
| 1661 | mmc_delay(10); | 1663 | mmc_delay(host->ios.power_delay_ms); |
| 1662 | 1664 | ||
| 1663 | mmc_pwrseq_post_power_on(host); | 1665 | mmc_pwrseq_post_power_on(host); |
| 1664 | 1666 | ||
| @@ -1671,7 +1673,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
| 1671 | * This delay must be at least 74 clock sizes, or 1 ms, or the | 1673 | * This delay must be at least 74 clock sizes, or 1 ms, or the |
| 1672 | * time required to reach a stable voltage. | 1674 | * time required to reach a stable voltage. |
| 1673 | */ | 1675 | */ |
| 1674 | mmc_delay(10); | 1676 | mmc_delay(host->ios.power_delay_ms); |
| 1675 | } | 1677 | } |
| 1676 | 1678 | ||
| 1677 | void mmc_power_off(struct mmc_host *host) | 1679 | void mmc_power_off(struct mmc_host *host) |
| @@ -1967,6 +1969,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, | |||
| 1967 | unsigned int qty = 0, busy_timeout = 0; | 1969 | unsigned int qty = 0, busy_timeout = 0; |
| 1968 | bool use_r1b_resp = false; | 1970 | bool use_r1b_resp = false; |
| 1969 | unsigned long timeout; | 1971 | unsigned long timeout; |
| 1972 | int loop_udelay=64, udelay_max=32768; | ||
| 1970 | int err; | 1973 | int err; |
| 1971 | 1974 | ||
| 1972 | mmc_retune_hold(card->host); | 1975 | mmc_retune_hold(card->host); |
| @@ -2091,9 +2094,15 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, | |||
| 2091 | err = -EIO; | 2094 | err = -EIO; |
| 2092 | goto out; | 2095 | goto out; |
| 2093 | } | 2096 | } |
| 2097 | if ((cmd.resp[0] & R1_READY_FOR_DATA) && | ||
| 2098 | R1_CURRENT_STATE(cmd.resp[0]) != R1_STATE_PRG) | ||
| 2099 | break; | ||
| 2100 | |||
| 2101 | usleep_range(loop_udelay, loop_udelay*2); | ||
| 2102 | if (loop_udelay < udelay_max) | ||
| 2103 | loop_udelay *= 2; | ||
| 2104 | } while (1); | ||
| 2094 | 2105 | ||
| 2095 | } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || | ||
| 2096 | (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG)); | ||
| 2097 | out: | 2106 | out: |
| 2098 | mmc_retune_release(card->host); | 2107 | mmc_retune_release(card->host); |
| 2099 | return err; | 2108 | return err; |
| @@ -2435,22 +2444,46 @@ int mmc_hw_reset(struct mmc_host *host) | |||
| 2435 | return -EINVAL; | 2444 | return -EINVAL; |
| 2436 | 2445 | ||
| 2437 | mmc_bus_get(host); | 2446 | mmc_bus_get(host); |
| 2438 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->reset) { | 2447 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->hw_reset) { |
| 2439 | mmc_bus_put(host); | 2448 | mmc_bus_put(host); |
| 2440 | return -EOPNOTSUPP; | 2449 | return -EOPNOTSUPP; |
| 2441 | } | 2450 | } |
| 2442 | 2451 | ||
| 2443 | ret = host->bus_ops->reset(host); | 2452 | ret = host->bus_ops->hw_reset(host); |
| 2444 | mmc_bus_put(host); | 2453 | mmc_bus_put(host); |
| 2445 | 2454 | ||
| 2446 | if (ret) | 2455 | if (ret) |
| 2447 | pr_warn("%s: tried to reset card, got error %d\n", | 2456 | pr_warn("%s: tried to HW reset card, got error %d\n", |
| 2448 | mmc_hostname(host), ret); | 2457 | mmc_hostname(host), ret); |
| 2449 | 2458 | ||
| 2450 | return ret; | 2459 | return ret; |
| 2451 | } | 2460 | } |
| 2452 | EXPORT_SYMBOL(mmc_hw_reset); | 2461 | EXPORT_SYMBOL(mmc_hw_reset); |
| 2453 | 2462 | ||
| 2463 | int mmc_sw_reset(struct mmc_host *host) | ||
| 2464 | { | ||
| 2465 | int ret; | ||
| 2466 | |||
| 2467 | if (!host->card) | ||
| 2468 | return -EINVAL; | ||
| 2469 | |||
| 2470 | mmc_bus_get(host); | ||
| 2471 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->sw_reset) { | ||
| 2472 | mmc_bus_put(host); | ||
| 2473 | return -EOPNOTSUPP; | ||
| 2474 | } | ||
| 2475 | |||
| 2476 | ret = host->bus_ops->sw_reset(host); | ||
| 2477 | mmc_bus_put(host); | ||
| 2478 | |||
| 2479 | if (ret) | ||
| 2480 | pr_warn("%s: tried to SW reset card, got error %d\n", | ||
| 2481 | mmc_hostname(host), ret); | ||
| 2482 | |||
| 2483 | return ret; | ||
| 2484 | } | ||
| 2485 | EXPORT_SYMBOL(mmc_sw_reset); | ||
| 2486 | |||
| 2454 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) | 2487 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) |
| 2455 | { | 2488 | { |
| 2456 | host->f_init = freq; | 2489 | host->f_init = freq; |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index d6303d69071b..9d8f09ac0821 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
| @@ -32,7 +32,8 @@ struct mmc_bus_ops { | |||
| 32 | int (*power_restore)(struct mmc_host *); | 32 | int (*power_restore)(struct mmc_host *); |
| 33 | int (*alive)(struct mmc_host *); | 33 | int (*alive)(struct mmc_host *); |
| 34 | int (*shutdown)(struct mmc_host *); | 34 | int (*shutdown)(struct mmc_host *); |
| 35 | int (*reset)(struct mmc_host *); | 35 | int (*hw_reset)(struct mmc_host *); |
| 36 | int (*sw_reset)(struct mmc_host *); | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 39 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
| @@ -51,6 +52,7 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | |||
| 51 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); | 52 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); |
| 52 | int mmc_host_set_uhs_voltage(struct mmc_host *host); | 53 | int mmc_host_set_uhs_voltage(struct mmc_host *host); |
| 53 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); | 54 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); |
| 55 | void mmc_set_initial_signal_voltage(struct mmc_host *host); | ||
| 54 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | 56 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); |
| 55 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); | 57 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); |
| 56 | int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr, | 58 | int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr, |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 64b03d6eaf18..abf9e884386c 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
| @@ -143,9 +143,6 @@ int mmc_retune(struct mmc_host *host) | |||
| 143 | goto out; | 143 | goto out; |
| 144 | 144 | ||
| 145 | return_to_hs400 = true; | 145 | return_to_hs400 = true; |
| 146 | |||
| 147 | if (host->ops->prepare_hs400_tuning) | ||
| 148 | host->ops->prepare_hs400_tuning(host, &host->ios); | ||
| 149 | } | 146 | } |
| 150 | 147 | ||
| 151 | err = mmc_execute_tuning(host->card); | 148 | err = mmc_execute_tuning(host->card); |
| @@ -179,7 +176,7 @@ static void mmc_retune_timer(struct timer_list *t) | |||
| 179 | int mmc_of_parse(struct mmc_host *host) | 176 | int mmc_of_parse(struct mmc_host *host) |
| 180 | { | 177 | { |
| 181 | struct device *dev = host->parent; | 178 | struct device *dev = host->parent; |
| 182 | u32 bus_width, drv_type; | 179 | u32 bus_width, drv_type, cd_debounce_delay_ms; |
| 183 | int ret; | 180 | int ret; |
| 184 | bool cd_cap_invert, cd_gpio_invert = false; | 181 | bool cd_cap_invert, cd_gpio_invert = false; |
| 185 | bool ro_cap_invert, ro_gpio_invert = false; | 182 | bool ro_cap_invert, ro_gpio_invert = false; |
| @@ -230,11 +227,16 @@ int mmc_of_parse(struct mmc_host *host) | |||
| 230 | } else { | 227 | } else { |
| 231 | cd_cap_invert = device_property_read_bool(dev, "cd-inverted"); | 228 | cd_cap_invert = device_property_read_bool(dev, "cd-inverted"); |
| 232 | 229 | ||
| 230 | if (device_property_read_u32(dev, "cd-debounce-delay-ms", | ||
| 231 | &cd_debounce_delay_ms)) | ||
| 232 | cd_debounce_delay_ms = 200; | ||
| 233 | |||
| 233 | if (device_property_read_bool(dev, "broken-cd")) | 234 | if (device_property_read_bool(dev, "broken-cd")) |
| 234 | host->caps |= MMC_CAP_NEEDS_POLL; | 235 | host->caps |= MMC_CAP_NEEDS_POLL; |
| 235 | 236 | ||
| 236 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, | 237 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, |
| 237 | 0, &cd_gpio_invert); | 238 | cd_debounce_delay_ms, |
| 239 | &cd_gpio_invert); | ||
| 238 | if (!ret) | 240 | if (!ret) |
| 239 | dev_info(host->parent, "Got CD GPIO\n"); | 241 | dev_info(host->parent, "Got CD GPIO\n"); |
| 240 | else if (ret != -ENOENT && ret != -ENOSYS) | 242 | else if (ret != -ENOENT && ret != -ENOSYS) |
| @@ -338,6 +340,9 @@ int mmc_of_parse(struct mmc_host *host) | |||
| 338 | host->dsr_req = 0; | 340 | host->dsr_req = 0; |
| 339 | } | 341 | } |
| 340 | 342 | ||
| 343 | device_property_read_u32(dev, "post-power-on-delay-ms", | ||
| 344 | &host->ios.power_delay_ms); | ||
| 345 | |||
| 341 | return mmc_pwrseq_alloc(host); | 346 | return mmc_pwrseq_alloc(host); |
| 342 | } | 347 | } |
| 343 | 348 | ||
| @@ -403,6 +408,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
| 403 | host->max_blk_count = PAGE_SIZE / 512; | 408 | host->max_blk_count = PAGE_SIZE / 512; |
| 404 | 409 | ||
| 405 | host->fixed_drv_type = -EINVAL; | 410 | host->fixed_drv_type = -EINVAL; |
| 411 | host->ios.power_delay_ms = 10; | ||
| 406 | 412 | ||
| 407 | return host; | 413 | return host; |
| 408 | } | 414 | } |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 6f8ebd6caa4c..4466f5de54d4 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
| @@ -1282,6 +1282,10 @@ int mmc_hs400_to_hs200(struct mmc_card *card) | |||
| 1282 | 1282 | ||
| 1283 | mmc_set_bus_speed(card); | 1283 | mmc_set_bus_speed(card); |
| 1284 | 1284 | ||
| 1285 | /* Prepare tuning for HS400 mode. */ | ||
| 1286 | if (host->ops->prepare_hs400_tuning) | ||
| 1287 | host->ops->prepare_hs400_tuning(host, &host->ios); | ||
| 1288 | |||
| 1285 | return 0; | 1289 | return 0; |
| 1286 | 1290 | ||
| 1287 | out_err: | 1291 | out_err: |
| @@ -1830,6 +1834,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 1830 | } | 1834 | } |
| 1831 | } | 1835 | } |
| 1832 | 1836 | ||
| 1837 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && | ||
| 1838 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
| 1839 | pr_err("%s: Host failed to negotiate down from 3.3V\n", | ||
| 1840 | mmc_hostname(host)); | ||
| 1841 | err = -EINVAL; | ||
| 1842 | goto free_card; | ||
| 1843 | } | ||
| 1844 | |||
| 1833 | if (!oldcard) | 1845 | if (!oldcard) |
| 1834 | host->card = card; | 1846 | host->card = card; |
| 1835 | 1847 | ||
| @@ -2117,7 +2129,7 @@ static int mmc_can_reset(struct mmc_card *card) | |||
| 2117 | return 1; | 2129 | return 1; |
| 2118 | } | 2130 | } |
| 2119 | 2131 | ||
| 2120 | static int mmc_reset(struct mmc_host *host) | 2132 | static int _mmc_hw_reset(struct mmc_host *host) |
| 2121 | { | 2133 | { |
| 2122 | struct mmc_card *card = host->card; | 2134 | struct mmc_card *card = host->card; |
| 2123 | 2135 | ||
| @@ -2151,7 +2163,7 @@ static const struct mmc_bus_ops mmc_ops = { | |||
| 2151 | .runtime_resume = mmc_runtime_resume, | 2163 | .runtime_resume = mmc_runtime_resume, |
| 2152 | .alive = mmc_alive, | 2164 | .alive = mmc_alive, |
| 2153 | .shutdown = mmc_shutdown, | 2165 | .shutdown = mmc_shutdown, |
| 2154 | .reset = mmc_reset, | 2166 | .hw_reset = _mmc_hw_reset, |
| 2155 | }; | 2167 | }; |
| 2156 | 2168 | ||
| 2157 | /* | 2169 | /* |
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c index 13ef162cf066..a8b9fee4d62a 100644 --- a/drivers/mmc/core/pwrseq_simple.c +++ b/drivers/mmc/core/pwrseq_simple.c | |||
| @@ -40,14 +40,18 @@ static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, | |||
| 40 | struct gpio_descs *reset_gpios = pwrseq->reset_gpios; | 40 | struct gpio_descs *reset_gpios = pwrseq->reset_gpios; |
| 41 | 41 | ||
| 42 | if (!IS_ERR(reset_gpios)) { | 42 | if (!IS_ERR(reset_gpios)) { |
| 43 | int i; | 43 | int i, *values; |
| 44 | int values[reset_gpios->ndescs]; | 44 | int nvalues = reset_gpios->ndescs; |
| 45 | 45 | ||
| 46 | for (i = 0; i < reset_gpios->ndescs; i++) | 46 | values = kmalloc_array(nvalues, sizeof(int), GFP_KERNEL); |
| 47 | if (!values) | ||
| 48 | return; | ||
| 49 | |||
| 50 | for (i = 0; i < nvalues; i++) | ||
| 47 | values[i] = value; | 51 | values[i] = value; |
| 48 | 52 | ||
| 49 | gpiod_set_array_value_cansleep( | 53 | gpiod_set_array_value_cansleep(nvalues, reset_gpios->desc, values); |
| 50 | reset_gpios->ndescs, reset_gpios->desc, values); | 54 | kfree(values); |
| 51 | } | 55 | } |
| 52 | } | 56 | } |
| 53 | 57 | ||
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 5153577754f0..dd2f73af8f2c 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h | |||
| @@ -132,6 +132,9 @@ static const struct mmc_fixup sdio_fixup_methods[] = { | |||
| 132 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, | 132 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, |
| 133 | add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), | 133 | add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), |
| 134 | 134 | ||
| 135 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8887WLAN, | ||
| 136 | add_limit_rate_quirk, 150000000), | ||
| 137 | |||
| 135 | END_FIXUP | 138 | END_FIXUP |
| 136 | }; | 139 | }; |
| 137 | 140 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index baf3d5da4ccb..d0d9f90e7cdf 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
| @@ -1058,6 +1058,14 @@ retry: | |||
| 1058 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | 1058 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
| 1059 | } | 1059 | } |
| 1060 | } | 1060 | } |
| 1061 | |||
| 1062 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && | ||
| 1063 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
| 1064 | pr_err("%s: Host failed to negotiate down from 3.3V\n", | ||
| 1065 | mmc_hostname(host)); | ||
| 1066 | err = -EINVAL; | ||
| 1067 | goto free_card; | ||
| 1068 | } | ||
| 1061 | done: | 1069 | done: |
| 1062 | host->card = card; | 1070 | host->card = card; |
| 1063 | return 0; | 1071 | return 0; |
| @@ -1214,7 +1222,7 @@ static int mmc_sd_runtime_resume(struct mmc_host *host) | |||
| 1214 | return 0; | 1222 | return 0; |
| 1215 | } | 1223 | } |
| 1216 | 1224 | ||
| 1217 | static int mmc_sd_reset(struct mmc_host *host) | 1225 | static int mmc_sd_hw_reset(struct mmc_host *host) |
| 1218 | { | 1226 | { |
| 1219 | mmc_power_cycle(host, host->card->ocr); | 1227 | mmc_power_cycle(host, host->card->ocr); |
| 1220 | return mmc_sd_init_card(host, host->card->ocr, host->card); | 1228 | return mmc_sd_init_card(host, host->card->ocr, host->card); |
| @@ -1229,7 +1237,7 @@ static const struct mmc_bus_ops mmc_sd_ops = { | |||
| 1229 | .resume = mmc_sd_resume, | 1237 | .resume = mmc_sd_resume, |
| 1230 | .alive = mmc_sd_alive, | 1238 | .alive = mmc_sd_alive, |
| 1231 | .shutdown = mmc_sd_suspend, | 1239 | .shutdown = mmc_sd_suspend, |
| 1232 | .reset = mmc_sd_reset, | 1240 | .hw_reset = mmc_sd_hw_reset, |
| 1233 | }; | 1241 | }; |
| 1234 | 1242 | ||
| 1235 | /* | 1243 | /* |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index c599a628a387..a86490dbca70 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
| @@ -444,6 +444,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) | |||
| 444 | unsigned int bus_speed, timing; | 444 | unsigned int bus_speed, timing; |
| 445 | int err; | 445 | int err; |
| 446 | unsigned char speed; | 446 | unsigned char speed; |
| 447 | unsigned int max_rate; | ||
| 447 | 448 | ||
| 448 | /* | 449 | /* |
| 449 | * If the host doesn't support any of the UHS-I modes, fallback on | 450 | * If the host doesn't support any of the UHS-I modes, fallback on |
| @@ -500,9 +501,12 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) | |||
| 500 | if (err) | 501 | if (err) |
| 501 | return err; | 502 | return err; |
| 502 | 503 | ||
| 504 | max_rate = min_not_zero(card->quirk_max_rate, | ||
| 505 | card->sw_caps.uhs_max_dtr); | ||
| 506 | |||
| 503 | if (bus_speed) { | 507 | if (bus_speed) { |
| 504 | mmc_set_timing(card->host, timing); | 508 | mmc_set_timing(card->host, timing); |
| 505 | mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); | 509 | mmc_set_clock(card->host, max_rate); |
| 506 | } | 510 | } |
| 507 | 511 | ||
| 508 | return 0; | 512 | return 0; |
| @@ -788,6 +792,14 @@ try_again: | |||
| 788 | if (err) | 792 | if (err) |
| 789 | goto remove; | 793 | goto remove; |
| 790 | } | 794 | } |
| 795 | |||
| 796 | if (host->caps2 & MMC_CAP2_AVOID_3_3V && | ||
| 797 | host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
| 798 | pr_err("%s: Host failed to negotiate down from 3.3V\n", | ||
| 799 | mmc_hostname(host)); | ||
| 800 | err = -EINVAL; | ||
| 801 | goto remove; | ||
| 802 | } | ||
| 791 | finish: | 803 | finish: |
| 792 | if (!oldcard) | 804 | if (!oldcard) |
| 793 | host->card = card; | 805 | host->card = card; |
| @@ -801,6 +813,22 @@ err: | |||
| 801 | return err; | 813 | return err; |
| 802 | } | 814 | } |
| 803 | 815 | ||
| 816 | static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume) | ||
| 817 | { | ||
| 818 | int ret; | ||
| 819 | |||
| 820 | sdio_reset(host); | ||
| 821 | mmc_go_idle(host); | ||
| 822 | mmc_send_if_cond(host, host->card->ocr); | ||
| 823 | |||
| 824 | ret = mmc_send_io_op_cond(host, 0, NULL); | ||
| 825 | if (ret) | ||
| 826 | return ret; | ||
| 827 | |||
| 828 | return mmc_sdio_init_card(host, host->card->ocr, host->card, | ||
| 829 | powered_resume); | ||
| 830 | } | ||
| 831 | |||
| 804 | /* | 832 | /* |
| 805 | * Host is being removed. Free up the current card. | 833 | * Host is being removed. Free up the current card. |
| 806 | */ | 834 | */ |
| @@ -948,14 +976,7 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
| 948 | 976 | ||
| 949 | /* No need to reinitialize powered-resumed nonremovable cards */ | 977 | /* No need to reinitialize powered-resumed nonremovable cards */ |
| 950 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { | 978 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { |
| 951 | sdio_reset(host); | 979 | err = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); |
| 952 | mmc_go_idle(host); | ||
| 953 | mmc_send_if_cond(host, host->card->ocr); | ||
| 954 | err = mmc_send_io_op_cond(host, 0, NULL); | ||
| 955 | if (!err) | ||
| 956 | err = mmc_sdio_init_card(host, host->card->ocr, | ||
| 957 | host->card, | ||
| 958 | mmc_card_keep_power(host)); | ||
| 959 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { | 980 | } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { |
| 960 | /* We may have switched to 1-bit mode during suspend */ | 981 | /* We may have switched to 1-bit mode during suspend */ |
| 961 | err = sdio_enable_4bit_bus(host->card); | 982 | err = sdio_enable_4bit_bus(host->card); |
| @@ -978,8 +999,6 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
| 978 | { | 999 | { |
| 979 | int ret; | 1000 | int ret; |
| 980 | 1001 | ||
| 981 | mmc_claim_host(host); | ||
| 982 | |||
| 983 | /* | 1002 | /* |
| 984 | * Reset the card by performing the same steps that are taken by | 1003 | * Reset the card by performing the same steps that are taken by |
| 985 | * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. | 1004 | * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. |
| @@ -997,20 +1016,12 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
| 997 | * | 1016 | * |
| 998 | */ | 1017 | */ |
| 999 | 1018 | ||
| 1000 | sdio_reset(host); | 1019 | mmc_claim_host(host); |
| 1001 | mmc_go_idle(host); | ||
| 1002 | mmc_send_if_cond(host, host->card->ocr); | ||
| 1003 | |||
| 1004 | ret = mmc_send_io_op_cond(host, 0, NULL); | ||
| 1005 | if (ret) | ||
| 1006 | goto out; | ||
| 1007 | 1020 | ||
| 1008 | ret = mmc_sdio_init_card(host, host->card->ocr, host->card, | 1021 | ret = mmc_sdio_reinit_card(host, mmc_card_keep_power(host)); |
| 1009 | mmc_card_keep_power(host)); | ||
| 1010 | if (!ret && host->sdio_irqs) | 1022 | if (!ret && host->sdio_irqs) |
| 1011 | mmc_signal_sdio_irq(host); | 1023 | mmc_signal_sdio_irq(host); |
| 1012 | 1024 | ||
| 1013 | out: | ||
| 1014 | mmc_release_host(host); | 1025 | mmc_release_host(host); |
| 1015 | 1026 | ||
| 1016 | return ret; | 1027 | return ret; |
| @@ -1039,12 +1050,24 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host) | |||
| 1039 | return ret; | 1050 | return ret; |
| 1040 | } | 1051 | } |
| 1041 | 1052 | ||
| 1042 | static int mmc_sdio_reset(struct mmc_host *host) | 1053 | static int mmc_sdio_hw_reset(struct mmc_host *host) |
| 1043 | { | 1054 | { |
| 1044 | mmc_power_cycle(host, host->card->ocr); | 1055 | mmc_power_cycle(host, host->card->ocr); |
| 1045 | return mmc_sdio_power_restore(host); | 1056 | return mmc_sdio_power_restore(host); |
| 1046 | } | 1057 | } |
| 1047 | 1058 | ||
| 1059 | static int mmc_sdio_sw_reset(struct mmc_host *host) | ||
| 1060 | { | ||
| 1061 | mmc_set_clock(host, host->f_init); | ||
| 1062 | sdio_reset(host); | ||
| 1063 | mmc_go_idle(host); | ||
| 1064 | |||
| 1065 | mmc_set_initial_state(host); | ||
| 1066 | mmc_set_initial_signal_voltage(host); | ||
| 1067 | |||
| 1068 | return mmc_sdio_reinit_card(host, 0); | ||
| 1069 | } | ||
| 1070 | |||
| 1048 | static const struct mmc_bus_ops mmc_sdio_ops = { | 1071 | static const struct mmc_bus_ops mmc_sdio_ops = { |
| 1049 | .remove = mmc_sdio_remove, | 1072 | .remove = mmc_sdio_remove, |
| 1050 | .detect = mmc_sdio_detect, | 1073 | .detect = mmc_sdio_detect, |
| @@ -1055,7 +1078,8 @@ static const struct mmc_bus_ops mmc_sdio_ops = { | |||
| 1055 | .runtime_resume = mmc_sdio_runtime_resume, | 1078 | .runtime_resume = mmc_sdio_runtime_resume, |
| 1056 | .power_restore = mmc_sdio_power_restore, | 1079 | .power_restore = mmc_sdio_power_restore, |
| 1057 | .alive = mmc_sdio_alive, | 1080 | .alive = mmc_sdio_alive, |
| 1058 | .reset = mmc_sdio_reset, | 1081 | .hw_reset = mmc_sdio_hw_reset, |
| 1082 | .sw_reset = mmc_sdio_sw_reset, | ||
| 1059 | }; | 1083 | }; |
| 1060 | 1084 | ||
| 1061 | 1085 | ||
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 31f7dbb15668..ef05e0039378 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c | |||
| @@ -28,15 +28,17 @@ struct mmc_gpio { | |||
| 28 | irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); | 28 | irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); |
| 29 | char *ro_label; | 29 | char *ro_label; |
| 30 | char cd_label[0]; | 30 | char cd_label[0]; |
| 31 | u32 cd_debounce_delay_ms; | ||
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| 33 | static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) | 34 | static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) |
| 34 | { | 35 | { |
| 35 | /* Schedule a card detection after a debounce timeout */ | 36 | /* Schedule a card detection after a debounce timeout */ |
| 36 | struct mmc_host *host = dev_id; | 37 | struct mmc_host *host = dev_id; |
| 38 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
| 37 | 39 | ||
| 38 | host->trigger_card_event = true; | 40 | host->trigger_card_event = true; |
| 39 | mmc_detect_change(host, msecs_to_jiffies(200)); | 41 | mmc_detect_change(host, msecs_to_jiffies(ctx->cd_debounce_delay_ms)); |
| 40 | 42 | ||
| 41 | return IRQ_HANDLED; | 43 | return IRQ_HANDLED; |
| 42 | } | 44 | } |
| @@ -49,6 +51,7 @@ int mmc_gpio_alloc(struct mmc_host *host) | |||
| 49 | 51 | ||
| 50 | if (ctx) { | 52 | if (ctx) { |
| 51 | ctx->ro_label = ctx->cd_label + len; | 53 | ctx->ro_label = ctx->cd_label + len; |
| 54 | ctx->cd_debounce_delay_ms = 200; | ||
| 52 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); | 55 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); |
| 53 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); | 56 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); |
| 54 | host->slot.handler_priv = ctx; | 57 | host->slot.handler_priv = ctx; |
| @@ -76,15 +79,22 @@ EXPORT_SYMBOL(mmc_gpio_get_ro); | |||
| 76 | int mmc_gpio_get_cd(struct mmc_host *host) | 79 | int mmc_gpio_get_cd(struct mmc_host *host) |
| 77 | { | 80 | { |
| 78 | struct mmc_gpio *ctx = host->slot.handler_priv; | 81 | struct mmc_gpio *ctx = host->slot.handler_priv; |
| 82 | int cansleep; | ||
| 79 | 83 | ||
| 80 | if (!ctx || !ctx->cd_gpio) | 84 | if (!ctx || !ctx->cd_gpio) |
| 81 | return -ENOSYS; | 85 | return -ENOSYS; |
| 82 | 86 | ||
| 83 | if (ctx->override_cd_active_level) | 87 | cansleep = gpiod_cansleep(ctx->cd_gpio); |
| 84 | return !gpiod_get_raw_value_cansleep(ctx->cd_gpio) ^ | 88 | if (ctx->override_cd_active_level) { |
| 85 | !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); | 89 | int value = cansleep ? |
| 90 | gpiod_get_raw_value_cansleep(ctx->cd_gpio) : | ||
| 91 | gpiod_get_raw_value(ctx->cd_gpio); | ||
| 92 | return !value ^ !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); | ||
| 93 | } | ||
| 86 | 94 | ||
| 87 | return gpiod_get_value_cansleep(ctx->cd_gpio); | 95 | return cansleep ? |
| 96 | gpiod_get_value_cansleep(ctx->cd_gpio) : | ||
| 97 | gpiod_get_value(ctx->cd_gpio); | ||
| 88 | } | 98 | } |
| 89 | EXPORT_SYMBOL(mmc_gpio_get_cd); | 99 | EXPORT_SYMBOL(mmc_gpio_get_cd); |
| 90 | 100 | ||
| @@ -261,7 +271,7 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | |||
| 261 | if (debounce) { | 271 | if (debounce) { |
| 262 | ret = gpiod_set_debounce(desc, debounce); | 272 | ret = gpiod_set_debounce(desc, debounce); |
| 263 | if (ret < 0) | 273 | if (ret < 0) |
| 264 | return ret; | 274 | ctx->cd_debounce_delay_ms = debounce; |
| 265 | } | 275 | } |
| 266 | 276 | ||
| 267 | if (gpio_invert) | 277 | if (gpio_invert) |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9589f9c9046f..0581c199c996 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
| @@ -345,11 +345,11 @@ config MMC_SDHCI_IPROC | |||
| 345 | If unsure, say N. | 345 | If unsure, say N. |
| 346 | 346 | ||
| 347 | config MMC_MESON_GX | 347 | config MMC_MESON_GX |
| 348 | tristate "Amlogic S905/GX* SD/MMC Host Controller support" | 348 | tristate "Amlogic S905/GX*/AXG SD/MMC Host Controller support" |
| 349 | depends on ARCH_MESON && MMC | 349 | depends on ARCH_MESON && MMC |
| 350 | help | 350 | help |
| 351 | This selects support for the Amlogic SD/MMC Host Controller | 351 | This selects support for the Amlogic SD/MMC Host Controller |
| 352 | found on the S905/GX* family of SoCs. This controller is | 352 | found on the S905/GX*/AXG family of SoCs. This controller is |
| 353 | MMC 5.1 compliant and supports SD, eMMC and SDIO interfaces. | 353 | MMC 5.1 compliant and supports SD, eMMC and SDIO interfaces. |
| 354 | 354 | ||
| 355 | If you have a controller with this interface, say Y here. | 355 | If you have a controller with this interface, say Y here. |
| @@ -358,7 +358,6 @@ config MMC_MESON_MX_SDIO | |||
| 358 | tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support" | 358 | tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support" |
| 359 | depends on ARCH_MESON || COMPILE_TEST | 359 | depends on ARCH_MESON || COMPILE_TEST |
| 360 | depends on COMMON_CLK | 360 | depends on COMMON_CLK |
| 361 | depends on HAS_DMA | ||
| 362 | depends on OF | 361 | depends on OF |
| 363 | help | 362 | help |
| 364 | This selects support for the SD/MMC Host Controller on | 363 | This selects support for the SD/MMC Host Controller on |
| @@ -401,7 +400,6 @@ config MMC_OMAP | |||
| 401 | 400 | ||
| 402 | config MMC_OMAP_HS | 401 | config MMC_OMAP_HS |
| 403 | tristate "TI OMAP High Speed Multimedia Card Interface support" | 402 | tristate "TI OMAP High Speed Multimedia Card Interface support" |
| 404 | depends on HAS_DMA | ||
| 405 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST | 403 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST |
| 406 | help | 404 | help |
| 407 | This selects the TI OMAP High Speed Multimedia card Interface. | 405 | This selects the TI OMAP High Speed Multimedia card Interface. |
| @@ -511,7 +509,6 @@ config MMC_DAVINCI | |||
| 511 | 509 | ||
| 512 | config MMC_GOLDFISH | 510 | config MMC_GOLDFISH |
| 513 | tristate "goldfish qemu Multimedia Card Interface support" | 511 | tristate "goldfish qemu Multimedia Card Interface support" |
| 514 | depends on HAS_DMA | ||
| 515 | depends on GOLDFISH || COMPILE_TEST | 512 | depends on GOLDFISH || COMPILE_TEST |
| 516 | help | 513 | help |
| 517 | This selects the Goldfish Multimedia card Interface emulation | 514 | This selects the Goldfish Multimedia card Interface emulation |
| @@ -605,7 +602,7 @@ config MMC_SDHI | |||
| 605 | 602 | ||
| 606 | config MMC_SDHI_SYS_DMAC | 603 | config MMC_SDHI_SYS_DMAC |
| 607 | tristate "DMA for SDHI SD/SDIO controllers using SYS-DMAC" | 604 | tristate "DMA for SDHI SD/SDIO controllers using SYS-DMAC" |
| 608 | depends on MMC_SDHI && HAS_DMA | 605 | depends on MMC_SDHI |
| 609 | default MMC_SDHI if (SUPERH || ARM) | 606 | default MMC_SDHI if (SUPERH || ARM) |
| 610 | help | 607 | help |
| 611 | This provides DMA support for SDHI SD/SDIO controllers | 608 | This provides DMA support for SDHI SD/SDIO controllers |
| @@ -615,7 +612,7 @@ config MMC_SDHI_SYS_DMAC | |||
| 615 | config MMC_SDHI_INTERNAL_DMAC | 612 | config MMC_SDHI_INTERNAL_DMAC |
| 616 | tristate "DMA for SDHI SD/SDIO controllers using on-chip bus mastering" | 613 | tristate "DMA for SDHI SD/SDIO controllers using on-chip bus mastering" |
| 617 | depends on ARM64 || COMPILE_TEST | 614 | depends on ARM64 || COMPILE_TEST |
| 618 | depends on MMC_SDHI && HAS_DMA | 615 | depends on MMC_SDHI |
| 619 | default MMC_SDHI if ARM64 | 616 | default MMC_SDHI if ARM64 |
| 620 | help | 617 | help |
| 621 | This provides DMA support for SDHI SD/SDIO controllers | 618 | This provides DMA support for SDHI SD/SDIO controllers |
| @@ -669,7 +666,6 @@ config MMC_CAVIUM_THUNDERX | |||
| 669 | 666 | ||
| 670 | config MMC_DW | 667 | config MMC_DW |
| 671 | tristate "Synopsys DesignWare Memory Card Interface" | 668 | tristate "Synopsys DesignWare Memory Card Interface" |
| 672 | depends on HAS_DMA | ||
| 673 | depends on ARC || ARM || ARM64 || MIPS || COMPILE_TEST | 669 | depends on ARC || ARM || ARM64 || MIPS || COMPILE_TEST |
| 674 | help | 670 | help |
| 675 | This selects support for the Synopsys DesignWare Mobile Storage IP | 671 | This selects support for the Synopsys DesignWare Mobile Storage IP |
| @@ -690,6 +686,15 @@ config MMC_DW_PLTFM | |||
| 690 | 686 | ||
| 691 | If unsure, say Y. | 687 | If unsure, say Y. |
| 692 | 688 | ||
| 689 | config MMC_DW_BLUEFIELD | ||
| 690 | tristate "BlueField specific extensions for Synopsys DW Memory Card Interface" | ||
| 691 | depends on MMC_DW | ||
| 692 | select MMC_DW_PLTFM | ||
| 693 | help | ||
| 694 | This selects support for Mellanox BlueField SoC specific extensions to | ||
| 695 | the Synopsys DesignWare Memory Card Interface driver. Select this | ||
| 696 | option for platforms based on Mellanox BlueField SoC's. | ||
| 697 | |||
| 693 | config MMC_DW_EXYNOS | 698 | config MMC_DW_EXYNOS |
| 694 | tristate "Exynos specific extensions for Synopsys DW Memory Card Interface" | 699 | tristate "Exynos specific extensions for Synopsys DW Memory Card Interface" |
| 695 | depends on MMC_DW | 700 | depends on MMC_DW |
| @@ -748,7 +753,6 @@ config MMC_DW_ZX | |||
| 748 | 753 | ||
| 749 | config MMC_SH_MMCIF | 754 | config MMC_SH_MMCIF |
| 750 | tristate "SuperH Internal MMCIF support" | 755 | tristate "SuperH Internal MMCIF support" |
| 751 | depends on HAS_DMA | ||
| 752 | depends on SUPERH || ARCH_RENESAS || COMPILE_TEST | 756 | depends on SUPERH || ARCH_RENESAS || COMPILE_TEST |
| 753 | help | 757 | help |
| 754 | This selects the MMC Host Interface controller (MMCIF) found in various | 758 | This selects the MMC Host Interface controller (MMCIF) found in various |
| @@ -756,11 +760,12 @@ config MMC_SH_MMCIF | |||
| 756 | 760 | ||
| 757 | 761 | ||
| 758 | config MMC_JZ4740 | 762 | config MMC_JZ4740 |
| 759 | tristate "JZ4740 SD/Multimedia Card Interface support" | 763 | tristate "Ingenic JZ47xx SD/Multimedia Card Interface support" |
| 760 | depends on MACH_JZ4740 | 764 | depends on MACH_JZ4740 || MACH_JZ4780 |
| 761 | help | 765 | help |
| 762 | This selects support for the SD/MMC controller on Ingenic JZ4740 | 766 | This selects support for the SD/MMC controller on Ingenic |
| 763 | SoCs. | 767 | JZ4740, JZ4750, JZ4770 and JZ4780 SoCs. |
| 768 | |||
| 764 | If you have a board based on such a SoC and with a SD/MMC slot, | 769 | If you have a board based on such a SoC and with a SD/MMC slot, |
| 765 | say Y or M here. | 770 | say Y or M here. |
| 766 | 771 | ||
| @@ -868,7 +873,6 @@ config MMC_TOSHIBA_PCI | |||
| 868 | config MMC_BCM2835 | 873 | config MMC_BCM2835 |
| 869 | tristate "Broadcom BCM2835 SDHOST MMC Controller support" | 874 | tristate "Broadcom BCM2835 SDHOST MMC Controller support" |
| 870 | depends on ARCH_BCM2835 || COMPILE_TEST | 875 | depends on ARCH_BCM2835 || COMPILE_TEST |
| 871 | depends on HAS_DMA | ||
| 872 | help | 876 | help |
| 873 | This selects the BCM2835 SDHOST MMC controller. If you have | 877 | This selects the BCM2835 SDHOST MMC controller. If you have |
| 874 | a BCM2835 platform with SD or MMC devices, say Y or M here. | 878 | a BCM2835 platform with SD or MMC devices, say Y or M here. |
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 6aead24879b4..85dc1322c3de 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
| @@ -49,6 +49,7 @@ thunderx-mmc-objs := cavium.o cavium-thunderx.o | |||
| 49 | obj-$(CONFIG_MMC_CAVIUM_THUNDERX) += thunderx-mmc.o | 49 | obj-$(CONFIG_MMC_CAVIUM_THUNDERX) += thunderx-mmc.o |
| 50 | obj-$(CONFIG_MMC_DW) += dw_mmc.o | 50 | obj-$(CONFIG_MMC_DW) += dw_mmc.o |
| 51 | obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o | 51 | obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o |
| 52 | obj-$(CONFIG_MMC_DW_BLUEFIELD) += dw_mmc-bluefield.o | ||
| 52 | obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o | 53 | obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o |
| 53 | obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o | 54 | obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o |
| 54 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o | 55 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o |
diff --git a/drivers/mmc/host/android-goldfish.c b/drivers/mmc/host/android-goldfish.c index 63d27589cd89..294de177632c 100644 --- a/drivers/mmc/host/android-goldfish.c +++ b/drivers/mmc/host/android-goldfish.c | |||
| @@ -217,8 +217,8 @@ static void goldfish_mmc_xfer_done(struct goldfish_mmc_host *host, | |||
| 217 | * We don't really have DMA, so we need | 217 | * We don't really have DMA, so we need |
| 218 | * to copy from our platform driver buffer | 218 | * to copy from our platform driver buffer |
| 219 | */ | 219 | */ |
| 220 | uint8_t *dest = (uint8_t *)sg_virt(data->sg); | 220 | sg_copy_to_buffer(data->sg, 1, host->virt_base, |
| 221 | memcpy(dest, host->virt_base, data->sg->length); | 221 | data->sg->length); |
| 222 | } | 222 | } |
| 223 | host->data->bytes_xfered += data->sg->length; | 223 | host->data->bytes_xfered += data->sg->length; |
| 224 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, | 224 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, |
| @@ -393,8 +393,8 @@ static void goldfish_mmc_prepare_data(struct goldfish_mmc_host *host, | |||
| 393 | * We don't really have DMA, so we need to copy to our | 393 | * We don't really have DMA, so we need to copy to our |
| 394 | * platform driver buffer | 394 | * platform driver buffer |
| 395 | */ | 395 | */ |
| 396 | const uint8_t *src = (uint8_t *)sg_virt(data->sg); | 396 | sg_copy_from_buffer(data->sg, 1, host->virt_base, |
| 397 | memcpy(host->virt_base, src, data->sg->length); | 397 | data->sg->length); |
| 398 | } | 398 | } |
| 399 | } | 399 | } |
| 400 | 400 | ||
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index e55f3932d580..5aa2c9404e92 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
| @@ -1967,7 +1967,6 @@ static void atmci_tasklet_func(unsigned long priv) | |||
| 1967 | static void atmci_read_data_pio(struct atmel_mci *host) | 1967 | static void atmci_read_data_pio(struct atmel_mci *host) |
| 1968 | { | 1968 | { |
| 1969 | struct scatterlist *sg = host->sg; | 1969 | struct scatterlist *sg = host->sg; |
| 1970 | void *buf = sg_virt(sg); | ||
| 1971 | unsigned int offset = host->pio_offset; | 1970 | unsigned int offset = host->pio_offset; |
| 1972 | struct mmc_data *data = host->data; | 1971 | struct mmc_data *data = host->data; |
| 1973 | u32 value; | 1972 | u32 value; |
| @@ -1977,7 +1976,7 @@ static void atmci_read_data_pio(struct atmel_mci *host) | |||
| 1977 | do { | 1976 | do { |
| 1978 | value = atmci_readl(host, ATMCI_RDR); | 1977 | value = atmci_readl(host, ATMCI_RDR); |
| 1979 | if (likely(offset + 4 <= sg->length)) { | 1978 | if (likely(offset + 4 <= sg->length)) { |
| 1980 | put_unaligned(value, (u32 *)(buf + offset)); | 1979 | sg_pcopy_to_buffer(sg, 1, &value, sizeof(u32), offset); |
| 1981 | 1980 | ||
| 1982 | offset += 4; | 1981 | offset += 4; |
| 1983 | nbytes += 4; | 1982 | nbytes += 4; |
| @@ -1990,11 +1989,11 @@ static void atmci_read_data_pio(struct atmel_mci *host) | |||
| 1990 | goto done; | 1989 | goto done; |
| 1991 | 1990 | ||
| 1992 | offset = 0; | 1991 | offset = 0; |
| 1993 | buf = sg_virt(sg); | ||
| 1994 | } | 1992 | } |
| 1995 | } else { | 1993 | } else { |
| 1996 | unsigned int remaining = sg->length - offset; | 1994 | unsigned int remaining = sg->length - offset; |
| 1997 | memcpy(buf + offset, &value, remaining); | 1995 | |
| 1996 | sg_pcopy_to_buffer(sg, 1, &value, remaining, offset); | ||
| 1998 | nbytes += remaining; | 1997 | nbytes += remaining; |
| 1999 | 1998 | ||
| 2000 | flush_dcache_page(sg_page(sg)); | 1999 | flush_dcache_page(sg_page(sg)); |
| @@ -2004,8 +2003,8 @@ static void atmci_read_data_pio(struct atmel_mci *host) | |||
| 2004 | goto done; | 2003 | goto done; |
| 2005 | 2004 | ||
| 2006 | offset = 4 - remaining; | 2005 | offset = 4 - remaining; |
| 2007 | buf = sg_virt(sg); | 2006 | sg_pcopy_to_buffer(sg, 1, (u8 *)&value + remaining, |
| 2008 | memcpy(buf, (u8 *)&value + remaining, offset); | 2007 | offset, 0); |
| 2009 | nbytes += offset; | 2008 | nbytes += offset; |
| 2010 | } | 2009 | } |
| 2011 | 2010 | ||
| @@ -2035,7 +2034,6 @@ done: | |||
| 2035 | static void atmci_write_data_pio(struct atmel_mci *host) | 2034 | static void atmci_write_data_pio(struct atmel_mci *host) |
| 2036 | { | 2035 | { |
| 2037 | struct scatterlist *sg = host->sg; | 2036 | struct scatterlist *sg = host->sg; |
| 2038 | void *buf = sg_virt(sg); | ||
| 2039 | unsigned int offset = host->pio_offset; | 2037 | unsigned int offset = host->pio_offset; |
| 2040 | struct mmc_data *data = host->data; | 2038 | struct mmc_data *data = host->data; |
| 2041 | u32 value; | 2039 | u32 value; |
| @@ -2044,7 +2042,7 @@ static void atmci_write_data_pio(struct atmel_mci *host) | |||
| 2044 | 2042 | ||
| 2045 | do { | 2043 | do { |
| 2046 | if (likely(offset + 4 <= sg->length)) { | 2044 | if (likely(offset + 4 <= sg->length)) { |
| 2047 | value = get_unaligned((u32 *)(buf + offset)); | 2045 | sg_pcopy_from_buffer(sg, 1, &value, sizeof(u32), offset); |
| 2048 | atmci_writel(host, ATMCI_TDR, value); | 2046 | atmci_writel(host, ATMCI_TDR, value); |
| 2049 | 2047 | ||
| 2050 | offset += 4; | 2048 | offset += 4; |
| @@ -2056,13 +2054,12 @@ static void atmci_write_data_pio(struct atmel_mci *host) | |||
| 2056 | goto done; | 2054 | goto done; |
| 2057 | 2055 | ||
| 2058 | offset = 0; | 2056 | offset = 0; |
| 2059 | buf = sg_virt(sg); | ||
| 2060 | } | 2057 | } |
| 2061 | } else { | 2058 | } else { |
| 2062 | unsigned int remaining = sg->length - offset; | 2059 | unsigned int remaining = sg->length - offset; |
| 2063 | 2060 | ||
| 2064 | value = 0; | 2061 | value = 0; |
| 2065 | memcpy(&value, buf + offset, remaining); | 2062 | sg_pcopy_from_buffer(sg, 1, &value, remaining, offset); |
| 2066 | nbytes += remaining; | 2063 | nbytes += remaining; |
| 2067 | 2064 | ||
| 2068 | host->sg = sg = sg_next(sg); | 2065 | host->sg = sg = sg_next(sg); |
| @@ -2073,8 +2070,8 @@ static void atmci_write_data_pio(struct atmel_mci *host) | |||
| 2073 | } | 2070 | } |
| 2074 | 2071 | ||
| 2075 | offset = 4 - remaining; | 2072 | offset = 4 - remaining; |
| 2076 | buf = sg_virt(sg); | 2073 | sg_pcopy_from_buffer(sg, 1, (u8 *)&value + remaining, |
| 2077 | memcpy((u8 *)&value + remaining, buf, offset); | 2074 | offset, 0); |
| 2078 | atmci_writel(host, ATMCI_TDR, value); | 2075 | atmci_writel(host, ATMCI_TDR, value); |
| 2079 | nbytes += offset; | 2076 | nbytes += offset; |
| 2080 | } | 2077 | } |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index ed77fbfa4774..9b4be67330dd 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
| 41 | #include <linux/dma-mapping.h> | 41 | #include <linux/dma-mapping.h> |
| 42 | #include <linux/scatterlist.h> | 42 | #include <linux/scatterlist.h> |
| 43 | #include <linux/highmem.h> | ||
| 43 | #include <linux/leds.h> | 44 | #include <linux/leds.h> |
| 44 | #include <linux/mmc/host.h> | 45 | #include <linux/mmc/host.h> |
| 45 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
| @@ -405,7 +406,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) | |||
| 405 | 406 | ||
| 406 | /* This is the pointer to the data buffer */ | 407 | /* This is the pointer to the data buffer */ |
| 407 | sg = &data->sg[host->pio.index]; | 408 | sg = &data->sg[host->pio.index]; |
| 408 | sg_ptr = sg_virt(sg) + host->pio.offset; | 409 | sg_ptr = kmap_atomic(sg_page(sg)) + sg->offset + host->pio.offset; |
| 409 | 410 | ||
| 410 | /* This is the space left inside the buffer */ | 411 | /* This is the space left inside the buffer */ |
| 411 | sg_len = data->sg[host->pio.index].length - host->pio.offset; | 412 | sg_len = data->sg[host->pio.index].length - host->pio.offset; |
| @@ -421,11 +422,12 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) | |||
| 421 | if (!(status & SD_STATUS_TH)) | 422 | if (!(status & SD_STATUS_TH)) |
| 422 | break; | 423 | break; |
| 423 | 424 | ||
| 424 | val = *sg_ptr++; | 425 | val = sg_ptr[count]; |
| 425 | 426 | ||
| 426 | __raw_writel((unsigned long)val, HOST_TXPORT(host)); | 427 | __raw_writel((unsigned long)val, HOST_TXPORT(host)); |
| 427 | wmb(); /* drain writebuffer */ | 428 | wmb(); /* drain writebuffer */ |
| 428 | } | 429 | } |
| 430 | kunmap_atomic(sg_ptr); | ||
| 429 | 431 | ||
| 430 | host->pio.len -= count; | 432 | host->pio.len -= count; |
| 431 | host->pio.offset += count; | 433 | host->pio.offset += count; |
| @@ -462,7 +464,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) | |||
| 462 | 464 | ||
| 463 | if (host->pio.index < host->dma.len) { | 465 | if (host->pio.index < host->dma.len) { |
| 464 | sg = &data->sg[host->pio.index]; | 466 | sg = &data->sg[host->pio.index]; |
| 465 | sg_ptr = sg_virt(sg) + host->pio.offset; | 467 | sg_ptr = kmap_atomic(sg_page(sg)) + sg->offset + host->pio.offset; |
| 466 | 468 | ||
| 467 | /* This is the space left inside the buffer */ | 469 | /* This is the space left inside the buffer */ |
| 468 | sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; | 470 | sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset; |
| @@ -501,8 +503,10 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) | |||
| 501 | val = __raw_readl(HOST_RXPORT(host)); | 503 | val = __raw_readl(HOST_RXPORT(host)); |
| 502 | 504 | ||
| 503 | if (sg_ptr) | 505 | if (sg_ptr) |
| 504 | *sg_ptr++ = (unsigned char)(val & 0xFF); | 506 | sg_ptr[count] = (unsigned char)(val & 0xFF); |
| 505 | } | 507 | } |
| 508 | if (sg_ptr) | ||
| 509 | kunmap_atomic(sg_ptr); | ||
| 506 | 510 | ||
| 507 | host->pio.len -= count; | 511 | host->pio.len -= count; |
| 508 | host->pio.offset += count; | 512 | host->pio.offset += count; |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 8e363174f9d6..9e68c3645e22 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c | |||
| @@ -1377,8 +1377,7 @@ static int __exit davinci_mmcsd_remove(struct platform_device *pdev) | |||
| 1377 | #ifdef CONFIG_PM | 1377 | #ifdef CONFIG_PM |
| 1378 | static int davinci_mmcsd_suspend(struct device *dev) | 1378 | static int davinci_mmcsd_suspend(struct device *dev) |
| 1379 | { | 1379 | { |
| 1380 | struct platform_device *pdev = to_platform_device(dev); | 1380 | struct mmc_davinci_host *host = dev_get_drvdata(dev); |
| 1381 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
| 1382 | 1381 | ||
| 1383 | writel(0, host->base + DAVINCI_MMCIM); | 1382 | writel(0, host->base + DAVINCI_MMCIM); |
| 1384 | mmc_davinci_reset_ctrl(host, 1); | 1383 | mmc_davinci_reset_ctrl(host, 1); |
| @@ -1389,8 +1388,7 @@ static int davinci_mmcsd_suspend(struct device *dev) | |||
| 1389 | 1388 | ||
| 1390 | static int davinci_mmcsd_resume(struct device *dev) | 1389 | static int davinci_mmcsd_resume(struct device *dev) |
| 1391 | { | 1390 | { |
| 1392 | struct platform_device *pdev = to_platform_device(dev); | 1391 | struct mmc_davinci_host *host = dev_get_drvdata(dev); |
| 1393 | struct mmc_davinci_host *host = platform_get_drvdata(pdev); | ||
| 1394 | 1392 | ||
| 1395 | clk_enable(host->clk); | 1393 | clk_enable(host->clk); |
| 1396 | mmc_davinci_reset_ctrl(host, 0); | 1394 | mmc_davinci_reset_ctrl(host, 0); |
diff --git a/drivers/mmc/host/dw_mmc-bluefield.c b/drivers/mmc/host/dw_mmc-bluefield.c new file mode 100644 index 000000000000..54c3fbb4a391 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-bluefield.c | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2018 Mellanox Technologies. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/bitfield.h> | ||
| 12 | #include <linux/bitops.h> | ||
| 13 | #include <linux/mmc/host.h> | ||
| 14 | #include <linux/mmc/mmc.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/of.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/pm_runtime.h> | ||
| 19 | |||
| 20 | #include "dw_mmc.h" | ||
| 21 | #include "dw_mmc-pltfm.h" | ||
| 22 | |||
| 23 | #define UHS_REG_EXT_SAMPLE_MASK GENMASK(22, 16) | ||
| 24 | #define UHS_REG_EXT_DRIVE_MASK GENMASK(29, 23) | ||
| 25 | #define BLUEFIELD_UHS_REG_EXT_SAMPLE 2 | ||
| 26 | #define BLUEFIELD_UHS_REG_EXT_DRIVE 4 | ||
| 27 | |||
| 28 | static void dw_mci_bluefield_set_ios(struct dw_mci *host, struct mmc_ios *ios) | ||
| 29 | { | ||
| 30 | u32 reg; | ||
| 31 | |||
| 32 | /* Update the Drive and Sample fields in register UHS_REG_EXT. */ | ||
| 33 | reg = mci_readl(host, UHS_REG_EXT); | ||
| 34 | reg &= ~UHS_REG_EXT_SAMPLE_MASK; | ||
| 35 | reg |= FIELD_PREP(UHS_REG_EXT_SAMPLE_MASK, | ||
| 36 | BLUEFIELD_UHS_REG_EXT_SAMPLE); | ||
| 37 | reg &= ~UHS_REG_EXT_DRIVE_MASK; | ||
| 38 | reg |= FIELD_PREP(UHS_REG_EXT_DRIVE_MASK, BLUEFIELD_UHS_REG_EXT_DRIVE); | ||
| 39 | mci_writel(host, UHS_REG_EXT, reg); | ||
| 40 | } | ||
| 41 | |||
| 42 | static const struct dw_mci_drv_data bluefield_drv_data = { | ||
| 43 | .set_ios = dw_mci_bluefield_set_ios | ||
| 44 | }; | ||
| 45 | |||
| 46 | static const struct of_device_id dw_mci_bluefield_match[] = { | ||
| 47 | { .compatible = "mellanox,bluefield-dw-mshc", | ||
| 48 | .data = &bluefield_drv_data }, | ||
| 49 | {}, | ||
| 50 | }; | ||
| 51 | MODULE_DEVICE_TABLE(of, dw_mci_bluefield_match); | ||
| 52 | |||
| 53 | static int dw_mci_bluefield_probe(struct platform_device *pdev) | ||
| 54 | { | ||
| 55 | const struct dw_mci_drv_data *drv_data = NULL; | ||
| 56 | const struct of_device_id *match; | ||
| 57 | |||
| 58 | if (pdev->dev.of_node) { | ||
| 59 | match = of_match_node(dw_mci_bluefield_match, | ||
| 60 | pdev->dev.of_node); | ||
| 61 | drv_data = match->data; | ||
| 62 | } | ||
| 63 | |||
| 64 | return dw_mci_pltfm_register(pdev, drv_data); | ||
| 65 | } | ||
| 66 | |||
| 67 | static struct platform_driver dw_mci_bluefield_pltfm_driver = { | ||
| 68 | .probe = dw_mci_bluefield_probe, | ||
| 69 | .remove = dw_mci_pltfm_remove, | ||
| 70 | .driver = { | ||
| 71 | .name = "dwmmc_bluefield", | ||
| 72 | .of_match_table = dw_mci_bluefield_match, | ||
| 73 | .pm = &dw_mci_pltfm_pmops, | ||
| 74 | }, | ||
| 75 | }; | ||
| 76 | |||
| 77 | module_platform_driver(dw_mci_bluefield_pltfm_driver); | ||
| 78 | |||
| 79 | MODULE_DESCRIPTION("BlueField DW Multimedia Card driver"); | ||
| 80 | MODULE_AUTHOR("Mellanox Technologies"); | ||
| 81 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 40d7de2eea12..8c86a800a8fd 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c | |||
| @@ -44,9 +44,8 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) | |||
| 44 | * bus_hz = cclkin / RK3288_CLKGEN_DIV | 44 | * bus_hz = cclkin / RK3288_CLKGEN_DIV |
| 45 | * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) | 45 | * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) |
| 46 | * | 46 | * |
| 47 | * Note: div can only be 0 or 1 | 47 | * Note: div can only be 0 or 1, but div must be set to 1 for eMMC |
| 48 | * if DDR50 8bit mode(only emmc work in 8bit mode), | 48 | * DDR52 8-bit mode. |
| 49 | * div must be set 1 | ||
| 50 | */ | 49 | */ |
| 51 | if (ios->bus_width == MMC_BUS_WIDTH_8 && | 50 | if (ios->bus_width == MMC_BUS_WIDTH_8 && |
| 52 | ios->timing == MMC_TIMING_MMC_DDR52) | 51 | ios->timing == MMC_TIMING_MMC_DDR52) |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 29a1afa81f66..623f4d27fa01 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
| @@ -1230,6 +1230,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
| 1230 | if (host->state == STATE_WAITING_CMD11_DONE) | 1230 | if (host->state == STATE_WAITING_CMD11_DONE) |
| 1231 | sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH; | 1231 | sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH; |
| 1232 | 1232 | ||
| 1233 | slot->mmc->actual_clock = 0; | ||
| 1234 | |||
| 1233 | if (!clock) { | 1235 | if (!clock) { |
| 1234 | mci_writel(host, CLKENA, 0); | 1236 | mci_writel(host, CLKENA, 0); |
| 1235 | mci_send_cmd(slot, sdmmc_cmd_bits, 0); | 1237 | mci_send_cmd(slot, sdmmc_cmd_bits, 0); |
| @@ -1288,6 +1290,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
| 1288 | 1290 | ||
| 1289 | /* keep the last clock value that was requested from core */ | 1291 | /* keep the last clock value that was requested from core */ |
| 1290 | slot->__clk_old = clock; | 1292 | slot->__clk_old = clock; |
| 1293 | slot->mmc->actual_clock = div ? ((host->bus_hz / div) >> 1) : | ||
| 1294 | host->bus_hz; | ||
| 1291 | } | 1295 | } |
| 1292 | 1296 | ||
| 1293 | host->current_speed = clock; | 1297 | host->current_speed = clock; |
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index a0168e9e4fce..993386c9ea50 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> | 2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> |
| 3 | * Copyright (C) 2013, Imagination Technologies | ||
| 4 | * | ||
| 3 | * JZ4740 SD/MMC controller driver | 5 | * JZ4740 SD/MMC controller driver |
| 4 | * | 6 | * |
| 5 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
| @@ -13,24 +15,25 @@ | |||
| 13 | * | 15 | * |
| 14 | */ | 16 | */ |
| 15 | 17 | ||
| 16 | #include <linux/mmc/host.h> | 18 | #include <linux/bitops.h> |
| 17 | #include <linux/mmc/slot-gpio.h> | 19 | #include <linux/clk.h> |
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/dmaengine.h> | ||
| 22 | #include <linux/dma-mapping.h> | ||
| 18 | #include <linux/err.h> | 23 | #include <linux/err.h> |
| 24 | #include <linux/gpio.h> | ||
| 25 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/io.h> | 26 | #include <linux/io.h> |
| 20 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
| 21 | #include <linux/interrupt.h> | 28 | #include <linux/mmc/host.h> |
| 29 | #include <linux/mmc/slot-gpio.h> | ||
| 22 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 31 | #include <linux/of_device.h> | ||
| 23 | #include <linux/pinctrl/consumer.h> | 32 | #include <linux/pinctrl/consumer.h> |
| 24 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
| 25 | #include <linux/delay.h> | ||
| 26 | #include <linux/scatterlist.h> | 34 | #include <linux/scatterlist.h> |
| 27 | #include <linux/clk.h> | ||
| 28 | 35 | ||
| 29 | #include <linux/bitops.h> | ||
| 30 | #include <linux/gpio.h> | ||
| 31 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
| 32 | #include <linux/dma-mapping.h> | ||
| 33 | #include <linux/dmaengine.h> | ||
| 34 | 37 | ||
| 35 | #include <asm/mach-jz4740/dma.h> | 38 | #include <asm/mach-jz4740/dma.h> |
| 36 | #include <asm/mach-jz4740/jz4740_mmc.h> | 39 | #include <asm/mach-jz4740/jz4740_mmc.h> |
| @@ -51,6 +54,7 @@ | |||
| 51 | #define JZ_REG_MMC_RESP_FIFO 0x34 | 54 | #define JZ_REG_MMC_RESP_FIFO 0x34 |
| 52 | #define JZ_REG_MMC_RXFIFO 0x38 | 55 | #define JZ_REG_MMC_RXFIFO 0x38 |
| 53 | #define JZ_REG_MMC_TXFIFO 0x3C | 56 | #define JZ_REG_MMC_TXFIFO 0x3C |
| 57 | #define JZ_REG_MMC_DMAC 0x44 | ||
| 54 | 58 | ||
| 55 | #define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7) | 59 | #define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7) |
| 56 | #define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6) | 60 | #define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6) |
| @@ -104,9 +108,17 @@ | |||
| 104 | #define JZ_MMC_IRQ_PRG_DONE BIT(1) | 108 | #define JZ_MMC_IRQ_PRG_DONE BIT(1) |
| 105 | #define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0) | 109 | #define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0) |
| 106 | 110 | ||
| 111 | #define JZ_MMC_DMAC_DMA_SEL BIT(1) | ||
| 112 | #define JZ_MMC_DMAC_DMA_EN BIT(0) | ||
| 107 | 113 | ||
| 108 | #define JZ_MMC_CLK_RATE 24000000 | 114 | #define JZ_MMC_CLK_RATE 24000000 |
| 109 | 115 | ||
| 116 | enum jz4740_mmc_version { | ||
| 117 | JZ_MMC_JZ4740, | ||
| 118 | JZ_MMC_JZ4750, | ||
| 119 | JZ_MMC_JZ4780, | ||
| 120 | }; | ||
| 121 | |||
| 110 | enum jz4740_mmc_state { | 122 | enum jz4740_mmc_state { |
| 111 | JZ4740_MMC_STATE_READ_RESPONSE, | 123 | JZ4740_MMC_STATE_READ_RESPONSE, |
| 112 | JZ4740_MMC_STATE_TRANSFER_DATA, | 124 | JZ4740_MMC_STATE_TRANSFER_DATA, |
| @@ -125,6 +137,8 @@ struct jz4740_mmc_host { | |||
| 125 | struct jz4740_mmc_platform_data *pdata; | 137 | struct jz4740_mmc_platform_data *pdata; |
| 126 | struct clk *clk; | 138 | struct clk *clk; |
| 127 | 139 | ||
| 140 | enum jz4740_mmc_version version; | ||
| 141 | |||
| 128 | int irq; | 142 | int irq; |
| 129 | int card_detect_irq; | 143 | int card_detect_irq; |
| 130 | 144 | ||
| @@ -137,7 +151,7 @@ struct jz4740_mmc_host { | |||
| 137 | 151 | ||
| 138 | uint32_t cmdat; | 152 | uint32_t cmdat; |
| 139 | 153 | ||
| 140 | uint16_t irq_mask; | 154 | uint32_t irq_mask; |
| 141 | 155 | ||
| 142 | spinlock_t lock; | 156 | spinlock_t lock; |
| 143 | 157 | ||
| @@ -159,6 +173,32 @@ struct jz4740_mmc_host { | |||
| 159 | #define JZ4740_MMC_FIFO_HALF_SIZE 8 | 173 | #define JZ4740_MMC_FIFO_HALF_SIZE 8 |
| 160 | }; | 174 | }; |
| 161 | 175 | ||
| 176 | static void jz4740_mmc_write_irq_mask(struct jz4740_mmc_host *host, | ||
| 177 | uint32_t val) | ||
| 178 | { | ||
| 179 | if (host->version >= JZ_MMC_JZ4750) | ||
| 180 | return writel(val, host->base + JZ_REG_MMC_IMASK); | ||
| 181 | else | ||
| 182 | return writew(val, host->base + JZ_REG_MMC_IMASK); | ||
| 183 | } | ||
| 184 | |||
| 185 | static void jz4740_mmc_write_irq_reg(struct jz4740_mmc_host *host, | ||
| 186 | uint32_t val) | ||
| 187 | { | ||
| 188 | if (host->version >= JZ_MMC_JZ4780) | ||
| 189 | return writel(val, host->base + JZ_REG_MMC_IREG); | ||
| 190 | else | ||
| 191 | return writew(val, host->base + JZ_REG_MMC_IREG); | ||
| 192 | } | ||
| 193 | |||
| 194 | static uint32_t jz4740_mmc_read_irq_reg(struct jz4740_mmc_host *host) | ||
| 195 | { | ||
| 196 | if (host->version >= JZ_MMC_JZ4780) | ||
| 197 | return readl(host->base + JZ_REG_MMC_IREG); | ||
| 198 | else | ||
| 199 | return readw(host->base + JZ_REG_MMC_IREG); | ||
| 200 | } | ||
| 201 | |||
| 162 | /*----------------------------------------------------------------------------*/ | 202 | /*----------------------------------------------------------------------------*/ |
| 163 | /* DMA infrastructure */ | 203 | /* DMA infrastructure */ |
| 164 | 204 | ||
| @@ -173,31 +213,23 @@ static void jz4740_mmc_release_dma_channels(struct jz4740_mmc_host *host) | |||
| 173 | 213 | ||
| 174 | static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host) | 214 | static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host) |
| 175 | { | 215 | { |
| 176 | dma_cap_mask_t mask; | 216 | host->dma_tx = dma_request_chan(mmc_dev(host->mmc), "tx"); |
| 177 | 217 | if (IS_ERR(host->dma_tx)) { | |
| 178 | dma_cap_zero(mask); | ||
| 179 | dma_cap_set(DMA_SLAVE, mask); | ||
| 180 | |||
| 181 | host->dma_tx = dma_request_channel(mask, NULL, host); | ||
| 182 | if (!host->dma_tx) { | ||
| 183 | dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n"); | 218 | dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n"); |
| 184 | return -ENODEV; | 219 | return PTR_ERR(host->dma_tx); |
| 185 | } | 220 | } |
| 186 | 221 | ||
| 187 | host->dma_rx = dma_request_channel(mask, NULL, host); | 222 | host->dma_rx = dma_request_chan(mmc_dev(host->mmc), "rx"); |
| 188 | if (!host->dma_rx) { | 223 | if (IS_ERR(host->dma_rx)) { |
| 189 | dev_err(mmc_dev(host->mmc), "Failed to get dma_rx channel\n"); | 224 | dev_err(mmc_dev(host->mmc), "Failed to get dma_rx channel\n"); |
| 190 | goto free_master_write; | 225 | dma_release_channel(host->dma_tx); |
| 226 | return PTR_ERR(host->dma_rx); | ||
| 191 | } | 227 | } |
| 192 | 228 | ||
| 193 | /* Initialize DMA pre request cookie */ | 229 | /* Initialize DMA pre request cookie */ |
| 194 | host->next_data.cookie = 1; | 230 | host->next_data.cookie = 1; |
| 195 | 231 | ||
| 196 | return 0; | 232 | return 0; |
| 197 | |||
| 198 | free_master_write: | ||
| 199 | dma_release_channel(host->dma_tx); | ||
| 200 | return -ENODEV; | ||
| 201 | } | 233 | } |
| 202 | 234 | ||
| 203 | static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host, | 235 | static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host, |
| @@ -363,7 +395,7 @@ static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host, | |||
| 363 | else | 395 | else |
| 364 | host->irq_mask |= irq; | 396 | host->irq_mask |= irq; |
| 365 | 397 | ||
| 366 | writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); | 398 | jz4740_mmc_write_irq_mask(host, host->irq_mask); |
| 367 | spin_unlock_irqrestore(&host->lock, flags); | 399 | spin_unlock_irqrestore(&host->lock, flags); |
| 368 | } | 400 | } |
| 369 | 401 | ||
| @@ -415,10 +447,10 @@ static unsigned int jz4740_mmc_poll_irq(struct jz4740_mmc_host *host, | |||
| 415 | unsigned int irq) | 447 | unsigned int irq) |
| 416 | { | 448 | { |
| 417 | unsigned int timeout = 0x800; | 449 | unsigned int timeout = 0x800; |
| 418 | uint16_t status; | 450 | uint32_t status; |
| 419 | 451 | ||
| 420 | do { | 452 | do { |
| 421 | status = readw(host->base + JZ_REG_MMC_IREG); | 453 | status = jz4740_mmc_read_irq_reg(host); |
| 422 | } while (!(status & irq) && --timeout); | 454 | } while (!(status & irq) && --timeout); |
| 423 | 455 | ||
| 424 | if (timeout == 0) { | 456 | if (timeout == 0) { |
| @@ -518,7 +550,7 @@ static bool jz4740_mmc_read_data(struct jz4740_mmc_host *host, | |||
| 518 | void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO; | 550 | void __iomem *fifo_addr = host->base + JZ_REG_MMC_RXFIFO; |
| 519 | uint32_t *buf; | 551 | uint32_t *buf; |
| 520 | uint32_t d; | 552 | uint32_t d; |
| 521 | uint16_t status; | 553 | uint32_t status; |
| 522 | size_t i, j; | 554 | size_t i, j; |
| 523 | unsigned int timeout; | 555 | unsigned int timeout; |
| 524 | 556 | ||
| @@ -654,8 +686,25 @@ static void jz4740_mmc_send_command(struct jz4740_mmc_host *host, | |||
| 654 | cmdat |= JZ_MMC_CMDAT_DATA_EN; | 686 | cmdat |= JZ_MMC_CMDAT_DATA_EN; |
| 655 | if (cmd->data->flags & MMC_DATA_WRITE) | 687 | if (cmd->data->flags & MMC_DATA_WRITE) |
| 656 | cmdat |= JZ_MMC_CMDAT_WRITE; | 688 | cmdat |= JZ_MMC_CMDAT_WRITE; |
| 657 | if (host->use_dma) | 689 | if (host->use_dma) { |
| 658 | cmdat |= JZ_MMC_CMDAT_DMA_EN; | 690 | /* |
| 691 | * The 4780's MMC controller has integrated DMA ability | ||
| 692 | * in addition to being able to use the external DMA | ||
| 693 | * controller. It moves DMA control bits to a separate | ||
| 694 | * register. The DMA_SEL bit chooses the external | ||
| 695 | * controller over the integrated one. Earlier SoCs | ||
| 696 | * can only use the external controller, and have a | ||
| 697 | * single DMA enable bit in CMDAT. | ||
| 698 | */ | ||
| 699 | if (host->version >= JZ_MMC_JZ4780) { | ||
| 700 | writel(JZ_MMC_DMAC_DMA_EN | JZ_MMC_DMAC_DMA_SEL, | ||
| 701 | host->base + JZ_REG_MMC_DMAC); | ||
| 702 | } else { | ||
| 703 | cmdat |= JZ_MMC_CMDAT_DMA_EN; | ||
| 704 | } | ||
| 705 | } else if (host->version >= JZ_MMC_JZ4780) { | ||
| 706 | writel(0, host->base + JZ_REG_MMC_DMAC); | ||
| 707 | } | ||
| 659 | 708 | ||
| 660 | writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN); | 709 | writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN); |
| 661 | writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB); | 710 | writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB); |
| @@ -736,7 +785,7 @@ static irqreturn_t jz_mmc_irq_worker(int irq, void *devid) | |||
| 736 | host->state = JZ4740_MMC_STATE_SEND_STOP; | 785 | host->state = JZ4740_MMC_STATE_SEND_STOP; |
| 737 | break; | 786 | break; |
| 738 | } | 787 | } |
| 739 | writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG); | 788 | jz4740_mmc_write_irq_reg(host, JZ_MMC_IRQ_DATA_TRAN_DONE); |
| 740 | 789 | ||
| 741 | case JZ4740_MMC_STATE_SEND_STOP: | 790 | case JZ4740_MMC_STATE_SEND_STOP: |
| 742 | if (!req->stop) | 791 | if (!req->stop) |
| @@ -766,9 +815,10 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
| 766 | { | 815 | { |
| 767 | struct jz4740_mmc_host *host = devid; | 816 | struct jz4740_mmc_host *host = devid; |
| 768 | struct mmc_command *cmd = host->cmd; | 817 | struct mmc_command *cmd = host->cmd; |
| 769 | uint16_t irq_reg, status, tmp; | 818 | uint32_t irq_reg, status, tmp; |
| 770 | 819 | ||
| 771 | irq_reg = readw(host->base + JZ_REG_MMC_IREG); | 820 | status = readl(host->base + JZ_REG_MMC_STATUS); |
| 821 | irq_reg = jz4740_mmc_read_irq_reg(host); | ||
| 772 | 822 | ||
| 773 | tmp = irq_reg; | 823 | tmp = irq_reg; |
| 774 | irq_reg &= ~host->irq_mask; | 824 | irq_reg &= ~host->irq_mask; |
| @@ -777,10 +827,10 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
| 777 | JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE); | 827 | JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE); |
| 778 | 828 | ||
| 779 | if (tmp != irq_reg) | 829 | if (tmp != irq_reg) |
| 780 | writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG); | 830 | jz4740_mmc_write_irq_reg(host, tmp & ~irq_reg); |
| 781 | 831 | ||
| 782 | if (irq_reg & JZ_MMC_IRQ_SDIO) { | 832 | if (irq_reg & JZ_MMC_IRQ_SDIO) { |
| 783 | writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG); | 833 | jz4740_mmc_write_irq_reg(host, JZ_MMC_IRQ_SDIO); |
| 784 | mmc_signal_sdio_irq(host->mmc); | 834 | mmc_signal_sdio_irq(host->mmc); |
| 785 | irq_reg &= ~JZ_MMC_IRQ_SDIO; | 835 | irq_reg &= ~JZ_MMC_IRQ_SDIO; |
| 786 | } | 836 | } |
| @@ -789,8 +839,6 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
| 789 | if (test_and_clear_bit(0, &host->waiting)) { | 839 | if (test_and_clear_bit(0, &host->waiting)) { |
| 790 | del_timer(&host->timeout_timer); | 840 | del_timer(&host->timeout_timer); |
| 791 | 841 | ||
| 792 | status = readl(host->base + JZ_REG_MMC_STATUS); | ||
| 793 | |||
| 794 | if (status & JZ_MMC_STATUS_TIMEOUT_RES) { | 842 | if (status & JZ_MMC_STATUS_TIMEOUT_RES) { |
| 795 | cmd->error = -ETIMEDOUT; | 843 | cmd->error = -ETIMEDOUT; |
| 796 | } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) { | 844 | } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) { |
| @@ -803,7 +851,7 @@ static irqreturn_t jz_mmc_irq(int irq, void *devid) | |||
| 803 | } | 851 | } |
| 804 | 852 | ||
| 805 | jz4740_mmc_set_irq_enabled(host, irq_reg, false); | 853 | jz4740_mmc_set_irq_enabled(host, irq_reg, false); |
| 806 | writew(irq_reg, host->base + JZ_REG_MMC_IREG); | 854 | jz4740_mmc_write_irq_reg(host, irq_reg); |
| 807 | 855 | ||
| 808 | return IRQ_WAKE_THREAD; | 856 | return IRQ_WAKE_THREAD; |
| 809 | } | 857 | } |
| @@ -818,7 +866,7 @@ static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate) | |||
| 818 | int real_rate; | 866 | int real_rate; |
| 819 | 867 | ||
| 820 | jz4740_mmc_clock_disable(host); | 868 | jz4740_mmc_clock_disable(host); |
| 821 | clk_set_rate(host->clk, JZ_MMC_CLK_RATE); | 869 | clk_set_rate(host->clk, host->mmc->f_max); |
| 822 | 870 | ||
| 823 | real_rate = clk_get_rate(host->clk); | 871 | real_rate = clk_get_rate(host->clk); |
| 824 | 872 | ||
| @@ -837,9 +885,7 @@ static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req) | |||
| 837 | 885 | ||
| 838 | host->req = req; | 886 | host->req = req; |
| 839 | 887 | ||
| 840 | writew(0xffff, host->base + JZ_REG_MMC_IREG); | 888 | jz4740_mmc_write_irq_reg(host, ~0); |
| 841 | |||
| 842 | writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG); | ||
| 843 | jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true); | 889 | jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, true); |
| 844 | 890 | ||
| 845 | host->state = JZ4740_MMC_STATE_READ_RESPONSE; | 891 | host->state = JZ4740_MMC_STATE_READ_RESPONSE; |
| @@ -857,7 +903,7 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 857 | switch (ios->power_mode) { | 903 | switch (ios->power_mode) { |
| 858 | case MMC_POWER_UP: | 904 | case MMC_POWER_UP: |
| 859 | jz4740_mmc_reset(host); | 905 | jz4740_mmc_reset(host); |
| 860 | if (gpio_is_valid(host->pdata->gpio_power)) | 906 | if (host->pdata && gpio_is_valid(host->pdata->gpio_power)) |
| 861 | gpio_set_value(host->pdata->gpio_power, | 907 | gpio_set_value(host->pdata->gpio_power, |
| 862 | !host->pdata->power_active_low); | 908 | !host->pdata->power_active_low); |
| 863 | host->cmdat |= JZ_MMC_CMDAT_INIT; | 909 | host->cmdat |= JZ_MMC_CMDAT_INIT; |
| @@ -866,7 +912,7 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 866 | case MMC_POWER_ON: | 912 | case MMC_POWER_ON: |
| 867 | break; | 913 | break; |
| 868 | default: | 914 | default: |
| 869 | if (gpio_is_valid(host->pdata->gpio_power)) | 915 | if (host->pdata && gpio_is_valid(host->pdata->gpio_power)) |
| 870 | gpio_set_value(host->pdata->gpio_power, | 916 | gpio_set_value(host->pdata->gpio_power, |
| 871 | host->pdata->power_active_low); | 917 | host->pdata->power_active_low); |
| 872 | clk_disable_unprepare(host->clk); | 918 | clk_disable_unprepare(host->clk); |
| @@ -926,7 +972,7 @@ static int jz4740_mmc_request_gpio(struct device *dev, int gpio, | |||
| 926 | static int jz4740_mmc_request_gpios(struct mmc_host *mmc, | 972 | static int jz4740_mmc_request_gpios(struct mmc_host *mmc, |
| 927 | struct platform_device *pdev) | 973 | struct platform_device *pdev) |
| 928 | { | 974 | { |
| 929 | struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data; | 975 | struct jz4740_mmc_platform_data *pdata = dev_get_platdata(&pdev->dev); |
| 930 | int ret = 0; | 976 | int ret = 0; |
| 931 | 977 | ||
| 932 | if (!pdata) | 978 | if (!pdata) |
| @@ -955,7 +1001,7 @@ static int jz4740_mmc_request_gpios(struct mmc_host *mmc, | |||
| 955 | 1001 | ||
| 956 | static void jz4740_mmc_free_gpios(struct platform_device *pdev) | 1002 | static void jz4740_mmc_free_gpios(struct platform_device *pdev) |
| 957 | { | 1003 | { |
| 958 | struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data; | 1004 | struct jz4740_mmc_platform_data *pdata = dev_get_platdata(&pdev->dev); |
| 959 | 1005 | ||
| 960 | if (!pdata) | 1006 | if (!pdata) |
| 961 | return; | 1007 | return; |
| @@ -964,14 +1010,22 @@ static void jz4740_mmc_free_gpios(struct platform_device *pdev) | |||
| 964 | gpio_free(pdata->gpio_power); | 1010 | gpio_free(pdata->gpio_power); |
| 965 | } | 1011 | } |
| 966 | 1012 | ||
| 1013 | static const struct of_device_id jz4740_mmc_of_match[] = { | ||
| 1014 | { .compatible = "ingenic,jz4740-mmc", .data = (void *) JZ_MMC_JZ4740 }, | ||
| 1015 | { .compatible = "ingenic,jz4780-mmc", .data = (void *) JZ_MMC_JZ4780 }, | ||
| 1016 | {}, | ||
| 1017 | }; | ||
| 1018 | MODULE_DEVICE_TABLE(of, jz4740_mmc_of_match); | ||
| 1019 | |||
| 967 | static int jz4740_mmc_probe(struct platform_device* pdev) | 1020 | static int jz4740_mmc_probe(struct platform_device* pdev) |
| 968 | { | 1021 | { |
| 969 | int ret; | 1022 | int ret; |
| 970 | struct mmc_host *mmc; | 1023 | struct mmc_host *mmc; |
| 971 | struct jz4740_mmc_host *host; | 1024 | struct jz4740_mmc_host *host; |
| 1025 | const struct of_device_id *match; | ||
| 972 | struct jz4740_mmc_platform_data *pdata; | 1026 | struct jz4740_mmc_platform_data *pdata; |
| 973 | 1027 | ||
| 974 | pdata = pdev->dev.platform_data; | 1028 | pdata = dev_get_platdata(&pdev->dev); |
| 975 | 1029 | ||
| 976 | mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev); | 1030 | mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev); |
| 977 | if (!mmc) { | 1031 | if (!mmc) { |
| @@ -982,6 +1036,27 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
| 982 | host = mmc_priv(mmc); | 1036 | host = mmc_priv(mmc); |
| 983 | host->pdata = pdata; | 1037 | host->pdata = pdata; |
| 984 | 1038 | ||
| 1039 | match = of_match_device(jz4740_mmc_of_match, &pdev->dev); | ||
| 1040 | if (match) { | ||
| 1041 | host->version = (enum jz4740_mmc_version)match->data; | ||
| 1042 | ret = mmc_of_parse(mmc); | ||
| 1043 | if (ret) { | ||
| 1044 | if (ret != -EPROBE_DEFER) | ||
| 1045 | dev_err(&pdev->dev, | ||
| 1046 | "could not parse of data: %d\n", ret); | ||
| 1047 | goto err_free_host; | ||
| 1048 | } | ||
| 1049 | } else { | ||
| 1050 | /* JZ4740 should be the only one using legacy probe */ | ||
| 1051 | host->version = JZ_MMC_JZ4740; | ||
| 1052 | mmc->caps |= MMC_CAP_SDIO_IRQ; | ||
| 1053 | if (!(pdata && pdata->data_1bit)) | ||
| 1054 | mmc->caps |= MMC_CAP_4_BIT_DATA; | ||
| 1055 | ret = jz4740_mmc_request_gpios(mmc, pdev); | ||
| 1056 | if (ret) | ||
| 1057 | goto err_free_host; | ||
| 1058 | } | ||
| 1059 | |||
| 985 | host->irq = platform_get_irq(pdev, 0); | 1060 | host->irq = platform_get_irq(pdev, 0); |
| 986 | if (host->irq < 0) { | 1061 | if (host->irq < 0) { |
| 987 | ret = host->irq; | 1062 | ret = host->irq; |
| @@ -1004,16 +1079,11 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
| 1004 | goto err_free_host; | 1079 | goto err_free_host; |
| 1005 | } | 1080 | } |
| 1006 | 1081 | ||
| 1007 | ret = jz4740_mmc_request_gpios(mmc, pdev); | ||
| 1008 | if (ret) | ||
| 1009 | goto err_release_dma; | ||
| 1010 | |||
| 1011 | mmc->ops = &jz4740_mmc_ops; | 1082 | mmc->ops = &jz4740_mmc_ops; |
| 1012 | mmc->f_min = JZ_MMC_CLK_RATE / 128; | 1083 | if (!mmc->f_max) |
| 1013 | mmc->f_max = JZ_MMC_CLK_RATE; | 1084 | mmc->f_max = JZ_MMC_CLK_RATE; |
| 1085 | mmc->f_min = mmc->f_max / 128; | ||
| 1014 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 1086 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
| 1015 | mmc->caps = (pdata && pdata->data_1bit) ? 0 : MMC_CAP_4_BIT_DATA; | ||
| 1016 | mmc->caps |= MMC_CAP_SDIO_IRQ; | ||
| 1017 | 1087 | ||
| 1018 | mmc->max_blk_size = (1 << 10) - 1; | 1088 | mmc->max_blk_size = (1 << 10) - 1; |
| 1019 | mmc->max_blk_count = (1 << 15) - 1; | 1089 | mmc->max_blk_count = (1 << 15) - 1; |
| @@ -1025,7 +1095,9 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
| 1025 | host->mmc = mmc; | 1095 | host->mmc = mmc; |
| 1026 | host->pdev = pdev; | 1096 | host->pdev = pdev; |
| 1027 | spin_lock_init(&host->lock); | 1097 | spin_lock_init(&host->lock); |
| 1028 | host->irq_mask = 0xffff; | 1098 | host->irq_mask = ~0; |
| 1099 | |||
| 1100 | jz4740_mmc_reset(host); | ||
| 1029 | 1101 | ||
| 1030 | ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, 0, | 1102 | ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, 0, |
| 1031 | dev_name(&pdev->dev), host); | 1103 | dev_name(&pdev->dev), host); |
| @@ -1034,20 +1106,20 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
| 1034 | goto err_free_gpios; | 1106 | goto err_free_gpios; |
| 1035 | } | 1107 | } |
| 1036 | 1108 | ||
| 1037 | jz4740_mmc_reset(host); | ||
| 1038 | jz4740_mmc_clock_disable(host); | 1109 | jz4740_mmc_clock_disable(host); |
| 1039 | timer_setup(&host->timeout_timer, jz4740_mmc_timeout, 0); | 1110 | timer_setup(&host->timeout_timer, jz4740_mmc_timeout, 0); |
| 1040 | 1111 | ||
| 1041 | host->use_dma = true; | 1112 | ret = jz4740_mmc_acquire_dma_channels(host); |
| 1042 | if (host->use_dma && jz4740_mmc_acquire_dma_channels(host) != 0) | 1113 | if (ret == -EPROBE_DEFER) |
| 1043 | host->use_dma = false; | 1114 | goto err_free_irq; |
| 1115 | host->use_dma = !ret; | ||
| 1044 | 1116 | ||
| 1045 | platform_set_drvdata(pdev, host); | 1117 | platform_set_drvdata(pdev, host); |
| 1046 | ret = mmc_add_host(mmc); | 1118 | ret = mmc_add_host(mmc); |
| 1047 | 1119 | ||
| 1048 | if (ret) { | 1120 | if (ret) { |
| 1049 | dev_err(&pdev->dev, "Failed to add mmc host: %d\n", ret); | 1121 | dev_err(&pdev->dev, "Failed to add mmc host: %d\n", ret); |
| 1050 | goto err_free_irq; | 1122 | goto err_release_dma; |
| 1051 | } | 1123 | } |
| 1052 | dev_info(&pdev->dev, "JZ SD/MMC card driver registered\n"); | 1124 | dev_info(&pdev->dev, "JZ SD/MMC card driver registered\n"); |
| 1053 | 1125 | ||
| @@ -1057,13 +1129,13 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
| 1057 | 1129 | ||
| 1058 | return 0; | 1130 | return 0; |
| 1059 | 1131 | ||
| 1132 | err_release_dma: | ||
| 1133 | if (host->use_dma) | ||
| 1134 | jz4740_mmc_release_dma_channels(host); | ||
| 1060 | err_free_irq: | 1135 | err_free_irq: |
| 1061 | free_irq(host->irq, host); | 1136 | free_irq(host->irq, host); |
| 1062 | err_free_gpios: | 1137 | err_free_gpios: |
| 1063 | jz4740_mmc_free_gpios(pdev); | 1138 | jz4740_mmc_free_gpios(pdev); |
| 1064 | err_release_dma: | ||
| 1065 | if (host->use_dma) | ||
| 1066 | jz4740_mmc_release_dma_channels(host); | ||
| 1067 | err_free_host: | 1139 | err_free_host: |
| 1068 | mmc_free_host(mmc); | 1140 | mmc_free_host(mmc); |
| 1069 | 1141 | ||
| @@ -1116,6 +1188,7 @@ static struct platform_driver jz4740_mmc_driver = { | |||
| 1116 | .remove = jz4740_mmc_remove, | 1188 | .remove = jz4740_mmc_remove, |
| 1117 | .driver = { | 1189 | .driver = { |
| 1118 | .name = "jz4740-mmc", | 1190 | .name = "jz4740-mmc", |
| 1191 | .of_match_table = of_match_ptr(jz4740_mmc_of_match), | ||
| 1119 | .pm = JZ4740_MMC_PM_OPS, | 1192 | .pm = JZ4740_MMC_PM_OPS, |
| 1120 | }, | 1193 | }, |
| 1121 | }; | 1194 | }; |
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 4f972b879fe6..c201c378537e 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
| 36 | #include <linux/clk-provider.h> | 36 | #include <linux/clk-provider.h> |
| 37 | #include <linux/regulator/consumer.h> | 37 | #include <linux/regulator/consumer.h> |
| 38 | #include <linux/reset.h> | ||
| 38 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
| 39 | #include <linux/bitfield.h> | 40 | #include <linux/bitfield.h> |
| 40 | #include <linux/pinctrl/consumer.h> | 41 | #include <linux/pinctrl/consumer.h> |
| @@ -47,15 +48,29 @@ | |||
| 47 | #define CLK_CORE_PHASE_MASK GENMASK(9, 8) | 48 | #define CLK_CORE_PHASE_MASK GENMASK(9, 8) |
| 48 | #define CLK_TX_PHASE_MASK GENMASK(11, 10) | 49 | #define CLK_TX_PHASE_MASK GENMASK(11, 10) |
| 49 | #define CLK_RX_PHASE_MASK GENMASK(13, 12) | 50 | #define CLK_RX_PHASE_MASK GENMASK(13, 12) |
| 50 | #define CLK_TX_DELAY_MASK GENMASK(19, 16) | 51 | #define CLK_V2_TX_DELAY_MASK GENMASK(19, 16) |
| 51 | #define CLK_RX_DELAY_MASK GENMASK(23, 20) | 52 | #define CLK_V2_RX_DELAY_MASK GENMASK(23, 20) |
| 53 | #define CLK_V2_ALWAYS_ON BIT(24) | ||
| 54 | |||
| 55 | #define CLK_V3_TX_DELAY_MASK GENMASK(21, 16) | ||
| 56 | #define CLK_V3_RX_DELAY_MASK GENMASK(27, 22) | ||
| 57 | #define CLK_V3_ALWAYS_ON BIT(28) | ||
| 58 | |||
| 52 | #define CLK_DELAY_STEP_PS 200 | 59 | #define CLK_DELAY_STEP_PS 200 |
| 53 | #define CLK_PHASE_STEP 30 | 60 | #define CLK_PHASE_STEP 30 |
| 54 | #define CLK_PHASE_POINT_NUM (360 / CLK_PHASE_STEP) | 61 | #define CLK_PHASE_POINT_NUM (360 / CLK_PHASE_STEP) |
| 55 | #define CLK_ALWAYS_ON BIT(24) | 62 | |
| 63 | #define CLK_TX_DELAY_MASK(h) (h->data->tx_delay_mask) | ||
| 64 | #define CLK_RX_DELAY_MASK(h) (h->data->rx_delay_mask) | ||
| 65 | #define CLK_ALWAYS_ON(h) (h->data->always_on) | ||
| 56 | 66 | ||
| 57 | #define SD_EMMC_DELAY 0x4 | 67 | #define SD_EMMC_DELAY 0x4 |
| 58 | #define SD_EMMC_ADJUST 0x8 | 68 | #define SD_EMMC_ADJUST 0x8 |
| 69 | |||
| 70 | #define SD_EMMC_DELAY1 0x4 | ||
| 71 | #define SD_EMMC_DELAY2 0x8 | ||
| 72 | #define SD_EMMC_V3_ADJUST 0xc | ||
| 73 | |||
| 59 | #define SD_EMMC_CALOUT 0x10 | 74 | #define SD_EMMC_CALOUT 0x10 |
| 60 | #define SD_EMMC_START 0x40 | 75 | #define SD_EMMC_START 0x40 |
| 61 | #define START_DESC_INIT BIT(0) | 76 | #define START_DESC_INIT BIT(0) |
| @@ -122,6 +137,12 @@ | |||
| 122 | 137 | ||
| 123 | #define MUX_CLK_NUM_PARENTS 2 | 138 | #define MUX_CLK_NUM_PARENTS 2 |
| 124 | 139 | ||
| 140 | struct meson_mmc_data { | ||
| 141 | unsigned int tx_delay_mask; | ||
| 142 | unsigned int rx_delay_mask; | ||
| 143 | unsigned int always_on; | ||
| 144 | }; | ||
| 145 | |||
| 125 | struct sd_emmc_desc { | 146 | struct sd_emmc_desc { |
| 126 | u32 cmd_cfg; | 147 | u32 cmd_cfg; |
| 127 | u32 cmd_arg; | 148 | u32 cmd_arg; |
| @@ -131,6 +152,7 @@ struct sd_emmc_desc { | |||
| 131 | 152 | ||
| 132 | struct meson_host { | 153 | struct meson_host { |
| 133 | struct device *dev; | 154 | struct device *dev; |
| 155 | struct meson_mmc_data *data; | ||
| 134 | struct mmc_host *mmc; | 156 | struct mmc_host *mmc; |
| 135 | struct mmc_command *cmd; | 157 | struct mmc_command *cmd; |
| 136 | 158 | ||
| @@ -474,7 +496,7 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 474 | 496 | ||
| 475 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ | 497 | /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */ |
| 476 | clk_reg = 0; | 498 | clk_reg = 0; |
| 477 | clk_reg |= CLK_ALWAYS_ON; | 499 | clk_reg |= CLK_ALWAYS_ON(host); |
| 478 | clk_reg |= CLK_DIV_MASK; | 500 | clk_reg |= CLK_DIV_MASK; |
| 479 | writel(clk_reg, host->regs + SD_EMMC_CLOCK); | 501 | writel(clk_reg, host->regs + SD_EMMC_CLOCK); |
| 480 | 502 | ||
| @@ -574,7 +596,7 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 574 | 596 | ||
| 575 | tx->reg = host->regs + SD_EMMC_CLOCK; | 597 | tx->reg = host->regs + SD_EMMC_CLOCK; |
| 576 | tx->phase_mask = CLK_TX_PHASE_MASK; | 598 | tx->phase_mask = CLK_TX_PHASE_MASK; |
| 577 | tx->delay_mask = CLK_TX_DELAY_MASK; | 599 | tx->delay_mask = CLK_TX_DELAY_MASK(host); |
| 578 | tx->delay_step_ps = CLK_DELAY_STEP_PS; | 600 | tx->delay_step_ps = CLK_DELAY_STEP_PS; |
| 579 | tx->hw.init = &init; | 601 | tx->hw.init = &init; |
| 580 | 602 | ||
| @@ -597,7 +619,7 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
| 597 | 619 | ||
| 598 | rx->reg = host->regs + SD_EMMC_CLOCK; | 620 | rx->reg = host->regs + SD_EMMC_CLOCK; |
| 599 | rx->phase_mask = CLK_RX_PHASE_MASK; | 621 | rx->phase_mask = CLK_RX_PHASE_MASK; |
| 600 | rx->delay_mask = CLK_RX_DELAY_MASK; | 622 | rx->delay_mask = CLK_RX_DELAY_MASK(host); |
| 601 | rx->delay_step_ps = CLK_DELAY_STEP_PS; | 623 | rx->delay_step_ps = CLK_DELAY_STEP_PS; |
| 602 | rx->hw.init = &init; | 624 | rx->hw.init = &init; |
| 603 | 625 | ||
| @@ -1184,6 +1206,21 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
| 1184 | goto free_host; | 1206 | goto free_host; |
| 1185 | } | 1207 | } |
| 1186 | 1208 | ||
| 1209 | host->data = (struct meson_mmc_data *) | ||
| 1210 | of_device_get_match_data(&pdev->dev); | ||
| 1211 | if (!host->data) { | ||
| 1212 | ret = -EINVAL; | ||
| 1213 | goto free_host; | ||
| 1214 | } | ||
| 1215 | |||
| 1216 | ret = device_reset_optional(&pdev->dev); | ||
| 1217 | if (ret) { | ||
| 1218 | if (ret != -EPROBE_DEFER) | ||
| 1219 | dev_err(&pdev->dev, "device reset failed: %d\n", ret); | ||
| 1220 | |||
| 1221 | return ret; | ||
| 1222 | } | ||
| 1223 | |||
| 1187 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1224 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1188 | host->regs = devm_ioremap_resource(&pdev->dev, res); | 1225 | host->regs = devm_ioremap_resource(&pdev->dev, res); |
| 1189 | if (IS_ERR(host->regs)) { | 1226 | if (IS_ERR(host->regs)) { |
| @@ -1315,11 +1352,24 @@ static int meson_mmc_remove(struct platform_device *pdev) | |||
| 1315 | return 0; | 1352 | return 0; |
| 1316 | } | 1353 | } |
| 1317 | 1354 | ||
| 1355 | static const struct meson_mmc_data meson_gx_data = { | ||
| 1356 | .tx_delay_mask = CLK_V2_TX_DELAY_MASK, | ||
| 1357 | .rx_delay_mask = CLK_V2_RX_DELAY_MASK, | ||
| 1358 | .always_on = CLK_V2_ALWAYS_ON, | ||
| 1359 | }; | ||
| 1360 | |||
| 1361 | static const struct meson_mmc_data meson_axg_data = { | ||
| 1362 | .tx_delay_mask = CLK_V3_TX_DELAY_MASK, | ||
| 1363 | .rx_delay_mask = CLK_V3_RX_DELAY_MASK, | ||
| 1364 | .always_on = CLK_V3_ALWAYS_ON, | ||
| 1365 | }; | ||
| 1366 | |||
| 1318 | static const struct of_device_id meson_mmc_of_match[] = { | 1367 | static const struct of_device_id meson_mmc_of_match[] = { |
| 1319 | { .compatible = "amlogic,meson-gx-mmc", }, | 1368 | { .compatible = "amlogic,meson-gx-mmc", .data = &meson_gx_data }, |
| 1320 | { .compatible = "amlogic,meson-gxbb-mmc", }, | 1369 | { .compatible = "amlogic,meson-gxbb-mmc", .data = &meson_gx_data }, |
| 1321 | { .compatible = "amlogic,meson-gxl-mmc", }, | 1370 | { .compatible = "amlogic,meson-gxl-mmc", .data = &meson_gx_data }, |
| 1322 | { .compatible = "amlogic,meson-gxm-mmc", }, | 1371 | { .compatible = "amlogic,meson-gxm-mmc", .data = &meson_gx_data }, |
| 1372 | { .compatible = "amlogic,meson-axg-mmc", .data = &meson_axg_data }, | ||
| 1323 | {} | 1373 | {} |
| 1324 | }; | 1374 | }; |
| 1325 | MODULE_DEVICE_TABLE(of, meson_mmc_of_match); | 1375 | MODULE_DEVICE_TABLE(of, meson_mmc_of_match); |
| @@ -1335,6 +1385,6 @@ static struct platform_driver meson_mmc_driver = { | |||
| 1335 | 1385 | ||
| 1336 | module_platform_driver(meson_mmc_driver); | 1386 | module_platform_driver(meson_mmc_driver); |
| 1337 | 1387 | ||
| 1338 | MODULE_DESCRIPTION("Amlogic S905*/GX* SD/eMMC driver"); | 1388 | MODULE_DESCRIPTION("Amlogic S905*/GX*/AXG SD/eMMC driver"); |
| 1339 | MODULE_AUTHOR("Kevin Hilman <khilman@baylibre.com>"); | 1389 | MODULE_AUTHOR("Kevin Hilman <khilman@baylibre.com>"); |
| 1340 | MODULE_LICENSE("GPL v2"); | 1390 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 70b0df8b9c78..f1849775e47e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -1253,15 +1253,12 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
| 1253 | struct sg_mapping_iter *sg_miter = &host->sg_miter; | 1253 | struct sg_mapping_iter *sg_miter = &host->sg_miter; |
| 1254 | struct variant_data *variant = host->variant; | 1254 | struct variant_data *variant = host->variant; |
| 1255 | void __iomem *base = host->base; | 1255 | void __iomem *base = host->base; |
| 1256 | unsigned long flags; | ||
| 1257 | u32 status; | 1256 | u32 status; |
| 1258 | 1257 | ||
| 1259 | status = readl(base + MMCISTATUS); | 1258 | status = readl(base + MMCISTATUS); |
| 1260 | 1259 | ||
| 1261 | dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); | 1260 | dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status); |
| 1262 | 1261 | ||
| 1263 | local_irq_save(flags); | ||
| 1264 | |||
| 1265 | do { | 1262 | do { |
| 1266 | unsigned int remain, len; | 1263 | unsigned int remain, len; |
| 1267 | char *buffer; | 1264 | char *buffer; |
| @@ -1301,8 +1298,6 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) | |||
| 1301 | 1298 | ||
| 1302 | sg_miter_stop(sg_miter); | 1299 | sg_miter_stop(sg_miter); |
| 1303 | 1300 | ||
| 1304 | local_irq_restore(flags); | ||
| 1305 | |||
| 1306 | /* | 1301 | /* |
| 1307 | * If we have less than the fifo 'half-full' threshold to transfer, | 1302 | * If we have less than the fifo 'half-full' threshold to transfer, |
| 1308 | * trigger a PIO interrupt as soon as any data is available. | 1303 | * trigger a PIO interrupt as soon as any data is available. |
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index cb274e822293..04841386b65d 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/ioport.h> | 19 | #include <linux/ioport.h> |
| 20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
| 22 | #include <linux/of_device.h> | ||
| 22 | #include <linux/of_irq.h> | 23 | #include <linux/of_irq.h> |
| 23 | #include <linux/of_gpio.h> | 24 | #include <linux/of_gpio.h> |
| 24 | #include <linux/pinctrl/consumer.h> | 25 | #include <linux/pinctrl/consumer.h> |
| @@ -70,6 +71,7 @@ | |||
| 70 | #define SDC_ADV_CFG0 0x64 | 71 | #define SDC_ADV_CFG0 0x64 |
| 71 | #define EMMC_IOCON 0x7c | 72 | #define EMMC_IOCON 0x7c |
| 72 | #define SDC_ACMD_RESP 0x80 | 73 | #define SDC_ACMD_RESP 0x80 |
| 74 | #define DMA_SA_H4BIT 0x8c | ||
| 73 | #define MSDC_DMA_SA 0x90 | 75 | #define MSDC_DMA_SA 0x90 |
| 74 | #define MSDC_DMA_CTRL 0x98 | 76 | #define MSDC_DMA_CTRL 0x98 |
| 75 | #define MSDC_DMA_CFG 0x9c | 77 | #define MSDC_DMA_CFG 0x9c |
| @@ -194,6 +196,9 @@ | |||
| 194 | /* SDC_ADV_CFG0 mask */ | 196 | /* SDC_ADV_CFG0 mask */ |
| 195 | #define SDC_RX_ENHANCE_EN (0x1 << 20) /* RW */ | 197 | #define SDC_RX_ENHANCE_EN (0x1 << 20) /* RW */ |
| 196 | 198 | ||
| 199 | /* DMA_SA_H4BIT mask */ | ||
| 200 | #define DMA_ADDR_HIGH_4BIT (0xf << 0) /* RW */ | ||
| 201 | |||
| 197 | /* MSDC_DMA_CTRL mask */ | 202 | /* MSDC_DMA_CTRL mask */ |
| 198 | #define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ | 203 | #define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ |
| 199 | #define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ | 204 | #define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ |
| @@ -227,6 +232,7 @@ | |||
| 227 | 232 | ||
| 228 | #define MSDC_PATCH_BIT2_CFGRESP (0x1 << 15) /* RW */ | 233 | #define MSDC_PATCH_BIT2_CFGRESP (0x1 << 15) /* RW */ |
| 229 | #define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28) /* RW */ | 234 | #define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28) /* RW */ |
| 235 | #define MSDC_PB2_SUPPORT_64G (0x1 << 1) /* RW */ | ||
| 230 | #define MSDC_PB2_RESPWAIT (0x3 << 2) /* RW */ | 236 | #define MSDC_PB2_RESPWAIT (0x3 << 2) /* RW */ |
| 231 | #define MSDC_PB2_RESPSTSENSEL (0x7 << 16) /* RW */ | 237 | #define MSDC_PB2_RESPSTSENSEL (0x7 << 16) /* RW */ |
| 232 | #define MSDC_PB2_CRCSTSENSEL (0x7 << 29) /* RW */ | 238 | #define MSDC_PB2_CRCSTSENSEL (0x7 << 29) /* RW */ |
| @@ -280,6 +286,8 @@ struct mt_gpdma_desc { | |||
| 280 | #define GPDMA_DESC_BDP (0x1 << 1) | 286 | #define GPDMA_DESC_BDP (0x1 << 1) |
| 281 | #define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ | 287 | #define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ |
| 282 | #define GPDMA_DESC_INT (0x1 << 16) | 288 | #define GPDMA_DESC_INT (0x1 << 16) |
| 289 | #define GPDMA_DESC_NEXT_H4 (0xf << 24) | ||
| 290 | #define GPDMA_DESC_PTR_H4 (0xf << 28) | ||
| 283 | u32 next; | 291 | u32 next; |
| 284 | u32 ptr; | 292 | u32 ptr; |
| 285 | u32 gpd_data_len; | 293 | u32 gpd_data_len; |
| @@ -296,6 +304,8 @@ struct mt_bdma_desc { | |||
| 296 | #define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ | 304 | #define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ |
| 297 | #define BDMA_DESC_BLKPAD (0x1 << 17) | 305 | #define BDMA_DESC_BLKPAD (0x1 << 17) |
| 298 | #define BDMA_DESC_DWPAD (0x1 << 18) | 306 | #define BDMA_DESC_DWPAD (0x1 << 18) |
| 307 | #define BDMA_DESC_NEXT_H4 (0xf << 24) | ||
| 308 | #define BDMA_DESC_PTR_H4 (0xf << 28) | ||
| 299 | u32 next; | 309 | u32 next; |
| 300 | u32 ptr; | 310 | u32 ptr; |
| 301 | u32 bd_data_len; | 311 | u32 bd_data_len; |
| @@ -334,6 +344,7 @@ struct mtk_mmc_compatible { | |||
| 334 | bool busy_check; | 344 | bool busy_check; |
| 335 | bool stop_clk_fix; | 345 | bool stop_clk_fix; |
| 336 | bool enhance_rx; | 346 | bool enhance_rx; |
| 347 | bool support_64g; | ||
| 337 | }; | 348 | }; |
| 338 | 349 | ||
| 339 | struct msdc_tune_para { | 350 | struct msdc_tune_para { |
| @@ -403,6 +414,7 @@ static const struct mtk_mmc_compatible mt8135_compat = { | |||
| 403 | .busy_check = false, | 414 | .busy_check = false, |
| 404 | .stop_clk_fix = false, | 415 | .stop_clk_fix = false, |
| 405 | .enhance_rx = false, | 416 | .enhance_rx = false, |
| 417 | .support_64g = false, | ||
| 406 | }; | 418 | }; |
| 407 | 419 | ||
| 408 | static const struct mtk_mmc_compatible mt8173_compat = { | 420 | static const struct mtk_mmc_compatible mt8173_compat = { |
| @@ -414,6 +426,7 @@ static const struct mtk_mmc_compatible mt8173_compat = { | |||
| 414 | .busy_check = false, | 426 | .busy_check = false, |
| 415 | .stop_clk_fix = false, | 427 | .stop_clk_fix = false, |
| 416 | .enhance_rx = false, | 428 | .enhance_rx = false, |
| 429 | .support_64g = false, | ||
| 417 | }; | 430 | }; |
| 418 | 431 | ||
| 419 | static const struct mtk_mmc_compatible mt2701_compat = { | 432 | static const struct mtk_mmc_compatible mt2701_compat = { |
| @@ -425,6 +438,7 @@ static const struct mtk_mmc_compatible mt2701_compat = { | |||
| 425 | .busy_check = false, | 438 | .busy_check = false, |
| 426 | .stop_clk_fix = false, | 439 | .stop_clk_fix = false, |
| 427 | .enhance_rx = false, | 440 | .enhance_rx = false, |
| 441 | .support_64g = false, | ||
| 428 | }; | 442 | }; |
| 429 | 443 | ||
| 430 | static const struct mtk_mmc_compatible mt2712_compat = { | 444 | static const struct mtk_mmc_compatible mt2712_compat = { |
| @@ -436,6 +450,7 @@ static const struct mtk_mmc_compatible mt2712_compat = { | |||
| 436 | .busy_check = true, | 450 | .busy_check = true, |
| 437 | .stop_clk_fix = true, | 451 | .stop_clk_fix = true, |
| 438 | .enhance_rx = true, | 452 | .enhance_rx = true, |
| 453 | .support_64g = true, | ||
| 439 | }; | 454 | }; |
| 440 | 455 | ||
| 441 | static const struct mtk_mmc_compatible mt7622_compat = { | 456 | static const struct mtk_mmc_compatible mt7622_compat = { |
| @@ -447,6 +462,7 @@ static const struct mtk_mmc_compatible mt7622_compat = { | |||
| 447 | .busy_check = true, | 462 | .busy_check = true, |
| 448 | .stop_clk_fix = true, | 463 | .stop_clk_fix = true, |
| 449 | .enhance_rx = true, | 464 | .enhance_rx = true, |
| 465 | .support_64g = false, | ||
| 450 | }; | 466 | }; |
| 451 | 467 | ||
| 452 | static const struct of_device_id msdc_of_ids[] = { | 468 | static const struct of_device_id msdc_of_ids[] = { |
| @@ -556,7 +572,12 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, | |||
| 556 | /* init bd */ | 572 | /* init bd */ |
| 557 | bd[j].bd_info &= ~BDMA_DESC_BLKPAD; | 573 | bd[j].bd_info &= ~BDMA_DESC_BLKPAD; |
| 558 | bd[j].bd_info &= ~BDMA_DESC_DWPAD; | 574 | bd[j].bd_info &= ~BDMA_DESC_DWPAD; |
| 559 | bd[j].ptr = (u32)dma_address; | 575 | bd[j].ptr = lower_32_bits(dma_address); |
| 576 | if (host->dev_comp->support_64g) { | ||
| 577 | bd[j].bd_info &= ~BDMA_DESC_PTR_H4; | ||
| 578 | bd[j].bd_info |= (upper_32_bits(dma_address) & 0xf) | ||
| 579 | << 28; | ||
| 580 | } | ||
| 560 | bd[j].bd_data_len &= ~BDMA_DESC_BUFLEN; | 581 | bd[j].bd_data_len &= ~BDMA_DESC_BUFLEN; |
| 561 | bd[j].bd_data_len |= (dma_len & BDMA_DESC_BUFLEN); | 582 | bd[j].bd_data_len |= (dma_len & BDMA_DESC_BUFLEN); |
| 562 | 583 | ||
| @@ -575,7 +596,10 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, | |||
| 575 | dma_ctrl &= ~(MSDC_DMA_CTRL_BRUSTSZ | MSDC_DMA_CTRL_MODE); | 596 | dma_ctrl &= ~(MSDC_DMA_CTRL_BRUSTSZ | MSDC_DMA_CTRL_MODE); |
| 576 | dma_ctrl |= (MSDC_BURST_64B << 12 | 1 << 8); | 597 | dma_ctrl |= (MSDC_BURST_64B << 12 | 1 << 8); |
| 577 | writel_relaxed(dma_ctrl, host->base + MSDC_DMA_CTRL); | 598 | writel_relaxed(dma_ctrl, host->base + MSDC_DMA_CTRL); |
| 578 | writel((u32)dma->gpd_addr, host->base + MSDC_DMA_SA); | 599 | if (host->dev_comp->support_64g) |
| 600 | sdr_set_field(host->base + DMA_SA_H4BIT, DMA_ADDR_HIGH_4BIT, | ||
| 601 | upper_32_bits(dma->gpd_addr) & 0xf); | ||
| 602 | writel(lower_32_bits(dma->gpd_addr), host->base + MSDC_DMA_SA); | ||
| 579 | } | 603 | } |
| 580 | 604 | ||
| 581 | static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) | 605 | static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) |
| @@ -1366,6 +1390,9 @@ static void msdc_init_hw(struct msdc_host *host) | |||
| 1366 | MSDC_PATCH_BIT2_CFGCRCSTS); | 1390 | MSDC_PATCH_BIT2_CFGCRCSTS); |
| 1367 | } | 1391 | } |
| 1368 | 1392 | ||
| 1393 | if (host->dev_comp->support_64g) | ||
| 1394 | sdr_set_bits(host->base + MSDC_PATCH_BIT2, | ||
| 1395 | MSDC_PB2_SUPPORT_64G); | ||
| 1369 | if (host->dev_comp->data_tune) { | 1396 | if (host->dev_comp->data_tune) { |
| 1370 | sdr_set_bits(host->base + tune_reg, | 1397 | sdr_set_bits(host->base + tune_reg, |
| 1371 | MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); | 1398 | MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); |
| @@ -1407,19 +1434,32 @@ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma) | |||
| 1407 | { | 1434 | { |
| 1408 | struct mt_gpdma_desc *gpd = dma->gpd; | 1435 | struct mt_gpdma_desc *gpd = dma->gpd; |
| 1409 | struct mt_bdma_desc *bd = dma->bd; | 1436 | struct mt_bdma_desc *bd = dma->bd; |
| 1437 | dma_addr_t dma_addr; | ||
| 1410 | int i; | 1438 | int i; |
| 1411 | 1439 | ||
| 1412 | memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2); | 1440 | memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2); |
| 1413 | 1441 | ||
| 1442 | dma_addr = dma->gpd_addr + sizeof(struct mt_gpdma_desc); | ||
| 1414 | gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */ | 1443 | gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */ |
| 1415 | gpd->ptr = (u32)dma->bd_addr; /* physical address */ | ||
| 1416 | /* gpd->next is must set for desc DMA | 1444 | /* gpd->next is must set for desc DMA |
| 1417 | * That's why must alloc 2 gpd structure. | 1445 | * That's why must alloc 2 gpd structure. |
| 1418 | */ | 1446 | */ |
| 1419 | gpd->next = (u32)dma->gpd_addr + sizeof(struct mt_gpdma_desc); | 1447 | gpd->next = lower_32_bits(dma_addr); |
| 1448 | if (host->dev_comp->support_64g) | ||
| 1449 | gpd->gpd_info |= (upper_32_bits(dma_addr) & 0xf) << 24; | ||
| 1450 | |||
| 1451 | dma_addr = dma->bd_addr; | ||
| 1452 | gpd->ptr = lower_32_bits(dma->bd_addr); /* physical address */ | ||
| 1453 | if (host->dev_comp->support_64g) | ||
| 1454 | gpd->gpd_info |= (upper_32_bits(dma_addr) & 0xf) << 28; | ||
| 1455 | |||
| 1420 | memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM); | 1456 | memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM); |
| 1421 | for (i = 0; i < (MAX_BD_NUM - 1); i++) | 1457 | for (i = 0; i < (MAX_BD_NUM - 1); i++) { |
| 1422 | bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1); | 1458 | dma_addr = dma->bd_addr + sizeof(*bd) * (i + 1); |
| 1459 | bd[i].next = lower_32_bits(dma_addr); | ||
| 1460 | if (host->dev_comp->support_64g) | ||
| 1461 | bd[i].bd_info |= (upper_32_bits(dma_addr) & 0xf) << 24; | ||
| 1462 | } | ||
| 1423 | } | 1463 | } |
| 1424 | 1464 | ||
| 1425 | static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 1465 | static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| @@ -1820,7 +1860,6 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
| 1820 | struct mmc_host *mmc; | 1860 | struct mmc_host *mmc; |
| 1821 | struct msdc_host *host; | 1861 | struct msdc_host *host; |
| 1822 | struct resource *res; | 1862 | struct resource *res; |
| 1823 | const struct of_device_id *of_id; | ||
| 1824 | int ret; | 1863 | int ret; |
| 1825 | 1864 | ||
| 1826 | if (!pdev->dev.of_node) { | 1865 | if (!pdev->dev.of_node) { |
| @@ -1828,9 +1867,6 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
| 1828 | return -EINVAL; | 1867 | return -EINVAL; |
| 1829 | } | 1868 | } |
| 1830 | 1869 | ||
| 1831 | of_id = of_match_node(msdc_of_ids, pdev->dev.of_node); | ||
| 1832 | if (!of_id) | ||
| 1833 | return -EINVAL; | ||
| 1834 | /* Allocate MMC host for this device */ | 1870 | /* Allocate MMC host for this device */ |
| 1835 | mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); | 1871 | mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); |
| 1836 | if (!mmc) | 1872 | if (!mmc) |
| @@ -1899,7 +1935,7 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
| 1899 | msdc_of_property_parse(pdev, host); | 1935 | msdc_of_property_parse(pdev, host); |
| 1900 | 1936 | ||
| 1901 | host->dev = &pdev->dev; | 1937 | host->dev = &pdev->dev; |
| 1902 | host->dev_comp = of_id->data; | 1938 | host->dev_comp = of_device_get_match_data(&pdev->dev); |
| 1903 | host->mmc = mmc; | 1939 | host->mmc = mmc; |
| 1904 | host->src_clk_freq = clk_get_rate(host->src_clk); | 1940 | host->src_clk_freq = clk_get_rate(host->src_clk); |
| 1905 | /* Set host parameters to mmc */ | 1941 | /* Set host parameters to mmc */ |
| @@ -1916,7 +1952,10 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
| 1916 | mmc->max_blk_size = 2048; | 1952 | mmc->max_blk_size = 2048; |
| 1917 | mmc->max_req_size = 512 * 1024; | 1953 | mmc->max_req_size = 512 * 1024; |
| 1918 | mmc->max_blk_count = mmc->max_req_size / 512; | 1954 | mmc->max_blk_count = mmc->max_req_size / 512; |
| 1919 | host->dma_mask = DMA_BIT_MASK(32); | 1955 | if (host->dev_comp->support_64g) |
| 1956 | host->dma_mask = DMA_BIT_MASK(36); | ||
| 1957 | else | ||
| 1958 | host->dma_mask = DMA_BIT_MASK(32); | ||
| 1920 | mmc_dev(mmc)->dma_mask = &host->dma_mask; | 1959 | mmc_dev(mmc)->dma_mask = &host->dma_mask; |
| 1921 | 1960 | ||
| 1922 | host->timeout_clks = 3 * 1048576; | 1961 | host->timeout_clks = 3 * 1048576; |
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index 210247b3d11a..e22bbff89c8d 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
| @@ -143,6 +143,7 @@ static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 143 | struct mmc_command *cmd = mrq->cmd; | 143 | struct mmc_command *cmd = mrq->cmd; |
| 144 | u32 cmdreg = 0, xfer = 0, intr = 0; | 144 | u32 cmdreg = 0, xfer = 0, intr = 0; |
| 145 | unsigned long flags; | 145 | unsigned long flags; |
| 146 | unsigned int timeout; | ||
| 146 | 147 | ||
| 147 | BUG_ON(host->mrq != NULL); | 148 | BUG_ON(host->mrq != NULL); |
| 148 | host->mrq = mrq; | 149 | host->mrq = mrq; |
| @@ -234,7 +235,8 @@ static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 234 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | 235 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); |
| 235 | mvsd_write(MVSD_ERR_INTR_EN, 0xffff); | 236 | mvsd_write(MVSD_ERR_INTR_EN, 0xffff); |
| 236 | 237 | ||
| 237 | mod_timer(&host->timer, jiffies + 5 * HZ); | 238 | timeout = cmd->busy_timeout ? cmd->busy_timeout : 5000; |
| 239 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout)); | ||
| 238 | 240 | ||
| 239 | spin_unlock_irqrestore(&host->lock, flags); | 241 | spin_unlock_irqrestore(&host->lock, flags); |
| 240 | } | 242 | } |
| @@ -755,6 +757,8 @@ static int mvsd_probe(struct platform_device *pdev) | |||
| 755 | if (maxfreq) | 757 | if (maxfreq) |
| 756 | mmc->f_max = maxfreq; | 758 | mmc->f_max = maxfreq; |
| 757 | 759 | ||
| 760 | mmc->caps |= MMC_CAP_ERASE; | ||
| 761 | |||
| 758 | spin_lock_init(&host->lock); | 762 | spin_lock_init(&host->lock); |
| 759 | 763 | ||
| 760 | host->base = devm_ioremap_resource(&pdev->dev, r); | 764 | host->base = devm_ioremap_resource(&pdev->dev, r); |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 5ff8ef7223cc..75f781c11e89 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/highmem.h> | ||
| 24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 25 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
| 26 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
| @@ -291,8 +292,10 @@ static void mxcmci_swap_buffers(struct mmc_data *data) | |||
| 291 | struct scatterlist *sg; | 292 | struct scatterlist *sg; |
| 292 | int i; | 293 | int i; |
| 293 | 294 | ||
| 294 | for_each_sg(data->sg, sg, data->sg_len, i) | 295 | for_each_sg(data->sg, sg, data->sg_len, i) { |
| 295 | buffer_swap32(sg_virt(sg), sg->length); | 296 | void *buf = kmap_atomic(sg_page(sg) + sg->offset; |
| 297 | buffer_swap32(buf, sg->length); | ||
| 298 | kunmap_atomic(buf); | ||
| 296 | } | 299 | } |
| 297 | #else | 300 | #else |
| 298 | static inline void mxcmci_swap_buffers(struct mmc_data *data) {} | 301 | static inline void mxcmci_swap_buffers(struct mmc_data *data) {} |
| @@ -609,6 +612,7 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) | |||
| 609 | { | 612 | { |
| 610 | struct mmc_data *data = host->req->data; | 613 | struct mmc_data *data = host->req->data; |
| 611 | struct scatterlist *sg; | 614 | struct scatterlist *sg; |
| 615 | void *buf; | ||
| 612 | int stat, i; | 616 | int stat, i; |
| 613 | 617 | ||
| 614 | host->data = data; | 618 | host->data = data; |
| @@ -616,14 +620,18 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) | |||
| 616 | 620 | ||
| 617 | if (data->flags & MMC_DATA_READ) { | 621 | if (data->flags & MMC_DATA_READ) { |
| 618 | for_each_sg(data->sg, sg, data->sg_len, i) { | 622 | for_each_sg(data->sg, sg, data->sg_len, i) { |
| 619 | stat = mxcmci_pull(host, sg_virt(sg), sg->length); | 623 | buf = kmap_atomic(sg_page(sg) + sg->offset); |
| 624 | stat = mxcmci_pull(host, buf, sg->length); | ||
| 625 | kunmap(buf); | ||
| 620 | if (stat) | 626 | if (stat) |
| 621 | return stat; | 627 | return stat; |
| 622 | host->datasize += sg->length; | 628 | host->datasize += sg->length; |
| 623 | } | 629 | } |
| 624 | } else { | 630 | } else { |
| 625 | for_each_sg(data->sg, sg, data->sg_len, i) { | 631 | for_each_sg(data->sg, sg, data->sg_len, i) { |
| 626 | stat = mxcmci_push(host, sg_virt(sg), sg->length); | 632 | buf = kmap_atomic(sg_page(sg) + sg->offset); |
| 633 | stat = mxcmci_push(host, buf, sg->length); | ||
| 634 | kunmap(buf); | ||
| 627 | if (stat) | 635 | if (stat) |
| 628 | return stat; | 636 | return stat; |
| 629 | host->datasize += sg->length; | 637 | host->datasize += sg->length; |
| @@ -1206,7 +1214,8 @@ static int mxcmci_remove(struct platform_device *pdev) | |||
| 1206 | return 0; | 1214 | return 0; |
| 1207 | } | 1215 | } |
| 1208 | 1216 | ||
| 1209 | static int __maybe_unused mxcmci_suspend(struct device *dev) | 1217 | #ifdef CONFIG_PM_SLEEP |
| 1218 | static int mxcmci_suspend(struct device *dev) | ||
| 1210 | { | 1219 | { |
| 1211 | struct mmc_host *mmc = dev_get_drvdata(dev); | 1220 | struct mmc_host *mmc = dev_get_drvdata(dev); |
| 1212 | struct mxcmci_host *host = mmc_priv(mmc); | 1221 | struct mxcmci_host *host = mmc_priv(mmc); |
| @@ -1216,7 +1225,7 @@ static int __maybe_unused mxcmci_suspend(struct device *dev) | |||
| 1216 | return 0; | 1225 | return 0; |
| 1217 | } | 1226 | } |
| 1218 | 1227 | ||
| 1219 | static int __maybe_unused mxcmci_resume(struct device *dev) | 1228 | static int mxcmci_resume(struct device *dev) |
| 1220 | { | 1229 | { |
| 1221 | struct mmc_host *mmc = dev_get_drvdata(dev); | 1230 | struct mmc_host *mmc = dev_get_drvdata(dev); |
| 1222 | struct mxcmci_host *host = mmc_priv(mmc); | 1231 | struct mxcmci_host *host = mmc_priv(mmc); |
| @@ -1232,6 +1241,7 @@ static int __maybe_unused mxcmci_resume(struct device *dev) | |||
| 1232 | 1241 | ||
| 1233 | return ret; | 1242 | return ret; |
| 1234 | } | 1243 | } |
| 1244 | #endif | ||
| 1235 | 1245 | ||
| 1236 | static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); | 1246 | static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume); |
| 1237 | 1247 | ||
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 51e01f03fb99..45c015da2e75 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> |
| 29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
| 30 | #include <linux/mmc/host.h> | 30 | #include <linux/mmc/host.h> |
| 31 | #include <linux/mmc/slot-gpio.h> | ||
| 31 | #include <linux/mfd/tmio.h> | 32 | #include <linux/mfd/tmio.h> |
| 32 | #include <linux/sh_dma.h> | 33 | #include <linux/sh_dma.h> |
| 33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| @@ -534,6 +535,10 @@ int renesas_sdhi_probe(struct platform_device *pdev, | |||
| 534 | host->multi_io_quirk = renesas_sdhi_multi_io_quirk; | 535 | host->multi_io_quirk = renesas_sdhi_multi_io_quirk; |
| 535 | host->dma_ops = dma_ops; | 536 | host->dma_ops = dma_ops; |
| 536 | 537 | ||
| 538 | /* For some SoC, we disable internal WP. GPIO may override this */ | ||
| 539 | if (mmc_can_gpio_ro(host->mmc)) | ||
| 540 | mmc_data->capabilities2 &= ~MMC_CAP2_NO_WRITE_PROTECT; | ||
| 541 | |||
| 537 | /* SDR speeds are only available on Gen2+ */ | 542 | /* SDR speeds are only available on Gen2+ */ |
| 538 | if (mmc_data->flags & TMIO_MMC_MIN_RCAR2) { | 543 | if (mmc_data->flags & TMIO_MMC_MIN_RCAR2) { |
| 539 | /* card_busy caused issues on r8a73a4 (pre-Gen2) CD-less SDHI */ | 544 | /* card_busy caused issues on r8a73a4 (pre-Gen2) CD-less SDHI */ |
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index 6af946d16d24..f7f9773d161f 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c | |||
| @@ -87,11 +87,12 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { | |||
| 87 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, | 87 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, |
| 88 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | | 88 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
| 89 | MMC_CAP_CMD23, | 89 | MMC_CAP_CMD23, |
| 90 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
| 90 | .bus_shift = 2, | 91 | .bus_shift = 2, |
| 91 | .scc_offset = 0x1000, | 92 | .scc_offset = 0x1000, |
| 92 | .taps = rcar_gen3_scc_taps, | 93 | .taps = rcar_gen3_scc_taps, |
| 93 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), | 94 | .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), |
| 94 | /* Gen3 SDHI DMAC can handle 0xffffffff blk count, but seg = 1 */ | 95 | /* DMAC can handle 0xffffffff blk count but only 1 segment */ |
| 95 | .max_blk_count = 0xffffffff, | 96 | .max_blk_count = 0xffffffff, |
| 96 | .max_segs = 1, | 97 | .max_segs = 1, |
| 97 | }; | 98 | }; |
| @@ -157,38 +158,34 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, | |||
| 157 | { | 158 | { |
| 158 | struct scatterlist *sg = host->sg_ptr; | 159 | struct scatterlist *sg = host->sg_ptr; |
| 159 | u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE; | 160 | u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE; |
| 160 | enum dma_data_direction dir; | ||
| 161 | int ret; | ||
| 162 | 161 | ||
| 163 | /* This DMAC cannot handle if sg_len is not 1 */ | 162 | if (!dma_map_sg(&host->pdev->dev, sg, host->sg_len, |
| 164 | WARN_ON(host->sg_len > 1); | 163 | mmc_get_dma_dir(data))) |
| 164 | goto force_pio; | ||
| 165 | 165 | ||
| 166 | /* This DMAC cannot handle if buffer is not 8-bytes alignment */ | 166 | /* This DMAC cannot handle if buffer is not 8-bytes alignment */ |
| 167 | if (!IS_ALIGNED(sg->offset, 8)) | 167 | if (!IS_ALIGNED(sg_dma_address(sg), 8)) { |
| 168 | dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, | ||
| 169 | mmc_get_dma_dir(data)); | ||
| 168 | goto force_pio; | 170 | goto force_pio; |
| 171 | } | ||
| 169 | 172 | ||
| 170 | if (data->flags & MMC_DATA_READ) { | 173 | if (data->flags & MMC_DATA_READ) { |
| 171 | dtran_mode |= DTRAN_MODE_CH_NUM_CH1; | 174 | dtran_mode |= DTRAN_MODE_CH_NUM_CH1; |
| 172 | dir = DMA_FROM_DEVICE; | ||
| 173 | if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && | 175 | if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) && |
| 174 | test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) | 176 | test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags)) |
| 175 | goto force_pio; | 177 | goto force_pio; |
| 176 | } else { | 178 | } else { |
| 177 | dtran_mode |= DTRAN_MODE_CH_NUM_CH0; | 179 | dtran_mode |= DTRAN_MODE_CH_NUM_CH0; |
| 178 | dir = DMA_TO_DEVICE; | ||
| 179 | } | 180 | } |
| 180 | 181 | ||
| 181 | ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir); | ||
| 182 | if (ret == 0) | ||
| 183 | goto force_pio; | ||
| 184 | |||
| 185 | renesas_sdhi_internal_dmac_enable_dma(host, true); | 182 | renesas_sdhi_internal_dmac_enable_dma(host, true); |
| 186 | 183 | ||
| 187 | /* set dma parameters */ | 184 | /* set dma parameters */ |
| 188 | renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE, | 185 | renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE, |
| 189 | dtran_mode); | 186 | dtran_mode); |
| 190 | renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR, | 187 | renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR, |
| 191 | sg->dma_address); | 188 | sg_dma_address(sg)); |
| 192 | 189 | ||
| 193 | return; | 190 | return; |
| 194 | 191 | ||
| @@ -272,12 +269,17 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = { | |||
| 272 | * implementation as others may use a different implementation. | 269 | * implementation as others may use a different implementation. |
| 273 | */ | 270 | */ |
| 274 | static const struct soc_device_attribute gen3_soc_whitelist[] = { | 271 | static const struct soc_device_attribute gen3_soc_whitelist[] = { |
| 272 | /* specific ones */ | ||
| 275 | { .soc_id = "r8a7795", .revision = "ES1.*", | 273 | { .soc_id = "r8a7795", .revision = "ES1.*", |
| 276 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, | 274 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, |
| 277 | { .soc_id = "r8a7795", .revision = "ES2.0" }, | ||
| 278 | { .soc_id = "r8a7796", .revision = "ES1.0", | 275 | { .soc_id = "r8a7796", .revision = "ES1.0", |
| 279 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, | 276 | .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) }, |
| 280 | { .soc_id = "r8a77995", .revision = "ES1.0" }, | 277 | /* generic ones */ |
| 278 | { .soc_id = "r8a7795" }, | ||
| 279 | { .soc_id = "r8a7796" }, | ||
| 280 | { .soc_id = "r8a77965" }, | ||
| 281 | { .soc_id = "r8a77980" }, | ||
| 282 | { .soc_id = "r8a77995" }, | ||
| 281 | { /* sentinel */ } | 283 | { /* sentinel */ } |
| 282 | }; | 284 | }; |
| 283 | 285 | ||
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c index 848e50c1638a..4bb46c489d71 100644 --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c | |||
| @@ -42,6 +42,7 @@ static const struct renesas_sdhi_of_data of_rz_compatible = { | |||
| 42 | static const struct renesas_sdhi_of_data of_rcar_gen1_compatible = { | 42 | static const struct renesas_sdhi_of_data of_rcar_gen1_compatible = { |
| 43 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL, | 43 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL, |
| 44 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, | 44 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, |
| 45 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
| 45 | }; | 46 | }; |
| 46 | 47 | ||
| 47 | /* Definitions for sampling clocks */ | 48 | /* Definitions for sampling clocks */ |
| @@ -61,6 +62,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen2_compatible = { | |||
| 61 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, | 62 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, |
| 62 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | | 63 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
| 63 | MMC_CAP_CMD23, | 64 | MMC_CAP_CMD23, |
| 65 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
| 64 | .dma_buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES, | 66 | .dma_buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES, |
| 65 | .dma_rx_offset = 0x2000, | 67 | .dma_rx_offset = 0x2000, |
| 66 | .scc_offset = 0x0300, | 68 | .scc_offset = 0x0300, |
| @@ -81,6 +83,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { | |||
| 81 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, | 83 | TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, |
| 82 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | | 84 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
| 83 | MMC_CAP_CMD23, | 85 | MMC_CAP_CMD23, |
| 86 | .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, | ||
| 84 | .bus_shift = 2, | 87 | .bus_shift = 2, |
| 85 | .scc_offset = 0x1000, | 88 | .scc_offset = 0x1000, |
| 86 | .taps = rcar_gen3_scc_taps, | 89 | .taps = rcar_gen3_scc_taps, |
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c index 78422079ecfa..9a3ff22dd0fe 100644 --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
| 27 | #include <linux/mmc/mmc.h> | 27 | #include <linux/mmc/mmc.h> |
| 28 | #include <linux/mmc/sd.h> | 28 | #include <linux/mmc/sd.h> |
| 29 | #include <linux/mmc/sdio.h> | ||
| 30 | #include <linux/mmc/card.h> | 29 | #include <linux/mmc/card.h> |
| 31 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
| 32 | #include <linux/pm_runtime.h> | 31 | #include <linux/pm_runtime.h> |
| @@ -343,7 +342,7 @@ static void sd_send_cmd_get_rsp(struct rtsx_usb_sdmmc *host, | |||
| 343 | } | 342 | } |
| 344 | 343 | ||
| 345 | if (rsp_type == SD_RSP_TYPE_R1b) | 344 | if (rsp_type == SD_RSP_TYPE_R1b) |
| 346 | timeout = 3000; | 345 | timeout = cmd->busy_timeout ? cmd->busy_timeout : 3000; |
| 347 | 346 | ||
| 348 | if (cmd->opcode == SD_SWITCH_VOLTAGE) { | 347 | if (cmd->opcode == SD_SWITCH_VOLTAGE) { |
| 349 | err = rtsx_usb_write_register(ucr, SD_BUS_STAT, | 348 | err = rtsx_usb_write_register(ucr, SD_BUS_STAT, |
| @@ -839,17 +838,6 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 839 | goto finish_detect_card; | 838 | goto finish_detect_card; |
| 840 | } | 839 | } |
| 841 | 840 | ||
| 842 | /* | ||
| 843 | * Reject SDIO CMDs to speed up card identification | ||
| 844 | * since unsupported | ||
| 845 | */ | ||
| 846 | if (cmd->opcode == SD_IO_SEND_OP_COND || | ||
| 847 | cmd->opcode == SD_IO_RW_DIRECT || | ||
| 848 | cmd->opcode == SD_IO_RW_EXTENDED) { | ||
| 849 | cmd->error = -EINVAL; | ||
| 850 | goto finish; | ||
| 851 | } | ||
| 852 | |||
| 853 | mutex_lock(&ucr->dev_mutex); | 841 | mutex_lock(&ucr->dev_mutex); |
| 854 | 842 | ||
| 855 | mutex_lock(&host->host_mutex); | 843 | mutex_lock(&host->host_mutex); |
| @@ -1332,8 +1320,9 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host) | |||
| 1332 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | | 1320 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | |
| 1333 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST | | 1321 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST | |
| 1334 | MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | | 1322 | MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | |
| 1335 | MMC_CAP_NEEDS_POLL; | 1323 | MMC_CAP_NEEDS_POLL | MMC_CAP_ERASE; |
| 1336 | mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE; | 1324 | mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE | |
| 1325 | MMC_CAP2_NO_SDIO; | ||
| 1337 | 1326 | ||
| 1338 | mmc->max_current_330 = 400; | 1327 | mmc->max_current_330 = 400; |
| 1339 | mmc->max_current_180 = 800; | 1328 | mmc->max_current_180 = 800; |
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c index 11ca95c60bcf..bdbd4897c0f7 100644 --- a/drivers/mmc/host/sdhci-bcm-kona.c +++ b/drivers/mmc/host/sdhci-bcm-kona.c | |||
| @@ -284,10 +284,8 @@ static int sdhci_bcm_kona_probe(struct platform_device *pdev) | |||
| 284 | sdhci_bcm_kona_sd_init(host); | 284 | sdhci_bcm_kona_sd_init(host); |
| 285 | 285 | ||
| 286 | ret = sdhci_add_host(host); | 286 | ret = sdhci_add_host(host); |
| 287 | if (ret) { | 287 | if (ret) |
| 288 | dev_err(dev, "Failed sdhci_add_host\n"); | ||
| 289 | goto err_reset; | 288 | goto err_reset; |
| 290 | } | ||
| 291 | 289 | ||
| 292 | /* if device is eMMC, emulate card insert right here */ | 290 | /* if device is eMMC, emulate card insert right here */ |
| 293 | if (!mmc_card_is_removable(host->mmc)) { | 291 | if (!mmc_card_is_removable(host->mmc)) { |
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 0f589e26ee63..7a343b87b5e5 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c | |||
| @@ -253,6 +253,7 @@ static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) | |||
| 253 | struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); | 253 | struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); |
| 254 | void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS06; | 254 | void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS06; |
| 255 | u32 tmp; | 255 | u32 tmp; |
| 256 | int i, ret; | ||
| 256 | 257 | ||
| 257 | if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val))) | 258 | if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val))) |
| 258 | return -EINVAL; | 259 | return -EINVAL; |
| @@ -260,11 +261,24 @@ static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) | |||
| 260 | tmp = readl(reg); | 261 | tmp = readl(reg); |
| 261 | tmp &= ~SDHCI_CDNS_HRS06_TUNE; | 262 | tmp &= ~SDHCI_CDNS_HRS06_TUNE; |
| 262 | tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val); | 263 | tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val); |
| 263 | tmp |= SDHCI_CDNS_HRS06_TUNE_UP; | ||
| 264 | writel(tmp, reg); | ||
| 265 | 264 | ||
| 266 | return readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS06_TUNE_UP), | 265 | /* |
| 267 | 0, 1); | 266 | * Workaround for IP errata: |
| 267 | * The IP6116 SD/eMMC PHY design has a timing issue on receive data | ||
| 268 | * path. Send tune request twice. | ||
| 269 | */ | ||
| 270 | for (i = 0; i < 2; i++) { | ||
| 271 | tmp |= SDHCI_CDNS_HRS06_TUNE_UP; | ||
| 272 | writel(tmp, reg); | ||
| 273 | |||
| 274 | ret = readl_poll_timeout(reg, tmp, | ||
| 275 | !(tmp & SDHCI_CDNS_HRS06_TUNE_UP), | ||
| 276 | 0, 1); | ||
| 277 | if (ret) | ||
| 278 | return ret; | ||
| 279 | } | ||
| 280 | |||
| 281 | return 0; | ||
| 268 | } | 282 | } |
| 269 | 283 | ||
| 270 | static int sdhci_cdns_execute_tuning(struct mmc_host *mmc, u32 opcode) | 284 | static int sdhci_cdns_execute_tuning(struct mmc_host *mmc, u32 opcode) |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index cd2b5f643a15..d6aef70d34fa 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
| @@ -41,6 +41,12 @@ | |||
| 41 | #define ESDHC_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8) | 41 | #define ESDHC_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8) |
| 42 | #define ESDHC_WTMK_LVL 0x44 | 42 | #define ESDHC_WTMK_LVL 0x44 |
| 43 | #define ESDHC_WTMK_DEFAULT_VAL 0x10401040 | 43 | #define ESDHC_WTMK_DEFAULT_VAL 0x10401040 |
| 44 | #define ESDHC_WTMK_LVL_RD_WML_MASK 0x000000FF | ||
| 45 | #define ESDHC_WTMK_LVL_RD_WML_SHIFT 0 | ||
| 46 | #define ESDHC_WTMK_LVL_WR_WML_MASK 0x00FF0000 | ||
| 47 | #define ESDHC_WTMK_LVL_WR_WML_SHIFT 16 | ||
| 48 | #define ESDHC_WTMK_LVL_WML_VAL_DEF 64 | ||
| 49 | #define ESDHC_WTMK_LVL_WML_VAL_MAX 128 | ||
| 44 | #define ESDHC_MIX_CTRL 0x48 | 50 | #define ESDHC_MIX_CTRL 0x48 |
| 45 | #define ESDHC_MIX_CTRL_DDREN (1 << 3) | 51 | #define ESDHC_MIX_CTRL_DDREN (1 << 3) |
| 46 | #define ESDHC_MIX_CTRL_AC23EN (1 << 7) | 52 | #define ESDHC_MIX_CTRL_AC23EN (1 << 7) |
| @@ -516,6 +522,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) | |||
| 516 | } | 522 | } |
| 517 | 523 | ||
| 518 | if (esdhc_is_usdhc(imx_data)) { | 524 | if (esdhc_is_usdhc(imx_data)) { |
| 525 | u32 wml; | ||
| 519 | u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); | 526 | u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL); |
| 520 | /* Swap AC23 bit */ | 527 | /* Swap AC23 bit */ |
| 521 | if (val & SDHCI_TRNS_AUTO_CMD23) { | 528 | if (val & SDHCI_TRNS_AUTO_CMD23) { |
| @@ -524,6 +531,21 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) | |||
| 524 | } | 531 | } |
| 525 | m = val | (m & ~ESDHC_MIX_CTRL_SDHCI_MASK); | 532 | m = val | (m & ~ESDHC_MIX_CTRL_SDHCI_MASK); |
| 526 | writel(m, host->ioaddr + ESDHC_MIX_CTRL); | 533 | writel(m, host->ioaddr + ESDHC_MIX_CTRL); |
| 534 | |||
| 535 | /* Set watermark levels for PIO access to maximum value | ||
| 536 | * (128 words) to accommodate full 512 bytes buffer. | ||
| 537 | * For DMA access restore the levels to default value. | ||
| 538 | */ | ||
| 539 | m = readl(host->ioaddr + ESDHC_WTMK_LVL); | ||
| 540 | if (val & SDHCI_TRNS_DMA) | ||
| 541 | wml = ESDHC_WTMK_LVL_WML_VAL_DEF; | ||
| 542 | else | ||
| 543 | wml = ESDHC_WTMK_LVL_WML_VAL_MAX; | ||
| 544 | m &= ~(ESDHC_WTMK_LVL_RD_WML_MASK | | ||
| 545 | ESDHC_WTMK_LVL_WR_WML_MASK); | ||
| 546 | m |= (wml << ESDHC_WTMK_LVL_RD_WML_SHIFT) | | ||
| 547 | (wml << ESDHC_WTMK_LVL_WR_WML_SHIFT); | ||
| 548 | writel(m, host->ioaddr + ESDHC_WTMK_LVL); | ||
| 527 | } else { | 549 | } else { |
| 528 | /* | 550 | /* |
| 529 | * Postpone this write, we must do it together with a | 551 | * Postpone this write, we must do it together with a |
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index c283291db705..646bf377ba77 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/pm_runtime.h> | 21 | #include <linux/pm_runtime.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/iopoll.h> | 23 | #include <linux/iopoll.h> |
| 24 | #include <linux/regulator/consumer.h> | ||
| 24 | 25 | ||
| 25 | #include "sdhci-pltfm.h" | 26 | #include "sdhci-pltfm.h" |
| 26 | 27 | ||
| @@ -77,10 +78,16 @@ | |||
| 77 | #define CORE_HC_MCLK_SEL_DFLT (2 << 8) | 78 | #define CORE_HC_MCLK_SEL_DFLT (2 << 8) |
| 78 | #define CORE_HC_MCLK_SEL_HS400 (3 << 8) | 79 | #define CORE_HC_MCLK_SEL_HS400 (3 << 8) |
| 79 | #define CORE_HC_MCLK_SEL_MASK (3 << 8) | 80 | #define CORE_HC_MCLK_SEL_MASK (3 << 8) |
| 81 | #define CORE_IO_PAD_PWR_SWITCH_EN (1 << 15) | ||
| 82 | #define CORE_IO_PAD_PWR_SWITCH (1 << 16) | ||
| 80 | #define CORE_HC_SELECT_IN_EN BIT(18) | 83 | #define CORE_HC_SELECT_IN_EN BIT(18) |
| 81 | #define CORE_HC_SELECT_IN_HS400 (6 << 19) | 84 | #define CORE_HC_SELECT_IN_HS400 (6 << 19) |
| 82 | #define CORE_HC_SELECT_IN_MASK (7 << 19) | 85 | #define CORE_HC_SELECT_IN_MASK (7 << 19) |
| 83 | 86 | ||
| 87 | #define CORE_3_0V_SUPPORT (1 << 25) | ||
| 88 | #define CORE_1_8V_SUPPORT (1 << 26) | ||
| 89 | #define CORE_VOLT_SUPPORT (CORE_3_0V_SUPPORT | CORE_1_8V_SUPPORT) | ||
| 90 | |||
| 84 | #define CORE_CSR_CDC_CTLR_CFG0 0x130 | 91 | #define CORE_CSR_CDC_CTLR_CFG0 0x130 |
| 85 | #define CORE_SW_TRIG_FULL_CALIB BIT(16) | 92 | #define CORE_SW_TRIG_FULL_CALIB BIT(16) |
| 86 | #define CORE_HW_AUTOCAL_ENA BIT(17) | 93 | #define CORE_HW_AUTOCAL_ENA BIT(17) |
| @@ -148,6 +155,7 @@ struct sdhci_msm_host { | |||
| 148 | u32 curr_io_level; | 155 | u32 curr_io_level; |
| 149 | wait_queue_head_t pwr_irq_wait; | 156 | wait_queue_head_t pwr_irq_wait; |
| 150 | bool pwr_irq_flag; | 157 | bool pwr_irq_flag; |
| 158 | u32 caps_0; | ||
| 151 | }; | 159 | }; |
| 152 | 160 | ||
| 153 | static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, | 161 | static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, |
| @@ -1103,8 +1111,8 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) | |||
| 1103 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 1111 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
| 1104 | u32 irq_status, irq_ack = 0; | 1112 | u32 irq_status, irq_ack = 0; |
| 1105 | int retry = 10; | 1113 | int retry = 10; |
| 1106 | int pwr_state = 0, io_level = 0; | 1114 | u32 pwr_state = 0, io_level = 0; |
| 1107 | 1115 | u32 config; | |
| 1108 | 1116 | ||
| 1109 | irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); | 1117 | irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); |
| 1110 | irq_status &= INT_MASK; | 1118 | irq_status &= INT_MASK; |
| @@ -1161,6 +1169,38 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) | |||
| 1161 | */ | 1169 | */ |
| 1162 | writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); | 1170 | writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); |
| 1163 | 1171 | ||
| 1172 | /* | ||
| 1173 | * If we don't have info regarding the voltage levels supported by | ||
| 1174 | * regulators, don't change the IO PAD PWR SWITCH. | ||
| 1175 | */ | ||
| 1176 | if (msm_host->caps_0 & CORE_VOLT_SUPPORT) { | ||
| 1177 | u32 new_config; | ||
| 1178 | /* | ||
| 1179 | * We should unset IO PAD PWR switch only if the register write | ||
| 1180 | * can set IO lines high and the regulator also switches to 3 V. | ||
| 1181 | * Else, we should keep the IO PAD PWR switch set. | ||
| 1182 | * This is applicable to certain targets where eMMC vccq supply | ||
| 1183 | * is only 1.8V. In such targets, even during REQ_IO_HIGH, the | ||
| 1184 | * IO PAD PWR switch must be kept set to reflect actual | ||
| 1185 | * regulator voltage. This way, during initialization of | ||
| 1186 | * controllers with only 1.8V, we will set the IO PAD bit | ||
| 1187 | * without waiting for a REQ_IO_LOW. | ||
| 1188 | */ | ||
| 1189 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
| 1190 | new_config = config; | ||
| 1191 | |||
| 1192 | if ((io_level & REQ_IO_HIGH) && | ||
| 1193 | (msm_host->caps_0 & CORE_3_0V_SUPPORT)) | ||
| 1194 | new_config &= ~CORE_IO_PAD_PWR_SWITCH; | ||
| 1195 | else if ((io_level & REQ_IO_LOW) || | ||
| 1196 | (msm_host->caps_0 & CORE_1_8V_SUPPORT)) | ||
| 1197 | new_config |= CORE_IO_PAD_PWR_SWITCH; | ||
| 1198 | |||
| 1199 | if (config ^ new_config) | ||
| 1200 | writel_relaxed(new_config, | ||
| 1201 | host->ioaddr + CORE_VENDOR_SPEC); | ||
| 1202 | } | ||
| 1203 | |||
| 1164 | if (pwr_state) | 1204 | if (pwr_state) |
| 1165 | msm_host->curr_pwr_state = pwr_state; | 1205 | msm_host->curr_pwr_state = pwr_state; |
| 1166 | if (io_level) | 1206 | if (io_level) |
| @@ -1313,6 +1353,45 @@ static void sdhci_msm_writeb(struct sdhci_host *host, u8 val, int reg) | |||
| 1313 | sdhci_msm_check_power_status(host, req_type); | 1353 | sdhci_msm_check_power_status(host, req_type); |
| 1314 | } | 1354 | } |
| 1315 | 1355 | ||
| 1356 | static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host) | ||
| 1357 | { | ||
| 1358 | struct mmc_host *mmc = msm_host->mmc; | ||
| 1359 | struct regulator *supply = mmc->supply.vqmmc; | ||
| 1360 | u32 caps = 0, config; | ||
| 1361 | struct sdhci_host *host = mmc_priv(mmc); | ||
| 1362 | |||
| 1363 | if (!IS_ERR(mmc->supply.vqmmc)) { | ||
| 1364 | if (regulator_is_supported_voltage(supply, 1700000, 1950000)) | ||
| 1365 | caps |= CORE_1_8V_SUPPORT; | ||
| 1366 | if (regulator_is_supported_voltage(supply, 2700000, 3600000)) | ||
| 1367 | caps |= CORE_3_0V_SUPPORT; | ||
| 1368 | |||
| 1369 | if (!caps) | ||
| 1370 | pr_warn("%s: 1.8/3V not supported for vqmmc\n", | ||
| 1371 | mmc_hostname(mmc)); | ||
| 1372 | } | ||
| 1373 | |||
| 1374 | if (caps) { | ||
| 1375 | /* | ||
| 1376 | * Set the PAD_PWR_SWITCH_EN bit so that the PAD_PWR_SWITCH | ||
| 1377 | * bit can be used as required later on. | ||
| 1378 | */ | ||
| 1379 | u32 io_level = msm_host->curr_io_level; | ||
| 1380 | |||
| 1381 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
| 1382 | config |= CORE_IO_PAD_PWR_SWITCH_EN; | ||
| 1383 | |||
| 1384 | if ((io_level & REQ_IO_HIGH) && (caps & CORE_3_0V_SUPPORT)) | ||
| 1385 | config &= ~CORE_IO_PAD_PWR_SWITCH; | ||
| 1386 | else if ((io_level & REQ_IO_LOW) || (caps & CORE_1_8V_SUPPORT)) | ||
| 1387 | config |= CORE_IO_PAD_PWR_SWITCH; | ||
| 1388 | |||
| 1389 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
| 1390 | } | ||
| 1391 | msm_host->caps_0 |= caps; | ||
| 1392 | pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps); | ||
| 1393 | } | ||
| 1394 | |||
| 1316 | static const struct of_device_id sdhci_msm_dt_match[] = { | 1395 | static const struct of_device_id sdhci_msm_dt_match[] = { |
| 1317 | { .compatible = "qcom,sdhci-msm-v4" }, | 1396 | { .compatible = "qcom,sdhci-msm-v4" }, |
| 1318 | {}, | 1397 | {}, |
| @@ -1333,7 +1412,6 @@ static const struct sdhci_ops sdhci_msm_ops = { | |||
| 1333 | 1412 | ||
| 1334 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { | 1413 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { |
| 1335 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | | 1414 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | |
| 1336 | SDHCI_QUIRK_NO_CARD_NO_RESET | | ||
| 1337 | SDHCI_QUIRK_SINGLE_POWER_WRITE | | 1415 | SDHCI_QUIRK_SINGLE_POWER_WRITE | |
| 1338 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | 1416 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
| 1339 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, | 1417 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
| @@ -1530,6 +1608,7 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
| 1530 | ret = sdhci_add_host(host); | 1608 | ret = sdhci_add_host(host); |
| 1531 | if (ret) | 1609 | if (ret) |
| 1532 | goto pm_runtime_disable; | 1610 | goto pm_runtime_disable; |
| 1611 | sdhci_msm_set_regulator_caps(msm_host); | ||
| 1533 | 1612 | ||
| 1534 | pm_runtime_mark_last_busy(&pdev->dev); | 1613 | pm_runtime_mark_last_busy(&pdev->dev); |
| 1535 | pm_runtime_put_autosuspend(&pdev->dev); | 1614 | pm_runtime_put_autosuspend(&pdev->dev); |
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index c33a5f7393bd..e3332a522a5d 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c | |||
| @@ -290,7 +290,8 @@ static const struct sdhci_pltfm_data sdhci_arasan_pdata = { | |||
| 290 | .ops = &sdhci_arasan_ops, | 290 | .ops = &sdhci_arasan_ops, |
| 291 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | 291 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
| 292 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 292 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
| 293 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, | 293 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | |
| 294 | SDHCI_QUIRK2_STOP_WITH_TC, | ||
| 294 | }; | 295 | }; |
| 295 | 296 | ||
| 296 | static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask) | 297 | static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask) |
| @@ -359,8 +360,7 @@ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = { | |||
| 359 | */ | 360 | */ |
| 360 | static int sdhci_arasan_suspend(struct device *dev) | 361 | static int sdhci_arasan_suspend(struct device *dev) |
| 361 | { | 362 | { |
| 362 | struct platform_device *pdev = to_platform_device(dev); | 363 | struct sdhci_host *host = dev_get_drvdata(dev); |
| 363 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
| 364 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 364 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 365 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | 365 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
| 366 | int ret; | 366 | int ret; |
| @@ -403,8 +403,7 @@ static int sdhci_arasan_suspend(struct device *dev) | |||
| 403 | */ | 403 | */ |
| 404 | static int sdhci_arasan_resume(struct device *dev) | 404 | static int sdhci_arasan_resume(struct device *dev) |
| 405 | { | 405 | { |
| 406 | struct platform_device *pdev = to_platform_device(dev); | 406 | struct sdhci_host *host = dev_get_drvdata(dev); |
| 407 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
| 408 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 407 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 409 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | 408 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
| 410 | int ret; | 409 | int ret; |
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index 1456abd5eeb9..f3a7c8ece4be 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 27 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
| 28 | #include <linux/pinctrl/consumer.h> | 28 | #include <linux/pinctrl/consumer.h> |
| 29 | #include <linux/sys_soc.h> | ||
| 29 | 30 | ||
| 30 | #include "sdhci-pltfm.h" | 31 | #include "sdhci-pltfm.h" |
| 31 | 32 | ||
| @@ -35,6 +36,7 @@ | |||
| 35 | #define CON_DDR BIT(19) | 36 | #define CON_DDR BIT(19) |
| 36 | #define CON_CLKEXTFREE BIT(16) | 37 | #define CON_CLKEXTFREE BIT(16) |
| 37 | #define CON_PADEN BIT(15) | 38 | #define CON_PADEN BIT(15) |
| 39 | #define CON_CTPL BIT(11) | ||
| 38 | #define CON_INIT BIT(1) | 40 | #define CON_INIT BIT(1) |
| 39 | #define CON_OD BIT(0) | 41 | #define CON_OD BIT(0) |
| 40 | 42 | ||
| @@ -100,6 +102,7 @@ struct sdhci_omap_data { | |||
| 100 | }; | 102 | }; |
| 101 | 103 | ||
| 102 | struct sdhci_omap_host { | 104 | struct sdhci_omap_host { |
| 105 | char *version; | ||
| 103 | void __iomem *base; | 106 | void __iomem *base; |
| 104 | struct device *dev; | 107 | struct device *dev; |
| 105 | struct regulator *pbias; | 108 | struct regulator *pbias; |
| @@ -224,6 +227,23 @@ static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host, | |||
| 224 | } | 227 | } |
| 225 | } | 228 | } |
| 226 | 229 | ||
| 230 | static void sdhci_omap_enable_sdio_irq(struct mmc_host *mmc, int enable) | ||
| 231 | { | ||
| 232 | struct sdhci_host *host = mmc_priv(mmc); | ||
| 233 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
| 234 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | ||
| 235 | u32 reg; | ||
| 236 | |||
| 237 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); | ||
| 238 | if (enable) | ||
| 239 | reg |= (CON_CTPL | CON_CLKEXTFREE); | ||
| 240 | else | ||
| 241 | reg &= ~(CON_CTPL | CON_CLKEXTFREE); | ||
| 242 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); | ||
| 243 | |||
| 244 | sdhci_enable_sdio_irq(mmc, enable); | ||
| 245 | } | ||
| 246 | |||
| 227 | static inline void sdhci_omap_set_dll(struct sdhci_omap_host *omap_host, | 247 | static inline void sdhci_omap_set_dll(struct sdhci_omap_host *omap_host, |
| 228 | int count) | 248 | int count) |
| 229 | { | 249 | { |
| @@ -713,10 +733,15 @@ static const struct sdhci_pltfm_data sdhci_omap_pdata = { | |||
| 713 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, | 733 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, |
| 714 | .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | | 734 | .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | |
| 715 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 735 | SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
| 716 | SDHCI_QUIRK2_RSP_136_HAS_CRC, | 736 | SDHCI_QUIRK2_RSP_136_HAS_CRC | |
| 737 | SDHCI_QUIRK2_DISABLE_HW_TIMEOUT, | ||
| 717 | .ops = &sdhci_omap_ops, | 738 | .ops = &sdhci_omap_ops, |
| 718 | }; | 739 | }; |
| 719 | 740 | ||
| 741 | static const struct sdhci_omap_data k2g_data = { | ||
| 742 | .offset = 0x200, | ||
| 743 | }; | ||
| 744 | |||
| 720 | static const struct sdhci_omap_data dra7_data = { | 745 | static const struct sdhci_omap_data dra7_data = { |
| 721 | .offset = 0x200, | 746 | .offset = 0x200, |
| 722 | .flags = SDHCI_OMAP_REQUIRE_IODELAY, | 747 | .flags = SDHCI_OMAP_REQUIRE_IODELAY, |
| @@ -724,6 +749,7 @@ static const struct sdhci_omap_data dra7_data = { | |||
| 724 | 749 | ||
| 725 | static const struct of_device_id omap_sdhci_match[] = { | 750 | static const struct of_device_id omap_sdhci_match[] = { |
| 726 | { .compatible = "ti,dra7-sdhci", .data = &dra7_data }, | 751 | { .compatible = "ti,dra7-sdhci", .data = &dra7_data }, |
| 752 | { .compatible = "ti,k2g-sdhci", .data = &k2g_data }, | ||
| 727 | {}, | 753 | {}, |
| 728 | }; | 754 | }; |
| 729 | MODULE_DEVICE_TABLE(of, omap_sdhci_match); | 755 | MODULE_DEVICE_TABLE(of, omap_sdhci_match); |
| @@ -733,12 +759,21 @@ static struct pinctrl_state | |||
| 733 | u32 *caps, u32 capmask) | 759 | u32 *caps, u32 capmask) |
| 734 | { | 760 | { |
| 735 | struct device *dev = omap_host->dev; | 761 | struct device *dev = omap_host->dev; |
| 762 | char *version = omap_host->version; | ||
| 736 | struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV); | 763 | struct pinctrl_state *pinctrl_state = ERR_PTR(-ENODEV); |
| 764 | char str[20]; | ||
| 737 | 765 | ||
| 738 | if (!(*caps & capmask)) | 766 | if (!(*caps & capmask)) |
| 739 | goto ret; | 767 | goto ret; |
| 740 | 768 | ||
| 741 | pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode); | 769 | if (version) { |
| 770 | snprintf(str, 20, "%s-%s", mode, version); | ||
| 771 | pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, str); | ||
| 772 | } | ||
| 773 | |||
| 774 | if (IS_ERR(pinctrl_state)) | ||
| 775 | pinctrl_state = pinctrl_lookup_state(omap_host->pinctrl, mode); | ||
| 776 | |||
| 742 | if (IS_ERR(pinctrl_state)) { | 777 | if (IS_ERR(pinctrl_state)) { |
| 743 | dev_err(dev, "no pinctrl state for %s mode", mode); | 778 | dev_err(dev, "no pinctrl state for %s mode", mode); |
| 744 | *caps &= ~capmask; | 779 | *caps &= ~capmask; |
| @@ -807,8 +842,15 @@ static int sdhci_omap_config_iodelay_pinctrl_state(struct sdhci_omap_host | |||
| 807 | 842 | ||
| 808 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_1_8v", caps, | 843 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_1_8v", caps, |
| 809 | MMC_CAP_1_8V_DDR); | 844 | MMC_CAP_1_8V_DDR); |
| 810 | if (!IS_ERR(state)) | 845 | if (!IS_ERR(state)) { |
| 811 | pinctrl_state[MMC_TIMING_MMC_DDR52] = state; | 846 | pinctrl_state[MMC_TIMING_MMC_DDR52] = state; |
| 847 | } else { | ||
| 848 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "ddr_3_3v", | ||
| 849 | caps, | ||
| 850 | MMC_CAP_3_3V_DDR); | ||
| 851 | if (!IS_ERR(state)) | ||
| 852 | pinctrl_state[MMC_TIMING_MMC_DDR52] = state; | ||
| 853 | } | ||
| 812 | 854 | ||
| 813 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps, | 855 | state = sdhci_omap_iodelay_pinctrl_state(omap_host, "hs", caps, |
| 814 | MMC_CAP_SD_HIGHSPEED); | 856 | MMC_CAP_SD_HIGHSPEED); |
| @@ -830,6 +872,16 @@ static int sdhci_omap_config_iodelay_pinctrl_state(struct sdhci_omap_host | |||
| 830 | return 0; | 872 | return 0; |
| 831 | } | 873 | } |
| 832 | 874 | ||
| 875 | static const struct soc_device_attribute sdhci_omap_soc_devices[] = { | ||
| 876 | { | ||
| 877 | .machine = "DRA7[45]*", | ||
| 878 | .revision = "ES1.[01]", | ||
| 879 | }, | ||
| 880 | { | ||
| 881 | /* sentinel */ | ||
| 882 | } | ||
| 883 | }; | ||
| 884 | |||
| 833 | static int sdhci_omap_probe(struct platform_device *pdev) | 885 | static int sdhci_omap_probe(struct platform_device *pdev) |
| 834 | { | 886 | { |
| 835 | int ret; | 887 | int ret; |
| @@ -841,6 +893,7 @@ static int sdhci_omap_probe(struct platform_device *pdev) | |||
| 841 | struct mmc_host *mmc; | 893 | struct mmc_host *mmc; |
| 842 | const struct of_device_id *match; | 894 | const struct of_device_id *match; |
| 843 | struct sdhci_omap_data *data; | 895 | struct sdhci_omap_data *data; |
| 896 | const struct soc_device_attribute *soc; | ||
| 844 | 897 | ||
| 845 | match = of_match_device(omap_sdhci_match, dev); | 898 | match = of_match_device(omap_sdhci_match, dev); |
| 846 | if (!match) | 899 | if (!match) |
| @@ -871,10 +924,22 @@ static int sdhci_omap_probe(struct platform_device *pdev) | |||
| 871 | host->ioaddr += offset; | 924 | host->ioaddr += offset; |
| 872 | 925 | ||
| 873 | mmc = host->mmc; | 926 | mmc = host->mmc; |
| 927 | sdhci_get_of_property(pdev); | ||
| 874 | ret = mmc_of_parse(mmc); | 928 | ret = mmc_of_parse(mmc); |
| 875 | if (ret) | 929 | if (ret) |
| 876 | goto err_pltfm_free; | 930 | goto err_pltfm_free; |
| 877 | 931 | ||
| 932 | soc = soc_device_match(sdhci_omap_soc_devices); | ||
| 933 | if (soc) { | ||
| 934 | omap_host->version = "rev11"; | ||
| 935 | if (!strcmp(dev_name(dev), "4809c000.mmc")) | ||
| 936 | mmc->f_max = 96000000; | ||
| 937 | if (!strcmp(dev_name(dev), "480b4000.mmc")) | ||
| 938 | mmc->f_max = 48000000; | ||
| 939 | if (!strcmp(dev_name(dev), "480ad000.mmc")) | ||
| 940 | mmc->f_max = 48000000; | ||
| 941 | } | ||
| 942 | |||
| 878 | pltfm_host->clk = devm_clk_get(dev, "fck"); | 943 | pltfm_host->clk = devm_clk_get(dev, "fck"); |
| 879 | if (IS_ERR(pltfm_host->clk)) { | 944 | if (IS_ERR(pltfm_host->clk)) { |
| 880 | ret = PTR_ERR(pltfm_host->clk); | 945 | ret = PTR_ERR(pltfm_host->clk); |
| @@ -916,26 +981,31 @@ static int sdhci_omap_probe(struct platform_device *pdev) | |||
| 916 | goto err_put_sync; | 981 | goto err_put_sync; |
| 917 | } | 982 | } |
| 918 | 983 | ||
| 919 | ret = sdhci_omap_config_iodelay_pinctrl_state(omap_host); | ||
| 920 | if (ret) | ||
| 921 | goto err_put_sync; | ||
| 922 | |||
| 923 | host->mmc_host_ops.get_ro = mmc_gpio_get_ro; | 984 | host->mmc_host_ops.get_ro = mmc_gpio_get_ro; |
| 924 | host->mmc_host_ops.start_signal_voltage_switch = | 985 | host->mmc_host_ops.start_signal_voltage_switch = |
| 925 | sdhci_omap_start_signal_voltage_switch; | 986 | sdhci_omap_start_signal_voltage_switch; |
| 926 | host->mmc_host_ops.set_ios = sdhci_omap_set_ios; | 987 | host->mmc_host_ops.set_ios = sdhci_omap_set_ios; |
| 927 | host->mmc_host_ops.card_busy = sdhci_omap_card_busy; | 988 | host->mmc_host_ops.card_busy = sdhci_omap_card_busy; |
| 928 | host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; | 989 | host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; |
| 990 | host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq; | ||
| 929 | 991 | ||
| 930 | sdhci_read_caps(host); | 992 | ret = sdhci_setup_host(host); |
| 931 | host->caps |= SDHCI_CAN_DO_ADMA2; | ||
| 932 | |||
| 933 | ret = sdhci_add_host(host); | ||
| 934 | if (ret) | 993 | if (ret) |
| 935 | goto err_put_sync; | 994 | goto err_put_sync; |
| 936 | 995 | ||
| 996 | ret = sdhci_omap_config_iodelay_pinctrl_state(omap_host); | ||
| 997 | if (ret) | ||
| 998 | goto err_cleanup_host; | ||
| 999 | |||
| 1000 | ret = __sdhci_add_host(host); | ||
| 1001 | if (ret) | ||
| 1002 | goto err_cleanup_host; | ||
| 1003 | |||
| 937 | return 0; | 1004 | return 0; |
| 938 | 1005 | ||
| 1006 | err_cleanup_host: | ||
| 1007 | sdhci_cleanup_host(host); | ||
| 1008 | |||
| 939 | err_put_sync: | 1009 | err_put_sync: |
| 940 | pm_runtime_put_sync(dev); | 1010 | pm_runtime_put_sync(dev); |
| 941 | 1011 | ||
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 78c25ad35fd2..77dd3521daae 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c | |||
| @@ -453,6 +453,7 @@ static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = { | |||
| 453 | enum { | 453 | enum { |
| 454 | INTEL_DSM_FNS = 0, | 454 | INTEL_DSM_FNS = 0, |
| 455 | INTEL_DSM_V18_SWITCH = 3, | 455 | INTEL_DSM_V18_SWITCH = 3, |
| 456 | INTEL_DSM_V33_SWITCH = 4, | ||
| 456 | INTEL_DSM_DRV_STRENGTH = 9, | 457 | INTEL_DSM_DRV_STRENGTH = 9, |
| 457 | INTEL_DSM_D3_RETUNE = 10, | 458 | INTEL_DSM_D3_RETUNE = 10, |
| 458 | }; | 459 | }; |
| @@ -620,17 +621,37 @@ static void intel_hs400_enhanced_strobe(struct mmc_host *mmc, | |||
| 620 | sdhci_writel(host, val, INTEL_HS400_ES_REG); | 621 | sdhci_writel(host, val, INTEL_HS400_ES_REG); |
| 621 | } | 622 | } |
| 622 | 623 | ||
| 623 | static void sdhci_intel_voltage_switch(struct sdhci_host *host) | 624 | static int intel_start_signal_voltage_switch(struct mmc_host *mmc, |
| 625 | struct mmc_ios *ios) | ||
| 624 | { | 626 | { |
| 627 | struct device *dev = mmc_dev(mmc); | ||
| 628 | struct sdhci_host *host = mmc_priv(mmc); | ||
| 625 | struct sdhci_pci_slot *slot = sdhci_priv(host); | 629 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
| 626 | struct intel_host *intel_host = sdhci_pci_priv(slot); | 630 | struct intel_host *intel_host = sdhci_pci_priv(slot); |
| 627 | struct device *dev = &slot->chip->pdev->dev; | 631 | unsigned int fn; |
| 628 | u32 result = 0; | 632 | u32 result = 0; |
| 629 | int err; | 633 | int err; |
| 630 | 634 | ||
| 631 | err = intel_dsm(intel_host, dev, INTEL_DSM_V18_SWITCH, &result); | 635 | err = sdhci_start_signal_voltage_switch(mmc, ios); |
| 632 | pr_debug("%s: %s DSM error %d result %u\n", | 636 | if (err) |
| 633 | mmc_hostname(host->mmc), __func__, err, result); | 637 | return err; |
| 638 | |||
| 639 | switch (ios->signal_voltage) { | ||
| 640 | case MMC_SIGNAL_VOLTAGE_330: | ||
| 641 | fn = INTEL_DSM_V33_SWITCH; | ||
| 642 | break; | ||
| 643 | case MMC_SIGNAL_VOLTAGE_180: | ||
| 644 | fn = INTEL_DSM_V18_SWITCH; | ||
| 645 | break; | ||
| 646 | default: | ||
| 647 | return 0; | ||
| 648 | } | ||
| 649 | |||
| 650 | err = intel_dsm(intel_host, dev, fn, &result); | ||
| 651 | pr_debug("%s: %s DSM fn %u error %d result %u\n", | ||
| 652 | mmc_hostname(mmc), __func__, fn, err, result); | ||
| 653 | |||
| 654 | return 0; | ||
| 634 | } | 655 | } |
| 635 | 656 | ||
| 636 | static const struct sdhci_ops sdhci_intel_byt_ops = { | 657 | static const struct sdhci_ops sdhci_intel_byt_ops = { |
| @@ -641,7 +662,6 @@ static const struct sdhci_ops sdhci_intel_byt_ops = { | |||
| 641 | .reset = sdhci_reset, | 662 | .reset = sdhci_reset, |
| 642 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 663 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 643 | .hw_reset = sdhci_pci_hw_reset, | 664 | .hw_reset = sdhci_pci_hw_reset, |
| 644 | .voltage_switch = sdhci_intel_voltage_switch, | ||
| 645 | }; | 665 | }; |
| 646 | 666 | ||
| 647 | static const struct sdhci_ops sdhci_intel_glk_ops = { | 667 | static const struct sdhci_ops sdhci_intel_glk_ops = { |
| @@ -652,7 +672,6 @@ static const struct sdhci_ops sdhci_intel_glk_ops = { | |||
| 652 | .reset = sdhci_reset, | 672 | .reset = sdhci_reset, |
| 653 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 673 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
| 654 | .hw_reset = sdhci_pci_hw_reset, | 674 | .hw_reset = sdhci_pci_hw_reset, |
| 655 | .voltage_switch = sdhci_intel_voltage_switch, | ||
| 656 | .irq = sdhci_cqhci_irq, | 675 | .irq = sdhci_cqhci_irq, |
| 657 | }; | 676 | }; |
| 658 | 677 | ||
| @@ -691,6 +710,7 @@ static void byt_probe_slot(struct sdhci_pci_slot *slot) | |||
| 691 | byt_read_dsm(slot); | 710 | byt_read_dsm(slot); |
| 692 | 711 | ||
| 693 | ops->execute_tuning = intel_execute_tuning; | 712 | ops->execute_tuning = intel_execute_tuning; |
| 713 | ops->start_signal_voltage_switch = intel_start_signal_voltage_switch; | ||
| 694 | } | 714 | } |
| 695 | 715 | ||
| 696 | static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) | 716 | static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) |
| @@ -832,6 +852,10 @@ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) | |||
| 832 | slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_SD) | 852 | slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_SD) |
| 833 | slot->host->mmc_host_ops.get_cd = bxt_get_cd; | 853 | slot->host->mmc_host_ops.get_cd = bxt_get_cd; |
| 834 | 854 | ||
| 855 | if (slot->chip->pdev->subsystem_vendor == PCI_VENDOR_ID_NI && | ||
| 856 | slot->chip->pdev->subsystem_device == PCI_SUBDEVICE_ID_NI_78E3) | ||
| 857 | slot->host->mmc->caps2 |= MMC_CAP2_AVOID_3_3V; | ||
| 858 | |||
| 835 | return 0; | 859 | return 0; |
| 836 | } | 860 | } |
| 837 | 861 | ||
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 5cbcdc448f98..db9cb54ef700 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #define PCI_DEVICE_ID_REALTEK_5250 0x5250 | 54 | #define PCI_DEVICE_ID_REALTEK_5250 0x5250 |
| 55 | 55 | ||
| 56 | #define PCI_SUBDEVICE_ID_NI_7884 0x7884 | 56 | #define PCI_SUBDEVICE_ID_NI_7884 0x7884 |
| 57 | #define PCI_SUBDEVICE_ID_NI_78E3 0x78e3 | ||
| 57 | 58 | ||
| 58 | #define PCI_VENDOR_ID_ARASAN 0x16e6 | 59 | #define PCI_VENDOR_ID_ARASAN 0x16e6 |
| 59 | #define PCI_DEVICE_ID_ARASAN_PHY_EMMC 0x0670 | 60 | #define PCI_DEVICE_ID_ARASAN_PHY_EMMC 0x0670 |
diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c index a6caa49ca25a..a11e6397d4ff 100644 --- a/drivers/mmc/host/sdhci-pic32.c +++ b/drivers/mmc/host/sdhci-pic32.c | |||
| @@ -200,10 +200,8 @@ static int pic32_sdhci_probe(struct platform_device *pdev) | |||
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | ret = sdhci_add_host(host); | 202 | ret = sdhci_add_host(host); |
| 203 | if (ret) { | 203 | if (ret) |
| 204 | dev_err(&pdev->dev, "error adding host\n"); | ||
| 205 | goto err_base_clk; | 204 | goto err_base_clk; |
| 206 | } | ||
| 207 | 205 | ||
| 208 | dev_info(&pdev->dev, "Successfully added sdhci host\n"); | 206 | dev_info(&pdev->dev, "Successfully added sdhci host\n"); |
| 209 | return 0; | 207 | return 0; |
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index 8986f9d9cf98..2c3827f54927 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c | |||
| @@ -221,10 +221,8 @@ static int sdhci_pxav2_probe(struct platform_device *pdev) | |||
| 221 | host->ops = &pxav2_sdhci_ops; | 221 | host->ops = &pxav2_sdhci_ops; |
| 222 | 222 | ||
| 223 | ret = sdhci_add_host(host); | 223 | ret = sdhci_add_host(host); |
| 224 | if (ret) { | 224 | if (ret) |
| 225 | dev_err(&pdev->dev, "failed to add host\n"); | ||
| 226 | goto disable_clk; | 225 | goto disable_clk; |
| 227 | } | ||
| 228 | 226 | ||
| 229 | return 0; | 227 | return 0; |
| 230 | 228 | ||
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index a34434166ca7..b8e96f392428 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
| @@ -472,10 +472,8 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
| 472 | pm_suspend_ignore_children(&pdev->dev, 1); | 472 | pm_suspend_ignore_children(&pdev->dev, 1); |
| 473 | 473 | ||
| 474 | ret = sdhci_add_host(host); | 474 | ret = sdhci_add_host(host); |
| 475 | if (ret) { | 475 | if (ret) |
| 476 | dev_err(&pdev->dev, "failed to add host\n"); | ||
| 477 | goto err_add_host; | 476 | goto err_add_host; |
| 478 | } | ||
| 479 | 477 | ||
| 480 | if (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ) | 478 | if (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ) |
| 481 | device_init_wakeup(&pdev->dev, 1); | 479 | device_init_wakeup(&pdev->dev, 1); |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index cda83ccb2702..9ef89d00970e 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -655,10 +655,8 @@ static int sdhci_s3c_probe(struct platform_device *pdev) | |||
| 655 | goto err_req_regs; | 655 | goto err_req_regs; |
| 656 | 656 | ||
| 657 | ret = sdhci_add_host(host); | 657 | ret = sdhci_add_host(host); |
| 658 | if (ret) { | 658 | if (ret) |
| 659 | dev_err(dev, "sdhci_add_host() failed\n"); | ||
| 660 | goto err_req_regs; | 659 | goto err_req_regs; |
| 661 | } | ||
| 662 | 660 | ||
| 663 | #ifdef CONFIG_PM | 661 | #ifdef CONFIG_PM |
| 664 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) | 662 | if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) |
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 14511526a3a8..9247d51f2eed 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c | |||
| @@ -126,10 +126,8 @@ static int sdhci_probe(struct platform_device *pdev) | |||
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | ret = sdhci_add_host(host); | 128 | ret = sdhci_add_host(host); |
| 129 | if (ret) { | 129 | if (ret) |
| 130 | dev_dbg(&pdev->dev, "error adding host\n"); | ||
| 131 | goto disable_clk; | 130 | goto disable_clk; |
| 132 | } | ||
| 133 | 131 | ||
| 134 | platform_set_drvdata(pdev, host); | 132 | platform_set_drvdata(pdev, host); |
| 135 | 133 | ||
diff --git a/drivers/mmc/host/sdhci-st.c b/drivers/mmc/host/sdhci-st.c index c32daed0d418..8f95647195d9 100644 --- a/drivers/mmc/host/sdhci-st.c +++ b/drivers/mmc/host/sdhci-st.c | |||
| @@ -422,10 +422,8 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
| 422 | st_mmcss_cconfig(np, host); | 422 | st_mmcss_cconfig(np, host); |
| 423 | 423 | ||
| 424 | ret = sdhci_add_host(host); | 424 | ret = sdhci_add_host(host); |
| 425 | if (ret) { | 425 | if (ret) |
| 426 | dev_err(&pdev->dev, "Failed sdhci_add_host\n"); | ||
| 427 | goto err_out; | 426 | goto err_out; |
| 428 | } | ||
| 429 | 427 | ||
| 430 | host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); | 428 | host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); |
| 431 | 429 | ||
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index b877c13184c2..970d38f68939 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
| @@ -231,7 +231,7 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host, | |||
| 231 | if (timing == MMC_TIMING_UHS_DDR50) | 231 | if (timing == MMC_TIMING_UHS_DDR50) |
| 232 | tegra_host->ddr_signaling = true; | 232 | tegra_host->ddr_signaling = true; |
| 233 | 233 | ||
| 234 | return sdhci_set_uhs_signaling(host, timing); | 234 | sdhci_set_uhs_signaling(host, timing); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host) | 237 | static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host) |
diff --git a/drivers/mmc/host/sdhci-xenon-phy.c b/drivers/mmc/host/sdhci-xenon-phy.c index ec8794335241..a35804b203a7 100644 --- a/drivers/mmc/host/sdhci-xenon-phy.c +++ b/drivers/mmc/host/sdhci-xenon-phy.c | |||
| @@ -814,15 +814,10 @@ static int xenon_add_phy(struct device_node *np, struct sdhci_host *host, | |||
| 814 | { | 814 | { |
| 815 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 815 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 816 | struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); | 816 | struct xenon_priv *priv = sdhci_pltfm_priv(pltfm_host); |
| 817 | int i, ret; | 817 | int ret; |
| 818 | 818 | ||
| 819 | for (i = 0; i < NR_PHY_TYPES; i++) { | 819 | priv->phy_type = match_string(phy_types, NR_PHY_TYPES, phy_name); |
| 820 | if (!strcmp(phy_name, phy_types[i])) { | 820 | if (priv->phy_type < 0) { |
| 821 | priv->phy_type = i; | ||
| 822 | break; | ||
| 823 | } | ||
| 824 | } | ||
| 825 | if (i == NR_PHY_TYPES) { | ||
| 826 | dev_err(mmc_dev(host->mmc), | 821 | dev_err(mmc_dev(host->mmc), |
| 827 | "Unable to determine PHY name %s. Use default eMMC 5.1 PHY\n", | 822 | "Unable to determine PHY name %s. Use default eMMC 5.1 PHY\n", |
| 828 | phy_name); | 823 | phy_name); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 2ededa7f43df..1c828e0e9905 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -709,29 +709,16 @@ static u32 sdhci_sdma_address(struct sdhci_host *host) | |||
| 709 | return sg_dma_address(host->data->sg); | 709 | return sg_dma_address(host->data->sg); |
| 710 | } | 710 | } |
| 711 | 711 | ||
| 712 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | 712 | static unsigned int sdhci_target_timeout(struct sdhci_host *host, |
| 713 | struct mmc_command *cmd, | ||
| 714 | struct mmc_data *data) | ||
| 713 | { | 715 | { |
| 714 | u8 count; | 716 | unsigned int target_timeout; |
| 715 | struct mmc_data *data = cmd->data; | ||
| 716 | unsigned target_timeout, current_timeout; | ||
| 717 | |||
| 718 | /* | ||
| 719 | * If the host controller provides us with an incorrect timeout | ||
| 720 | * value, just skip the check and use 0xE. The hardware may take | ||
| 721 | * longer to time out, but that's much better than having a too-short | ||
| 722 | * timeout value. | ||
| 723 | */ | ||
| 724 | if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) | ||
| 725 | return 0xE; | ||
| 726 | |||
| 727 | /* Unspecified timeout, assume max */ | ||
| 728 | if (!data && !cmd->busy_timeout) | ||
| 729 | return 0xE; | ||
| 730 | 717 | ||
| 731 | /* timeout in us */ | 718 | /* timeout in us */ |
| 732 | if (!data) | 719 | if (!data) { |
| 733 | target_timeout = cmd->busy_timeout * 1000; | 720 | target_timeout = cmd->busy_timeout * 1000; |
| 734 | else { | 721 | } else { |
| 735 | target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000); | 722 | target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000); |
| 736 | if (host->clock && data->timeout_clks) { | 723 | if (host->clock && data->timeout_clks) { |
| 737 | unsigned long long val; | 724 | unsigned long long val; |
| @@ -748,6 +735,67 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | |||
| 748 | } | 735 | } |
| 749 | } | 736 | } |
| 750 | 737 | ||
| 738 | return target_timeout; | ||
| 739 | } | ||
| 740 | |||
| 741 | static void sdhci_calc_sw_timeout(struct sdhci_host *host, | ||
| 742 | struct mmc_command *cmd) | ||
| 743 | { | ||
| 744 | struct mmc_data *data = cmd->data; | ||
| 745 | struct mmc_host *mmc = host->mmc; | ||
| 746 | struct mmc_ios *ios = &mmc->ios; | ||
| 747 | unsigned char bus_width = 1 << ios->bus_width; | ||
| 748 | unsigned int blksz; | ||
| 749 | unsigned int freq; | ||
| 750 | u64 target_timeout; | ||
| 751 | u64 transfer_time; | ||
| 752 | |||
| 753 | target_timeout = sdhci_target_timeout(host, cmd, data); | ||
| 754 | target_timeout *= NSEC_PER_USEC; | ||
| 755 | |||
| 756 | if (data) { | ||
| 757 | blksz = data->blksz; | ||
| 758 | freq = host->mmc->actual_clock ? : host->clock; | ||
| 759 | transfer_time = (u64)blksz * NSEC_PER_SEC * (8 / bus_width); | ||
| 760 | do_div(transfer_time, freq); | ||
| 761 | /* multiply by '2' to account for any unknowns */ | ||
| 762 | transfer_time = transfer_time * 2; | ||
| 763 | /* calculate timeout for the entire data */ | ||
| 764 | host->data_timeout = data->blocks * target_timeout + | ||
| 765 | transfer_time; | ||
| 766 | } else { | ||
| 767 | host->data_timeout = target_timeout; | ||
| 768 | } | ||
| 769 | |||
| 770 | if (host->data_timeout) | ||
| 771 | host->data_timeout += MMC_CMD_TRANSFER_TIME; | ||
| 772 | } | ||
| 773 | |||
| 774 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd, | ||
| 775 | bool *too_big) | ||
| 776 | { | ||
| 777 | u8 count; | ||
| 778 | struct mmc_data *data = cmd->data; | ||
| 779 | unsigned target_timeout, current_timeout; | ||
| 780 | |||
| 781 | *too_big = true; | ||
| 782 | |||
| 783 | /* | ||
| 784 | * If the host controller provides us with an incorrect timeout | ||
| 785 | * value, just skip the check and use 0xE. The hardware may take | ||
| 786 | * longer to time out, but that's much better than having a too-short | ||
| 787 | * timeout value. | ||
| 788 | */ | ||
| 789 | if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) | ||
| 790 | return 0xE; | ||
| 791 | |||
| 792 | /* Unspecified timeout, assume max */ | ||
| 793 | if (!data && !cmd->busy_timeout) | ||
| 794 | return 0xE; | ||
| 795 | |||
| 796 | /* timeout in us */ | ||
| 797 | target_timeout = sdhci_target_timeout(host, cmd, data); | ||
| 798 | |||
| 751 | /* | 799 | /* |
| 752 | * Figure out needed cycles. | 800 | * Figure out needed cycles. |
| 753 | * We do this in steps in order to fit inside a 32 bit int. | 801 | * We do this in steps in order to fit inside a 32 bit int. |
| @@ -768,9 +816,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | |||
| 768 | } | 816 | } |
| 769 | 817 | ||
| 770 | if (count >= 0xF) { | 818 | if (count >= 0xF) { |
| 771 | DBG("Too large timeout 0x%x requested for CMD%d!\n", | 819 | if (!(host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT)) |
| 772 | count, cmd->opcode); | 820 | DBG("Too large timeout 0x%x requested for CMD%d!\n", |
| 821 | count, cmd->opcode); | ||
| 773 | count = 0xE; | 822 | count = 0xE; |
| 823 | } else { | ||
| 824 | *too_big = false; | ||
| 774 | } | 825 | } |
| 775 | 826 | ||
| 776 | return count; | 827 | return count; |
| @@ -790,6 +841,16 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host) | |||
| 790 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | 841 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); |
| 791 | } | 842 | } |
| 792 | 843 | ||
| 844 | static void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable) | ||
| 845 | { | ||
| 846 | if (enable) | ||
| 847 | host->ier |= SDHCI_INT_DATA_TIMEOUT; | ||
| 848 | else | ||
| 849 | host->ier &= ~SDHCI_INT_DATA_TIMEOUT; | ||
| 850 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); | ||
| 851 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | ||
| 852 | } | ||
| 853 | |||
| 793 | static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) | 854 | static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) |
| 794 | { | 855 | { |
| 795 | u8 count; | 856 | u8 count; |
| @@ -797,7 +858,18 @@ static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) | |||
| 797 | if (host->ops->set_timeout) { | 858 | if (host->ops->set_timeout) { |
| 798 | host->ops->set_timeout(host, cmd); | 859 | host->ops->set_timeout(host, cmd); |
| 799 | } else { | 860 | } else { |
| 800 | count = sdhci_calc_timeout(host, cmd); | 861 | bool too_big = false; |
| 862 | |||
| 863 | count = sdhci_calc_timeout(host, cmd, &too_big); | ||
| 864 | |||
| 865 | if (too_big && | ||
| 866 | host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT) { | ||
| 867 | sdhci_calc_sw_timeout(host, cmd); | ||
| 868 | sdhci_set_data_timeout_irq(host, false); | ||
| 869 | } else if (!(host->ier & SDHCI_INT_DATA_TIMEOUT)) { | ||
| 870 | sdhci_set_data_timeout_irq(host, true); | ||
| 871 | } | ||
| 872 | |||
| 801 | sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); | 873 | sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); |
| 802 | } | 874 | } |
| 803 | } | 875 | } |
| @@ -807,6 +879,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
| 807 | u8 ctrl; | 879 | u8 ctrl; |
| 808 | struct mmc_data *data = cmd->data; | 880 | struct mmc_data *data = cmd->data; |
| 809 | 881 | ||
| 882 | host->data_timeout = 0; | ||
| 883 | |||
| 810 | if (sdhci_data_line_cmd(cmd)) | 884 | if (sdhci_data_line_cmd(cmd)) |
| 811 | sdhci_set_timeout(host, cmd); | 885 | sdhci_set_timeout(host, cmd); |
| 812 | 886 | ||
| @@ -1160,13 +1234,6 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
| 1160 | mdelay(1); | 1234 | mdelay(1); |
| 1161 | } | 1235 | } |
| 1162 | 1236 | ||
| 1163 | timeout = jiffies; | ||
| 1164 | if (!cmd->data && cmd->busy_timeout > 9000) | ||
| 1165 | timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; | ||
| 1166 | else | ||
| 1167 | timeout += 10 * HZ; | ||
| 1168 | sdhci_mod_timer(host, cmd->mrq, timeout); | ||
| 1169 | |||
| 1170 | host->cmd = cmd; | 1237 | host->cmd = cmd; |
| 1171 | if (sdhci_data_line_cmd(cmd)) { | 1238 | if (sdhci_data_line_cmd(cmd)) { |
| 1172 | WARN_ON(host->data_cmd); | 1239 | WARN_ON(host->data_cmd); |
| @@ -1206,6 +1273,15 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
| 1206 | cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) | 1273 | cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) |
| 1207 | flags |= SDHCI_CMD_DATA; | 1274 | flags |= SDHCI_CMD_DATA; |
| 1208 | 1275 | ||
| 1276 | timeout = jiffies; | ||
| 1277 | if (host->data_timeout) | ||
| 1278 | timeout += nsecs_to_jiffies(host->data_timeout); | ||
| 1279 | else if (!cmd->data && cmd->busy_timeout > 9000) | ||
| 1280 | timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; | ||
| 1281 | else | ||
| 1282 | timeout += 10 * HZ; | ||
| 1283 | sdhci_mod_timer(host, cmd->mrq, timeout); | ||
| 1284 | |||
| 1209 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); | 1285 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); |
| 1210 | } | 1286 | } |
| 1211 | EXPORT_SYMBOL_GPL(sdhci_send_command); | 1287 | EXPORT_SYMBOL_GPL(sdhci_send_command); |
| @@ -3616,6 +3692,10 @@ int sdhci_setup_host(struct sdhci_host *host) | |||
| 3616 | mmc->max_busy_timeout /= host->timeout_clk; | 3692 | mmc->max_busy_timeout /= host->timeout_clk; |
| 3617 | } | 3693 | } |
| 3618 | 3694 | ||
| 3695 | if (host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT && | ||
| 3696 | !host->ops->get_max_timeout_count) | ||
| 3697 | mmc->max_busy_timeout = 0; | ||
| 3698 | |||
| 3619 | mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; | 3699 | mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; |
| 3620 | mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; | 3700 | mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; |
| 3621 | 3701 | ||
| @@ -3672,6 +3752,16 @@ int sdhci_setup_host(struct sdhci_host *host) | |||
| 3672 | if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) { | 3752 | if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) { |
| 3673 | host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | | 3753 | host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | |
| 3674 | SDHCI_SUPPORT_DDR50); | 3754 | SDHCI_SUPPORT_DDR50); |
| 3755 | /* | ||
| 3756 | * The SDHCI controller in a SoC might support HS200/HS400 | ||
| 3757 | * (indicated using mmc-hs200-1_8v/mmc-hs400-1_8v dt property), | ||
| 3758 | * but if the board is modeled such that the IO lines are not | ||
| 3759 | * connected to 1.8v then HS200/HS400 cannot be supported. | ||
| 3760 | * Disable HS200/HS400 if the board does not have 1.8v connected | ||
| 3761 | * to the IO lines. (Applicable for other modes in 1.8v) | ||
| 3762 | */ | ||
| 3763 | mmc->caps2 &= ~(MMC_CAP2_HSX00_1_8V | MMC_CAP2_HS400_ES); | ||
| 3764 | mmc->caps &= ~(MMC_CAP_1_8V_DDR | MMC_CAP_UHS); | ||
| 3675 | } | 3765 | } |
| 3676 | 3766 | ||
| 3677 | /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ | 3767 | /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index c95b0a4a7594..23966f887da6 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
| @@ -332,6 +332,14 @@ struct sdhci_adma2_64_desc { | |||
| 332 | /* Allow for a a command request and a data request at the same time */ | 332 | /* Allow for a a command request and a data request at the same time */ |
| 333 | #define SDHCI_MAX_MRQS 2 | 333 | #define SDHCI_MAX_MRQS 2 |
| 334 | 334 | ||
| 335 | /* | ||
| 336 | * 48bit command and 136 bit response in 100KHz clock could take upto 2.48ms. | ||
| 337 | * However since the start time of the command, the time between | ||
| 338 | * command and response, and the time between response and start of data is | ||
| 339 | * not known, set the command transfer time to 10ms. | ||
| 340 | */ | ||
| 341 | #define MMC_CMD_TRANSFER_TIME (10 * NSEC_PER_MSEC) /* max 10 ms */ | ||
| 342 | |||
| 335 | enum sdhci_cookie { | 343 | enum sdhci_cookie { |
| 336 | COOKIE_UNMAPPED, | 344 | COOKIE_UNMAPPED, |
| 337 | COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */ | 345 | COOKIE_PRE_MAPPED, /* mapped by sdhci_pre_req() */ |
| @@ -437,6 +445,11 @@ struct sdhci_host { | |||
| 437 | #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) | 445 | #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN (1<<15) |
| 438 | /* Controller has CRC in 136 bit Command Response */ | 446 | /* Controller has CRC in 136 bit Command Response */ |
| 439 | #define SDHCI_QUIRK2_RSP_136_HAS_CRC (1<<16) | 447 | #define SDHCI_QUIRK2_RSP_136_HAS_CRC (1<<16) |
| 448 | /* | ||
| 449 | * Disable HW timeout if the requested timeout is more than the maximum | ||
| 450 | * obtainable timeout. | ||
| 451 | */ | ||
| 452 | #define SDHCI_QUIRK2_DISABLE_HW_TIMEOUT (1<<17) | ||
| 440 | 453 | ||
| 441 | int irq; /* Device IRQ */ | 454 | int irq; /* Device IRQ */ |
| 442 | void __iomem *ioaddr; /* Mapped address */ | 455 | void __iomem *ioaddr; /* Mapped address */ |
| @@ -550,6 +563,8 @@ struct sdhci_host { | |||
| 550 | /* Host SDMA buffer boundary. */ | 563 | /* Host SDMA buffer boundary. */ |
| 551 | u32 sdma_boundary; | 564 | u32 sdma_boundary; |
| 552 | 565 | ||
| 566 | u64 data_timeout; | ||
| 567 | |||
| 553 | unsigned long private[0] ____cacheline_aligned; | 568 | unsigned long private[0] ____cacheline_aligned; |
| 554 | }; | 569 | }; |
| 555 | 570 | ||
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 20cfb20418f3..e7472590f2ed 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c | |||
| @@ -13,36 +13,34 @@ | |||
| 13 | * the License, or (at your option) any later version. | 13 | * the License, or (at your option) any later version. |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/io.h> | ||
| 19 | #include <linux/device.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/err.h> | ||
| 23 | |||
| 24 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 25 | #include <linux/clk/sunxi-ng.h> | 17 | #include <linux/clk/sunxi-ng.h> |
| 26 | #include <linux/gpio.h> | 18 | #include <linux/delay.h> |
| 27 | #include <linux/platform_device.h> | 19 | #include <linux/device.h> |
| 28 | #include <linux/spinlock.h> | ||
| 29 | #include <linux/scatterlist.h> | ||
| 30 | #include <linux/dma-mapping.h> | 20 | #include <linux/dma-mapping.h> |
| 31 | #include <linux/slab.h> | 21 | #include <linux/err.h> |
| 32 | #include <linux/reset.h> | 22 | #include <linux/gpio.h> |
| 33 | #include <linux/regulator/consumer.h> | 23 | #include <linux/interrupt.h> |
| 34 | 24 | #include <linux/io.h> | |
| 35 | #include <linux/of_address.h> | 25 | #include <linux/kernel.h> |
| 36 | #include <linux/of_gpio.h> | 26 | #include <linux/mmc/card.h> |
| 37 | #include <linux/of_platform.h> | 27 | #include <linux/mmc/core.h> |
| 38 | |||
| 39 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
| 29 | #include <linux/mmc/mmc.h> | ||
| 40 | #include <linux/mmc/sd.h> | 30 | #include <linux/mmc/sd.h> |
| 41 | #include <linux/mmc/sdio.h> | 31 | #include <linux/mmc/sdio.h> |
| 42 | #include <linux/mmc/mmc.h> | ||
| 43 | #include <linux/mmc/core.h> | ||
| 44 | #include <linux/mmc/card.h> | ||
| 45 | #include <linux/mmc/slot-gpio.h> | 32 | #include <linux/mmc/slot-gpio.h> |
| 33 | #include <linux/module.h> | ||
| 34 | #include <linux/of_address.h> | ||
| 35 | #include <linux/of_gpio.h> | ||
| 36 | #include <linux/of_platform.h> | ||
| 37 | #include <linux/platform_device.h> | ||
| 38 | #include <linux/pm_runtime.h> | ||
| 39 | #include <linux/regulator/consumer.h> | ||
| 40 | #include <linux/reset.h> | ||
| 41 | #include <linux/scatterlist.h> | ||
| 42 | #include <linux/slab.h> | ||
| 43 | #include <linux/spinlock.h> | ||
| 46 | 44 | ||
| 47 | /* register offset definitions */ | 45 | /* register offset definitions */ |
| 48 | #define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */ | 46 | #define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */ |
| @@ -322,10 +320,9 @@ static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host) | |||
| 322 | return 0; | 320 | return 0; |
| 323 | } | 321 | } |
| 324 | 322 | ||
| 325 | static int sunxi_mmc_init_host(struct mmc_host *mmc) | 323 | static int sunxi_mmc_init_host(struct sunxi_mmc_host *host) |
| 326 | { | 324 | { |
| 327 | u32 rval; | 325 | u32 rval; |
| 328 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
| 329 | 326 | ||
| 330 | if (sunxi_mmc_reset_host(host)) | 327 | if (sunxi_mmc_reset_host(host)) |
| 331 | return -EIO; | 328 | return -EIO; |
| @@ -859,17 +856,48 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | |||
| 859 | return 0; | 856 | return 0; |
| 860 | } | 857 | } |
| 861 | 858 | ||
| 862 | static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 859 | static void sunxi_mmc_set_bus_width(struct sunxi_mmc_host *host, |
| 860 | unsigned char width) | ||
| 861 | { | ||
| 862 | switch (width) { | ||
| 863 | case MMC_BUS_WIDTH_1: | ||
| 864 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH1); | ||
| 865 | break; | ||
| 866 | case MMC_BUS_WIDTH_4: | ||
| 867 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH4); | ||
| 868 | break; | ||
| 869 | case MMC_BUS_WIDTH_8: | ||
| 870 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH8); | ||
| 871 | break; | ||
| 872 | } | ||
| 873 | } | ||
| 874 | |||
| 875 | static void sunxi_mmc_set_clk(struct sunxi_mmc_host *host, struct mmc_ios *ios) | ||
| 863 | { | 876 | { |
| 864 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
| 865 | u32 rval; | 877 | u32 rval; |
| 866 | 878 | ||
| 867 | /* Set the power state */ | 879 | /* set ddr mode */ |
| 868 | switch (ios->power_mode) { | 880 | rval = mmc_readl(host, REG_GCTRL); |
| 869 | case MMC_POWER_ON: | 881 | if (ios->timing == MMC_TIMING_UHS_DDR50 || |
| 870 | break; | 882 | ios->timing == MMC_TIMING_MMC_DDR52) |
| 883 | rval |= SDXC_DDR_MODE; | ||
| 884 | else | ||
| 885 | rval &= ~SDXC_DDR_MODE; | ||
| 886 | mmc_writel(host, REG_GCTRL, rval); | ||
| 887 | |||
| 888 | host->ferror = sunxi_mmc_clk_set_rate(host, ios); | ||
| 889 | /* Android code had a usleep_range(50000, 55000); here */ | ||
| 890 | } | ||
| 871 | 891 | ||
| 892 | static void sunxi_mmc_card_power(struct sunxi_mmc_host *host, | ||
| 893 | struct mmc_ios *ios) | ||
| 894 | { | ||
| 895 | struct mmc_host *mmc = host->mmc; | ||
| 896 | |||
| 897 | switch (ios->power_mode) { | ||
| 872 | case MMC_POWER_UP: | 898 | case MMC_POWER_UP: |
| 899 | dev_dbg(mmc_dev(mmc), "Powering card up\n"); | ||
| 900 | |||
| 873 | if (!IS_ERR(mmc->supply.vmmc)) { | 901 | if (!IS_ERR(mmc->supply.vmmc)) { |
| 874 | host->ferror = mmc_regulator_set_ocr(mmc, | 902 | host->ferror = mmc_regulator_set_ocr(mmc, |
| 875 | mmc->supply.vmmc, | 903 | mmc->supply.vmmc, |
| @@ -887,53 +915,33 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 887 | } | 915 | } |
| 888 | host->vqmmc_enabled = true; | 916 | host->vqmmc_enabled = true; |
| 889 | } | 917 | } |
| 890 | |||
| 891 | host->ferror = sunxi_mmc_init_host(mmc); | ||
| 892 | if (host->ferror) | ||
| 893 | return; | ||
| 894 | |||
| 895 | dev_dbg(mmc_dev(mmc), "power on!\n"); | ||
| 896 | break; | 918 | break; |
| 897 | 919 | ||
| 898 | case MMC_POWER_OFF: | 920 | case MMC_POWER_OFF: |
| 899 | dev_dbg(mmc_dev(mmc), "power off!\n"); | 921 | dev_dbg(mmc_dev(mmc), "Powering card off\n"); |
| 900 | sunxi_mmc_reset_host(host); | 922 | |
| 901 | if (!IS_ERR(mmc->supply.vmmc)) | 923 | if (!IS_ERR(mmc->supply.vmmc)) |
| 902 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); | 924 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); |
| 903 | 925 | ||
| 904 | if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) | 926 | if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) |
| 905 | regulator_disable(mmc->supply.vqmmc); | 927 | regulator_disable(mmc->supply.vqmmc); |
| 928 | |||
| 906 | host->vqmmc_enabled = false; | 929 | host->vqmmc_enabled = false; |
| 907 | break; | 930 | break; |
| 908 | } | ||
| 909 | 931 | ||
| 910 | /* set bus width */ | 932 | default: |
| 911 | switch (ios->bus_width) { | 933 | dev_dbg(mmc_dev(mmc), "Ignoring unknown card power state\n"); |
| 912 | case MMC_BUS_WIDTH_1: | ||
| 913 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH1); | ||
| 914 | break; | ||
| 915 | case MMC_BUS_WIDTH_4: | ||
| 916 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH4); | ||
| 917 | break; | ||
| 918 | case MMC_BUS_WIDTH_8: | ||
| 919 | mmc_writel(host, REG_WIDTH, SDXC_WIDTH8); | ||
| 920 | break; | 934 | break; |
| 921 | } | 935 | } |
| 936 | } | ||
| 922 | 937 | ||
| 923 | /* set ddr mode */ | 938 | static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 924 | rval = mmc_readl(host, REG_GCTRL); | 939 | { |
| 925 | if (ios->timing == MMC_TIMING_UHS_DDR50 || | 940 | struct sunxi_mmc_host *host = mmc_priv(mmc); |
| 926 | ios->timing == MMC_TIMING_MMC_DDR52) | ||
| 927 | rval |= SDXC_DDR_MODE; | ||
| 928 | else | ||
| 929 | rval &= ~SDXC_DDR_MODE; | ||
| 930 | mmc_writel(host, REG_GCTRL, rval); | ||
| 931 | 941 | ||
| 932 | /* set up clock */ | 942 | sunxi_mmc_card_power(host, ios); |
| 933 | if (ios->power_mode) { | 943 | sunxi_mmc_set_bus_width(host, ios->bus_width); |
| 934 | host->ferror = sunxi_mmc_clk_set_rate(host, ios); | 944 | sunxi_mmc_set_clk(host, ios); |
| 935 | /* Android code had a usleep_range(50000, 55000); here */ | ||
| 936 | } | ||
| 937 | } | 945 | } |
| 938 | 946 | ||
| 939 | static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) | 947 | static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) |
| @@ -955,6 +963,9 @@ static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
| 955 | unsigned long flags; | 963 | unsigned long flags; |
| 956 | u32 imask; | 964 | u32 imask; |
| 957 | 965 | ||
| 966 | if (enable) | ||
| 967 | pm_runtime_get_noresume(host->dev); | ||
| 968 | |||
| 958 | spin_lock_irqsave(&host->lock, flags); | 969 | spin_lock_irqsave(&host->lock, flags); |
| 959 | 970 | ||
| 960 | imask = mmc_readl(host, REG_IMASK); | 971 | imask = mmc_readl(host, REG_IMASK); |
| @@ -967,6 +978,9 @@ static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
| 967 | } | 978 | } |
| 968 | mmc_writel(host, REG_IMASK, imask); | 979 | mmc_writel(host, REG_IMASK, imask); |
| 969 | spin_unlock_irqrestore(&host->lock, flags); | 980 | spin_unlock_irqrestore(&host->lock, flags); |
| 981 | |||
| 982 | if (!enable) | ||
| 983 | pm_runtime_put_noidle(host->mmc->parent); | ||
| 970 | } | 984 | } |
| 971 | 985 | ||
| 972 | static void sunxi_mmc_hw_reset(struct mmc_host *mmc) | 986 | static void sunxi_mmc_hw_reset(struct mmc_host *mmc) |
| @@ -1380,6 +1394,15 @@ static int sunxi_mmc_probe(struct platform_device *pdev) | |||
| 1380 | if (ret) | 1394 | if (ret) |
| 1381 | goto error_free_dma; | 1395 | goto error_free_dma; |
| 1382 | 1396 | ||
| 1397 | ret = sunxi_mmc_init_host(host); | ||
| 1398 | if (ret) | ||
| 1399 | goto error_free_dma; | ||
| 1400 | |||
| 1401 | pm_runtime_set_active(&pdev->dev); | ||
| 1402 | pm_runtime_set_autosuspend_delay(&pdev->dev, 50); | ||
| 1403 | pm_runtime_use_autosuspend(&pdev->dev); | ||
| 1404 | pm_runtime_enable(&pdev->dev); | ||
| 1405 | |||
| 1383 | ret = mmc_add_host(mmc); | 1406 | ret = mmc_add_host(mmc); |
| 1384 | if (ret) | 1407 | if (ret) |
| 1385 | goto error_free_dma; | 1408 | goto error_free_dma; |
| @@ -1400,6 +1423,7 @@ static int sunxi_mmc_remove(struct platform_device *pdev) | |||
| 1400 | struct sunxi_mmc_host *host = mmc_priv(mmc); | 1423 | struct sunxi_mmc_host *host = mmc_priv(mmc); |
| 1401 | 1424 | ||
| 1402 | mmc_remove_host(mmc); | 1425 | mmc_remove_host(mmc); |
| 1426 | pm_runtime_force_suspend(&pdev->dev); | ||
| 1403 | disable_irq(host->irq); | 1427 | disable_irq(host->irq); |
| 1404 | sunxi_mmc_disable(host); | 1428 | sunxi_mmc_disable(host); |
| 1405 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); | 1429 | dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); |
| @@ -1408,10 +1432,47 @@ static int sunxi_mmc_remove(struct platform_device *pdev) | |||
| 1408 | return 0; | 1432 | return 0; |
| 1409 | } | 1433 | } |
| 1410 | 1434 | ||
| 1435 | #ifdef CONFIG_PM | ||
| 1436 | static int sunxi_mmc_runtime_resume(struct device *dev) | ||
| 1437 | { | ||
| 1438 | struct mmc_host *mmc = dev_get_drvdata(dev); | ||
| 1439 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
| 1440 | int ret; | ||
| 1441 | |||
| 1442 | ret = sunxi_mmc_enable(host); | ||
| 1443 | if (ret) | ||
| 1444 | return ret; | ||
| 1445 | |||
| 1446 | sunxi_mmc_init_host(host); | ||
| 1447 | sunxi_mmc_set_bus_width(host, mmc->ios.bus_width); | ||
| 1448 | sunxi_mmc_set_clk(host, &mmc->ios); | ||
| 1449 | |||
| 1450 | return 0; | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | static int sunxi_mmc_runtime_suspend(struct device *dev) | ||
| 1454 | { | ||
| 1455 | struct mmc_host *mmc = dev_get_drvdata(dev); | ||
| 1456 | struct sunxi_mmc_host *host = mmc_priv(mmc); | ||
| 1457 | |||
| 1458 | sunxi_mmc_reset_host(host); | ||
| 1459 | sunxi_mmc_disable(host); | ||
| 1460 | |||
| 1461 | return 0; | ||
| 1462 | } | ||
| 1463 | #endif | ||
| 1464 | |||
| 1465 | static const struct dev_pm_ops sunxi_mmc_pm_ops = { | ||
| 1466 | SET_RUNTIME_PM_OPS(sunxi_mmc_runtime_suspend, | ||
| 1467 | sunxi_mmc_runtime_resume, | ||
| 1468 | NULL) | ||
| 1469 | }; | ||
| 1470 | |||
| 1411 | static struct platform_driver sunxi_mmc_driver = { | 1471 | static struct platform_driver sunxi_mmc_driver = { |
| 1412 | .driver = { | 1472 | .driver = { |
| 1413 | .name = "sunxi-mmc", | 1473 | .name = "sunxi-mmc", |
| 1414 | .of_match_table = of_match_ptr(sunxi_mmc_of_match), | 1474 | .of_match_table = of_match_ptr(sunxi_mmc_of_match), |
| 1475 | .pm = &sunxi_mmc_pm_ops, | ||
| 1415 | }, | 1476 | }, |
| 1416 | .probe = sunxi_mmc_probe, | 1477 | .probe = sunxi_mmc_probe, |
| 1417 | .remove = sunxi_mmc_remove, | 1478 | .remove = sunxi_mmc_remove, |
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index 81dac17064d7..b2b379b10dfa 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c | |||
| @@ -300,8 +300,10 @@ static void ushc_request(struct mmc_host *mmc, struct mmc_request *req) | |||
| 300 | pipe = usb_sndbulkpipe(ushc->usb_dev, 2); | 300 | pipe = usb_sndbulkpipe(ushc->usb_dev, 2); |
| 301 | 301 | ||
| 302 | usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe, | 302 | usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe, |
| 303 | sg_virt(data->sg), data->sg->length, | 303 | NULL, data->sg->length, |
| 304 | data_callback, ushc); | 304 | data_callback, ushc); |
| 305 | ushc->data_urb->num_sgs = 1; | ||
| 306 | ushc->data_urb->sg = data->sg; | ||
| 305 | ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC); | 307 | ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC); |
| 306 | if (ret < 0) | 308 | if (ret < 0) |
| 307 | goto out; | 309 | goto out; |
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index f4233576153b..1e54bbf13d75 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
| @@ -268,43 +268,29 @@ static inline int wbsd_next_sg(struct wbsd_host *host) | |||
| 268 | return host->num_sg; | 268 | return host->num_sg; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | static inline char *wbsd_sg_to_buffer(struct wbsd_host *host) | 271 | static inline char *wbsd_map_sg(struct wbsd_host *host) |
| 272 | { | 272 | { |
| 273 | return sg_virt(host->cur_sg); | 273 | return kmap_atomic(sg_page(host->cur_sg)) + host->cur_sg->offset; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) | 276 | static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) |
| 277 | { | 277 | { |
| 278 | unsigned int len, i; | 278 | size_t len = 0; |
| 279 | struct scatterlist *sg; | 279 | int i; |
| 280 | char *dmabuf = host->dma_buffer; | 280 | |
| 281 | char *sgbuf; | 281 | for (i = 0; i < data->sg_len; i++) |
| 282 | 282 | len += data->sg[i].length; | |
| 283 | sg = data->sg; | 283 | sg_copy_to_buffer(data->sg, data->sg_len, host->dma_buffer, len); |
| 284 | len = data->sg_len; | ||
| 285 | |||
| 286 | for (i = 0; i < len; i++) { | ||
| 287 | sgbuf = sg_virt(&sg[i]); | ||
| 288 | memcpy(dmabuf, sgbuf, sg[i].length); | ||
| 289 | dmabuf += sg[i].length; | ||
| 290 | } | ||
| 291 | } | 284 | } |
| 292 | 285 | ||
| 293 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) | 286 | static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) |
| 294 | { | 287 | { |
| 295 | unsigned int len, i; | 288 | size_t len = 0; |
| 296 | struct scatterlist *sg; | 289 | int i; |
| 297 | char *dmabuf = host->dma_buffer; | 290 | |
| 298 | char *sgbuf; | 291 | for (i = 0; i < data->sg_len; i++) |
| 299 | 292 | len += data->sg[i].length; | |
| 300 | sg = data->sg; | 293 | sg_copy_from_buffer(data->sg, data->sg_len, host->dma_buffer, len); |
| 301 | len = data->sg_len; | ||
| 302 | |||
| 303 | for (i = 0; i < len; i++) { | ||
| 304 | sgbuf = sg_virt(&sg[i]); | ||
| 305 | memcpy(sgbuf, dmabuf, sg[i].length); | ||
| 306 | dmabuf += sg[i].length; | ||
| 307 | } | ||
| 308 | } | 294 | } |
| 309 | 295 | ||
| 310 | /* | 296 | /* |
| @@ -418,7 +404,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
| 418 | { | 404 | { |
| 419 | struct mmc_data *data = host->mrq->cmd->data; | 405 | struct mmc_data *data = host->mrq->cmd->data; |
| 420 | char *buffer; | 406 | char *buffer; |
| 421 | int i, fsr, fifo; | 407 | int i, idx, fsr, fifo; |
| 422 | 408 | ||
| 423 | /* | 409 | /* |
| 424 | * Handle excessive data. | 410 | * Handle excessive data. |
| @@ -426,7 +412,8 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
| 426 | if (host->num_sg == 0) | 412 | if (host->num_sg == 0) |
| 427 | return; | 413 | return; |
| 428 | 414 | ||
| 429 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 415 | buffer = wbsd_map_sg(host) + host->offset; |
| 416 | idx = 0; | ||
| 430 | 417 | ||
| 431 | /* | 418 | /* |
| 432 | * Drain the fifo. This has a tendency to loop longer | 419 | * Drain the fifo. This has a tendency to loop longer |
| @@ -445,8 +432,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
| 445 | fifo = 1; | 432 | fifo = 1; |
| 446 | 433 | ||
| 447 | for (i = 0; i < fifo; i++) { | 434 | for (i = 0; i < fifo; i++) { |
| 448 | *buffer = inb(host->base + WBSD_DFR); | 435 | buffer[idx++] = inb(host->base + WBSD_DFR); |
| 449 | buffer++; | ||
| 450 | host->offset++; | 436 | host->offset++; |
| 451 | host->remain--; | 437 | host->remain--; |
| 452 | 438 | ||
| @@ -456,16 +442,19 @@ static void wbsd_empty_fifo(struct wbsd_host *host) | |||
| 456 | * End of scatter list entry? | 442 | * End of scatter list entry? |
| 457 | */ | 443 | */ |
| 458 | if (host->remain == 0) { | 444 | if (host->remain == 0) { |
| 445 | kunmap_atomic(buffer); | ||
| 459 | /* | 446 | /* |
| 460 | * Get next entry. Check if last. | 447 | * Get next entry. Check if last. |
| 461 | */ | 448 | */ |
| 462 | if (!wbsd_next_sg(host)) | 449 | if (!wbsd_next_sg(host)) |
| 463 | return; | 450 | return; |
| 464 | 451 | ||
| 465 | buffer = wbsd_sg_to_buffer(host); | 452 | buffer = wbsd_map_sg(host); |
| 453 | idx = 0; | ||
| 466 | } | 454 | } |
| 467 | } | 455 | } |
| 468 | } | 456 | } |
| 457 | kunmap_atomic(buffer); | ||
| 469 | 458 | ||
| 470 | /* | 459 | /* |
| 471 | * This is a very dirty hack to solve a | 460 | * This is a very dirty hack to solve a |
| @@ -480,7 +469,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
| 480 | { | 469 | { |
| 481 | struct mmc_data *data = host->mrq->cmd->data; | 470 | struct mmc_data *data = host->mrq->cmd->data; |
| 482 | char *buffer; | 471 | char *buffer; |
| 483 | int i, fsr, fifo; | 472 | int i, idx, fsr, fifo; |
| 484 | 473 | ||
| 485 | /* | 474 | /* |
| 486 | * Check that we aren't being called after the | 475 | * Check that we aren't being called after the |
| @@ -489,7 +478,8 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
| 489 | if (host->num_sg == 0) | 478 | if (host->num_sg == 0) |
| 490 | return; | 479 | return; |
| 491 | 480 | ||
| 492 | buffer = wbsd_sg_to_buffer(host) + host->offset; | 481 | buffer = wbsd_map_sg(host) + host->offset; |
| 482 | idx = 0; | ||
| 493 | 483 | ||
| 494 | /* | 484 | /* |
| 495 | * Fill the fifo. This has a tendency to loop longer | 485 | * Fill the fifo. This has a tendency to loop longer |
| @@ -508,8 +498,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
| 508 | fifo = 15; | 498 | fifo = 15; |
| 509 | 499 | ||
| 510 | for (i = 16; i > fifo; i--) { | 500 | for (i = 16; i > fifo; i--) { |
| 511 | outb(*buffer, host->base + WBSD_DFR); | 501 | outb(buffer[idx], host->base + WBSD_DFR); |
| 512 | buffer++; | ||
| 513 | host->offset++; | 502 | host->offset++; |
| 514 | host->remain--; | 503 | host->remain--; |
| 515 | 504 | ||
| @@ -519,16 +508,19 @@ static void wbsd_fill_fifo(struct wbsd_host *host) | |||
| 519 | * End of scatter list entry? | 508 | * End of scatter list entry? |
| 520 | */ | 509 | */ |
| 521 | if (host->remain == 0) { | 510 | if (host->remain == 0) { |
| 511 | kunmap_atomic(buffer); | ||
| 522 | /* | 512 | /* |
| 523 | * Get next entry. Check if last. | 513 | * Get next entry. Check if last. |
| 524 | */ | 514 | */ |
| 525 | if (!wbsd_next_sg(host)) | 515 | if (!wbsd_next_sg(host)) |
| 526 | return; | 516 | return; |
| 527 | 517 | ||
| 528 | buffer = wbsd_sg_to_buffer(host); | 518 | buffer = wbsd_map_sg(host); |
| 519 | idx = 0; | ||
| 529 | } | 520 | } |
| 530 | } | 521 | } |
| 531 | } | 522 | } |
| 523 | kunmap_atomic(buffer); | ||
| 532 | 524 | ||
| 533 | /* | 525 | /* |
| 534 | * The controller stops sending interrupts for | 526 | * The controller stops sending interrupts for |
diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index fd30ac7da5e5..3ba42f508014 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c | |||
| @@ -928,8 +928,7 @@ static int wmt_mci_remove(struct platform_device *pdev) | |||
| 928 | static int wmt_mci_suspend(struct device *dev) | 928 | static int wmt_mci_suspend(struct device *dev) |
| 929 | { | 929 | { |
| 930 | u32 reg_tmp; | 930 | u32 reg_tmp; |
| 931 | struct platform_device *pdev = to_platform_device(dev); | 931 | struct mmc_host *mmc = dev_get_drvdata(dev); |
| 932 | struct mmc_host *mmc = platform_get_drvdata(pdev); | ||
| 933 | struct wmt_mci_priv *priv; | 932 | struct wmt_mci_priv *priv; |
| 934 | 933 | ||
| 935 | if (!mmc) | 934 | if (!mmc) |
| @@ -953,8 +952,7 @@ static int wmt_mci_suspend(struct device *dev) | |||
| 953 | static int wmt_mci_resume(struct device *dev) | 952 | static int wmt_mci_resume(struct device *dev) |
| 954 | { | 953 | { |
| 955 | u32 reg_tmp; | 954 | u32 reg_tmp; |
| 956 | struct platform_device *pdev = to_platform_device(dev); | 955 | struct mmc_host *mmc = dev_get_drvdata(dev); |
| 957 | struct mmc_host *mmc = platform_get_drvdata(pdev); | ||
| 958 | struct wmt_mci_priv *priv; | 956 | struct wmt_mci_priv *priv; |
| 959 | 957 | ||
| 960 | if (mmc) { | 958 | if (mmc) { |
diff --git a/include/dt-bindings/dma/jz4780-dma.h b/include/dt-bindings/dma/jz4780-dma.h new file mode 100644 index 000000000000..df017fdfb44e --- /dev/null +++ b/include/dt-bindings/dma/jz4780-dma.h | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | #ifndef __DT_BINDINGS_DMA_JZ4780_DMA_H__ | ||
| 2 | #define __DT_BINDINGS_DMA_JZ4780_DMA_H__ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Request type numbers for the JZ4780 DMA controller (written to the DRTn | ||
| 6 | * register for the channel). | ||
| 7 | */ | ||
| 8 | #define JZ4780_DMA_I2S1_TX 0x4 | ||
| 9 | #define JZ4780_DMA_I2S1_RX 0x5 | ||
| 10 | #define JZ4780_DMA_I2S0_TX 0x6 | ||
| 11 | #define JZ4780_DMA_I2S0_RX 0x7 | ||
| 12 | #define JZ4780_DMA_AUTO 0x8 | ||
| 13 | #define JZ4780_DMA_SADC_RX 0x9 | ||
| 14 | #define JZ4780_DMA_UART4_TX 0xc | ||
| 15 | #define JZ4780_DMA_UART4_RX 0xd | ||
| 16 | #define JZ4780_DMA_UART3_TX 0xe | ||
| 17 | #define JZ4780_DMA_UART3_RX 0xf | ||
| 18 | #define JZ4780_DMA_UART2_TX 0x10 | ||
| 19 | #define JZ4780_DMA_UART2_RX 0x11 | ||
| 20 | #define JZ4780_DMA_UART1_TX 0x12 | ||
| 21 | #define JZ4780_DMA_UART1_RX 0x13 | ||
| 22 | #define JZ4780_DMA_UART0_TX 0x14 | ||
| 23 | #define JZ4780_DMA_UART0_RX 0x15 | ||
| 24 | #define JZ4780_DMA_SSI0_TX 0x16 | ||
| 25 | #define JZ4780_DMA_SSI0_RX 0x17 | ||
| 26 | #define JZ4780_DMA_SSI1_TX 0x18 | ||
| 27 | #define JZ4780_DMA_SSI1_RX 0x19 | ||
| 28 | #define JZ4780_DMA_MSC0_TX 0x1a | ||
| 29 | #define JZ4780_DMA_MSC0_RX 0x1b | ||
| 30 | #define JZ4780_DMA_MSC1_TX 0x1c | ||
| 31 | #define JZ4780_DMA_MSC1_RX 0x1d | ||
| 32 | #define JZ4780_DMA_MSC2_TX 0x1e | ||
| 33 | #define JZ4780_DMA_MSC2_RX 0x1f | ||
| 34 | #define JZ4780_DMA_PCM0_TX 0x20 | ||
| 35 | #define JZ4780_DMA_PCM0_RX 0x21 | ||
| 36 | #define JZ4780_DMA_SMB0_TX 0x24 | ||
| 37 | #define JZ4780_DMA_SMB0_RX 0x25 | ||
| 38 | #define JZ4780_DMA_SMB1_TX 0x26 | ||
| 39 | #define JZ4780_DMA_SMB1_RX 0x27 | ||
| 40 | #define JZ4780_DMA_SMB2_TX 0x28 | ||
| 41 | #define JZ4780_DMA_SMB2_RX 0x29 | ||
| 42 | #define JZ4780_DMA_SMB3_TX 0x2a | ||
| 43 | #define JZ4780_DMA_SMB3_RX 0x2b | ||
| 44 | #define JZ4780_DMA_SMB4_TX 0x2c | ||
| 45 | #define JZ4780_DMA_SMB4_RX 0x2d | ||
| 46 | #define JZ4780_DMA_DES_TX 0x2e | ||
| 47 | #define JZ4780_DMA_DES_RX 0x2f | ||
| 48 | |||
| 49 | #endif /* __DT_BINDINGS_DMA_JZ4780_DMA_H__ */ | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 279b39008a33..de7377815b6b 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
| @@ -156,6 +156,7 @@ struct sd_switch_caps { | |||
| 156 | #define UHS_DDR50_MAX_DTR 50000000 | 156 | #define UHS_DDR50_MAX_DTR 50000000 |
| 157 | #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR | 157 | #define UHS_SDR25_MAX_DTR UHS_DDR50_MAX_DTR |
| 158 | #define UHS_SDR12_MAX_DTR 25000000 | 158 | #define UHS_SDR12_MAX_DTR 25000000 |
| 159 | #define DEFAULT_SPEED_MAX_DTR UHS_SDR12_MAX_DTR | ||
| 159 | unsigned int sd3_bus_mode; | 160 | unsigned int sd3_bus_mode; |
| 160 | #define UHS_SDR12_BUS_SPEED 0 | 161 | #define UHS_SDR12_BUS_SPEED 0 |
| 161 | #define HIGH_SPEED_BUS_SPEED 1 | 162 | #define HIGH_SPEED_BUS_SPEED 1 |
| @@ -252,6 +253,7 @@ struct mmc_card { | |||
| 252 | #define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ | 253 | #define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ |
| 253 | unsigned int state; /* (our) card state */ | 254 | unsigned int state; /* (our) card state */ |
| 254 | unsigned int quirks; /* card quirks */ | 255 | unsigned int quirks; /* card quirks */ |
| 256 | unsigned int quirk_max_rate; /* max rate set by quirks */ | ||
| 255 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ | 257 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ |
| 256 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ | 258 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ |
| 257 | /* for byte mode */ | 259 | /* for byte mode */ |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 927519385482..134a6483347a 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
| @@ -177,6 +177,7 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, | |||
| 177 | int retries); | 177 | int retries); |
| 178 | 178 | ||
| 179 | int mmc_hw_reset(struct mmc_host *host); | 179 | int mmc_hw_reset(struct mmc_host *host); |
| 180 | int mmc_sw_reset(struct mmc_host *host); | ||
| 180 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card); | 181 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card); |
| 181 | 182 | ||
| 182 | #endif /* LINUX_MMC_CORE_H */ | 183 | #endif /* LINUX_MMC_CORE_H */ |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 85146235231e..64300a48dcce 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | struct mmc_ios { | 22 | struct mmc_ios { |
| 23 | unsigned int clock; /* clock rate */ | 23 | unsigned int clock; /* clock rate */ |
| 24 | unsigned short vdd; | 24 | unsigned short vdd; |
| 25 | unsigned int power_delay_ms; /* waiting for stable power */ | ||
| 25 | 26 | ||
| 26 | /* vdd stores the bit number of the selected voltage range from below. */ | 27 | /* vdd stores the bit number of the selected voltage range from below. */ |
| 27 | 28 | ||
| @@ -320,6 +321,9 @@ struct mmc_host { | |||
| 320 | #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ | 321 | #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ |
| 321 | #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ | 322 | #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ |
| 322 | #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ | 323 | #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ |
| 324 | #define MMC_CAP_UHS (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | \ | ||
| 325 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ | ||
| 326 | MMC_CAP_UHS_DDR50) | ||
| 323 | /* (1 << 21) is free for reuse */ | 327 | /* (1 << 21) is free for reuse */ |
| 324 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ | 328 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ |
| 325 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ | 329 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ |
| @@ -345,6 +349,7 @@ struct mmc_host { | |||
| 345 | #define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */ | 349 | #define MMC_CAP2_HS400_1_2V (1 << 16) /* Can support HS400 1.2V */ |
| 346 | #define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \ | 350 | #define MMC_CAP2_HS400 (MMC_CAP2_HS400_1_8V | \ |
| 347 | MMC_CAP2_HS400_1_2V) | 351 | MMC_CAP2_HS400_1_2V) |
| 352 | #define MMC_CAP2_HSX00_1_8V (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V) | ||
| 348 | #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) | 353 | #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) |
| 349 | #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) | 354 | #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) |
| 350 | #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ | 355 | #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ |
| @@ -354,6 +359,7 @@ struct mmc_host { | |||
| 354 | #define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ | 359 | #define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ |
| 355 | #define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */ | 360 | #define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */ |
| 356 | #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ | 361 | #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ |
| 362 | #define MMC_CAP2_AVOID_3_3V (1 << 25) /* Host must negotiate down from 3.3V */ | ||
| 357 | 363 | ||
| 358 | int fixed_drv_type; /* fixed driver type for non-removable media */ | 364 | int fixed_drv_type; /* fixed driver type for non-removable media */ |
| 359 | 365 | ||
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index cdd66a5fbd5e..2836a96e014a 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 | 55 | #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 |
| 56 | #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 | 56 | #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 |
| 57 | #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 | 57 | #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 |
| 58 | #define SDIO_DEVICE_ID_MARVELL_8887WLAN 0x9134 | ||
| 58 | 59 | ||
| 59 | #define SDIO_VENDOR_ID_SIANO 0x039a | 60 | #define SDIO_VENDOR_ID_SIANO 0x039a |
| 60 | #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 | 61 | #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 |
