diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-13 13:17:35 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-13 13:17:35 -0500 |
commit | dee02770cdcd8bc06a48c917ce5df2fb56cf6059 (patch) | |
tree | c79799cc851a224a02c007ff5122e12992bde7ab | |
parent | e4a8ca3baa5557fa54557d42b5910ed0d3316922 (diff) | |
parent | 06641e8deae68ee2769c734158bc9170be257bb9 (diff) |
Merge tag 'mmc-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Introduce host claiming by context to support blkmq
- Preparations for enabling CQE (eMMC CMDQ) requests
- Re-factorizations to prepare for blkmq support
- Re-factorizations to prepare for CQE support
- Fix signal voltage switch for SD cards without power cycle
- Convert RPMB to a character device
- Export eMMC revision via sysfs
- Support eMMC DT binding for fixed driver type
- Document mmc_regulator_get_supply() API
MMC host:
- omap_hsmmc: Updated regulator management for PBIAS
- sdhci-omap: Add new OMAP SDHCI driver
- meson-mx-sdio: New driver for the Amlogic Meson8 and Meson8b SoCs
- sdhci-pci: Add support for Intel CDF
- sdhci-acpi: Fix voltage switch for some Intel host controllers
- sdhci-msm: Enable delay circuit calibration clocks
- sdhci-msm: Manage power IRQ properly
- mediatek: Add support of mt2701/mt2712
- mediatek: Updates management of clocks and tunings
- mediatek: Upgrade eMMC HS400 support
- rtsx_pci: Update tuning for gen3 PCI-Express
- renesas_sdhi: Support R-Car Gen[123] fallback compatibility strings
- Catch all errors when getting regulators
- Various additional improvements and cleanups"
* tag 'mmc-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (91 commits)
sdhci-fujitsu: add support for setting the CMD_DAT_DELAY attribute
dt-bindings: sdhci-fujitsu: document cmd-dat-delay property
mmc: tmio: Replace msleep() of 20ms or less with usleep_range()
mmc: dw_mmc: Convert timers to use timer_setup()
mmc: dw_mmc: Cleanup the DTO timer like the CTO one
mmc: vub300: Use common code in __download_offload_pseudocode()
mmc: tmio: Use common error handling code in tmio_mmc_host_probe()
mmc: Convert timers to use timer_setup()
mmc: sdhci-acpi: Fix voltage switch for some Intel host controllers
mmc: sdhci-acpi: Let devices define their own private data
mmc: mediatek: perfer to use rise edge latching for cmd line
mmc: mediatek: improve eMMC hs400 mode read performance
mmc: mediatek: add latch-ck support
mmc: mediatek: add support of source_cg clock
mmc: mediatek: add stop_clk fix and enhance_rx support
mmc: mediatek: add busy_check support
mmc: mediatek: add async fifo and data tune support
mmc: mediatek: add pad_tune0 support
mmc: mediatek: make hs400_tune_response only for mt8173
arm64: dts: mt8173: remove "mediatek, mt8135-mmc" from mmc nodes
...
66 files changed, 3256 insertions, 581 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-mmc b/Documentation/ABI/testing/sysfs-bus-mmc new file mode 100644 index 000000000000..519f028d19cc --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-mmc | |||
@@ -0,0 +1,4 @@ | |||
1 | What: /sys/bus/mmc/devices/.../rev | ||
2 | Date: October 2017 | ||
3 | Contact: Jin Qian <jinqian@android.com> | ||
4 | Description: Extended CSD revision number | ||
diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.txt b/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.txt new file mode 100644 index 000000000000..8765c605e6bc --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.txt | |||
@@ -0,0 +1,54 @@ | |||
1 | * Amlogic Meson6, Meson8 and Meson8b SDIO/MMC controller | ||
2 | |||
3 | The highspeed MMC host controller on Amlogic SoCs provides an interface | ||
4 | for MMC, SD, SDIO and SDHC types of memory cards. | ||
5 | |||
6 | Supported maximum speeds are the ones of the eMMC standard 4.41 as well | ||
7 | as the speed of SD standard 2.0. | ||
8 | |||
9 | The hardware provides an internal "mux" which allows up to three slots | ||
10 | to be controlled. Only one slot can be accessed at a time. | ||
11 | |||
12 | Required properties: | ||
13 | - compatible : must be one of | ||
14 | - "amlogic,meson8-sdio" | ||
15 | - "amlogic,meson8b-sdio" | ||
16 | along with the generic "amlogic,meson-mx-sdio" | ||
17 | - reg : mmc controller base registers | ||
18 | - interrupts : mmc controller interrupt | ||
19 | - #address-cells : must be 1 | ||
20 | - size-cells : must be 0 | ||
21 | - clocks : phandle to clock providers | ||
22 | - clock-names : must contain "core" and "clkin" | ||
23 | |||
24 | Required child nodes: | ||
25 | A node for each slot provided by the MMC controller is required. | ||
26 | NOTE: due to a driver limitation currently only one slot (= child node) | ||
27 | is supported! | ||
28 | |||
29 | Required properties on each child node (= slot): | ||
30 | - compatible : must be "mmc-slot" (see mmc.txt within this directory) | ||
31 | - reg : the slot (or "port") ID | ||
32 | |||
33 | Optional properties on each child node (= slot): | ||
34 | - bus-width : must be 1 or 4 (8-bit bus is not supported) | ||
35 | - for cd and all other additional generic mmc parameters | ||
36 | please refer to mmc.txt within this directory | ||
37 | |||
38 | Examples: | ||
39 | mmc@c1108c20 { | ||
40 | compatible = "amlogic,meson8-sdio", "amlogic,meson-mx-sdio"; | ||
41 | reg = <0xc1108c20 0x20>; | ||
42 | interrupts = <0 28 1>; | ||
43 | #address-cells = <1>; | ||
44 | #size-cells = <0>; | ||
45 | clocks = <&clkc CLKID_SDIO>, <&clkc CLKID_CLK81>; | ||
46 | clock-names = "core", "clkin"; | ||
47 | |||
48 | slot@1 { | ||
49 | compatible = "mmc-slot"; | ||
50 | reg = <1>; | ||
51 | |||
52 | bus-width = <4>; | ||
53 | }; | ||
54 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index b32ade645ad9..94a90b49a692 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt | |||
@@ -53,6 +53,9 @@ Optional properties: | |||
53 | - no-sdio: controller is limited to send sdio cmd during initialization | 53 | - no-sdio: controller is limited to send sdio cmd during initialization |
54 | - no-sd: controller is limited to send sd cmd during initialization | 54 | - no-sd: controller is limited to send sd cmd during initialization |
55 | - no-mmc: controller is limited to send mmc cmd during initialization | 55 | - no-mmc: controller is limited to send mmc cmd during initialization |
56 | - 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 | ||
58 | (table 206 in spec version 5.1). | ||
56 | 59 | ||
57 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line | 60 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line |
58 | polarity properties, we have to fix the meaning of the "normal" and "inverted" | 61 | polarity properties, we have to fix the meaning of the "normal" and "inverted" |
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt index 4182ea36ca5b..72d2a734ab85 100644 --- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt | |||
@@ -7,10 +7,18 @@ This file documents differences between the core properties in mmc.txt | |||
7 | and the properties used by the msdc driver. | 7 | and the properties used by the msdc driver. |
8 | 8 | ||
9 | Required properties: | 9 | Required properties: |
10 | - compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc" | 10 | - compatible: value should be either of the following. |
11 | "mediatek,mt8135-mmc": for mmc host ip compatible with mt8135 | ||
12 | "mediatek,mt8173-mmc": for mmc host ip compatible with mt8173 | ||
13 | "mediatek,mt2701-mmc": for mmc host ip compatible with mt2701 | ||
14 | "mediatek,mt2712-mmc": for mmc host ip compatible with mt2712 | ||
15 | - reg: physical base address of the controller and length | ||
11 | - interrupts: Should contain MSDC interrupt number | 16 | - interrupts: Should contain MSDC interrupt number |
12 | - clocks: MSDC source clock, HCLK | 17 | - clocks: Should contain phandle for the clock feeding the MMC controller |
13 | - clock-names: "source", "hclk" | 18 | - clock-names: Should contain the following: |
19 | "source" - source clock (required) | ||
20 | "hclk" - HCLK which used for host (required) | ||
21 | "source_cg" - independent source clock gate (required for MT2712) | ||
14 | - pinctrl-names: should be "default", "state_uhs" | 22 | - pinctrl-names: should be "default", "state_uhs" |
15 | - pinctrl-0: should contain default/high speed pin ctrl | 23 | - pinctrl-0: should contain default/high speed pin ctrl |
16 | - pinctrl-1: should contain uhs mode pin ctrl | 24 | - pinctrl-1: should contain uhs mode pin ctrl |
@@ -30,6 +38,10 @@ Optional properties: | |||
30 | - mediatek,hs400-cmd-resp-sel-rising: HS400 command response sample selection | 38 | - mediatek,hs400-cmd-resp-sel-rising: HS400 command response sample selection |
31 | If present,HS400 command responses are sampled on rising edges. | 39 | If present,HS400 command responses are sampled on rising edges. |
32 | If not present,HS400 command responses are sampled on falling edges. | 40 | If not present,HS400 command responses are sampled on falling edges. |
41 | - mediatek,latch-ck: Some SoCs do not support enhance_rx, need set correct latch-ck to avoid data crc | ||
42 | error caused by stop clock(fifo full) | ||
43 | Valid range = [0:0x7]. if not present, default value is 0. | ||
44 | applied to compatible "mediatek,mt2701-mmc". | ||
33 | 45 | ||
34 | Examples: | 46 | Examples: |
35 | mmc0: mmc@11230000 { | 47 | mmc0: mmc@11230000 { |
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt index de2c53cff4f1..3ee9263adf73 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt | |||
@@ -15,6 +15,8 @@ Required properties: | |||
15 | Optional properties: | 15 | Optional properties: |
16 | - vqmmc-supply: phandle to the regulator device tree node, mentioned | 16 | - vqmmc-supply: phandle to the regulator device tree node, mentioned |
17 | as the VCCQ/VDD_IO supply in the eMMC/SD specs. | 17 | as the VCCQ/VDD_IO supply in the eMMC/SD specs. |
18 | - fujitsu,cmd-dat-delay-select: boolean property indicating that this host | ||
19 | requires the CMD_DAT_DELAY control to be enabled. | ||
18 | 20 | ||
19 | Example: | 21 | Example: |
20 | 22 | ||
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt index 0576264eab5e..bfdcdc4ccdff 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt | |||
@@ -18,6 +18,8 @@ Required properties: | |||
18 | "core" - SDC MMC clock (MCLK) (required) | 18 | "core" - SDC MMC clock (MCLK) (required) |
19 | "bus" - SDCC bus voter clock (optional) | 19 | "bus" - SDCC bus voter clock (optional) |
20 | "xo" - TCXO clock (optional) | 20 | "xo" - TCXO clock (optional) |
21 | "cal" - reference clock for RCLK delay calibration (optional) | ||
22 | "sleep" - sleep clock for RCLK delay calibration (optional) | ||
21 | 23 | ||
22 | Example: | 24 | Example: |
23 | 25 | ||
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt new file mode 100644 index 000000000000..51775a372c06 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | * TI OMAP SDHCI Controller | ||
2 | |||
3 | Refer to mmc.txt for standard MMC bindings. | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers | ||
7 | - ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1 | ||
8 | |||
9 | Example: | ||
10 | mmc1: mmc@4809c000 { | ||
11 | compatible = "ti,dra7-sdhci"; | ||
12 | reg = <0x4809c000 0x400>; | ||
13 | ti,hwmods = "mmc1"; | ||
14 | bus-width = <4>; | ||
15 | vmmc-supply = <&vmmc>; /* phandle to regulator node */ | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index 54ef642f23a0..3c6762430fd9 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt | |||
@@ -10,7 +10,7 @@ described in mmc.txt, can be used. Additionally the following tmio_mmc-specific | |||
10 | optional bindings can be used. | 10 | optional bindings can be used. |
11 | 11 | ||
12 | Required properties: | 12 | Required properties: |
13 | - compatible: "renesas,sdhi-shmobile" - a generic sh-mobile SDHI unit | 13 | - compatible: should contain one or more of the following: |
14 | "renesas,sdhi-sh73a0" - SDHI IP on SH73A0 SoC | 14 | "renesas,sdhi-sh73a0" - SDHI IP on SH73A0 SoC |
15 | "renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC | 15 | "renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC |
16 | "renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC | 16 | "renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC |
@@ -26,6 +26,16 @@ 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-shmobile" - a generic sh-mobile SDHI controller | ||
30 | "renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller | ||
31 | "renesas,rcar-gen2-sdhi" - a generic R-Car Gen2 or RZ/G1 | ||
32 | SDHI controller | ||
33 | "renesas,rcar-gen3-sdhi" - a generic R-Car Gen3 SDHI controller | ||
34 | |||
35 | |||
36 | When compatible with the generic version, nodes must list | ||
37 | the SoC-specific version corresponding to the platform | ||
38 | first followed by the generic version. | ||
29 | 39 | ||
30 | - clocks: Most controllers only have 1 clock source per channel. However, on | 40 | - clocks: Most controllers only have 1 clock source per channel. However, on |
31 | some variations of this controller, the internal card detection | 41 | some variations of this controller, the internal card detection |
@@ -43,3 +53,61 @@ Optional properties: | |||
43 | - pinctrl-names: should be "default", "state_uhs" | 53 | - pinctrl-names: should be "default", "state_uhs" |
44 | - pinctrl-0: should contain default/high speed pin ctrl | 54 | - pinctrl-0: should contain default/high speed pin ctrl |
45 | - pinctrl-1: should contain uhs mode pin ctrl | 55 | - pinctrl-1: should contain uhs mode pin ctrl |
56 | |||
57 | Example: R8A7790 (R-Car H2) SDHI controller nodes | ||
58 | |||
59 | sdhi0: sd@ee100000 { | ||
60 | compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi"; | ||
61 | reg = <0 0xee100000 0 0x328>; | ||
62 | interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>; | ||
63 | clocks = <&cpg CPG_MOD 314>; | ||
64 | dmas = <&dmac0 0xcd>, <&dmac0 0xce>, | ||
65 | <&dmac1 0xcd>, <&dmac1 0xce>; | ||
66 | dma-names = "tx", "rx", "tx", "rx"; | ||
67 | max-frequency = <195000000>; | ||
68 | power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; | ||
69 | resets = <&cpg 314>; | ||
70 | status = "disabled"; | ||
71 | }; | ||
72 | |||
73 | sdhi1: sd@ee120000 { | ||
74 | compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi"; | ||
75 | reg = <0 0xee120000 0 0x328>; | ||
76 | interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>; | ||
77 | clocks = <&cpg CPG_MOD 313>; | ||
78 | dmas = <&dmac0 0xc9>, <&dmac0 0xca>, | ||
79 | <&dmac1 0xc9>, <&dmac1 0xca>; | ||
80 | dma-names = "tx", "rx", "tx", "rx"; | ||
81 | max-frequency = <195000000>; | ||
82 | power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; | ||
83 | resets = <&cpg 313>; | ||
84 | status = "disabled"; | ||
85 | }; | ||
86 | |||
87 | sdhi2: sd@ee140000 { | ||
88 | compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi"; | ||
89 | reg = <0 0xee140000 0 0x100>; | ||
90 | interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>; | ||
91 | clocks = <&cpg CPG_MOD 312>; | ||
92 | dmas = <&dmac0 0xc1>, <&dmac0 0xc2>, | ||
93 | <&dmac1 0xc1>, <&dmac1 0xc2>; | ||
94 | dma-names = "tx", "rx", "tx", "rx"; | ||
95 | max-frequency = <97500000>; | ||
96 | power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; | ||
97 | resets = <&cpg 312>; | ||
98 | status = "disabled"; | ||
99 | }; | ||
100 | |||
101 | sdhi3: sd@ee160000 { | ||
102 | compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi"; | ||
103 | reg = <0 0xee160000 0 0x100>; | ||
104 | interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>; | ||
105 | clocks = <&cpg CPG_MOD 311>; | ||
106 | dmas = <&dmac0 0xd3>, <&dmac0 0xd4>, | ||
107 | <&dmac1 0xd3>, <&dmac1 0xd4>; | ||
108 | dma-names = "tx", "rx", "tx", "rx"; | ||
109 | max-frequency = <97500000>; | ||
110 | power-domains = <&sysc R8A7790_PD_ALWAYS_ON>; | ||
111 | resets = <&cpg 311>; | ||
112 | status = "disabled"; | ||
113 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 48d8f05bf92b..779fa6dde58b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -12067,6 +12067,12 @@ L: linux-mmc@vger.kernel.org | |||
12067 | S: Maintained | 12067 | S: Maintained |
12068 | F: drivers/mmc/host/sdhci-spear.c | 12068 | F: drivers/mmc/host/sdhci-spear.c |
12069 | 12069 | ||
12070 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) TI OMAP DRIVER | ||
12071 | M: Kishon Vijay Abraham I <kishon@ti.com> | ||
12072 | L: linux-mmc@vger.kernel.org | ||
12073 | S: Maintained | ||
12074 | F: drivers/mmc/host/sdhci-omap.c | ||
12075 | |||
12070 | SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER | 12076 | SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER |
12071 | M: Scott Bauer <scott.bauer@intel.com> | 12077 | M: Scott Bauer <scott.bauer@intel.com> |
12072 | M: Jonathan Derrick <jonathan.derrick@intel.com> | 12078 | M: Jonathan Derrick <jonathan.derrick@intel.com> |
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index b99a27372965..26396ef53bde 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi | |||
@@ -682,8 +682,7 @@ | |||
682 | }; | 682 | }; |
683 | 683 | ||
684 | mmc0: mmc@11230000 { | 684 | mmc0: mmc@11230000 { |
685 | compatible = "mediatek,mt8173-mmc", | 685 | compatible = "mediatek,mt8173-mmc"; |
686 | "mediatek,mt8135-mmc"; | ||
687 | reg = <0 0x11230000 0 0x1000>; | 686 | reg = <0 0x11230000 0 0x1000>; |
688 | interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>; | 687 | interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>; |
689 | clocks = <&pericfg CLK_PERI_MSDC30_0>, | 688 | clocks = <&pericfg CLK_PERI_MSDC30_0>, |
@@ -693,8 +692,7 @@ | |||
693 | }; | 692 | }; |
694 | 693 | ||
695 | mmc1: mmc@11240000 { | 694 | mmc1: mmc@11240000 { |
696 | compatible = "mediatek,mt8173-mmc", | 695 | compatible = "mediatek,mt8173-mmc"; |
697 | "mediatek,mt8135-mmc"; | ||
698 | reg = <0 0x11240000 0 0x1000>; | 696 | reg = <0 0x11240000 0 0x1000>; |
699 | interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>; | 697 | interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>; |
700 | clocks = <&pericfg CLK_PERI_MSDC30_1>, | 698 | clocks = <&pericfg CLK_PERI_MSDC30_1>, |
@@ -704,8 +702,7 @@ | |||
704 | }; | 702 | }; |
705 | 703 | ||
706 | mmc2: mmc@11250000 { | 704 | mmc2: mmc@11250000 { |
707 | compatible = "mediatek,mt8173-mmc", | 705 | compatible = "mediatek,mt8173-mmc"; |
708 | "mediatek,mt8135-mmc"; | ||
709 | reg = <0 0x11250000 0 0x1000>; | 706 | reg = <0 0x11250000 0 0x1000>; |
710 | interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>; | 707 | interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>; |
711 | clocks = <&pericfg CLK_PERI_MSDC30_2>, | 708 | clocks = <&pericfg CLK_PERI_MSDC30_2>, |
@@ -715,8 +712,7 @@ | |||
715 | }; | 712 | }; |
716 | 713 | ||
717 | mmc3: mmc@11260000 { | 714 | mmc3: mmc@11260000 { |
718 | compatible = "mediatek,mt8173-mmc", | 715 | compatible = "mediatek,mt8173-mmc"; |
719 | "mediatek,mt8135-mmc"; | ||
720 | reg = <0 0x11260000 0 0x1000>; | 716 | reg = <0 0x11260000 0 0x1000>; |
721 | interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_LOW>; | 717 | interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_LOW>; |
722 | clocks = <&pericfg CLK_PERI_MSDC30_3>, | 718 | clocks = <&pericfg CLK_PERI_MSDC30_3>, |
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 2ad7b5c69156..ea80ff4cd7f9 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/hdreg.h> | 28 | #include <linux/hdreg.h> |
29 | #include <linux/kdev_t.h> | 29 | #include <linux/kdev_t.h> |
30 | #include <linux/blkdev.h> | 30 | #include <linux/blkdev.h> |
31 | #include <linux/cdev.h> | ||
31 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
32 | #include <linux/scatterlist.h> | 33 | #include <linux/scatterlist.h> |
33 | #include <linux/string_helpers.h> | 34 | #include <linux/string_helpers.h> |
@@ -86,6 +87,7 @@ static int max_devices; | |||
86 | #define MAX_DEVICES 256 | 87 | #define MAX_DEVICES 256 |
87 | 88 | ||
88 | static DEFINE_IDA(mmc_blk_ida); | 89 | static DEFINE_IDA(mmc_blk_ida); |
90 | static DEFINE_IDA(mmc_rpmb_ida); | ||
89 | 91 | ||
90 | /* | 92 | /* |
91 | * There is one mmc_blk_data per slot. | 93 | * There is one mmc_blk_data per slot. |
@@ -96,6 +98,7 @@ struct mmc_blk_data { | |||
96 | struct gendisk *disk; | 98 | struct gendisk *disk; |
97 | struct mmc_queue queue; | 99 | struct mmc_queue queue; |
98 | struct list_head part; | 100 | struct list_head part; |
101 | struct list_head rpmbs; | ||
99 | 102 | ||
100 | unsigned int flags; | 103 | unsigned int flags; |
101 | #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ | 104 | #define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ |
@@ -121,6 +124,32 @@ struct mmc_blk_data { | |||
121 | int area_type; | 124 | int area_type; |
122 | }; | 125 | }; |
123 | 126 | ||
127 | /* Device type for RPMB character devices */ | ||
128 | static dev_t mmc_rpmb_devt; | ||
129 | |||
130 | /* Bus type for RPMB character devices */ | ||
131 | static struct bus_type mmc_rpmb_bus_type = { | ||
132 | .name = "mmc_rpmb", | ||
133 | }; | ||
134 | |||
135 | /** | ||
136 | * struct mmc_rpmb_data - special RPMB device type for these areas | ||
137 | * @dev: the device for the RPMB area | ||
138 | * @chrdev: character device for the RPMB area | ||
139 | * @id: unique device ID number | ||
140 | * @part_index: partition index (0 on first) | ||
141 | * @md: parent MMC block device | ||
142 | * @node: list item, so we can put this device on a list | ||
143 | */ | ||
144 | struct mmc_rpmb_data { | ||
145 | struct device dev; | ||
146 | struct cdev chrdev; | ||
147 | int id; | ||
148 | unsigned int part_index; | ||
149 | struct mmc_blk_data *md; | ||
150 | struct list_head node; | ||
151 | }; | ||
152 | |||
124 | static DEFINE_MUTEX(open_lock); | 153 | static DEFINE_MUTEX(open_lock); |
125 | 154 | ||
126 | module_param(perdev_minors, int, 0444); | 155 | module_param(perdev_minors, int, 0444); |
@@ -299,6 +328,7 @@ struct mmc_blk_ioc_data { | |||
299 | struct mmc_ioc_cmd ic; | 328 | struct mmc_ioc_cmd ic; |
300 | unsigned char *buf; | 329 | unsigned char *buf; |
301 | u64 buf_bytes; | 330 | u64 buf_bytes; |
331 | struct mmc_rpmb_data *rpmb; | ||
302 | }; | 332 | }; |
303 | 333 | ||
304 | static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( | 334 | static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( |
@@ -437,14 +467,25 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, | |||
437 | struct mmc_request mrq = {}; | 467 | struct mmc_request mrq = {}; |
438 | struct scatterlist sg; | 468 | struct scatterlist sg; |
439 | int err; | 469 | int err; |
440 | bool is_rpmb = false; | 470 | unsigned int target_part; |
441 | u32 status = 0; | 471 | u32 status = 0; |
442 | 472 | ||
443 | if (!card || !md || !idata) | 473 | if (!card || !md || !idata) |
444 | return -EINVAL; | 474 | return -EINVAL; |
445 | 475 | ||
446 | if (md->area_type & MMC_BLK_DATA_AREA_RPMB) | 476 | /* |
447 | is_rpmb = true; | 477 | * The RPMB accesses comes in from the character device, so we |
478 | * need to target these explicitly. Else we just target the | ||
479 | * partition type for the block device the ioctl() was issued | ||
480 | * on. | ||
481 | */ | ||
482 | if (idata->rpmb) { | ||
483 | /* Support multiple RPMB partitions */ | ||
484 | target_part = idata->rpmb->part_index; | ||
485 | target_part |= EXT_CSD_PART_CONFIG_ACC_RPMB; | ||
486 | } else { | ||
487 | target_part = md->part_type; | ||
488 | } | ||
448 | 489 | ||
449 | cmd.opcode = idata->ic.opcode; | 490 | cmd.opcode = idata->ic.opcode; |
450 | cmd.arg = idata->ic.arg; | 491 | cmd.arg = idata->ic.arg; |
@@ -488,7 +529,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, | |||
488 | 529 | ||
489 | mrq.cmd = &cmd; | 530 | mrq.cmd = &cmd; |
490 | 531 | ||
491 | err = mmc_blk_part_switch(card, md->part_type); | 532 | err = mmc_blk_part_switch(card, target_part); |
492 | if (err) | 533 | if (err) |
493 | return err; | 534 | return err; |
494 | 535 | ||
@@ -498,7 +539,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, | |||
498 | return err; | 539 | return err; |
499 | } | 540 | } |
500 | 541 | ||
501 | if (is_rpmb) { | 542 | if (idata->rpmb) { |
502 | err = mmc_set_blockcount(card, data.blocks, | 543 | err = mmc_set_blockcount(card, data.blocks, |
503 | idata->ic.write_flag & (1 << 31)); | 544 | idata->ic.write_flag & (1 << 31)); |
504 | if (err) | 545 | if (err) |
@@ -538,7 +579,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, | |||
538 | 579 | ||
539 | memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); | 580 | memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); |
540 | 581 | ||
541 | if (is_rpmb) { | 582 | if (idata->rpmb) { |
542 | /* | 583 | /* |
543 | * Ensure RPMB command has completed by polling CMD13 | 584 | * Ensure RPMB command has completed by polling CMD13 |
544 | * "Send Status". | 585 | * "Send Status". |
@@ -554,7 +595,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, | |||
554 | } | 595 | } |
555 | 596 | ||
556 | static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md, | 597 | static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md, |
557 | struct mmc_ioc_cmd __user *ic_ptr) | 598 | struct mmc_ioc_cmd __user *ic_ptr, |
599 | struct mmc_rpmb_data *rpmb) | ||
558 | { | 600 | { |
559 | struct mmc_blk_ioc_data *idata; | 601 | struct mmc_blk_ioc_data *idata; |
560 | struct mmc_blk_ioc_data *idatas[1]; | 602 | struct mmc_blk_ioc_data *idatas[1]; |
@@ -566,6 +608,8 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md, | |||
566 | idata = mmc_blk_ioctl_copy_from_user(ic_ptr); | 608 | idata = mmc_blk_ioctl_copy_from_user(ic_ptr); |
567 | if (IS_ERR(idata)) | 609 | if (IS_ERR(idata)) |
568 | return PTR_ERR(idata); | 610 | return PTR_ERR(idata); |
611 | /* This will be NULL on non-RPMB ioctl():s */ | ||
612 | idata->rpmb = rpmb; | ||
569 | 613 | ||
570 | card = md->queue.card; | 614 | card = md->queue.card; |
571 | if (IS_ERR(card)) { | 615 | if (IS_ERR(card)) { |
@@ -581,7 +625,8 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md, | |||
581 | idata->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, | 625 | idata->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, |
582 | __GFP_RECLAIM); | 626 | __GFP_RECLAIM); |
583 | idatas[0] = idata; | 627 | idatas[0] = idata; |
584 | req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_IOCTL; | 628 | req_to_mmc_queue_req(req)->drv_op = |
629 | rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL; | ||
585 | req_to_mmc_queue_req(req)->drv_op_data = idatas; | 630 | req_to_mmc_queue_req(req)->drv_op_data = idatas; |
586 | req_to_mmc_queue_req(req)->ioc_count = 1; | 631 | req_to_mmc_queue_req(req)->ioc_count = 1; |
587 | blk_execute_rq(mq->queue, NULL, req, 0); | 632 | blk_execute_rq(mq->queue, NULL, req, 0); |
@@ -596,7 +641,8 @@ cmd_done: | |||
596 | } | 641 | } |
597 | 642 | ||
598 | static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md, | 643 | static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md, |
599 | struct mmc_ioc_multi_cmd __user *user) | 644 | struct mmc_ioc_multi_cmd __user *user, |
645 | struct mmc_rpmb_data *rpmb) | ||
600 | { | 646 | { |
601 | struct mmc_blk_ioc_data **idata = NULL; | 647 | struct mmc_blk_ioc_data **idata = NULL; |
602 | struct mmc_ioc_cmd __user *cmds = user->cmds; | 648 | struct mmc_ioc_cmd __user *cmds = user->cmds; |
@@ -627,6 +673,8 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md, | |||
627 | num_of_cmds = i; | 673 | num_of_cmds = i; |
628 | goto cmd_err; | 674 | goto cmd_err; |
629 | } | 675 | } |
676 | /* This will be NULL on non-RPMB ioctl():s */ | ||
677 | idata[i]->rpmb = rpmb; | ||
630 | } | 678 | } |
631 | 679 | ||
632 | card = md->queue.card; | 680 | card = md->queue.card; |
@@ -643,7 +691,8 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md, | |||
643 | req = blk_get_request(mq->queue, | 691 | req = blk_get_request(mq->queue, |
644 | idata[0]->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, | 692 | idata[0]->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, |
645 | __GFP_RECLAIM); | 693 | __GFP_RECLAIM); |
646 | req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_IOCTL; | 694 | req_to_mmc_queue_req(req)->drv_op = |
695 | rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL; | ||
647 | req_to_mmc_queue_req(req)->drv_op_data = idata; | 696 | req_to_mmc_queue_req(req)->drv_op_data = idata; |
648 | req_to_mmc_queue_req(req)->ioc_count = num_of_cmds; | 697 | req_to_mmc_queue_req(req)->ioc_count = num_of_cmds; |
649 | blk_execute_rq(mq->queue, NULL, req, 0); | 698 | blk_execute_rq(mq->queue, NULL, req, 0); |
@@ -691,7 +740,8 @@ static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, | |||
691 | if (!md) | 740 | if (!md) |
692 | return -EINVAL; | 741 | return -EINVAL; |
693 | ret = mmc_blk_ioctl_cmd(md, | 742 | ret = mmc_blk_ioctl_cmd(md, |
694 | (struct mmc_ioc_cmd __user *)arg); | 743 | (struct mmc_ioc_cmd __user *)arg, |
744 | NULL); | ||
695 | mmc_blk_put(md); | 745 | mmc_blk_put(md); |
696 | return ret; | 746 | return ret; |
697 | case MMC_IOC_MULTI_CMD: | 747 | case MMC_IOC_MULTI_CMD: |
@@ -702,7 +752,8 @@ static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, | |||
702 | if (!md) | 752 | if (!md) |
703 | return -EINVAL; | 753 | return -EINVAL; |
704 | ret = mmc_blk_ioctl_multi_cmd(md, | 754 | ret = mmc_blk_ioctl_multi_cmd(md, |
705 | (struct mmc_ioc_multi_cmd __user *)arg); | 755 | (struct mmc_ioc_multi_cmd __user *)arg, |
756 | NULL); | ||
706 | mmc_blk_put(md); | 757 | mmc_blk_put(md); |
707 | return ret; | 758 | return ret; |
708 | default: | 759 | default: |
@@ -1152,18 +1203,6 @@ static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type) | |||
1152 | md->reset_done &= ~type; | 1203 | md->reset_done &= ~type; |
1153 | } | 1204 | } |
1154 | 1205 | ||
1155 | int mmc_access_rpmb(struct mmc_queue *mq) | ||
1156 | { | ||
1157 | struct mmc_blk_data *md = mq->blkdata; | ||
1158 | /* | ||
1159 | * If this is a RPMB partition access, return ture | ||
1160 | */ | ||
1161 | if (md && md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) | ||
1162 | return true; | ||
1163 | |||
1164 | return false; | ||
1165 | } | ||
1166 | |||
1167 | /* | 1206 | /* |
1168 | * The non-block commands come back from the block layer after it queued it and | 1207 | * The non-block commands come back from the block layer after it queued it and |
1169 | * processed it with all other requests and then they get issued in this | 1208 | * processed it with all other requests and then they get issued in this |
@@ -1174,17 +1213,19 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) | |||
1174 | struct mmc_queue_req *mq_rq; | 1213 | struct mmc_queue_req *mq_rq; |
1175 | struct mmc_card *card = mq->card; | 1214 | struct mmc_card *card = mq->card; |
1176 | struct mmc_blk_data *md = mq->blkdata; | 1215 | struct mmc_blk_data *md = mq->blkdata; |
1177 | struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); | ||
1178 | struct mmc_blk_ioc_data **idata; | 1216 | struct mmc_blk_ioc_data **idata; |
1217 | bool rpmb_ioctl; | ||
1179 | u8 **ext_csd; | 1218 | u8 **ext_csd; |
1180 | u32 status; | 1219 | u32 status; |
1181 | int ret; | 1220 | int ret; |
1182 | int i; | 1221 | int i; |
1183 | 1222 | ||
1184 | mq_rq = req_to_mmc_queue_req(req); | 1223 | mq_rq = req_to_mmc_queue_req(req); |
1224 | rpmb_ioctl = (mq_rq->drv_op == MMC_DRV_OP_IOCTL_RPMB); | ||
1185 | 1225 | ||
1186 | switch (mq_rq->drv_op) { | 1226 | switch (mq_rq->drv_op) { |
1187 | case MMC_DRV_OP_IOCTL: | 1227 | case MMC_DRV_OP_IOCTL: |
1228 | case MMC_DRV_OP_IOCTL_RPMB: | ||
1188 | idata = mq_rq->drv_op_data; | 1229 | idata = mq_rq->drv_op_data; |
1189 | for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { | 1230 | for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { |
1190 | ret = __mmc_blk_ioctl_cmd(card, md, idata[i]); | 1231 | ret = __mmc_blk_ioctl_cmd(card, md, idata[i]); |
@@ -1192,8 +1233,8 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) | |||
1192 | break; | 1233 | break; |
1193 | } | 1234 | } |
1194 | /* Always switch back to main area after RPMB access */ | 1235 | /* Always switch back to main area after RPMB access */ |
1195 | if (md->area_type & MMC_BLK_DATA_AREA_RPMB) | 1236 | if (rpmb_ioctl) |
1196 | mmc_blk_part_switch(card, main_md->part_type); | 1237 | mmc_blk_part_switch(card, 0); |
1197 | break; | 1238 | break; |
1198 | case MMC_DRV_OP_BOOT_WP: | 1239 | case MMC_DRV_OP_BOOT_WP: |
1199 | ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, | 1240 | ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, |
@@ -1534,25 +1575,27 @@ static enum mmc_blk_status mmc_blk_err_check(struct mmc_card *card, | |||
1534 | } | 1575 | } |
1535 | 1576 | ||
1536 | static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, | 1577 | static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, |
1537 | int disable_multi, bool *do_rel_wr, | 1578 | int disable_multi, bool *do_rel_wr_p, |
1538 | bool *do_data_tag) | 1579 | bool *do_data_tag_p) |
1539 | { | 1580 | { |
1540 | struct mmc_blk_data *md = mq->blkdata; | 1581 | struct mmc_blk_data *md = mq->blkdata; |
1541 | struct mmc_card *card = md->queue.card; | 1582 | struct mmc_card *card = md->queue.card; |
1542 | struct mmc_blk_request *brq = &mqrq->brq; | 1583 | struct mmc_blk_request *brq = &mqrq->brq; |
1543 | struct request *req = mmc_queue_req_to_req(mqrq); | 1584 | struct request *req = mmc_queue_req_to_req(mqrq); |
1585 | bool do_rel_wr, do_data_tag; | ||
1544 | 1586 | ||
1545 | /* | 1587 | /* |
1546 | * Reliable writes are used to implement Forced Unit Access and | 1588 | * Reliable writes are used to implement Forced Unit Access and |
1547 | * are supported only on MMCs. | 1589 | * are supported only on MMCs. |
1548 | */ | 1590 | */ |
1549 | *do_rel_wr = (req->cmd_flags & REQ_FUA) && | 1591 | do_rel_wr = (req->cmd_flags & REQ_FUA) && |
1550 | rq_data_dir(req) == WRITE && | 1592 | rq_data_dir(req) == WRITE && |
1551 | (md->flags & MMC_BLK_REL_WR); | 1593 | (md->flags & MMC_BLK_REL_WR); |
1552 | 1594 | ||
1553 | memset(brq, 0, sizeof(struct mmc_blk_request)); | 1595 | memset(brq, 0, sizeof(struct mmc_blk_request)); |
1554 | 1596 | ||
1555 | brq->mrq.data = &brq->data; | 1597 | brq->mrq.data = &brq->data; |
1598 | brq->mrq.tag = req->tag; | ||
1556 | 1599 | ||
1557 | brq->stop.opcode = MMC_STOP_TRANSMISSION; | 1600 | brq->stop.opcode = MMC_STOP_TRANSMISSION; |
1558 | brq->stop.arg = 0; | 1601 | brq->stop.arg = 0; |
@@ -1567,6 +1610,14 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, | |||
1567 | 1610 | ||
1568 | brq->data.blksz = 512; | 1611 | brq->data.blksz = 512; |
1569 | brq->data.blocks = blk_rq_sectors(req); | 1612 | brq->data.blocks = blk_rq_sectors(req); |
1613 | brq->data.blk_addr = blk_rq_pos(req); | ||
1614 | |||
1615 | /* | ||
1616 | * The command queue supports 2 priorities: "high" (1) and "simple" (0). | ||
1617 | * The eMMC will give "high" priority tasks priority over "simple" | ||
1618 | * priority tasks. Here we always set "simple" priority by not setting | ||
1619 | * MMC_DATA_PRIO. | ||
1620 | */ | ||
1570 | 1621 | ||
1571 | /* | 1622 | /* |
1572 | * The block layer doesn't support all sector count | 1623 | * The block layer doesn't support all sector count |
@@ -1596,18 +1647,23 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, | |||
1596 | brq->data.blocks); | 1647 | brq->data.blocks); |
1597 | } | 1648 | } |
1598 | 1649 | ||
1599 | if (*do_rel_wr) | 1650 | if (do_rel_wr) { |
1600 | mmc_apply_rel_rw(brq, card, req); | 1651 | mmc_apply_rel_rw(brq, card, req); |
1652 | brq->data.flags |= MMC_DATA_REL_WR; | ||
1653 | } | ||
1601 | 1654 | ||
1602 | /* | 1655 | /* |
1603 | * Data tag is used only during writing meta data to speed | 1656 | * Data tag is used only during writing meta data to speed |
1604 | * up write and any subsequent read of this meta data | 1657 | * up write and any subsequent read of this meta data |
1605 | */ | 1658 | */ |
1606 | *do_data_tag = card->ext_csd.data_tag_unit_size && | 1659 | do_data_tag = card->ext_csd.data_tag_unit_size && |
1607 | (req->cmd_flags & REQ_META) && | 1660 | (req->cmd_flags & REQ_META) && |
1608 | (rq_data_dir(req) == WRITE) && | 1661 | (rq_data_dir(req) == WRITE) && |
1609 | ((brq->data.blocks * brq->data.blksz) >= | 1662 | ((brq->data.blocks * brq->data.blksz) >= |
1610 | card->ext_csd.data_tag_unit_size); | 1663 | card->ext_csd.data_tag_unit_size); |
1664 | |||
1665 | if (do_data_tag) | ||
1666 | brq->data.flags |= MMC_DATA_DAT_TAG; | ||
1611 | 1667 | ||
1612 | mmc_set_data_timeout(&brq->data, card); | 1668 | mmc_set_data_timeout(&brq->data, card); |
1613 | 1669 | ||
@@ -1634,6 +1690,12 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, | |||
1634 | } | 1690 | } |
1635 | 1691 | ||
1636 | mqrq->areq.mrq = &brq->mrq; | 1692 | mqrq->areq.mrq = &brq->mrq; |
1693 | |||
1694 | if (do_rel_wr_p) | ||
1695 | *do_rel_wr_p = do_rel_wr; | ||
1696 | |||
1697 | if (do_data_tag_p) | ||
1698 | *do_data_tag_p = do_data_tag; | ||
1637 | } | 1699 | } |
1638 | 1700 | ||
1639 | static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, | 1701 | static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, |
@@ -1948,7 +2010,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1948 | 2010 | ||
1949 | if (req && !mq->qcnt) | 2011 | if (req && !mq->qcnt) |
1950 | /* claim host only for the first request */ | 2012 | /* claim host only for the first request */ |
1951 | mmc_get_card(card); | 2013 | mmc_get_card(card, NULL); |
1952 | 2014 | ||
1953 | ret = mmc_blk_part_switch(card, md->part_type); | 2015 | ret = mmc_blk_part_switch(card, md->part_type); |
1954 | if (ret) { | 2016 | if (ret) { |
@@ -2011,7 +2073,7 @@ void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
2011 | 2073 | ||
2012 | out: | 2074 | out: |
2013 | if (!mq->qcnt) | 2075 | if (!mq->qcnt) |
2014 | mmc_put_card(card); | 2076 | mmc_put_card(card, NULL); |
2015 | } | 2077 | } |
2016 | 2078 | ||
2017 | static inline int mmc_blk_readonly(struct mmc_card *card) | 2079 | static inline int mmc_blk_readonly(struct mmc_card *card) |
@@ -2068,6 +2130,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
2068 | 2130 | ||
2069 | spin_lock_init(&md->lock); | 2131 | spin_lock_init(&md->lock); |
2070 | INIT_LIST_HEAD(&md->part); | 2132 | INIT_LIST_HEAD(&md->part); |
2133 | INIT_LIST_HEAD(&md->rpmbs); | ||
2071 | md->usage = 1; | 2134 | md->usage = 1; |
2072 | 2135 | ||
2073 | ret = mmc_init_queue(&md->queue, card, &md->lock, subname); | 2136 | ret = mmc_init_queue(&md->queue, card, &md->lock, subname); |
@@ -2186,6 +2249,158 @@ static int mmc_blk_alloc_part(struct mmc_card *card, | |||
2186 | return 0; | 2249 | return 0; |
2187 | } | 2250 | } |
2188 | 2251 | ||
2252 | /** | ||
2253 | * mmc_rpmb_ioctl() - ioctl handler for the RPMB chardev | ||
2254 | * @filp: the character device file | ||
2255 | * @cmd: the ioctl() command | ||
2256 | * @arg: the argument from userspace | ||
2257 | * | ||
2258 | * This will essentially just redirect the ioctl()s coming in over to | ||
2259 | * the main block device spawning the RPMB character device. | ||
2260 | */ | ||
2261 | static long mmc_rpmb_ioctl(struct file *filp, unsigned int cmd, | ||
2262 | unsigned long arg) | ||
2263 | { | ||
2264 | struct mmc_rpmb_data *rpmb = filp->private_data; | ||
2265 | int ret; | ||
2266 | |||
2267 | switch (cmd) { | ||
2268 | case MMC_IOC_CMD: | ||
2269 | ret = mmc_blk_ioctl_cmd(rpmb->md, | ||
2270 | (struct mmc_ioc_cmd __user *)arg, | ||
2271 | rpmb); | ||
2272 | break; | ||
2273 | case MMC_IOC_MULTI_CMD: | ||
2274 | ret = mmc_blk_ioctl_multi_cmd(rpmb->md, | ||
2275 | (struct mmc_ioc_multi_cmd __user *)arg, | ||
2276 | rpmb); | ||
2277 | break; | ||
2278 | default: | ||
2279 | ret = -EINVAL; | ||
2280 | break; | ||
2281 | } | ||
2282 | |||
2283 | return 0; | ||
2284 | } | ||
2285 | |||
2286 | #ifdef CONFIG_COMPAT | ||
2287 | static long mmc_rpmb_ioctl_compat(struct file *filp, unsigned int cmd, | ||
2288 | unsigned long arg) | ||
2289 | { | ||
2290 | return mmc_rpmb_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); | ||
2291 | } | ||
2292 | #endif | ||
2293 | |||
2294 | static int mmc_rpmb_chrdev_open(struct inode *inode, struct file *filp) | ||
2295 | { | ||
2296 | struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev, | ||
2297 | struct mmc_rpmb_data, chrdev); | ||
2298 | |||
2299 | get_device(&rpmb->dev); | ||
2300 | filp->private_data = rpmb; | ||
2301 | mmc_blk_get(rpmb->md->disk); | ||
2302 | |||
2303 | return nonseekable_open(inode, filp); | ||
2304 | } | ||
2305 | |||
2306 | static int mmc_rpmb_chrdev_release(struct inode *inode, struct file *filp) | ||
2307 | { | ||
2308 | struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev, | ||
2309 | struct mmc_rpmb_data, chrdev); | ||
2310 | |||
2311 | put_device(&rpmb->dev); | ||
2312 | mmc_blk_put(rpmb->md); | ||
2313 | |||
2314 | return 0; | ||
2315 | } | ||
2316 | |||
2317 | static const struct file_operations mmc_rpmb_fileops = { | ||
2318 | .release = mmc_rpmb_chrdev_release, | ||
2319 | .open = mmc_rpmb_chrdev_open, | ||
2320 | .owner = THIS_MODULE, | ||
2321 | .llseek = no_llseek, | ||
2322 | .unlocked_ioctl = mmc_rpmb_ioctl, | ||
2323 | #ifdef CONFIG_COMPAT | ||
2324 | .compat_ioctl = mmc_rpmb_ioctl_compat, | ||
2325 | #endif | ||
2326 | }; | ||
2327 | |||
2328 | static void mmc_blk_rpmb_device_release(struct device *dev) | ||
2329 | { | ||
2330 | struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev); | ||
2331 | |||
2332 | ida_simple_remove(&mmc_rpmb_ida, rpmb->id); | ||
2333 | kfree(rpmb); | ||
2334 | } | ||
2335 | |||
2336 | static int mmc_blk_alloc_rpmb_part(struct mmc_card *card, | ||
2337 | struct mmc_blk_data *md, | ||
2338 | unsigned int part_index, | ||
2339 | sector_t size, | ||
2340 | const char *subname) | ||
2341 | { | ||
2342 | int devidx, ret; | ||
2343 | char rpmb_name[DISK_NAME_LEN]; | ||
2344 | char cap_str[10]; | ||
2345 | struct mmc_rpmb_data *rpmb; | ||
2346 | |||
2347 | /* This creates the minor number for the RPMB char device */ | ||
2348 | devidx = ida_simple_get(&mmc_rpmb_ida, 0, max_devices, GFP_KERNEL); | ||
2349 | if (devidx < 0) | ||
2350 | return devidx; | ||
2351 | |||
2352 | rpmb = kzalloc(sizeof(*rpmb), GFP_KERNEL); | ||
2353 | if (!rpmb) { | ||
2354 | ida_simple_remove(&mmc_rpmb_ida, devidx); | ||
2355 | return -ENOMEM; | ||
2356 | } | ||
2357 | |||
2358 | snprintf(rpmb_name, sizeof(rpmb_name), | ||
2359 | "mmcblk%u%s", card->host->index, subname ? subname : ""); | ||
2360 | |||
2361 | rpmb->id = devidx; | ||
2362 | rpmb->part_index = part_index; | ||
2363 | rpmb->dev.init_name = rpmb_name; | ||
2364 | rpmb->dev.bus = &mmc_rpmb_bus_type; | ||
2365 | rpmb->dev.devt = MKDEV(MAJOR(mmc_rpmb_devt), rpmb->id); | ||
2366 | rpmb->dev.parent = &card->dev; | ||
2367 | rpmb->dev.release = mmc_blk_rpmb_device_release; | ||
2368 | device_initialize(&rpmb->dev); | ||
2369 | dev_set_drvdata(&rpmb->dev, rpmb); | ||
2370 | rpmb->md = md; | ||
2371 | |||
2372 | cdev_init(&rpmb->chrdev, &mmc_rpmb_fileops); | ||
2373 | rpmb->chrdev.owner = THIS_MODULE; | ||
2374 | ret = cdev_device_add(&rpmb->chrdev, &rpmb->dev); | ||
2375 | if (ret) { | ||
2376 | pr_err("%s: could not add character device\n", rpmb_name); | ||
2377 | goto out_put_device; | ||
2378 | } | ||
2379 | |||
2380 | list_add(&rpmb->node, &md->rpmbs); | ||
2381 | |||
2382 | string_get_size((u64)size, 512, STRING_UNITS_2, | ||
2383 | cap_str, sizeof(cap_str)); | ||
2384 | |||
2385 | pr_info("%s: %s %s partition %u %s, chardev (%d:%d)\n", | ||
2386 | rpmb_name, mmc_card_id(card), | ||
2387 | mmc_card_name(card), EXT_CSD_PART_CONFIG_ACC_RPMB, cap_str, | ||
2388 | MAJOR(mmc_rpmb_devt), rpmb->id); | ||
2389 | |||
2390 | return 0; | ||
2391 | |||
2392 | out_put_device: | ||
2393 | put_device(&rpmb->dev); | ||
2394 | return ret; | ||
2395 | } | ||
2396 | |||
2397 | static void mmc_blk_remove_rpmb_part(struct mmc_rpmb_data *rpmb) | ||
2398 | |||
2399 | { | ||
2400 | cdev_device_del(&rpmb->chrdev, &rpmb->dev); | ||
2401 | put_device(&rpmb->dev); | ||
2402 | } | ||
2403 | |||
2189 | /* MMC Physical partitions consist of two boot partitions and | 2404 | /* MMC Physical partitions consist of two boot partitions and |
2190 | * up to four general purpose partitions. | 2405 | * up to four general purpose partitions. |
2191 | * For each partition enabled in EXT_CSD a block device will be allocatedi | 2406 | * For each partition enabled in EXT_CSD a block device will be allocatedi |
@@ -2194,13 +2409,26 @@ static int mmc_blk_alloc_part(struct mmc_card *card, | |||
2194 | 2409 | ||
2195 | static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) | 2410 | static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) |
2196 | { | 2411 | { |
2197 | int idx, ret = 0; | 2412 | int idx, ret; |
2198 | 2413 | ||
2199 | if (!mmc_card_mmc(card)) | 2414 | if (!mmc_card_mmc(card)) |
2200 | return 0; | 2415 | return 0; |
2201 | 2416 | ||
2202 | for (idx = 0; idx < card->nr_parts; idx++) { | 2417 | for (idx = 0; idx < card->nr_parts; idx++) { |
2203 | if (card->part[idx].size) { | 2418 | if (card->part[idx].area_type & MMC_BLK_DATA_AREA_RPMB) { |
2419 | /* | ||
2420 | * RPMB partitions does not provide block access, they | ||
2421 | * are only accessed using ioctl():s. Thus create | ||
2422 | * special RPMB block devices that do not have a | ||
2423 | * backing block queue for these. | ||
2424 | */ | ||
2425 | ret = mmc_blk_alloc_rpmb_part(card, md, | ||
2426 | card->part[idx].part_cfg, | ||
2427 | card->part[idx].size >> 9, | ||
2428 | card->part[idx].name); | ||
2429 | if (ret) | ||
2430 | return ret; | ||
2431 | } else if (card->part[idx].size) { | ||
2204 | ret = mmc_blk_alloc_part(card, md, | 2432 | ret = mmc_blk_alloc_part(card, md, |
2205 | card->part[idx].part_cfg, | 2433 | card->part[idx].part_cfg, |
2206 | card->part[idx].size >> 9, | 2434 | card->part[idx].size >> 9, |
@@ -2212,7 +2440,7 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) | |||
2212 | } | 2440 | } |
2213 | } | 2441 | } |
2214 | 2442 | ||
2215 | return ret; | 2443 | return 0; |
2216 | } | 2444 | } |
2217 | 2445 | ||
2218 | static void mmc_blk_remove_req(struct mmc_blk_data *md) | 2446 | static void mmc_blk_remove_req(struct mmc_blk_data *md) |
@@ -2249,7 +2477,15 @@ static void mmc_blk_remove_parts(struct mmc_card *card, | |||
2249 | { | 2477 | { |
2250 | struct list_head *pos, *q; | 2478 | struct list_head *pos, *q; |
2251 | struct mmc_blk_data *part_md; | 2479 | struct mmc_blk_data *part_md; |
2480 | struct mmc_rpmb_data *rpmb; | ||
2252 | 2481 | ||
2482 | /* Remove RPMB partitions */ | ||
2483 | list_for_each_safe(pos, q, &md->rpmbs) { | ||
2484 | rpmb = list_entry(pos, struct mmc_rpmb_data, node); | ||
2485 | list_del(pos); | ||
2486 | mmc_blk_remove_rpmb_part(rpmb); | ||
2487 | } | ||
2488 | /* Remove block partitions */ | ||
2253 | list_for_each_safe(pos, q, &md->part) { | 2489 | list_for_each_safe(pos, q, &md->part) { |
2254 | part_md = list_entry(pos, struct mmc_blk_data, part); | 2490 | part_md = list_entry(pos, struct mmc_blk_data, part); |
2255 | list_del(pos); | 2491 | list_del(pos); |
@@ -2568,6 +2804,17 @@ static int __init mmc_blk_init(void) | |||
2568 | { | 2804 | { |
2569 | int res; | 2805 | int res; |
2570 | 2806 | ||
2807 | res = bus_register(&mmc_rpmb_bus_type); | ||
2808 | if (res < 0) { | ||
2809 | pr_err("mmcblk: could not register RPMB bus type\n"); | ||
2810 | return res; | ||
2811 | } | ||
2812 | res = alloc_chrdev_region(&mmc_rpmb_devt, 0, MAX_DEVICES, "rpmb"); | ||
2813 | if (res < 0) { | ||
2814 | pr_err("mmcblk: failed to allocate rpmb chrdev region\n"); | ||
2815 | goto out_bus_unreg; | ||
2816 | } | ||
2817 | |||
2571 | if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) | 2818 | if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) |
2572 | pr_info("mmcblk: using %d minors per device\n", perdev_minors); | 2819 | pr_info("mmcblk: using %d minors per device\n", perdev_minors); |
2573 | 2820 | ||
@@ -2575,16 +2822,20 @@ static int __init mmc_blk_init(void) | |||
2575 | 2822 | ||
2576 | res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); | 2823 | res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); |
2577 | if (res) | 2824 | if (res) |
2578 | goto out; | 2825 | goto out_chrdev_unreg; |
2579 | 2826 | ||
2580 | res = mmc_register_driver(&mmc_driver); | 2827 | res = mmc_register_driver(&mmc_driver); |
2581 | if (res) | 2828 | if (res) |
2582 | goto out2; | 2829 | goto out_blkdev_unreg; |
2583 | 2830 | ||
2584 | return 0; | 2831 | return 0; |
2585 | out2: | 2832 | |
2833 | out_blkdev_unreg: | ||
2586 | unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); | 2834 | unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); |
2587 | out: | 2835 | out_chrdev_unreg: |
2836 | unregister_chrdev_region(mmc_rpmb_devt, MAX_DEVICES); | ||
2837 | out_bus_unreg: | ||
2838 | bus_unregister(&mmc_rpmb_bus_type); | ||
2588 | return res; | 2839 | return res; |
2589 | } | 2840 | } |
2590 | 2841 | ||
@@ -2592,6 +2843,7 @@ static void __exit mmc_blk_exit(void) | |||
2592 | { | 2843 | { |
2593 | mmc_unregister_driver(&mmc_driver); | 2844 | mmc_unregister_driver(&mmc_driver); |
2594 | unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); | 2845 | unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); |
2846 | unregister_chrdev_region(mmc_rpmb_devt, MAX_DEVICES); | ||
2595 | } | 2847 | } |
2596 | 2848 | ||
2597 | module_init(mmc_blk_init); | 2849 | module_init(mmc_blk_init); |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 301246513a37..a4b49e25fe96 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -369,10 +369,17 @@ int mmc_add_card(struct mmc_card *card) | |||
369 | */ | 369 | */ |
370 | void mmc_remove_card(struct mmc_card *card) | 370 | void mmc_remove_card(struct mmc_card *card) |
371 | { | 371 | { |
372 | struct mmc_host *host = card->host; | ||
373 | |||
372 | #ifdef CONFIG_DEBUG_FS | 374 | #ifdef CONFIG_DEBUG_FS |
373 | mmc_remove_card_debugfs(card); | 375 | mmc_remove_card_debugfs(card); |
374 | #endif | 376 | #endif |
375 | 377 | ||
378 | if (host->cqe_enabled) { | ||
379 | host->cqe_ops->cqe_disable(host); | ||
380 | host->cqe_enabled = false; | ||
381 | } | ||
382 | |||
376 | if (mmc_card_present(card)) { | 383 | if (mmc_card_present(card)) { |
377 | if (mmc_host_is_spi(card->host)) { | 384 | if (mmc_host_is_spi(card->host)) { |
378 | pr_info("%s: SPI card removed\n", | 385 | pr_info("%s: SPI card removed\n", |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 66c9cf49ad2f..1f0f44f4dd5f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -266,7 +266,8 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
266 | host->ops->request(host, mrq); | 266 | host->ops->request(host, mrq); |
267 | } | 267 | } |
268 | 268 | ||
269 | static void mmc_mrq_pr_debug(struct mmc_host *host, struct mmc_request *mrq) | 269 | static void mmc_mrq_pr_debug(struct mmc_host *host, struct mmc_request *mrq, |
270 | bool cqe) | ||
270 | { | 271 | { |
271 | if (mrq->sbc) { | 272 | if (mrq->sbc) { |
272 | pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n", | 273 | pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n", |
@@ -275,9 +276,12 @@ static void mmc_mrq_pr_debug(struct mmc_host *host, struct mmc_request *mrq) | |||
275 | } | 276 | } |
276 | 277 | ||
277 | if (mrq->cmd) { | 278 | if (mrq->cmd) { |
278 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", | 279 | pr_debug("%s: starting %sCMD%u arg %08x flags %08x\n", |
279 | mmc_hostname(host), mrq->cmd->opcode, mrq->cmd->arg, | 280 | mmc_hostname(host), cqe ? "CQE direct " : "", |
280 | mrq->cmd->flags); | 281 | mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); |
282 | } else if (cqe) { | ||
283 | pr_debug("%s: starting CQE transfer for tag %d blkaddr %u\n", | ||
284 | mmc_hostname(host), mrq->tag, mrq->data->blk_addr); | ||
281 | } | 285 | } |
282 | 286 | ||
283 | if (mrq->data) { | 287 | if (mrq->data) { |
@@ -333,7 +337,7 @@ static int mmc_mrq_prep(struct mmc_host *host, struct mmc_request *mrq) | |||
333 | return 0; | 337 | return 0; |
334 | } | 338 | } |
335 | 339 | ||
336 | static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | 340 | int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) |
337 | { | 341 | { |
338 | int err; | 342 | int err; |
339 | 343 | ||
@@ -342,7 +346,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
342 | if (mmc_card_removed(host->card)) | 346 | if (mmc_card_removed(host->card)) |
343 | return -ENOMEDIUM; | 347 | return -ENOMEDIUM; |
344 | 348 | ||
345 | mmc_mrq_pr_debug(host, mrq); | 349 | mmc_mrq_pr_debug(host, mrq, false); |
346 | 350 | ||
347 | WARN_ON(!host->claimed); | 351 | WARN_ON(!host->claimed); |
348 | 352 | ||
@@ -355,6 +359,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
355 | 359 | ||
356 | return 0; | 360 | return 0; |
357 | } | 361 | } |
362 | EXPORT_SYMBOL(mmc_start_request); | ||
358 | 363 | ||
359 | /* | 364 | /* |
360 | * mmc_wait_data_done() - done callback for data request | 365 | * mmc_wait_data_done() - done callback for data request |
@@ -482,6 +487,155 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq) | |||
482 | } | 487 | } |
483 | EXPORT_SYMBOL(mmc_wait_for_req_done); | 488 | EXPORT_SYMBOL(mmc_wait_for_req_done); |
484 | 489 | ||
490 | /* | ||
491 | * mmc_cqe_start_req - Start a CQE request. | ||
492 | * @host: MMC host to start the request | ||
493 | * @mrq: request to start | ||
494 | * | ||
495 | * Start the request, re-tuning if needed and it is possible. Returns an error | ||
496 | * code if the request fails to start or -EBUSY if CQE is busy. | ||
497 | */ | ||
498 | int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq) | ||
499 | { | ||
500 | int err; | ||
501 | |||
502 | /* | ||
503 | * CQE cannot process re-tuning commands. Caller must hold retuning | ||
504 | * while CQE is in use. Re-tuning can happen here only when CQE has no | ||
505 | * active requests i.e. this is the first. Note, re-tuning will call | ||
506 | * ->cqe_off(). | ||
507 | */ | ||
508 | err = mmc_retune(host); | ||
509 | if (err) | ||
510 | goto out_err; | ||
511 | |||
512 | mrq->host = host; | ||
513 | |||
514 | mmc_mrq_pr_debug(host, mrq, true); | ||
515 | |||
516 | err = mmc_mrq_prep(host, mrq); | ||
517 | if (err) | ||
518 | goto out_err; | ||
519 | |||
520 | err = host->cqe_ops->cqe_request(host, mrq); | ||
521 | if (err) | ||
522 | goto out_err; | ||
523 | |||
524 | trace_mmc_request_start(host, mrq); | ||
525 | |||
526 | return 0; | ||
527 | |||
528 | out_err: | ||
529 | if (mrq->cmd) { | ||
530 | pr_debug("%s: failed to start CQE direct CMD%u, error %d\n", | ||
531 | mmc_hostname(host), mrq->cmd->opcode, err); | ||
532 | } else { | ||
533 | pr_debug("%s: failed to start CQE transfer for tag %d, error %d\n", | ||
534 | mmc_hostname(host), mrq->tag, err); | ||
535 | } | ||
536 | return err; | ||
537 | } | ||
538 | EXPORT_SYMBOL(mmc_cqe_start_req); | ||
539 | |||
540 | /** | ||
541 | * mmc_cqe_request_done - CQE has finished processing an MMC request | ||
542 | * @host: MMC host which completed request | ||
543 | * @mrq: MMC request which completed | ||
544 | * | ||
545 | * CQE drivers should call this function when they have completed | ||
546 | * their processing of a request. | ||
547 | */ | ||
548 | void mmc_cqe_request_done(struct mmc_host *host, struct mmc_request *mrq) | ||
549 | { | ||
550 | mmc_should_fail_request(host, mrq); | ||
551 | |||
552 | /* Flag re-tuning needed on CRC errors */ | ||
553 | if ((mrq->cmd && mrq->cmd->error == -EILSEQ) || | ||
554 | (mrq->data && mrq->data->error == -EILSEQ)) | ||
555 | mmc_retune_needed(host); | ||
556 | |||
557 | trace_mmc_request_done(host, mrq); | ||
558 | |||
559 | if (mrq->cmd) { | ||
560 | pr_debug("%s: CQE req done (direct CMD%u): %d\n", | ||
561 | mmc_hostname(host), mrq->cmd->opcode, mrq->cmd->error); | ||
562 | } else { | ||
563 | pr_debug("%s: CQE transfer done tag %d\n", | ||
564 | mmc_hostname(host), mrq->tag); | ||
565 | } | ||
566 | |||
567 | if (mrq->data) { | ||
568 | pr_debug("%s: %d bytes transferred: %d\n", | ||
569 | mmc_hostname(host), | ||
570 | mrq->data->bytes_xfered, mrq->data->error); | ||
571 | } | ||
572 | |||
573 | mrq->done(mrq); | ||
574 | } | ||
575 | EXPORT_SYMBOL(mmc_cqe_request_done); | ||
576 | |||
577 | /** | ||
578 | * mmc_cqe_post_req - CQE post process of a completed MMC request | ||
579 | * @host: MMC host | ||
580 | * @mrq: MMC request to be processed | ||
581 | */ | ||
582 | void mmc_cqe_post_req(struct mmc_host *host, struct mmc_request *mrq) | ||
583 | { | ||
584 | if (host->cqe_ops->cqe_post_req) | ||
585 | host->cqe_ops->cqe_post_req(host, mrq); | ||
586 | } | ||
587 | EXPORT_SYMBOL(mmc_cqe_post_req); | ||
588 | |||
589 | /* Arbitrary 1 second timeout */ | ||
590 | #define MMC_CQE_RECOVERY_TIMEOUT 1000 | ||
591 | |||
592 | /* | ||
593 | * mmc_cqe_recovery - Recover from CQE errors. | ||
594 | * @host: MMC host to recover | ||
595 | * | ||
596 | * Recovery consists of stopping CQE, stopping eMMC, discarding the queue in | ||
597 | * in eMMC, and discarding the queue in CQE. CQE must call | ||
598 | * mmc_cqe_request_done() on all requests. An error is returned if the eMMC | ||
599 | * fails to discard its queue. | ||
600 | */ | ||
601 | int mmc_cqe_recovery(struct mmc_host *host) | ||
602 | { | ||
603 | struct mmc_command cmd; | ||
604 | int err; | ||
605 | |||
606 | mmc_retune_hold_now(host); | ||
607 | |||
608 | /* | ||
609 | * Recovery is expected seldom, if at all, but it reduces performance, | ||
610 | * so make sure it is not completely silent. | ||
611 | */ | ||
612 | pr_warn("%s: running CQE recovery\n", mmc_hostname(host)); | ||
613 | |||
614 | host->cqe_ops->cqe_recovery_start(host); | ||
615 | |||
616 | memset(&cmd, 0, sizeof(cmd)); | ||
617 | cmd.opcode = MMC_STOP_TRANSMISSION, | ||
618 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC, | ||
619 | cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ | ||
620 | cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT, | ||
621 | mmc_wait_for_cmd(host, &cmd, 0); | ||
622 | |||
623 | memset(&cmd, 0, sizeof(cmd)); | ||
624 | cmd.opcode = MMC_CMDQ_TASK_MGMT; | ||
625 | cmd.arg = 1; /* Discard entire queue */ | ||
626 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
627 | cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ | ||
628 | cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT, | ||
629 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
630 | |||
631 | host->cqe_ops->cqe_recovery_finish(host); | ||
632 | |||
633 | mmc_retune_release(host); | ||
634 | |||
635 | return err; | ||
636 | } | ||
637 | EXPORT_SYMBOL(mmc_cqe_recovery); | ||
638 | |||
485 | /** | 639 | /** |
486 | * mmc_is_req_done - Determine if a 'cap_cmd_during_tfr' request is done | 640 | * mmc_is_req_done - Determine if a 'cap_cmd_during_tfr' request is done |
487 | * @host: MMC host | 641 | * @host: MMC host |
@@ -832,9 +986,36 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) | |||
832 | } | 986 | } |
833 | EXPORT_SYMBOL(mmc_align_data_size); | 987 | EXPORT_SYMBOL(mmc_align_data_size); |
834 | 988 | ||
989 | /* | ||
990 | * Allow claiming an already claimed host if the context is the same or there is | ||
991 | * no context but the task is the same. | ||
992 | */ | ||
993 | static inline bool mmc_ctx_matches(struct mmc_host *host, struct mmc_ctx *ctx, | ||
994 | struct task_struct *task) | ||
995 | { | ||
996 | return host->claimer == ctx || | ||
997 | (!ctx && task && host->claimer->task == task); | ||
998 | } | ||
999 | |||
1000 | static inline void mmc_ctx_set_claimer(struct mmc_host *host, | ||
1001 | struct mmc_ctx *ctx, | ||
1002 | struct task_struct *task) | ||
1003 | { | ||
1004 | if (!host->claimer) { | ||
1005 | if (ctx) | ||
1006 | host->claimer = ctx; | ||
1007 | else | ||
1008 | host->claimer = &host->default_ctx; | ||
1009 | } | ||
1010 | if (task) | ||
1011 | host->claimer->task = task; | ||
1012 | } | ||
1013 | |||
835 | /** | 1014 | /** |
836 | * __mmc_claim_host - exclusively claim a host | 1015 | * __mmc_claim_host - exclusively claim a host |
837 | * @host: mmc host to claim | 1016 | * @host: mmc host to claim |
1017 | * @ctx: context that claims the host or NULL in which case the default | ||
1018 | * context will be used | ||
838 | * @abort: whether or not the operation should be aborted | 1019 | * @abort: whether or not the operation should be aborted |
839 | * | 1020 | * |
840 | * Claim a host for a set of operations. If @abort is non null and | 1021 | * Claim a host for a set of operations. If @abort is non null and |
@@ -842,8 +1023,10 @@ EXPORT_SYMBOL(mmc_align_data_size); | |||
842 | * that non-zero value without acquiring the lock. Returns zero | 1023 | * that non-zero value without acquiring the lock. Returns zero |
843 | * with the lock held otherwise. | 1024 | * with the lock held otherwise. |
844 | */ | 1025 | */ |
845 | int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) | 1026 | int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx, |
1027 | atomic_t *abort) | ||
846 | { | 1028 | { |
1029 | struct task_struct *task = ctx ? NULL : current; | ||
847 | DECLARE_WAITQUEUE(wait, current); | 1030 | DECLARE_WAITQUEUE(wait, current); |
848 | unsigned long flags; | 1031 | unsigned long flags; |
849 | int stop; | 1032 | int stop; |
@@ -856,7 +1039,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) | |||
856 | while (1) { | 1039 | while (1) { |
857 | set_current_state(TASK_UNINTERRUPTIBLE); | 1040 | set_current_state(TASK_UNINTERRUPTIBLE); |
858 | stop = abort ? atomic_read(abort) : 0; | 1041 | stop = abort ? atomic_read(abort) : 0; |
859 | if (stop || !host->claimed || host->claimer == current) | 1042 | if (stop || !host->claimed || mmc_ctx_matches(host, ctx, task)) |
860 | break; | 1043 | break; |
861 | spin_unlock_irqrestore(&host->lock, flags); | 1044 | spin_unlock_irqrestore(&host->lock, flags); |
862 | schedule(); | 1045 | schedule(); |
@@ -865,7 +1048,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort) | |||
865 | set_current_state(TASK_RUNNING); | 1048 | set_current_state(TASK_RUNNING); |
866 | if (!stop) { | 1049 | if (!stop) { |
867 | host->claimed = 1; | 1050 | host->claimed = 1; |
868 | host->claimer = current; | 1051 | mmc_ctx_set_claimer(host, ctx, task); |
869 | host->claim_cnt += 1; | 1052 | host->claim_cnt += 1; |
870 | if (host->claim_cnt == 1) | 1053 | if (host->claim_cnt == 1) |
871 | pm = true; | 1054 | pm = true; |
@@ -900,6 +1083,7 @@ void mmc_release_host(struct mmc_host *host) | |||
900 | spin_unlock_irqrestore(&host->lock, flags); | 1083 | spin_unlock_irqrestore(&host->lock, flags); |
901 | } else { | 1084 | } else { |
902 | host->claimed = 0; | 1085 | host->claimed = 0; |
1086 | host->claimer->task = NULL; | ||
903 | host->claimer = NULL; | 1087 | host->claimer = NULL; |
904 | spin_unlock_irqrestore(&host->lock, flags); | 1088 | spin_unlock_irqrestore(&host->lock, flags); |
905 | wake_up(&host->wq); | 1089 | wake_up(&host->wq); |
@@ -913,10 +1097,10 @@ EXPORT_SYMBOL(mmc_release_host); | |||
913 | * This is a helper function, which fetches a runtime pm reference for the | 1097 | * This is a helper function, which fetches a runtime pm reference for the |
914 | * card device and also claims the host. | 1098 | * card device and also claims the host. |
915 | */ | 1099 | */ |
916 | void mmc_get_card(struct mmc_card *card) | 1100 | void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx) |
917 | { | 1101 | { |
918 | pm_runtime_get_sync(&card->dev); | 1102 | pm_runtime_get_sync(&card->dev); |
919 | mmc_claim_host(card->host); | 1103 | __mmc_claim_host(card->host, ctx, NULL); |
920 | } | 1104 | } |
921 | EXPORT_SYMBOL(mmc_get_card); | 1105 | EXPORT_SYMBOL(mmc_get_card); |
922 | 1106 | ||
@@ -924,9 +1108,13 @@ EXPORT_SYMBOL(mmc_get_card); | |||
924 | * This is a helper function, which releases the host and drops the runtime | 1108 | * This is a helper function, which releases the host and drops the runtime |
925 | * pm reference for the card device. | 1109 | * pm reference for the card device. |
926 | */ | 1110 | */ |
927 | void mmc_put_card(struct mmc_card *card) | 1111 | void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx) |
928 | { | 1112 | { |
929 | mmc_release_host(card->host); | 1113 | struct mmc_host *host = card->host; |
1114 | |||
1115 | WARN_ON(ctx && host->claimer != ctx); | ||
1116 | |||
1117 | mmc_release_host(host); | ||
930 | pm_runtime_mark_last_busy(&card->dev); | 1118 | pm_runtime_mark_last_busy(&card->dev); |
931 | pm_runtime_put_autosuspend(&card->dev); | 1119 | pm_runtime_put_autosuspend(&card->dev); |
932 | } | 1120 | } |
@@ -1400,6 +1588,16 @@ EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc); | |||
1400 | 1588 | ||
1401 | #endif /* CONFIG_REGULATOR */ | 1589 | #endif /* CONFIG_REGULATOR */ |
1402 | 1590 | ||
1591 | /** | ||
1592 | * mmc_regulator_get_supply - try to get VMMC and VQMMC regulators for a host | ||
1593 | * @mmc: the host to regulate | ||
1594 | * | ||
1595 | * Returns 0 or errno. errno should be handled, it is either a critical error | ||
1596 | * or -EPROBE_DEFER. 0 means no critical error but it does not mean all | ||
1597 | * regulators have been found because they all are optional. If you require | ||
1598 | * certain regulators, you need to check separately in your driver if they got | ||
1599 | * populated after calling this function. | ||
1600 | */ | ||
1403 | int mmc_regulator_get_supply(struct mmc_host *mmc) | 1601 | int mmc_regulator_get_supply(struct mmc_host *mmc) |
1404 | { | 1602 | { |
1405 | struct device *dev = mmc_dev(mmc); | 1603 | struct device *dev = mmc_dev(mmc); |
@@ -1484,11 +1682,33 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) | |||
1484 | 1682 | ||
1485 | } | 1683 | } |
1486 | 1684 | ||
1685 | int mmc_host_set_uhs_voltage(struct mmc_host *host) | ||
1686 | { | ||
1687 | u32 clock; | ||
1688 | |||
1689 | /* | ||
1690 | * During a signal voltage level switch, the clock must be gated | ||
1691 | * for 5 ms according to the SD spec | ||
1692 | */ | ||
1693 | clock = host->ios.clock; | ||
1694 | host->ios.clock = 0; | ||
1695 | mmc_set_ios(host); | ||
1696 | |||
1697 | if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) | ||
1698 | return -EAGAIN; | ||
1699 | |||
1700 | /* Keep clock gated for at least 10 ms, though spec only says 5 ms */ | ||
1701 | mmc_delay(10); | ||
1702 | host->ios.clock = clock; | ||
1703 | mmc_set_ios(host); | ||
1704 | |||
1705 | return 0; | ||
1706 | } | ||
1707 | |||
1487 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr) | 1708 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr) |
1488 | { | 1709 | { |
1489 | struct mmc_command cmd = {}; | 1710 | struct mmc_command cmd = {}; |
1490 | int err = 0; | 1711 | int err = 0; |
1491 | u32 clock; | ||
1492 | 1712 | ||
1493 | /* | 1713 | /* |
1494 | * If we cannot switch voltages, return failure so the caller | 1714 | * If we cannot switch voltages, return failure so the caller |
@@ -1520,15 +1740,8 @@ int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr) | |||
1520 | err = -EAGAIN; | 1740 | err = -EAGAIN; |
1521 | goto power_cycle; | 1741 | goto power_cycle; |
1522 | } | 1742 | } |
1523 | /* | ||
1524 | * During a signal voltage level switch, the clock must be gated | ||
1525 | * for 5 ms according to the SD spec | ||
1526 | */ | ||
1527 | clock = host->ios.clock; | ||
1528 | host->ios.clock = 0; | ||
1529 | mmc_set_ios(host); | ||
1530 | 1743 | ||
1531 | if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) { | 1744 | if (mmc_host_set_uhs_voltage(host)) { |
1532 | /* | 1745 | /* |
1533 | * Voltages may not have been switched, but we've already | 1746 | * Voltages may not have been switched, but we've already |
1534 | * sent CMD11, so a power cycle is required anyway | 1747 | * sent CMD11, so a power cycle is required anyway |
@@ -1537,11 +1750,6 @@ int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr) | |||
1537 | goto power_cycle; | 1750 | goto power_cycle; |
1538 | } | 1751 | } |
1539 | 1752 | ||
1540 | /* Keep clock gated for at least 10 ms, though spec only says 5 ms */ | ||
1541 | mmc_delay(10); | ||
1542 | host->ios.clock = clock; | ||
1543 | mmc_set_ios(host); | ||
1544 | |||
1545 | /* Wait for at least 1 ms according to spec */ | 1753 | /* Wait for at least 1 ms according to spec */ |
1546 | mmc_delay(1); | 1754 | mmc_delay(1); |
1547 | 1755 | ||
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index ca861091a776..71e6c6d7ceb7 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -49,6 +49,7 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); | |||
49 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width); | 49 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width); |
50 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | 50 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); |
51 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); | 51 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); |
52 | int mmc_host_set_uhs_voltage(struct mmc_host *host); | ||
52 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); | 53 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); |
53 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | 54 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); |
54 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); | 55 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); |
@@ -107,6 +108,8 @@ static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { } | |||
107 | void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq); | 108 | void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq); |
108 | bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq); | 109 | bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq); |
109 | 110 | ||
111 | int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq); | ||
112 | |||
110 | struct mmc_async_req; | 113 | struct mmc_async_req; |
111 | 114 | ||
112 | struct mmc_async_req *mmc_start_areq(struct mmc_host *host, | 115 | struct mmc_async_req *mmc_start_areq(struct mmc_host *host, |
@@ -128,10 +131,11 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); | |||
128 | int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, | 131 | int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, |
129 | bool is_rel_write); | 132 | bool is_rel_write); |
130 | 133 | ||
131 | int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); | 134 | int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx, |
135 | atomic_t *abort); | ||
132 | void mmc_release_host(struct mmc_host *host); | 136 | void mmc_release_host(struct mmc_host *host); |
133 | void mmc_get_card(struct mmc_card *card); | 137 | void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx); |
134 | void mmc_put_card(struct mmc_card *card); | 138 | void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx); |
135 | 139 | ||
136 | /** | 140 | /** |
137 | * mmc_claim_host - exclusively claim a host | 141 | * mmc_claim_host - exclusively claim a host |
@@ -141,7 +145,11 @@ void mmc_put_card(struct mmc_card *card); | |||
141 | */ | 145 | */ |
142 | static inline void mmc_claim_host(struct mmc_host *host) | 146 | static inline void mmc_claim_host(struct mmc_host *host) |
143 | { | 147 | { |
144 | __mmc_claim_host(host, NULL); | 148 | __mmc_claim_host(host, NULL, NULL); |
145 | } | 149 | } |
146 | 150 | ||
151 | int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq); | ||
152 | void mmc_cqe_post_req(struct mmc_host *host, struct mmc_request *mrq); | ||
153 | int mmc_cqe_recovery(struct mmc_host *host); | ||
154 | |||
147 | #endif | 155 | #endif |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index ad88deb2e8f3..35a9e4fd1a9f 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -111,12 +111,6 @@ void mmc_retune_hold(struct mmc_host *host) | |||
111 | host->hold_retune += 1; | 111 | host->hold_retune += 1; |
112 | } | 112 | } |
113 | 113 | ||
114 | void mmc_retune_hold_now(struct mmc_host *host) | ||
115 | { | ||
116 | host->retune_now = 0; | ||
117 | host->hold_retune += 1; | ||
118 | } | ||
119 | |||
120 | void mmc_retune_release(struct mmc_host *host) | 114 | void mmc_retune_release(struct mmc_host *host) |
121 | { | 115 | { |
122 | if (host->hold_retune) | 116 | if (host->hold_retune) |
@@ -124,6 +118,7 @@ void mmc_retune_release(struct mmc_host *host) | |||
124 | else | 118 | else |
125 | WARN_ON(1); | 119 | WARN_ON(1); |
126 | } | 120 | } |
121 | EXPORT_SYMBOL(mmc_retune_release); | ||
127 | 122 | ||
128 | int mmc_retune(struct mmc_host *host) | 123 | int mmc_retune(struct mmc_host *host) |
129 | { | 124 | { |
@@ -184,7 +179,7 @@ static void mmc_retune_timer(unsigned long data) | |||
184 | int mmc_of_parse(struct mmc_host *host) | 179 | int mmc_of_parse(struct mmc_host *host) |
185 | { | 180 | { |
186 | struct device *dev = host->parent; | 181 | struct device *dev = host->parent; |
187 | u32 bus_width; | 182 | u32 bus_width, drv_type; |
188 | int ret; | 183 | int ret; |
189 | bool cd_cap_invert, cd_gpio_invert = false; | 184 | bool cd_cap_invert, cd_gpio_invert = false; |
190 | bool ro_cap_invert, ro_gpio_invert = false; | 185 | bool ro_cap_invert, ro_gpio_invert = false; |
@@ -326,6 +321,15 @@ int mmc_of_parse(struct mmc_host *host) | |||
326 | if (device_property_read_bool(dev, "no-mmc")) | 321 | if (device_property_read_bool(dev, "no-mmc")) |
327 | host->caps2 |= MMC_CAP2_NO_MMC; | 322 | host->caps2 |= MMC_CAP2_NO_MMC; |
328 | 323 | ||
324 | /* Must be after "non-removable" check */ | ||
325 | if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) { | ||
326 | if (host->caps & MMC_CAP_NONREMOVABLE) | ||
327 | host->fixed_drv_type = drv_type; | ||
328 | else | ||
329 | dev_err(host->parent, | ||
330 | "can't use fixed driver type, media is removable\n"); | ||
331 | } | ||
332 | |||
329 | host->dsr_req = !device_property_read_u32(dev, "dsr", &host->dsr); | 333 | host->dsr_req = !device_property_read_u32(dev, "dsr", &host->dsr); |
330 | if (host->dsr_req && (host->dsr & ~0xffff)) { | 334 | if (host->dsr_req && (host->dsr & ~0xffff)) { |
331 | dev_err(host->parent, | 335 | dev_err(host->parent, |
@@ -398,6 +402,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
398 | host->max_blk_size = 512; | 402 | host->max_blk_size = 512; |
399 | host->max_blk_count = PAGE_SIZE / 512; | 403 | host->max_blk_count = PAGE_SIZE / 512; |
400 | 404 | ||
405 | host->fixed_drv_type = -EINVAL; | ||
406 | |||
401 | return host; | 407 | return host; |
402 | } | 408 | } |
403 | 409 | ||
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 77d6f60d1bf9..fb689a1065ed 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h | |||
@@ -19,12 +19,17 @@ void mmc_unregister_host_class(void); | |||
19 | void mmc_retune_enable(struct mmc_host *host); | 19 | void mmc_retune_enable(struct mmc_host *host); |
20 | void mmc_retune_disable(struct mmc_host *host); | 20 | void mmc_retune_disable(struct mmc_host *host); |
21 | void mmc_retune_hold(struct mmc_host *host); | 21 | void mmc_retune_hold(struct mmc_host *host); |
22 | void mmc_retune_hold_now(struct mmc_host *host); | ||
23 | void mmc_retune_release(struct mmc_host *host); | 22 | void mmc_retune_release(struct mmc_host *host); |
24 | int mmc_retune(struct mmc_host *host); | 23 | int mmc_retune(struct mmc_host *host); |
25 | void mmc_retune_pause(struct mmc_host *host); | 24 | void mmc_retune_pause(struct mmc_host *host); |
26 | void mmc_retune_unpause(struct mmc_host *host); | 25 | void mmc_retune_unpause(struct mmc_host *host); |
27 | 26 | ||
27 | static inline void mmc_retune_hold_now(struct mmc_host *host) | ||
28 | { | ||
29 | host->retune_now = 0; | ||
30 | host->hold_retune += 1; | ||
31 | } | ||
32 | |||
28 | static inline void mmc_retune_recheck(struct mmc_host *host) | 33 | static inline void mmc_retune_recheck(struct mmc_host *host) |
29 | { | 34 | { |
30 | if (host->hold_retune <= 1) | 35 | if (host->hold_retune <= 1) |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 36217ad5e9b1..a552f61060d2 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -780,6 +780,7 @@ MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | |||
780 | MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); | 780 | MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); |
781 | MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); | 781 | MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); |
782 | MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); | 782 | MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); |
783 | MMC_DEV_ATTR(rev, "0x%x\n", card->ext_csd.rev); | ||
783 | MMC_DEV_ATTR(pre_eol_info, "%02x\n", card->ext_csd.pre_eol_info); | 784 | MMC_DEV_ATTR(pre_eol_info, "%02x\n", card->ext_csd.pre_eol_info); |
784 | MMC_DEV_ATTR(life_time, "0x%02x 0x%02x\n", | 785 | MMC_DEV_ATTR(life_time, "0x%02x 0x%02x\n", |
785 | card->ext_csd.device_life_time_est_typ_a, | 786 | card->ext_csd.device_life_time_est_typ_a, |
@@ -838,6 +839,7 @@ static struct attribute *mmc_std_attrs[] = { | |||
838 | &dev_attr_name.attr, | 839 | &dev_attr_name.attr, |
839 | &dev_attr_oemid.attr, | 840 | &dev_attr_oemid.attr, |
840 | &dev_attr_prv.attr, | 841 | &dev_attr_prv.attr, |
842 | &dev_attr_rev.attr, | ||
841 | &dev_attr_pre_eol_info.attr, | 843 | &dev_attr_pre_eol_info.attr, |
842 | &dev_attr_life_time.attr, | 844 | &dev_attr_life_time.attr, |
843 | &dev_attr_serial.attr, | 845 | &dev_attr_serial.attr, |
@@ -1289,13 +1291,18 @@ out_err: | |||
1289 | static void mmc_select_driver_type(struct mmc_card *card) | 1291 | static void mmc_select_driver_type(struct mmc_card *card) |
1290 | { | 1292 | { |
1291 | int card_drv_type, drive_strength, drv_type; | 1293 | int card_drv_type, drive_strength, drv_type; |
1294 | int fixed_drv_type = card->host->fixed_drv_type; | ||
1292 | 1295 | ||
1293 | card_drv_type = card->ext_csd.raw_driver_strength | | 1296 | card_drv_type = card->ext_csd.raw_driver_strength | |
1294 | mmc_driver_type_mask(0); | 1297 | mmc_driver_type_mask(0); |
1295 | 1298 | ||
1296 | drive_strength = mmc_select_drive_strength(card, | 1299 | if (fixed_drv_type >= 0) |
1297 | card->ext_csd.hs200_max_dtr, | 1300 | drive_strength = card_drv_type & mmc_driver_type_mask(fixed_drv_type) |
1298 | card_drv_type, &drv_type); | 1301 | ? fixed_drv_type : 0; |
1302 | else | ||
1303 | drive_strength = mmc_select_drive_strength(card, | ||
1304 | card->ext_csd.hs200_max_dtr, | ||
1305 | card_drv_type, &drv_type); | ||
1299 | 1306 | ||
1300 | card->drive_strength = drive_strength; | 1307 | card->drive_strength = drive_strength; |
1301 | 1308 | ||
@@ -1786,12 +1793,41 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1786 | } | 1793 | } |
1787 | 1794 | ||
1788 | /* | 1795 | /* |
1796 | * Enable Command Queue if supported. Note that Packed Commands cannot | ||
1797 | * be used with Command Queue. | ||
1798 | */ | ||
1799 | card->ext_csd.cmdq_en = false; | ||
1800 | if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) { | ||
1801 | err = mmc_cmdq_enable(card); | ||
1802 | if (err && err != -EBADMSG) | ||
1803 | goto free_card; | ||
1804 | if (err) { | ||
1805 | pr_warn("%s: Enabling CMDQ failed\n", | ||
1806 | mmc_hostname(card->host)); | ||
1807 | card->ext_csd.cmdq_support = false; | ||
1808 | card->ext_csd.cmdq_depth = 0; | ||
1809 | err = 0; | ||
1810 | } | ||
1811 | } | ||
1812 | /* | ||
1789 | * In some cases (e.g. RPMB or mmc_test), the Command Queue must be | 1813 | * In some cases (e.g. RPMB or mmc_test), the Command Queue must be |
1790 | * disabled for a time, so a flag is needed to indicate to re-enable the | 1814 | * disabled for a time, so a flag is needed to indicate to re-enable the |
1791 | * Command Queue. | 1815 | * Command Queue. |
1792 | */ | 1816 | */ |
1793 | card->reenable_cmdq = card->ext_csd.cmdq_en; | 1817 | card->reenable_cmdq = card->ext_csd.cmdq_en; |
1794 | 1818 | ||
1819 | if (card->ext_csd.cmdq_en && !host->cqe_enabled) { | ||
1820 | err = host->cqe_ops->cqe_enable(host, card); | ||
1821 | if (err) { | ||
1822 | pr_err("%s: Failed to enable CQE, error %d\n", | ||
1823 | mmc_hostname(host), err); | ||
1824 | } else { | ||
1825 | host->cqe_enabled = true; | ||
1826 | pr_info("%s: Command Queue Engine enabled\n", | ||
1827 | mmc_hostname(host)); | ||
1828 | } | ||
1829 | } | ||
1830 | |||
1795 | if (!oldcard) | 1831 | if (!oldcard) |
1796 | host->card = card; | 1832 | host->card = card; |
1797 | 1833 | ||
@@ -1911,14 +1947,14 @@ static void mmc_detect(struct mmc_host *host) | |||
1911 | { | 1947 | { |
1912 | int err; | 1948 | int err; |
1913 | 1949 | ||
1914 | mmc_get_card(host->card); | 1950 | mmc_get_card(host->card, NULL); |
1915 | 1951 | ||
1916 | /* | 1952 | /* |
1917 | * Just check if our card has been removed. | 1953 | * Just check if our card has been removed. |
1918 | */ | 1954 | */ |
1919 | err = _mmc_detect_card_removed(host); | 1955 | err = _mmc_detect_card_removed(host); |
1920 | 1956 | ||
1921 | mmc_put_card(host->card); | 1957 | mmc_put_card(host->card, NULL); |
1922 | 1958 | ||
1923 | if (err) { | 1959 | if (err) { |
1924 | mmc_remove(host); | 1960 | mmc_remove(host); |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 54686ca4bfb7..908e4db03535 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -977,7 +977,6 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) | |||
977 | from_exception) | 977 | from_exception) |
978 | return; | 978 | return; |
979 | 979 | ||
980 | mmc_claim_host(card->host); | ||
981 | if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) { | 980 | if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) { |
982 | timeout = MMC_OPS_TIMEOUT_MS; | 981 | timeout = MMC_OPS_TIMEOUT_MS; |
983 | use_busy_signal = true; | 982 | use_busy_signal = true; |
@@ -995,7 +994,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) | |||
995 | pr_warn("%s: Error %d starting bkops\n", | 994 | pr_warn("%s: Error %d starting bkops\n", |
996 | mmc_hostname(card->host), err); | 995 | mmc_hostname(card->host), err); |
997 | mmc_retune_release(card->host); | 996 | mmc_retune_release(card->host); |
998 | goto out; | 997 | return; |
999 | } | 998 | } |
1000 | 999 | ||
1001 | /* | 1000 | /* |
@@ -1007,9 +1006,8 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) | |||
1007 | mmc_card_set_doing_bkops(card); | 1006 | mmc_card_set_doing_bkops(card); |
1008 | else | 1007 | else |
1009 | mmc_retune_release(card->host); | 1008 | mmc_retune_release(card->host); |
1010 | out: | ||
1011 | mmc_release_host(card->host); | ||
1012 | } | 1009 | } |
1010 | EXPORT_SYMBOL(mmc_start_bkops); | ||
1013 | 1011 | ||
1014 | /* | 1012 | /* |
1015 | * Flush the cache to the non-volatile storage. | 1013 | * Flush the cache to the non-volatile storage. |
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 0a4e77a5ba33..4f33d277b125 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c | |||
@@ -30,7 +30,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
30 | { | 30 | { |
31 | struct mmc_queue *mq = q->queuedata; | 31 | struct mmc_queue *mq = q->queuedata; |
32 | 32 | ||
33 | if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq))) | 33 | if (mq && mmc_card_removed(mq->card)) |
34 | return BLKPREP_KILL; | 34 | return BLKPREP_KILL; |
35 | 35 | ||
36 | req->rq_flags |= RQF_DONTPREP; | 36 | req->rq_flags |= RQF_DONTPREP; |
@@ -177,6 +177,29 @@ static void mmc_exit_request(struct request_queue *q, struct request *req) | |||
177 | mq_rq->sg = NULL; | 177 | mq_rq->sg = NULL; |
178 | } | 178 | } |
179 | 179 | ||
180 | static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card) | ||
181 | { | ||
182 | struct mmc_host *host = card->host; | ||
183 | u64 limit = BLK_BOUNCE_HIGH; | ||
184 | |||
185 | if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) | ||
186 | limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; | ||
187 | |||
188 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); | ||
189 | queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue); | ||
190 | if (mmc_can_erase(card)) | ||
191 | mmc_queue_setup_discard(mq->queue, card); | ||
192 | |||
193 | blk_queue_bounce_limit(mq->queue, limit); | ||
194 | blk_queue_max_hw_sectors(mq->queue, | ||
195 | min(host->max_blk_count, host->max_req_size / 512)); | ||
196 | blk_queue_max_segments(mq->queue, host->max_segs); | ||
197 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); | ||
198 | |||
199 | /* Initialize thread_sem even if it is not used */ | ||
200 | sema_init(&mq->thread_sem, 1); | ||
201 | } | ||
202 | |||
180 | /** | 203 | /** |
181 | * mmc_init_queue - initialise a queue structure. | 204 | * mmc_init_queue - initialise a queue structure. |
182 | * @mq: mmc queue | 205 | * @mq: mmc queue |
@@ -190,12 +213,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, | |||
190 | spinlock_t *lock, const char *subname) | 213 | spinlock_t *lock, const char *subname) |
191 | { | 214 | { |
192 | struct mmc_host *host = card->host; | 215 | struct mmc_host *host = card->host; |
193 | u64 limit = BLK_BOUNCE_HIGH; | ||
194 | int ret = -ENOMEM; | 216 | int ret = -ENOMEM; |
195 | 217 | ||
196 | if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) | ||
197 | limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; | ||
198 | |||
199 | mq->card = card; | 218 | mq->card = card; |
200 | mq->queue = blk_alloc_queue(GFP_KERNEL); | 219 | mq->queue = blk_alloc_queue(GFP_KERNEL); |
201 | if (!mq->queue) | 220 | if (!mq->queue) |
@@ -214,18 +233,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, | |||
214 | } | 233 | } |
215 | 234 | ||
216 | blk_queue_prep_rq(mq->queue, mmc_prep_request); | 235 | blk_queue_prep_rq(mq->queue, mmc_prep_request); |
217 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); | ||
218 | queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue); | ||
219 | if (mmc_can_erase(card)) | ||
220 | mmc_queue_setup_discard(mq->queue, card); | ||
221 | 236 | ||
222 | blk_queue_bounce_limit(mq->queue, limit); | 237 | mmc_setup_queue(mq, card); |
223 | blk_queue_max_hw_sectors(mq->queue, | ||
224 | min(host->max_blk_count, host->max_req_size / 512)); | ||
225 | blk_queue_max_segments(mq->queue, host->max_segs); | ||
226 | blk_queue_max_segment_size(mq->queue, host->max_seg_size); | ||
227 | |||
228 | sema_init(&mq->thread_sem, 1); | ||
229 | 238 | ||
230 | mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s", | 239 | mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s", |
231 | host->index, subname ? subname : ""); | 240 | host->index, subname ? subname : ""); |
diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index 6bfba32ffa66..547b457c4251 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h | |||
@@ -36,12 +36,14 @@ struct mmc_blk_request { | |||
36 | /** | 36 | /** |
37 | * enum mmc_drv_op - enumerates the operations in the mmc_queue_req | 37 | * enum mmc_drv_op - enumerates the operations in the mmc_queue_req |
38 | * @MMC_DRV_OP_IOCTL: ioctl operation | 38 | * @MMC_DRV_OP_IOCTL: ioctl operation |
39 | * @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation | ||
39 | * @MMC_DRV_OP_BOOT_WP: write protect boot partitions | 40 | * @MMC_DRV_OP_BOOT_WP: write protect boot partitions |
40 | * @MMC_DRV_OP_GET_CARD_STATUS: get card status | 41 | * @MMC_DRV_OP_GET_CARD_STATUS: get card status |
41 | * @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card | 42 | * @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card |
42 | */ | 43 | */ |
43 | enum mmc_drv_op { | 44 | enum mmc_drv_op { |
44 | MMC_DRV_OP_IOCTL, | 45 | MMC_DRV_OP_IOCTL, |
46 | MMC_DRV_OP_IOCTL_RPMB, | ||
45 | MMC_DRV_OP_BOOT_WP, | 47 | MMC_DRV_OP_BOOT_WP, |
46 | MMC_DRV_OP_GET_CARD_STATUS, | 48 | MMC_DRV_OP_GET_CARD_STATUS, |
47 | MMC_DRV_OP_GET_EXT_CSD, | 49 | MMC_DRV_OP_GET_EXT_CSD, |
@@ -82,6 +84,4 @@ extern void mmc_queue_resume(struct mmc_queue *); | |||
82 | extern unsigned int mmc_queue_map_sg(struct mmc_queue *, | 84 | extern unsigned int mmc_queue_map_sg(struct mmc_queue *, |
83 | struct mmc_queue_req *); | 85 | struct mmc_queue_req *); |
84 | 86 | ||
85 | extern int mmc_access_rpmb(struct mmc_queue *); | ||
86 | |||
87 | #endif | 87 | #endif |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 4fd1620b732d..45bf78f32716 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -908,6 +908,18 @@ unsigned mmc_sd_get_max_clock(struct mmc_card *card) | |||
908 | return max_dtr; | 908 | return max_dtr; |
909 | } | 909 | } |
910 | 910 | ||
911 | static bool mmc_sd_card_using_v18(struct mmc_card *card) | ||
912 | { | ||
913 | /* | ||
914 | * According to the SD spec., the Bus Speed Mode (function group 1) bits | ||
915 | * 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus | ||
916 | * they can be used to determine if the card has already switched to | ||
917 | * 1.8V signaling. | ||
918 | */ | ||
919 | return card->sw_caps.sd3_bus_mode & | ||
920 | (SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50); | ||
921 | } | ||
922 | |||
911 | /* | 923 | /* |
912 | * Handle the detection and initialisation of a card. | 924 | * Handle the detection and initialisation of a card. |
913 | * | 925 | * |
@@ -921,9 +933,10 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
921 | int err; | 933 | int err; |
922 | u32 cid[4]; | 934 | u32 cid[4]; |
923 | u32 rocr = 0; | 935 | u32 rocr = 0; |
936 | bool v18_fixup_failed = false; | ||
924 | 937 | ||
925 | WARN_ON(!host->claimed); | 938 | WARN_ON(!host->claimed); |
926 | 939 | retry: | |
927 | err = mmc_sd_get_cid(host, ocr, cid, &rocr); | 940 | err = mmc_sd_get_cid(host, ocr, cid, &rocr); |
928 | if (err) | 941 | if (err) |
929 | return err; | 942 | return err; |
@@ -989,6 +1002,36 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
989 | if (err) | 1002 | if (err) |
990 | goto free_card; | 1003 | goto free_card; |
991 | 1004 | ||
1005 | /* | ||
1006 | * If the card has not been power cycled, it may still be using 1.8V | ||
1007 | * signaling. Detect that situation and try to initialize a UHS-I (1.8V) | ||
1008 | * transfer mode. | ||
1009 | */ | ||
1010 | if (!v18_fixup_failed && !mmc_host_is_spi(host) && mmc_host_uhs(host) && | ||
1011 | mmc_sd_card_using_v18(card) && | ||
1012 | host->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_180) { | ||
1013 | /* | ||
1014 | * Re-read switch information in case it has changed since | ||
1015 | * oldcard was initialized. | ||
1016 | */ | ||
1017 | if (oldcard) { | ||
1018 | err = mmc_read_switch(card); | ||
1019 | if (err) | ||
1020 | goto free_card; | ||
1021 | } | ||
1022 | if (mmc_sd_card_using_v18(card)) { | ||
1023 | if (mmc_host_set_uhs_voltage(host) || | ||
1024 | mmc_sd_init_uhs_card(card)) { | ||
1025 | v18_fixup_failed = true; | ||
1026 | mmc_power_cycle(host, ocr); | ||
1027 | if (!oldcard) | ||
1028 | mmc_remove_card(card); | ||
1029 | goto retry; | ||
1030 | } | ||
1031 | goto done; | ||
1032 | } | ||
1033 | } | ||
1034 | |||
992 | /* Initialization sequence for UHS-I cards */ | 1035 | /* Initialization sequence for UHS-I cards */ |
993 | if (rocr & SD_ROCR_S18A) { | 1036 | if (rocr & SD_ROCR_S18A) { |
994 | err = mmc_sd_init_uhs_card(card); | 1037 | err = mmc_sd_init_uhs_card(card); |
@@ -1021,7 +1064,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
1021 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); | 1064 | mmc_set_bus_width(host, MMC_BUS_WIDTH_4); |
1022 | } | 1065 | } |
1023 | } | 1066 | } |
1024 | 1067 | done: | |
1025 | host->card = card; | 1068 | host->card = card; |
1026 | return 0; | 1069 | return 0; |
1027 | 1070 | ||
@@ -1056,14 +1099,14 @@ static void mmc_sd_detect(struct mmc_host *host) | |||
1056 | { | 1099 | { |
1057 | int err; | 1100 | int err; |
1058 | 1101 | ||
1059 | mmc_get_card(host->card); | 1102 | mmc_get_card(host->card, NULL); |
1060 | 1103 | ||
1061 | /* | 1104 | /* |
1062 | * Just check if our card has been removed. | 1105 | * Just check if our card has been removed. |
1063 | */ | 1106 | */ |
1064 | err = _mmc_detect_card_removed(host); | 1107 | err = _mmc_detect_card_removed(host); |
1065 | 1108 | ||
1066 | mmc_put_card(host->card); | 1109 | mmc_put_card(host->card, NULL); |
1067 | 1110 | ||
1068 | if (err) { | 1111 | if (err) { |
1069 | mmc_sd_remove(host); | 1112 | mmc_sd_remove(host); |
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index c771843e4c15..7a2eaf8410a3 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c | |||
@@ -155,7 +155,8 @@ static int sdio_irq_thread(void *_host) | |||
155 | * holding of the host lock does not cover too much work | 155 | * holding of the host lock does not cover too much work |
156 | * that doesn't require that lock to be held. | 156 | * that doesn't require that lock to be held. |
157 | */ | 157 | */ |
158 | ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort); | 158 | ret = __mmc_claim_host(host, NULL, |
159 | &host->sdio_irq_thread_abort); | ||
159 | if (ret) | 160 | if (ret) |
160 | break; | 161 | break; |
161 | ret = process_sdio_pending_irqs(host); | 162 | ret = process_sdio_pending_irqs(host); |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 8c15637178ff..567028c9219a 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -352,6 +352,19 @@ config MMC_MESON_GX | |||
352 | 352 | ||
353 | If you have a controller with this interface, say Y here. | 353 | If you have a controller with this interface, say Y here. |
354 | 354 | ||
355 | config MMC_MESON_MX_SDIO | ||
356 | tristate "Amlogic Meson6/Meson8/Meson8b SD/MMC Host Controller support" | ||
357 | depends on ARCH_MESON || COMPILE_TEST | ||
358 | depends on COMMON_CLK | ||
359 | depends on HAS_DMA | ||
360 | depends on OF | ||
361 | help | ||
362 | This selects support for the SD/MMC Host Controller on | ||
363 | Amlogic Meson6, Meson8 and Meson8b SoCs. | ||
364 | |||
365 | If you have a controller with this interface, say Y or M here. | ||
366 | If unsure, say N. | ||
367 | |||
355 | config MMC_MOXART | 368 | config MMC_MOXART |
356 | tristate "MOXART SD/MMC Host Controller support" | 369 | tristate "MOXART SD/MMC Host Controller support" |
357 | depends on ARCH_MOXART && MMC | 370 | depends on ARCH_MOXART && MMC |
@@ -429,6 +442,7 @@ config MMC_SDHCI_MSM | |||
429 | tristate "Qualcomm SDHCI Controller Support" | 442 | tristate "Qualcomm SDHCI Controller Support" |
430 | depends on ARCH_QCOM || (ARM && COMPILE_TEST) | 443 | depends on ARCH_QCOM || (ARM && COMPILE_TEST) |
431 | depends on MMC_SDHCI_PLTFM | 444 | depends on MMC_SDHCI_PLTFM |
445 | select MMC_SDHCI_IO_ACCESSORS | ||
432 | help | 446 | help |
433 | This selects the Secure Digital Host Controller Interface (SDHCI) | 447 | This selects the Secure Digital Host Controller Interface (SDHCI) |
434 | support present in Qualcomm SOCs. The controller supports | 448 | support present in Qualcomm SOCs. The controller supports |
@@ -663,7 +677,7 @@ config MMC_CAVIUM_OCTEON | |||
663 | config MMC_CAVIUM_THUNDERX | 677 | config MMC_CAVIUM_THUNDERX |
664 | tristate "Cavium ThunderX SD/MMC Card Interface support" | 678 | tristate "Cavium ThunderX SD/MMC Card Interface support" |
665 | depends on PCI && 64BIT && (ARM64 || COMPILE_TEST) | 679 | depends on PCI && 64BIT && (ARM64 || COMPILE_TEST) |
666 | depends on GPIOLIB | 680 | depends on GPIO_THUNDERX |
667 | depends on OF_ADDRESS | 681 | depends on OF_ADDRESS |
668 | help | 682 | help |
669 | This selects Cavium ThunderX SD/MMC Card Interface. | 683 | This selects Cavium ThunderX SD/MMC Card Interface. |
@@ -899,3 +913,15 @@ config MMC_SDHCI_XENON | |||
899 | This selects Marvell Xenon eMMC/SD/SDIO SDHCI. | 913 | This selects Marvell Xenon eMMC/SD/SDIO SDHCI. |
900 | If you have a controller with this interface, say Y or M here. | 914 | If you have a controller with this interface, say Y or M here. |
901 | If unsure, say N. | 915 | If unsure, say N. |
916 | |||
917 | config MMC_SDHCI_OMAP | ||
918 | tristate "TI SDHCI Controller Support" | ||
919 | depends on MMC_SDHCI_PLTFM && OF | ||
920 | help | ||
921 | This selects the Secure Digital Host Controller Interface (SDHCI) | ||
922 | support present in TI's DRA7 SOCs. The controller supports | ||
923 | SD/MMC/SDIO devices. | ||
924 | |||
925 | If you have a controller with this interface, say Y or M here. | ||
926 | |||
927 | If unsure, say N. | ||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 7c7b29ff591a..a43cf0d5a5d3 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -65,6 +65,7 @@ obj-$(CONFIG_MMC_VUB300) += vub300.o | |||
65 | obj-$(CONFIG_MMC_USHC) += ushc.o | 65 | obj-$(CONFIG_MMC_USHC) += ushc.o |
66 | obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o | 66 | obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o |
67 | obj-$(CONFIG_MMC_MESON_GX) += meson-gx-mmc.o | 67 | obj-$(CONFIG_MMC_MESON_GX) += meson-gx-mmc.o |
68 | obj-$(CONFIG_MMC_MESON_MX_SDIO) += meson-mx-sdio.o | ||
68 | obj-$(CONFIG_MMC_MOXART) += moxart-mmc.o | 69 | obj-$(CONFIG_MMC_MOXART) += moxart-mmc.o |
69 | obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.o | 70 | obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.o |
70 | obj-$(CONFIG_MMC_USDHI6ROL0) += usdhi6rol0.o | 71 | obj-$(CONFIG_MMC_USDHI6ROL0) += usdhi6rol0.o |
@@ -90,6 +91,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o | |||
90 | obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o | 91 | obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o |
91 | obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o | 92 | obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o |
92 | obj-$(CONFIG_MMC_SDHCI_BRCMSTB) += sdhci-brcmstb.o | 93 | obj-$(CONFIG_MMC_SDHCI_BRCMSTB) += sdhci-brcmstb.o |
94 | obj-$(CONFIG_MMC_SDHCI_OMAP) += sdhci-omap.o | ||
93 | 95 | ||
94 | ifeq ($(CONFIG_CB710_DEBUG),y) | 96 | ifeq ($(CONFIG_CB710_DEBUG),y) |
95 | CFLAGS-cb710-mmc += -DDEBUG | 97 | CFLAGS-cb710-mmc += -DDEBUG |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 0a0ebf3a096d..e55f3932d580 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -732,11 +732,11 @@ static inline unsigned int atmci_convert_chksize(struct atmel_mci *host, | |||
732 | return 0; | 732 | return 0; |
733 | } | 733 | } |
734 | 734 | ||
735 | static void atmci_timeout_timer(unsigned long data) | 735 | static void atmci_timeout_timer(struct timer_list *t) |
736 | { | 736 | { |
737 | struct atmel_mci *host; | 737 | struct atmel_mci *host; |
738 | 738 | ||
739 | host = (struct atmel_mci *)data; | 739 | host = from_timer(host, t, timer); |
740 | 740 | ||
741 | dev_dbg(&host->pdev->dev, "software timeout\n"); | 741 | dev_dbg(&host->pdev->dev, "software timeout\n"); |
742 | 742 | ||
@@ -1661,9 +1661,9 @@ static void atmci_command_complete(struct atmel_mci *host, | |||
1661 | cmd->error = 0; | 1661 | cmd->error = 0; |
1662 | } | 1662 | } |
1663 | 1663 | ||
1664 | static void atmci_detect_change(unsigned long data) | 1664 | static void atmci_detect_change(struct timer_list *t) |
1665 | { | 1665 | { |
1666 | struct atmel_mci_slot *slot = (struct atmel_mci_slot *)data; | 1666 | struct atmel_mci_slot *slot = from_timer(slot, t, detect_timer); |
1667 | bool present; | 1667 | bool present; |
1668 | bool present_old; | 1668 | bool present_old; |
1669 | 1669 | ||
@@ -2349,8 +2349,7 @@ static int atmci_init_slot(struct atmel_mci *host, | |||
2349 | if (gpio_is_valid(slot->detect_pin)) { | 2349 | if (gpio_is_valid(slot->detect_pin)) { |
2350 | int ret; | 2350 | int ret; |
2351 | 2351 | ||
2352 | setup_timer(&slot->detect_timer, atmci_detect_change, | 2352 | timer_setup(&slot->detect_timer, atmci_detect_change, 0); |
2353 | (unsigned long)slot); | ||
2354 | 2353 | ||
2355 | ret = request_irq(gpio_to_irq(slot->detect_pin), | 2354 | ret = request_irq(gpio_to_irq(slot->detect_pin), |
2356 | atmci_detect_interrupt, | 2355 | atmci_detect_interrupt, |
@@ -2563,7 +2562,7 @@ static int atmci_probe(struct platform_device *pdev) | |||
2563 | 2562 | ||
2564 | platform_set_drvdata(pdev, host); | 2563 | platform_set_drvdata(pdev, host); |
2565 | 2564 | ||
2566 | setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); | 2565 | timer_setup(&host->timer, atmci_timeout_timer, 0); |
2567 | 2566 | ||
2568 | pm_runtime_get_noresume(&pdev->dev); | 2567 | pm_runtime_get_noresume(&pdev->dev); |
2569 | pm_runtime_set_active(&pdev->dev); | 2568 | pm_runtime_set_active(&pdev->dev); |
diff --git a/drivers/mmc/host/cavium.c b/drivers/mmc/host/cavium.c index fbd29f00fca0..ed5cefb83768 100644 --- a/drivers/mmc/host/cavium.c +++ b/drivers/mmc/host/cavium.c | |||
@@ -967,7 +967,7 @@ static int cvm_mmc_of_parse(struct device *dev, struct cvm_mmc_slot *slot) | |||
967 | } | 967 | } |
968 | 968 | ||
969 | ret = mmc_regulator_get_supply(mmc); | 969 | ret = mmc_regulator_get_supply(mmc); |
970 | if (ret == -EPROBE_DEFER) | 970 | if (ret) |
971 | return ret; | 971 | return ret; |
972 | /* | 972 | /* |
973 | * Legacy Octeon firmware has no regulator entry, fall-back to | 973 | * Legacy Octeon firmware has no regulator entry, fall-back to |
diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 64cda84b2302..73fd75c3c824 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c | |||
@@ -75,7 +75,7 @@ struct hs_timing { | |||
75 | u32 smpl_phase_min; | 75 | u32 smpl_phase_min; |
76 | }; | 76 | }; |
77 | 77 | ||
78 | struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = { | 78 | static struct hs_timing hs_timing_cfg[TIMING_MODE][TIMING_CFG_NUM] = { |
79 | { /* reserved */ }, | 79 | { /* reserved */ }, |
80 | { /* SD */ | 80 | { /* SD */ |
81 | {7, 0, 15, 15,}, /* 0: LEGACY 400k */ | 81 | {7, 0, 15, 15,}, /* 0: LEGACY 400k */ |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4f2806720c5c..0aa39975f33b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -817,7 +817,7 @@ static int dw_mci_edmac_start_dma(struct dw_mci *host, | |||
817 | struct dma_slave_config cfg; | 817 | struct dma_slave_config cfg; |
818 | struct dma_async_tx_descriptor *desc = NULL; | 818 | struct dma_async_tx_descriptor *desc = NULL; |
819 | struct scatterlist *sgl = host->data->sg; | 819 | struct scatterlist *sgl = host->data->sg; |
820 | const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256}; | 820 | static const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256}; |
821 | u32 sg_elems = host->data->sg_len; | 821 | u32 sg_elems = host->data->sg_len; |
822 | u32 fifoth_val; | 822 | u32 fifoth_val; |
823 | u32 fifo_offset = host->fifo_reg - host->regs; | 823 | u32 fifo_offset = host->fifo_reg - host->regs; |
@@ -1024,7 +1024,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
1024 | static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data) | 1024 | static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data) |
1025 | { | 1025 | { |
1026 | unsigned int blksz = data->blksz; | 1026 | unsigned int blksz = data->blksz; |
1027 | const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256}; | 1027 | static const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256}; |
1028 | u32 fifo_width = 1 << host->data_shift; | 1028 | u32 fifo_width = 1 << host->data_shift; |
1029 | u32 blksz_depth = blksz / fifo_width, fifoth_val; | 1029 | u32 blksz_depth = blksz / fifo_width, fifoth_val; |
1030 | u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers; | 1030 | u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers; |
@@ -1938,6 +1938,7 @@ static void dw_mci_set_drto(struct dw_mci *host) | |||
1938 | unsigned int drto_clks; | 1938 | unsigned int drto_clks; |
1939 | unsigned int drto_div; | 1939 | unsigned int drto_div; |
1940 | unsigned int drto_ms; | 1940 | unsigned int drto_ms; |
1941 | unsigned long irqflags; | ||
1941 | 1942 | ||
1942 | drto_clks = mci_readl(host, TMOUT) >> 8; | 1943 | drto_clks = mci_readl(host, TMOUT) >> 8; |
1943 | drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; | 1944 | drto_div = (mci_readl(host, CLKDIV) & 0xff) * 2; |
@@ -1949,7 +1950,11 @@ static void dw_mci_set_drto(struct dw_mci *host) | |||
1949 | /* add a bit spare time */ | 1950 | /* add a bit spare time */ |
1950 | drto_ms += 10; | 1951 | drto_ms += 10; |
1951 | 1952 | ||
1952 | mod_timer(&host->dto_timer, jiffies + msecs_to_jiffies(drto_ms)); | 1953 | spin_lock_irqsave(&host->irq_lock, irqflags); |
1954 | if (!test_bit(EVENT_DATA_COMPLETE, &host->pending_events)) | ||
1955 | mod_timer(&host->dto_timer, | ||
1956 | jiffies + msecs_to_jiffies(drto_ms)); | ||
1957 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
1953 | } | 1958 | } |
1954 | 1959 | ||
1955 | static bool dw_mci_clear_pending_cmd_complete(struct dw_mci *host) | 1960 | static bool dw_mci_clear_pending_cmd_complete(struct dw_mci *host) |
@@ -1970,6 +1975,18 @@ static bool dw_mci_clear_pending_cmd_complete(struct dw_mci *host) | |||
1970 | return true; | 1975 | return true; |
1971 | } | 1976 | } |
1972 | 1977 | ||
1978 | static bool dw_mci_clear_pending_data_complete(struct dw_mci *host) | ||
1979 | { | ||
1980 | if (!test_bit(EVENT_DATA_COMPLETE, &host->pending_events)) | ||
1981 | return false; | ||
1982 | |||
1983 | /* Extra paranoia just like dw_mci_clear_pending_cmd_complete() */ | ||
1984 | WARN_ON(del_timer_sync(&host->dto_timer)); | ||
1985 | clear_bit(EVENT_DATA_COMPLETE, &host->pending_events); | ||
1986 | |||
1987 | return true; | ||
1988 | } | ||
1989 | |||
1973 | static void dw_mci_tasklet_func(unsigned long priv) | 1990 | static void dw_mci_tasklet_func(unsigned long priv) |
1974 | { | 1991 | { |
1975 | struct dw_mci *host = (struct dw_mci *)priv; | 1992 | struct dw_mci *host = (struct dw_mci *)priv; |
@@ -2111,8 +2128,7 @@ static void dw_mci_tasklet_func(unsigned long priv) | |||
2111 | /* fall through */ | 2128 | /* fall through */ |
2112 | 2129 | ||
2113 | case STATE_DATA_BUSY: | 2130 | case STATE_DATA_BUSY: |
2114 | if (!test_and_clear_bit(EVENT_DATA_COMPLETE, | 2131 | if (!dw_mci_clear_pending_data_complete(host)) { |
2115 | &host->pending_events)) { | ||
2116 | /* | 2132 | /* |
2117 | * If data error interrupt comes but data over | 2133 | * If data error interrupt comes but data over |
2118 | * interrupt doesn't come within the given time. | 2134 | * interrupt doesn't come within the given time. |
@@ -2682,6 +2698,8 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
2682 | } | 2698 | } |
2683 | 2699 | ||
2684 | if (pending & SDMMC_INT_DATA_OVER) { | 2700 | if (pending & SDMMC_INT_DATA_OVER) { |
2701 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
2702 | |||
2685 | del_timer(&host->dto_timer); | 2703 | del_timer(&host->dto_timer); |
2686 | 2704 | ||
2687 | mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); | 2705 | mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); |
@@ -2694,6 +2712,8 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
2694 | } | 2712 | } |
2695 | set_bit(EVENT_DATA_COMPLETE, &host->pending_events); | 2713 | set_bit(EVENT_DATA_COMPLETE, &host->pending_events); |
2696 | tasklet_schedule(&host->tasklet); | 2714 | tasklet_schedule(&host->tasklet); |
2715 | |||
2716 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
2697 | } | 2717 | } |
2698 | 2718 | ||
2699 | if (pending & SDMMC_INT_RXDR) { | 2719 | if (pending & SDMMC_INT_RXDR) { |
@@ -2791,7 +2811,7 @@ static int dw_mci_init_slot(struct dw_mci *host) | |||
2791 | 2811 | ||
2792 | /*if there are external regulators, get them*/ | 2812 | /*if there are external regulators, get them*/ |
2793 | ret = mmc_regulator_get_supply(mmc); | 2813 | ret = mmc_regulator_get_supply(mmc); |
2794 | if (ret == -EPROBE_DEFER) | 2814 | if (ret) |
2795 | goto err_host_allocated; | 2815 | goto err_host_allocated; |
2796 | 2816 | ||
2797 | if (!mmc->ocr_avail) | 2817 | if (!mmc->ocr_avail) |
@@ -2971,9 +2991,9 @@ no_dma: | |||
2971 | host->use_dma = TRANS_MODE_PIO; | 2991 | host->use_dma = TRANS_MODE_PIO; |
2972 | } | 2992 | } |
2973 | 2993 | ||
2974 | static void dw_mci_cmd11_timer(unsigned long arg) | 2994 | static void dw_mci_cmd11_timer(struct timer_list *t) |
2975 | { | 2995 | { |
2976 | struct dw_mci *host = (struct dw_mci *)arg; | 2996 | struct dw_mci *host = from_timer(host, t, cmd11_timer); |
2977 | 2997 | ||
2978 | if (host->state != STATE_SENDING_CMD11) { | 2998 | if (host->state != STATE_SENDING_CMD11) { |
2979 | dev_warn(host->dev, "Unexpected CMD11 timeout\n"); | 2999 | dev_warn(host->dev, "Unexpected CMD11 timeout\n"); |
@@ -2985,9 +3005,9 @@ static void dw_mci_cmd11_timer(unsigned long arg) | |||
2985 | tasklet_schedule(&host->tasklet); | 3005 | tasklet_schedule(&host->tasklet); |
2986 | } | 3006 | } |
2987 | 3007 | ||
2988 | static void dw_mci_cto_timer(unsigned long arg) | 3008 | static void dw_mci_cto_timer(struct timer_list *t) |
2989 | { | 3009 | { |
2990 | struct dw_mci *host = (struct dw_mci *)arg; | 3010 | struct dw_mci *host = from_timer(host, t, cto_timer); |
2991 | unsigned long irqflags; | 3011 | unsigned long irqflags; |
2992 | u32 pending; | 3012 | u32 pending; |
2993 | 3013 | ||
@@ -3040,10 +3060,34 @@ exit: | |||
3040 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | 3060 | spin_unlock_irqrestore(&host->irq_lock, irqflags); |
3041 | } | 3061 | } |
3042 | 3062 | ||
3043 | static void dw_mci_dto_timer(unsigned long arg) | 3063 | static void dw_mci_dto_timer(struct timer_list *t) |
3044 | { | 3064 | { |
3045 | struct dw_mci *host = (struct dw_mci *)arg; | 3065 | struct dw_mci *host = from_timer(host, t, dto_timer); |
3066 | unsigned long irqflags; | ||
3067 | u32 pending; | ||
3068 | |||
3069 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
3046 | 3070 | ||
3071 | /* | ||
3072 | * The DTO timer is much longer than the CTO timer, so it's even less | ||
3073 | * likely that we'll these cases, but it pays to be paranoid. | ||
3074 | */ | ||
3075 | pending = mci_readl(host, MINTSTS); /* read-only mask reg */ | ||
3076 | if (pending & SDMMC_INT_DATA_OVER) { | ||
3077 | /* The interrupt should fire; no need to act but we can warn */ | ||
3078 | dev_warn(host->dev, "Unexpected data interrupt latency\n"); | ||
3079 | goto exit; | ||
3080 | } | ||
3081 | if (test_bit(EVENT_DATA_COMPLETE, &host->pending_events)) { | ||
3082 | /* Presumably interrupt handler couldn't delete the timer */ | ||
3083 | dev_warn(host->dev, "DTO timeout when already completed\n"); | ||
3084 | goto exit; | ||
3085 | } | ||
3086 | |||
3087 | /* | ||
3088 | * Continued paranoia to make sure we're in the state we expect. | ||
3089 | * This paranoia isn't really justified but it seems good to be safe. | ||
3090 | */ | ||
3047 | switch (host->state) { | 3091 | switch (host->state) { |
3048 | case STATE_SENDING_DATA: | 3092 | case STATE_SENDING_DATA: |
3049 | case STATE_DATA_BUSY: | 3093 | case STATE_DATA_BUSY: |
@@ -3058,8 +3102,13 @@ static void dw_mci_dto_timer(unsigned long arg) | |||
3058 | tasklet_schedule(&host->tasklet); | 3102 | tasklet_schedule(&host->tasklet); |
3059 | break; | 3103 | break; |
3060 | default: | 3104 | default: |
3105 | dev_warn(host->dev, "Unexpected data timeout, state %d\n", | ||
3106 | host->state); | ||
3061 | break; | 3107 | break; |
3062 | } | 3108 | } |
3109 | |||
3110 | exit: | ||
3111 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
3063 | } | 3112 | } |
3064 | 3113 | ||
3065 | #ifdef CONFIG_OF | 3114 | #ifdef CONFIG_OF |
@@ -3208,14 +3257,9 @@ int dw_mci_probe(struct dw_mci *host) | |||
3208 | } | 3257 | } |
3209 | } | 3258 | } |
3210 | 3259 | ||
3211 | setup_timer(&host->cmd11_timer, | 3260 | timer_setup(&host->cmd11_timer, dw_mci_cmd11_timer, 0); |
3212 | dw_mci_cmd11_timer, (unsigned long)host); | 3261 | timer_setup(&host->cto_timer, dw_mci_cto_timer, 0); |
3213 | 3262 | timer_setup(&host->dto_timer, dw_mci_dto_timer, 0); | |
3214 | setup_timer(&host->cto_timer, | ||
3215 | dw_mci_cto_timer, (unsigned long)host); | ||
3216 | |||
3217 | setup_timer(&host->dto_timer, | ||
3218 | dw_mci_dto_timer, (unsigned long)host); | ||
3219 | 3263 | ||
3220 | spin_lock_init(&host->lock); | 3264 | spin_lock_init(&host->lock); |
3221 | spin_lock_init(&host->irq_lock); | 3265 | spin_lock_init(&host->irq_lock); |
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 34474ad731aa..e3124f06a47e 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
@@ -74,7 +74,8 @@ struct dw_mci_dma_slave { | |||
74 | * @stop_abort: The command currently prepared for stoping transfer. | 74 | * @stop_abort: The command currently prepared for stoping transfer. |
75 | * @prev_blksz: The former transfer blksz record. | 75 | * @prev_blksz: The former transfer blksz record. |
76 | * @timing: Record of current ios timing. | 76 | * @timing: Record of current ios timing. |
77 | * @use_dma: Whether DMA channel is initialized or not. | 77 | * @use_dma: Which DMA channel is in use for the current transfer, zero |
78 | * denotes PIO mode. | ||
78 | * @using_dma: Whether DMA is in use for the current transfer. | 79 | * @using_dma: Whether DMA is in use for the current transfer. |
79 | * @dma_64bit_address: Whether DMA supports 64-bit address mode or not. | 80 | * @dma_64bit_address: Whether DMA supports 64-bit address mode or not. |
80 | * @sg_dma: Bus address of DMA buffer. | 81 | * @sg_dma: Bus address of DMA buffer. |
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 7db8c7a8d38d..712e08d9a45e 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c | |||
@@ -586,9 +586,9 @@ poll_timeout: | |||
586 | return true; | 586 | return true; |
587 | } | 587 | } |
588 | 588 | ||
589 | static void jz4740_mmc_timeout(unsigned long data) | 589 | static void jz4740_mmc_timeout(struct timer_list *t) |
590 | { | 590 | { |
591 | struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)data; | 591 | struct jz4740_mmc_host *host = from_timer(host, t, timeout_timer); |
592 | 592 | ||
593 | if (!test_and_clear_bit(0, &host->waiting)) | 593 | if (!test_and_clear_bit(0, &host->waiting)) |
594 | return; | 594 | return; |
@@ -1036,8 +1036,7 @@ static int jz4740_mmc_probe(struct platform_device* pdev) | |||
1036 | 1036 | ||
1037 | jz4740_mmc_reset(host); | 1037 | jz4740_mmc_reset(host); |
1038 | jz4740_mmc_clock_disable(host); | 1038 | jz4740_mmc_clock_disable(host); |
1039 | setup_timer(&host->timeout_timer, jz4740_mmc_timeout, | 1039 | timer_setup(&host->timeout_timer, jz4740_mmc_timeout, 0); |
1040 | (unsigned long)host); | ||
1041 | 1040 | ||
1042 | host->use_dma = true; | 1041 | host->use_dma = true; |
1043 | if (host->use_dma && jz4740_mmc_acquire_dma_channels(host) != 0) | 1042 | if (host->use_dma && jz4740_mmc_acquire_dma_channels(host) != 0) |
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 85745ef179e2..e0862d3f65b3 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c | |||
@@ -1190,7 +1190,7 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
1190 | /* Get regulators and the supported OCR mask */ | 1190 | /* Get regulators and the supported OCR mask */ |
1191 | host->vqmmc_enabled = false; | 1191 | host->vqmmc_enabled = false; |
1192 | ret = mmc_regulator_get_supply(mmc); | 1192 | ret = mmc_regulator_get_supply(mmc); |
1193 | if (ret == -EPROBE_DEFER) | 1193 | if (ret) |
1194 | goto free_host; | 1194 | goto free_host; |
1195 | 1195 | ||
1196 | ret = mmc_of_parse(mmc); | 1196 | ret = mmc_of_parse(mmc); |
diff --git a/drivers/mmc/host/meson-mx-sdio.c b/drivers/mmc/host/meson-mx-sdio.c new file mode 100644 index 000000000000..09cb89645d06 --- /dev/null +++ b/drivers/mmc/host/meson-mx-sdio.c | |||
@@ -0,0 +1,768 @@ | |||
1 | /* | ||
2 | * meson-mx-sdio.c - Meson6, Meson8 and Meson8b SDIO/MMC Host Controller | ||
3 | * | ||
4 | * Copyright (C) 2015 Endless Mobile, Inc. | ||
5 | * Author: Carlo Caione <carlo@endlessm.com> | ||
6 | * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or (at | ||
11 | * your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/bitfield.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/dma-mapping.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/of_platform.h> | ||
25 | #include <linux/timer.h> | ||
26 | #include <linux/types.h> | ||
27 | |||
28 | #include <linux/mmc/host.h> | ||
29 | #include <linux/mmc/mmc.h> | ||
30 | #include <linux/mmc/sdio.h> | ||
31 | #include <linux/mmc/slot-gpio.h> | ||
32 | |||
33 | #define MESON_MX_SDIO_ARGU 0x00 | ||
34 | |||
35 | #define MESON_MX_SDIO_SEND 0x04 | ||
36 | #define MESON_MX_SDIO_SEND_COMMAND_INDEX_MASK GENMASK(7, 0) | ||
37 | #define MESON_MX_SDIO_SEND_CMD_RESP_BITS_MASK GENMASK(15, 8) | ||
38 | #define MESON_MX_SDIO_SEND_RESP_WITHOUT_CRC7 BIT(16) | ||
39 | #define MESON_MX_SDIO_SEND_RESP_HAS_DATA BIT(17) | ||
40 | #define MESON_MX_SDIO_SEND_RESP_CRC7_FROM_8 BIT(18) | ||
41 | #define MESON_MX_SDIO_SEND_CHECK_DAT0_BUSY BIT(19) | ||
42 | #define MESON_MX_SDIO_SEND_DATA BIT(20) | ||
43 | #define MESON_MX_SDIO_SEND_USE_INT_WINDOW BIT(21) | ||
44 | #define MESON_MX_SDIO_SEND_REPEAT_PACKAGE_TIMES_MASK GENMASK(31, 24) | ||
45 | |||
46 | #define MESON_MX_SDIO_CONF 0x08 | ||
47 | #define MESON_MX_SDIO_CONF_CMD_CLK_DIV_SHIFT 0 | ||
48 | #define MESON_MX_SDIO_CONF_CMD_CLK_DIV_WIDTH 10 | ||
49 | #define MESON_MX_SDIO_CONF_CMD_DISABLE_CRC BIT(10) | ||
50 | #define MESON_MX_SDIO_CONF_CMD_OUT_AT_POSITIVE_EDGE BIT(11) | ||
51 | #define MESON_MX_SDIO_CONF_CMD_ARGUMENT_BITS_MASK GENMASK(17, 12) | ||
52 | #define MESON_MX_SDIO_CONF_RESP_LATCH_AT_NEGATIVE_EDGE BIT(18) | ||
53 | #define MESON_MX_SDIO_CONF_DATA_LATCH_AT_NEGATIVE_EDGE BIT(19) | ||
54 | #define MESON_MX_SDIO_CONF_BUS_WIDTH BIT(20) | ||
55 | #define MESON_MX_SDIO_CONF_M_ENDIAN_MASK GENMASK(22, 21) | ||
56 | #define MESON_MX_SDIO_CONF_WRITE_NWR_MASK GENMASK(28, 23) | ||
57 | #define MESON_MX_SDIO_CONF_WRITE_CRC_OK_STATUS_MASK GENMASK(31, 29) | ||
58 | |||
59 | #define MESON_MX_SDIO_IRQS 0x0c | ||
60 | #define MESON_MX_SDIO_IRQS_STATUS_STATE_MACHINE_MASK GENMASK(3, 0) | ||
61 | #define MESON_MX_SDIO_IRQS_CMD_BUSY BIT(4) | ||
62 | #define MESON_MX_SDIO_IRQS_RESP_CRC7_OK BIT(5) | ||
63 | #define MESON_MX_SDIO_IRQS_DATA_READ_CRC16_OK BIT(6) | ||
64 | #define MESON_MX_SDIO_IRQS_DATA_WRITE_CRC16_OK BIT(7) | ||
65 | #define MESON_MX_SDIO_IRQS_IF_INT BIT(8) | ||
66 | #define MESON_MX_SDIO_IRQS_CMD_INT BIT(9) | ||
67 | #define MESON_MX_SDIO_IRQS_STATUS_INFO_MASK GENMASK(15, 12) | ||
68 | #define MESON_MX_SDIO_IRQS_TIMING_OUT_INT BIT(16) | ||
69 | #define MESON_MX_SDIO_IRQS_AMRISC_TIMING_OUT_INT_EN BIT(17) | ||
70 | #define MESON_MX_SDIO_IRQS_ARC_TIMING_OUT_INT_EN BIT(18) | ||
71 | #define MESON_MX_SDIO_IRQS_TIMING_OUT_COUNT_MASK GENMASK(31, 19) | ||
72 | |||
73 | #define MESON_MX_SDIO_IRQC 0x10 | ||
74 | #define MESON_MX_SDIO_IRQC_ARC_IF_INT_EN BIT(3) | ||
75 | #define MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN BIT(4) | ||
76 | #define MESON_MX_SDIO_IRQC_IF_CONFIG_MASK GENMASK(7, 6) | ||
77 | #define MESON_MX_SDIO_IRQC_FORCE_DATA_CLK BIT(8) | ||
78 | #define MESON_MX_SDIO_IRQC_FORCE_DATA_CMD BIT(9) | ||
79 | #define MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK GENMASK(10, 13) | ||
80 | #define MESON_MX_SDIO_IRQC_SOFT_RESET BIT(15) | ||
81 | #define MESON_MX_SDIO_IRQC_FORCE_HALT BIT(30) | ||
82 | #define MESON_MX_SDIO_IRQC_HALT_HOLE BIT(31) | ||
83 | |||
84 | #define MESON_MX_SDIO_MULT 0x14 | ||
85 | #define MESON_MX_SDIO_MULT_PORT_SEL_MASK GENMASK(1, 0) | ||
86 | #define MESON_MX_SDIO_MULT_MEMORY_STICK_ENABLE BIT(2) | ||
87 | #define MESON_MX_SDIO_MULT_MEMORY_STICK_SCLK_ALWAYS BIT(3) | ||
88 | #define MESON_MX_SDIO_MULT_STREAM_ENABLE BIT(4) | ||
89 | #define MESON_MX_SDIO_MULT_STREAM_8BITS_MODE BIT(5) | ||
90 | #define MESON_MX_SDIO_MULT_WR_RD_OUT_INDEX BIT(8) | ||
91 | #define MESON_MX_SDIO_MULT_DAT0_DAT1_SWAPPED BIT(10) | ||
92 | #define MESON_MX_SDIO_MULT_DAT1_DAT0_SWAPPED BIT(11) | ||
93 | #define MESON_MX_SDIO_MULT_RESP_READ_INDEX_MASK GENMASK(15, 12) | ||
94 | |||
95 | #define MESON_MX_SDIO_ADDR 0x18 | ||
96 | |||
97 | #define MESON_MX_SDIO_EXT 0x1c | ||
98 | #define MESON_MX_SDIO_EXT_DATA_RW_NUMBER_MASK GENMASK(29, 16) | ||
99 | |||
100 | #define MESON_MX_SDIO_BOUNCE_REQ_SIZE (128 * 1024) | ||
101 | #define MESON_MX_SDIO_RESPONSE_CRC16_BITS (16 - 1) | ||
102 | #define MESON_MX_SDIO_MAX_SLOTS 3 | ||
103 | |||
104 | struct meson_mx_mmc_host { | ||
105 | struct device *controller_dev; | ||
106 | |||
107 | struct clk *parent_clk; | ||
108 | struct clk *core_clk; | ||
109 | struct clk_divider cfg_div; | ||
110 | struct clk *cfg_div_clk; | ||
111 | struct clk_fixed_factor fixed_factor; | ||
112 | struct clk *fixed_factor_clk; | ||
113 | |||
114 | void __iomem *base; | ||
115 | int irq; | ||
116 | spinlock_t irq_lock; | ||
117 | |||
118 | struct timer_list cmd_timeout; | ||
119 | |||
120 | unsigned int slot_id; | ||
121 | struct mmc_host *mmc; | ||
122 | |||
123 | struct mmc_request *mrq; | ||
124 | struct mmc_command *cmd; | ||
125 | int error; | ||
126 | }; | ||
127 | |||
128 | static void meson_mx_mmc_mask_bits(struct mmc_host *mmc, char reg, u32 mask, | ||
129 | u32 val) | ||
130 | { | ||
131 | struct meson_mx_mmc_host *host = mmc_priv(mmc); | ||
132 | u32 regval; | ||
133 | |||
134 | regval = readl(host->base + reg); | ||
135 | regval &= ~mask; | ||
136 | regval |= (val & mask); | ||
137 | |||
138 | writel(regval, host->base + reg); | ||
139 | } | ||
140 | |||
141 | static void meson_mx_mmc_soft_reset(struct meson_mx_mmc_host *host) | ||
142 | { | ||
143 | writel(MESON_MX_SDIO_IRQC_SOFT_RESET, host->base + MESON_MX_SDIO_IRQC); | ||
144 | udelay(2); | ||
145 | } | ||
146 | |||
147 | static struct mmc_command *meson_mx_mmc_get_next_cmd(struct mmc_command *cmd) | ||
148 | { | ||
149 | if (cmd->opcode == MMC_SET_BLOCK_COUNT && !cmd->error) | ||
150 | return cmd->mrq->cmd; | ||
151 | else if (mmc_op_multi(cmd->opcode) && | ||
152 | (!cmd->mrq->sbc || cmd->error || cmd->data->error)) | ||
153 | return cmd->mrq->stop; | ||
154 | else | ||
155 | return NULL; | ||
156 | } | ||
157 | |||
158 | static void meson_mx_mmc_start_cmd(struct mmc_host *mmc, | ||
159 | struct mmc_command *cmd) | ||
160 | { | ||
161 | struct meson_mx_mmc_host *host = mmc_priv(mmc); | ||
162 | unsigned int pack_size; | ||
163 | unsigned long irqflags, timeout; | ||
164 | u32 mult, send = 0, ext = 0; | ||
165 | |||
166 | host->cmd = cmd; | ||
167 | |||
168 | if (cmd->busy_timeout) | ||
169 | timeout = msecs_to_jiffies(cmd->busy_timeout); | ||
170 | else | ||
171 | timeout = msecs_to_jiffies(1000); | ||
172 | |||
173 | switch (mmc_resp_type(cmd)) { | ||
174 | case MMC_RSP_R1: | ||
175 | case MMC_RSP_R1B: | ||
176 | case MMC_RSP_R3: | ||
177 | /* 7 (CMD) + 32 (response) + 7 (CRC) -1 */ | ||
178 | send |= FIELD_PREP(MESON_MX_SDIO_SEND_CMD_RESP_BITS_MASK, 45); | ||
179 | break; | ||
180 | case MMC_RSP_R2: | ||
181 | /* 7 (CMD) + 120 (response) + 7 (CRC) -1 */ | ||
182 | send |= FIELD_PREP(MESON_MX_SDIO_SEND_CMD_RESP_BITS_MASK, 133); | ||
183 | send |= MESON_MX_SDIO_SEND_RESP_CRC7_FROM_8; | ||
184 | break; | ||
185 | default: | ||
186 | break; | ||
187 | } | ||
188 | |||
189 | if (!(cmd->flags & MMC_RSP_CRC)) | ||
190 | send |= MESON_MX_SDIO_SEND_RESP_WITHOUT_CRC7; | ||
191 | |||
192 | if (cmd->flags & MMC_RSP_BUSY) | ||
193 | send |= MESON_MX_SDIO_SEND_CHECK_DAT0_BUSY; | ||
194 | |||
195 | if (cmd->data) { | ||
196 | send |= FIELD_PREP(MESON_MX_SDIO_SEND_REPEAT_PACKAGE_TIMES_MASK, | ||
197 | (cmd->data->blocks - 1)); | ||
198 | |||
199 | pack_size = cmd->data->blksz * BITS_PER_BYTE; | ||
200 | if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) | ||
201 | pack_size += MESON_MX_SDIO_RESPONSE_CRC16_BITS * 4; | ||
202 | else | ||
203 | pack_size += MESON_MX_SDIO_RESPONSE_CRC16_BITS * 1; | ||
204 | |||
205 | ext |= FIELD_PREP(MESON_MX_SDIO_EXT_DATA_RW_NUMBER_MASK, | ||
206 | pack_size); | ||
207 | |||
208 | if (cmd->data->flags & MMC_DATA_WRITE) | ||
209 | send |= MESON_MX_SDIO_SEND_DATA; | ||
210 | else | ||
211 | send |= MESON_MX_SDIO_SEND_RESP_HAS_DATA; | ||
212 | |||
213 | cmd->data->bytes_xfered = 0; | ||
214 | } | ||
215 | |||
216 | send |= FIELD_PREP(MESON_MX_SDIO_SEND_COMMAND_INDEX_MASK, | ||
217 | (0x40 | cmd->opcode)); | ||
218 | |||
219 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
220 | |||
221 | mult = readl(host->base + MESON_MX_SDIO_MULT); | ||
222 | mult &= ~MESON_MX_SDIO_MULT_PORT_SEL_MASK; | ||
223 | mult |= FIELD_PREP(MESON_MX_SDIO_MULT_PORT_SEL_MASK, host->slot_id); | ||
224 | mult |= BIT(31); | ||
225 | writel(mult, host->base + MESON_MX_SDIO_MULT); | ||
226 | |||
227 | /* enable the CMD done interrupt */ | ||
228 | meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_IRQC, | ||
229 | MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN, | ||
230 | MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN); | ||
231 | |||
232 | /* clear pending interrupts */ | ||
233 | meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_IRQS, | ||
234 | MESON_MX_SDIO_IRQS_CMD_INT, | ||
235 | MESON_MX_SDIO_IRQS_CMD_INT); | ||
236 | |||
237 | writel(cmd->arg, host->base + MESON_MX_SDIO_ARGU); | ||
238 | writel(ext, host->base + MESON_MX_SDIO_EXT); | ||
239 | writel(send, host->base + MESON_MX_SDIO_SEND); | ||
240 | |||
241 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
242 | |||
243 | mod_timer(&host->cmd_timeout, jiffies + timeout); | ||
244 | } | ||
245 | |||
246 | static void meson_mx_mmc_request_done(struct meson_mx_mmc_host *host) | ||
247 | { | ||
248 | struct mmc_request *mrq; | ||
249 | |||
250 | mrq = host->mrq; | ||
251 | |||
252 | host->mrq = NULL; | ||
253 | host->cmd = NULL; | ||
254 | |||
255 | mmc_request_done(host->mmc, mrq); | ||
256 | } | ||
257 | |||
258 | static void meson_mx_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
259 | { | ||
260 | struct meson_mx_mmc_host *host = mmc_priv(mmc); | ||
261 | unsigned short vdd = ios->vdd; | ||
262 | unsigned long clk_rate = ios->clock; | ||
263 | |||
264 | switch (ios->bus_width) { | ||
265 | case MMC_BUS_WIDTH_1: | ||
266 | meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_CONF, | ||
267 | MESON_MX_SDIO_CONF_BUS_WIDTH, 0); | ||
268 | break; | ||
269 | |||
270 | case MMC_BUS_WIDTH_4: | ||
271 | meson_mx_mmc_mask_bits(mmc, MESON_MX_SDIO_CONF, | ||
272 | MESON_MX_SDIO_CONF_BUS_WIDTH, | ||
273 | MESON_MX_SDIO_CONF_BUS_WIDTH); | ||
274 | break; | ||
275 | |||
276 | case MMC_BUS_WIDTH_8: | ||
277 | default: | ||
278 | dev_err(mmc_dev(mmc), "unsupported bus width: %d\n", | ||
279 | ios->bus_width); | ||
280 | host->error = -EINVAL; | ||
281 | return; | ||
282 | } | ||
283 | |||
284 | host->error = clk_set_rate(host->cfg_div_clk, ios->clock); | ||
285 | if (host->error) { | ||
286 | dev_warn(mmc_dev(mmc), | ||
287 | "failed to set MMC clock to %lu: %d\n", | ||
288 | clk_rate, host->error); | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | mmc->actual_clock = clk_get_rate(host->cfg_div_clk); | ||
293 | |||
294 | switch (ios->power_mode) { | ||
295 | case MMC_POWER_OFF: | ||
296 | vdd = 0; | ||
297 | /* fall-through: */ | ||
298 | case MMC_POWER_UP: | ||
299 | if (!IS_ERR(mmc->supply.vmmc)) { | ||
300 | host->error = mmc_regulator_set_ocr(mmc, | ||
301 | mmc->supply.vmmc, | ||
302 | vdd); | ||
303 | if (host->error) | ||
304 | return; | ||
305 | } | ||
306 | break; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | static int meson_mx_mmc_map_dma(struct mmc_host *mmc, struct mmc_request *mrq) | ||
311 | { | ||
312 | struct mmc_data *data = mrq->data; | ||
313 | int dma_len; | ||
314 | struct scatterlist *sg; | ||
315 | |||
316 | if (!data) | ||
317 | return 0; | ||
318 | |||
319 | sg = data->sg; | ||
320 | if (sg->offset & 3 || sg->length & 3) { | ||
321 | dev_err(mmc_dev(mmc), | ||
322 | "unaligned scatterlist: offset %x length %d\n", | ||
323 | sg->offset, sg->length); | ||
324 | return -EINVAL; | ||
325 | } | ||
326 | |||
327 | dma_len = dma_map_sg(mmc_dev(mmc), data->sg, data->sg_len, | ||
328 | mmc_get_dma_dir(data)); | ||
329 | if (dma_len <= 0) { | ||
330 | dev_err(mmc_dev(mmc), "dma_map_sg failed\n"); | ||
331 | return -ENOMEM; | ||
332 | } | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static void meson_mx_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
338 | { | ||
339 | struct meson_mx_mmc_host *host = mmc_priv(mmc); | ||
340 | struct mmc_command *cmd = mrq->cmd; | ||
341 | |||
342 | if (!host->error) | ||
343 | host->error = meson_mx_mmc_map_dma(mmc, mrq); | ||
344 | |||
345 | if (host->error) { | ||
346 | cmd->error = host->error; | ||
347 | mmc_request_done(mmc, mrq); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | host->mrq = mrq; | ||
352 | |||
353 | if (mrq->data) | ||
354 | writel(sg_dma_address(mrq->data->sg), | ||
355 | host->base + MESON_MX_SDIO_ADDR); | ||
356 | |||
357 | if (mrq->sbc) | ||
358 | meson_mx_mmc_start_cmd(mmc, mrq->sbc); | ||
359 | else | ||
360 | meson_mx_mmc_start_cmd(mmc, mrq->cmd); | ||
361 | } | ||
362 | |||
363 | static int meson_mx_mmc_card_busy(struct mmc_host *mmc) | ||
364 | { | ||
365 | struct meson_mx_mmc_host *host = mmc_priv(mmc); | ||
366 | u32 irqc = readl(host->base + MESON_MX_SDIO_IRQC); | ||
367 | |||
368 | return !!(irqc & MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK); | ||
369 | } | ||
370 | |||
371 | static void meson_mx_mmc_read_response(struct mmc_host *mmc, | ||
372 | struct mmc_command *cmd) | ||
373 | { | ||
374 | struct meson_mx_mmc_host *host = mmc_priv(mmc); | ||
375 | u32 mult; | ||
376 | int i, resp[4]; | ||
377 | |||
378 | mult = readl(host->base + MESON_MX_SDIO_MULT); | ||
379 | mult |= MESON_MX_SDIO_MULT_WR_RD_OUT_INDEX; | ||
380 | mult &= ~MESON_MX_SDIO_MULT_RESP_READ_INDEX_MASK; | ||
381 | mult |= FIELD_PREP(MESON_MX_SDIO_MULT_RESP_READ_INDEX_MASK, 0); | ||
382 | writel(mult, host->base + MESON_MX_SDIO_MULT); | ||
383 | |||
384 | if (cmd->flags & MMC_RSP_136) { | ||
385 | for (i = 0; i <= 3; i++) | ||
386 | resp[3 - i] = readl(host->base + MESON_MX_SDIO_ARGU); | ||
387 | cmd->resp[0] = (resp[0] << 8) | ((resp[1] >> 24) & 0xff); | ||
388 | cmd->resp[1] = (resp[1] << 8) | ((resp[2] >> 24) & 0xff); | ||
389 | cmd->resp[2] = (resp[2] << 8) | ((resp[3] >> 24) & 0xff); | ||
390 | cmd->resp[3] = (resp[3] << 8); | ||
391 | } else if (cmd->flags & MMC_RSP_PRESENT) { | ||
392 | cmd->resp[0] = readl(host->base + MESON_MX_SDIO_ARGU); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static irqreturn_t meson_mx_mmc_process_cmd_irq(struct meson_mx_mmc_host *host, | ||
397 | u32 irqs, u32 send) | ||
398 | { | ||
399 | struct mmc_command *cmd = host->cmd; | ||
400 | |||
401 | /* | ||
402 | * NOTE: even though it shouldn't happen we sometimes get command | ||
403 | * interrupts twice (at least this is what it looks like). Ideally | ||
404 | * we find out why this happens and warn here as soon as it occurs. | ||
405 | */ | ||
406 | if (!cmd) | ||
407 | return IRQ_HANDLED; | ||
408 | |||
409 | cmd->error = 0; | ||
410 | meson_mx_mmc_read_response(host->mmc, cmd); | ||
411 | |||
412 | if (cmd->data) { | ||
413 | if (!((irqs & MESON_MX_SDIO_IRQS_DATA_READ_CRC16_OK) || | ||
414 | (irqs & MESON_MX_SDIO_IRQS_DATA_WRITE_CRC16_OK))) | ||
415 | cmd->error = -EILSEQ; | ||
416 | } else { | ||
417 | if (!((irqs & MESON_MX_SDIO_IRQS_RESP_CRC7_OK) || | ||
418 | (send & MESON_MX_SDIO_SEND_RESP_WITHOUT_CRC7))) | ||
419 | cmd->error = -EILSEQ; | ||
420 | } | ||
421 | |||
422 | return IRQ_WAKE_THREAD; | ||
423 | } | ||
424 | |||
425 | static irqreturn_t meson_mx_mmc_irq(int irq, void *data) | ||
426 | { | ||
427 | struct meson_mx_mmc_host *host = (void *) data; | ||
428 | u32 irqs, send; | ||
429 | unsigned long irqflags; | ||
430 | irqreturn_t ret; | ||
431 | |||
432 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
433 | |||
434 | irqs = readl(host->base + MESON_MX_SDIO_IRQS); | ||
435 | send = readl(host->base + MESON_MX_SDIO_SEND); | ||
436 | |||
437 | if (irqs & MESON_MX_SDIO_IRQS_CMD_INT) | ||
438 | ret = meson_mx_mmc_process_cmd_irq(host, irqs, send); | ||
439 | else | ||
440 | ret = IRQ_HANDLED; | ||
441 | |||
442 | /* finally ACK all pending interrupts */ | ||
443 | writel(irqs, host->base + MESON_MX_SDIO_IRQS); | ||
444 | |||
445 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
446 | |||
447 | return ret; | ||
448 | } | ||
449 | |||
450 | static irqreturn_t meson_mx_mmc_irq_thread(int irq, void *irq_data) | ||
451 | { | ||
452 | struct meson_mx_mmc_host *host = (void *) irq_data; | ||
453 | struct mmc_command *cmd = host->cmd, *next_cmd; | ||
454 | |||
455 | if (WARN_ON(!cmd)) | ||
456 | return IRQ_HANDLED; | ||
457 | |||
458 | del_timer_sync(&host->cmd_timeout); | ||
459 | |||
460 | if (cmd->data) { | ||
461 | dma_unmap_sg(mmc_dev(host->mmc), cmd->data->sg, | ||
462 | cmd->data->sg_len, | ||
463 | mmc_get_dma_dir(cmd->data)); | ||
464 | |||
465 | cmd->data->bytes_xfered = cmd->data->blksz * cmd->data->blocks; | ||
466 | } | ||
467 | |||
468 | next_cmd = meson_mx_mmc_get_next_cmd(cmd); | ||
469 | if (next_cmd) | ||
470 | meson_mx_mmc_start_cmd(host->mmc, next_cmd); | ||
471 | else | ||
472 | meson_mx_mmc_request_done(host); | ||
473 | |||
474 | return IRQ_HANDLED; | ||
475 | } | ||
476 | |||
477 | static void meson_mx_mmc_timeout(struct timer_list *t) | ||
478 | { | ||
479 | struct meson_mx_mmc_host *host = from_timer(host, t, cmd_timeout); | ||
480 | unsigned long irqflags; | ||
481 | u32 irqc; | ||
482 | |||
483 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
484 | |||
485 | /* disable the CMD interrupt */ | ||
486 | irqc = readl(host->base + MESON_MX_SDIO_IRQC); | ||
487 | irqc &= ~MESON_MX_SDIO_IRQC_ARC_CMD_INT_EN; | ||
488 | writel(irqc, host->base + MESON_MX_SDIO_IRQC); | ||
489 | |||
490 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
491 | |||
492 | /* | ||
493 | * skip the timeout handling if the interrupt handler already processed | ||
494 | * the command. | ||
495 | */ | ||
496 | if (!host->cmd) | ||
497 | return; | ||
498 | |||
499 | dev_dbg(mmc_dev(host->mmc), | ||
500 | "Timeout on CMD%u (IRQS = 0x%08x, ARGU = 0x%08x)\n", | ||
501 | host->cmd->opcode, readl(host->base + MESON_MX_SDIO_IRQS), | ||
502 | readl(host->base + MESON_MX_SDIO_ARGU)); | ||
503 | |||
504 | host->cmd->error = -ETIMEDOUT; | ||
505 | |||
506 | meson_mx_mmc_request_done(host); | ||
507 | } | ||
508 | |||
509 | static struct mmc_host_ops meson_mx_mmc_ops = { | ||
510 | .request = meson_mx_mmc_request, | ||
511 | .set_ios = meson_mx_mmc_set_ios, | ||
512 | .card_busy = meson_mx_mmc_card_busy, | ||
513 | .get_cd = mmc_gpio_get_cd, | ||
514 | .get_ro = mmc_gpio_get_ro, | ||
515 | }; | ||
516 | |||
517 | static struct platform_device *meson_mx_mmc_slot_pdev(struct device *parent) | ||
518 | { | ||
519 | struct device_node *slot_node; | ||
520 | |||
521 | /* | ||
522 | * TODO: the MMC core framework currently does not support | ||
523 | * controllers with multiple slots properly. So we only register | ||
524 | * the first slot for now | ||
525 | */ | ||
526 | slot_node = of_find_compatible_node(parent->of_node, NULL, "mmc-slot"); | ||
527 | if (!slot_node) { | ||
528 | dev_warn(parent, "no 'mmc-slot' sub-node found\n"); | ||
529 | return ERR_PTR(-ENOENT); | ||
530 | } | ||
531 | |||
532 | return of_platform_device_create(slot_node, NULL, parent); | ||
533 | } | ||
534 | |||
535 | static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host) | ||
536 | { | ||
537 | struct mmc_host *mmc = host->mmc; | ||
538 | struct device *slot_dev = mmc_dev(mmc); | ||
539 | int ret; | ||
540 | |||
541 | if (of_property_read_u32(slot_dev->of_node, "reg", &host->slot_id)) { | ||
542 | dev_err(slot_dev, "missing 'reg' property\n"); | ||
543 | return -EINVAL; | ||
544 | } | ||
545 | |||
546 | if (host->slot_id >= MESON_MX_SDIO_MAX_SLOTS) { | ||
547 | dev_err(slot_dev, "invalid 'reg' property value %d\n", | ||
548 | host->slot_id); | ||
549 | return -EINVAL; | ||
550 | } | ||
551 | |||
552 | /* Get regulators and the supported OCR mask */ | ||
553 | ret = mmc_regulator_get_supply(mmc); | ||
554 | if (ret) | ||
555 | return ret; | ||
556 | |||
557 | mmc->max_req_size = MESON_MX_SDIO_BOUNCE_REQ_SIZE; | ||
558 | mmc->max_seg_size = mmc->max_req_size; | ||
559 | mmc->max_blk_count = | ||
560 | FIELD_GET(MESON_MX_SDIO_SEND_REPEAT_PACKAGE_TIMES_MASK, | ||
561 | 0xffffffff); | ||
562 | mmc->max_blk_size = FIELD_GET(MESON_MX_SDIO_EXT_DATA_RW_NUMBER_MASK, | ||
563 | 0xffffffff); | ||
564 | mmc->max_blk_size -= (4 * MESON_MX_SDIO_RESPONSE_CRC16_BITS); | ||
565 | mmc->max_blk_size /= BITS_PER_BYTE; | ||
566 | |||
567 | /* Get the min and max supported clock rates */ | ||
568 | mmc->f_min = clk_round_rate(host->cfg_div_clk, 1); | ||
569 | mmc->f_max = clk_round_rate(host->cfg_div_clk, | ||
570 | clk_get_rate(host->parent_clk)); | ||
571 | |||
572 | mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; | ||
573 | mmc->ops = &meson_mx_mmc_ops; | ||
574 | |||
575 | ret = mmc_of_parse(mmc); | ||
576 | if (ret) | ||
577 | return ret; | ||
578 | |||
579 | ret = mmc_add_host(mmc); | ||
580 | if (ret) | ||
581 | return ret; | ||
582 | |||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | static int meson_mx_mmc_register_clks(struct meson_mx_mmc_host *host) | ||
587 | { | ||
588 | struct clk_init_data init; | ||
589 | const char *clk_div_parent, *clk_fixed_factor_parent; | ||
590 | |||
591 | clk_fixed_factor_parent = __clk_get_name(host->parent_clk); | ||
592 | init.name = devm_kasprintf(host->controller_dev, GFP_KERNEL, | ||
593 | "%s#fixed_factor", | ||
594 | dev_name(host->controller_dev)); | ||
595 | init.ops = &clk_fixed_factor_ops; | ||
596 | init.flags = 0; | ||
597 | init.parent_names = &clk_fixed_factor_parent; | ||
598 | init.num_parents = 1; | ||
599 | host->fixed_factor.div = 2; | ||
600 | host->fixed_factor.mult = 1; | ||
601 | host->fixed_factor.hw.init = &init; | ||
602 | |||
603 | host->fixed_factor_clk = devm_clk_register(host->controller_dev, | ||
604 | &host->fixed_factor.hw); | ||
605 | if (WARN_ON(IS_ERR(host->fixed_factor_clk))) | ||
606 | return PTR_ERR(host->fixed_factor_clk); | ||
607 | |||
608 | clk_div_parent = __clk_get_name(host->fixed_factor_clk); | ||
609 | init.name = devm_kasprintf(host->controller_dev, GFP_KERNEL, | ||
610 | "%s#div", dev_name(host->controller_dev)); | ||
611 | init.ops = &clk_divider_ops; | ||
612 | init.flags = CLK_SET_RATE_PARENT; | ||
613 | init.parent_names = &clk_div_parent; | ||
614 | init.num_parents = 1; | ||
615 | host->cfg_div.reg = host->base + MESON_MX_SDIO_CONF; | ||
616 | host->cfg_div.shift = MESON_MX_SDIO_CONF_CMD_CLK_DIV_SHIFT; | ||
617 | host->cfg_div.width = MESON_MX_SDIO_CONF_CMD_CLK_DIV_WIDTH; | ||
618 | host->cfg_div.hw.init = &init; | ||
619 | host->cfg_div.flags = CLK_DIVIDER_ALLOW_ZERO; | ||
620 | |||
621 | host->cfg_div_clk = devm_clk_register(host->controller_dev, | ||
622 | &host->cfg_div.hw); | ||
623 | if (WARN_ON(IS_ERR(host->cfg_div_clk))) | ||
624 | return PTR_ERR(host->cfg_div_clk); | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static int meson_mx_mmc_probe(struct platform_device *pdev) | ||
630 | { | ||
631 | struct platform_device *slot_pdev; | ||
632 | struct mmc_host *mmc; | ||
633 | struct meson_mx_mmc_host *host; | ||
634 | struct resource *res; | ||
635 | int ret, irq; | ||
636 | u32 conf; | ||
637 | |||
638 | slot_pdev = meson_mx_mmc_slot_pdev(&pdev->dev); | ||
639 | if (!slot_pdev) | ||
640 | return -ENODEV; | ||
641 | else if (IS_ERR(slot_pdev)) | ||
642 | return PTR_ERR(slot_pdev); | ||
643 | |||
644 | mmc = mmc_alloc_host(sizeof(*host), &slot_pdev->dev); | ||
645 | if (!mmc) { | ||
646 | ret = -ENOMEM; | ||
647 | goto error_unregister_slot_pdev; | ||
648 | } | ||
649 | |||
650 | host = mmc_priv(mmc); | ||
651 | host->mmc = mmc; | ||
652 | host->controller_dev = &pdev->dev; | ||
653 | |||
654 | spin_lock_init(&host->irq_lock); | ||
655 | timer_setup(&host->cmd_timeout, meson_mx_mmc_timeout, 0); | ||
656 | |||
657 | platform_set_drvdata(pdev, host); | ||
658 | |||
659 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
660 | host->base = devm_ioremap_resource(host->controller_dev, res); | ||
661 | if (IS_ERR(host->base)) { | ||
662 | ret = PTR_ERR(host->base); | ||
663 | goto error_free_mmc; | ||
664 | } | ||
665 | |||
666 | irq = platform_get_irq(pdev, 0); | ||
667 | ret = devm_request_threaded_irq(host->controller_dev, irq, | ||
668 | meson_mx_mmc_irq, | ||
669 | meson_mx_mmc_irq_thread, IRQF_ONESHOT, | ||
670 | NULL, host); | ||
671 | if (ret) | ||
672 | goto error_free_mmc; | ||
673 | |||
674 | host->core_clk = devm_clk_get(host->controller_dev, "core"); | ||
675 | if (IS_ERR(host->core_clk)) { | ||
676 | ret = PTR_ERR(host->core_clk); | ||
677 | goto error_free_mmc; | ||
678 | } | ||
679 | |||
680 | host->parent_clk = devm_clk_get(host->controller_dev, "clkin"); | ||
681 | if (IS_ERR(host->parent_clk)) { | ||
682 | ret = PTR_ERR(host->parent_clk); | ||
683 | goto error_free_mmc; | ||
684 | } | ||
685 | |||
686 | ret = meson_mx_mmc_register_clks(host); | ||
687 | if (ret) | ||
688 | goto error_free_mmc; | ||
689 | |||
690 | ret = clk_prepare_enable(host->core_clk); | ||
691 | if (ret) { | ||
692 | dev_err(host->controller_dev, "Failed to enable core clock\n"); | ||
693 | goto error_free_mmc; | ||
694 | } | ||
695 | |||
696 | ret = clk_prepare_enable(host->cfg_div_clk); | ||
697 | if (ret) { | ||
698 | dev_err(host->controller_dev, "Failed to enable MMC clock\n"); | ||
699 | goto error_disable_core_clk; | ||
700 | } | ||
701 | |||
702 | conf = 0; | ||
703 | conf |= FIELD_PREP(MESON_MX_SDIO_CONF_CMD_ARGUMENT_BITS_MASK, 39); | ||
704 | conf |= FIELD_PREP(MESON_MX_SDIO_CONF_M_ENDIAN_MASK, 0x3); | ||
705 | conf |= FIELD_PREP(MESON_MX_SDIO_CONF_WRITE_NWR_MASK, 0x2); | ||
706 | conf |= FIELD_PREP(MESON_MX_SDIO_CONF_WRITE_CRC_OK_STATUS_MASK, 0x2); | ||
707 | writel(conf, host->base + MESON_MX_SDIO_CONF); | ||
708 | |||
709 | meson_mx_mmc_soft_reset(host); | ||
710 | |||
711 | ret = meson_mx_mmc_add_host(host); | ||
712 | if (ret) | ||
713 | goto error_disable_clks; | ||
714 | |||
715 | return 0; | ||
716 | |||
717 | error_disable_clks: | ||
718 | clk_disable_unprepare(host->cfg_div_clk); | ||
719 | error_disable_core_clk: | ||
720 | clk_disable_unprepare(host->core_clk); | ||
721 | error_free_mmc: | ||
722 | mmc_free_host(mmc); | ||
723 | error_unregister_slot_pdev: | ||
724 | of_platform_device_destroy(&slot_pdev->dev, NULL); | ||
725 | return ret; | ||
726 | } | ||
727 | |||
728 | static int meson_mx_mmc_remove(struct platform_device *pdev) | ||
729 | { | ||
730 | struct meson_mx_mmc_host *host = platform_get_drvdata(pdev); | ||
731 | struct device *slot_dev = mmc_dev(host->mmc); | ||
732 | |||
733 | del_timer_sync(&host->cmd_timeout); | ||
734 | |||
735 | mmc_remove_host(host->mmc); | ||
736 | |||
737 | of_platform_device_destroy(slot_dev, NULL); | ||
738 | |||
739 | clk_disable_unprepare(host->cfg_div_clk); | ||
740 | clk_disable_unprepare(host->core_clk); | ||
741 | |||
742 | mmc_free_host(host->mmc); | ||
743 | |||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | static const struct of_device_id meson_mx_mmc_of_match[] = { | ||
748 | { .compatible = "amlogic,meson8-sdio", }, | ||
749 | { .compatible = "amlogic,meson8b-sdio", }, | ||
750 | { /* sentinel */ } | ||
751 | }; | ||
752 | MODULE_DEVICE_TABLE(of, meson_mx_mmc_of_match); | ||
753 | |||
754 | static struct platform_driver meson_mx_mmc_driver = { | ||
755 | .probe = meson_mx_mmc_probe, | ||
756 | .remove = meson_mx_mmc_remove, | ||
757 | .driver = { | ||
758 | .name = "meson-mx-sdio", | ||
759 | .of_match_table = of_match_ptr(meson_mx_mmc_of_match), | ||
760 | }, | ||
761 | }; | ||
762 | |||
763 | module_platform_driver(meson_mx_mmc_driver); | ||
764 | |||
765 | MODULE_DESCRIPTION("Meson6, Meson8 and Meson8b SDIO/MMC Host Driver"); | ||
766 | MODULE_AUTHOR("Carlo Caione <carlo@endlessm.com>"); | ||
767 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | ||
768 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f1f54a818489..e8a1bb1ae694 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -1658,7 +1658,7 @@ static int mmci_probe(struct amba_device *dev, | |||
1658 | 1658 | ||
1659 | /* Get regulators and the supported OCR mask */ | 1659 | /* Get regulators and the supported OCR mask */ |
1660 | ret = mmc_regulator_get_supply(mmc); | 1660 | ret = mmc_regulator_get_supply(mmc); |
1661 | if (ret == -EPROBE_DEFER) | 1661 | if (ret) |
1662 | goto clk_disable; | 1662 | goto clk_disable; |
1663 | 1663 | ||
1664 | if (!mmc->ocr_avail) | 1664 | if (!mmc->ocr_avail) |
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 267f7ab08420..6457a7d8880f 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #define SDC_RESP2 0x48 | 67 | #define SDC_RESP2 0x48 |
68 | #define SDC_RESP3 0x4c | 68 | #define SDC_RESP3 0x4c |
69 | #define SDC_BLK_NUM 0x50 | 69 | #define SDC_BLK_NUM 0x50 |
70 | #define SDC_ADV_CFG0 0x64 | ||
70 | #define EMMC_IOCON 0x7c | 71 | #define EMMC_IOCON 0x7c |
71 | #define SDC_ACMD_RESP 0x80 | 72 | #define SDC_ACMD_RESP 0x80 |
72 | #define MSDC_DMA_SA 0x90 | 73 | #define MSDC_DMA_SA 0x90 |
@@ -74,10 +75,14 @@ | |||
74 | #define MSDC_DMA_CFG 0x9c | 75 | #define MSDC_DMA_CFG 0x9c |
75 | #define MSDC_PATCH_BIT 0xb0 | 76 | #define MSDC_PATCH_BIT 0xb0 |
76 | #define MSDC_PATCH_BIT1 0xb4 | 77 | #define MSDC_PATCH_BIT1 0xb4 |
78 | #define MSDC_PATCH_BIT2 0xb8 | ||
77 | #define MSDC_PAD_TUNE 0xec | 79 | #define MSDC_PAD_TUNE 0xec |
80 | #define MSDC_PAD_TUNE0 0xf0 | ||
78 | #define PAD_DS_TUNE 0x188 | 81 | #define PAD_DS_TUNE 0x188 |
79 | #define PAD_CMD_TUNE 0x18c | 82 | #define PAD_CMD_TUNE 0x18c |
80 | #define EMMC50_CFG0 0x208 | 83 | #define EMMC50_CFG0 0x208 |
84 | #define EMMC50_CFG3 0x220 | ||
85 | #define SDC_FIFO_CFG 0x228 | ||
81 | 86 | ||
82 | /*--------------------------------------------------------------------------*/ | 87 | /*--------------------------------------------------------------------------*/ |
83 | /* Register Mask */ | 88 | /* Register Mask */ |
@@ -95,6 +100,9 @@ | |||
95 | #define MSDC_CFG_CKDIV (0xff << 8) /* RW */ | 100 | #define MSDC_CFG_CKDIV (0xff << 8) /* RW */ |
96 | #define MSDC_CFG_CKMOD (0x3 << 16) /* RW */ | 101 | #define MSDC_CFG_CKMOD (0x3 << 16) /* RW */ |
97 | #define MSDC_CFG_HS400_CK_MODE (0x1 << 18) /* RW */ | 102 | #define MSDC_CFG_HS400_CK_MODE (0x1 << 18) /* RW */ |
103 | #define MSDC_CFG_HS400_CK_MODE_EXTRA (0x1 << 22) /* RW */ | ||
104 | #define MSDC_CFG_CKDIV_EXTRA (0xfff << 8) /* RW */ | ||
105 | #define MSDC_CFG_CKMOD_EXTRA (0x3 << 20) /* RW */ | ||
98 | 106 | ||
99 | /* MSDC_IOCON mask */ | 107 | /* MSDC_IOCON mask */ |
100 | #define MSDC_IOCON_SDR104CKS (0x1 << 0) /* RW */ | 108 | #define MSDC_IOCON_SDR104CKS (0x1 << 0) /* RW */ |
@@ -183,6 +191,9 @@ | |||
183 | #define SDC_STS_CMDBUSY (0x1 << 1) /* RW */ | 191 | #define SDC_STS_CMDBUSY (0x1 << 1) /* RW */ |
184 | #define SDC_STS_SWR_COMPL (0x1 << 31) /* RW */ | 192 | #define SDC_STS_SWR_COMPL (0x1 << 31) /* RW */ |
185 | 193 | ||
194 | /* SDC_ADV_CFG0 mask */ | ||
195 | #define SDC_RX_ENHANCE_EN (0x1 << 20) /* RW */ | ||
196 | |||
186 | /* MSDC_DMA_CTRL mask */ | 197 | /* MSDC_DMA_CTRL mask */ |
187 | #define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ | 198 | #define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ |
188 | #define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ | 199 | #define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ |
@@ -212,11 +223,22 @@ | |||
212 | #define MSDC_PATCH_BIT_SPCPUSH (0x1 << 29) /* RW */ | 223 | #define MSDC_PATCH_BIT_SPCPUSH (0x1 << 29) /* RW */ |
213 | #define MSDC_PATCH_BIT_DECRCTMO (0x1 << 30) /* RW */ | 224 | #define MSDC_PATCH_BIT_DECRCTMO (0x1 << 30) /* RW */ |
214 | 225 | ||
226 | #define MSDC_PATCH_BIT1_STOP_DLY (0xf << 8) /* RW */ | ||
227 | |||
228 | #define MSDC_PATCH_BIT2_CFGRESP (0x1 << 15) /* RW */ | ||
229 | #define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28) /* RW */ | ||
230 | #define MSDC_PB2_RESPWAIT (0x3 << 2) /* RW */ | ||
231 | #define MSDC_PB2_RESPSTSENSEL (0x7 << 16) /* RW */ | ||
232 | #define MSDC_PB2_CRCSTSENSEL (0x7 << 29) /* RW */ | ||
233 | |||
215 | #define MSDC_PAD_TUNE_DATWRDLY (0x1f << 0) /* RW */ | 234 | #define MSDC_PAD_TUNE_DATWRDLY (0x1f << 0) /* RW */ |
216 | #define MSDC_PAD_TUNE_DATRRDLY (0x1f << 8) /* RW */ | 235 | #define MSDC_PAD_TUNE_DATRRDLY (0x1f << 8) /* RW */ |
217 | #define MSDC_PAD_TUNE_CMDRDLY (0x1f << 16) /* RW */ | 236 | #define MSDC_PAD_TUNE_CMDRDLY (0x1f << 16) /* RW */ |
218 | #define MSDC_PAD_TUNE_CMDRRDLY (0x1f << 22) /* RW */ | 237 | #define MSDC_PAD_TUNE_CMDRRDLY (0x1f << 22) /* RW */ |
219 | #define MSDC_PAD_TUNE_CLKTDLY (0x1f << 27) /* RW */ | 238 | #define MSDC_PAD_TUNE_CLKTDLY (0x1f << 27) /* RW */ |
239 | #define MSDC_PAD_TUNE_RXDLYSEL (0x1 << 15) /* RW */ | ||
240 | #define MSDC_PAD_TUNE_RD_SEL (0x1 << 13) /* RW */ | ||
241 | #define MSDC_PAD_TUNE_CMD_SEL (0x1 << 21) /* RW */ | ||
220 | 242 | ||
221 | #define PAD_DS_TUNE_DLY1 (0x1f << 2) /* RW */ | 243 | #define PAD_DS_TUNE_DLY1 (0x1f << 2) /* RW */ |
222 | #define PAD_DS_TUNE_DLY2 (0x1f << 7) /* RW */ | 244 | #define PAD_DS_TUNE_DLY2 (0x1f << 7) /* RW */ |
@@ -228,6 +250,11 @@ | |||
228 | #define EMMC50_CFG_CRCSTS_EDGE (0x1 << 3) /* RW */ | 250 | #define EMMC50_CFG_CRCSTS_EDGE (0x1 << 3) /* RW */ |
229 | #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4) /* RW */ | 251 | #define EMMC50_CFG_CFCSTS_SEL (0x1 << 4) /* RW */ |
230 | 252 | ||
253 | #define EMMC50_CFG3_OUTS_WR (0x1f << 0) /* RW */ | ||
254 | |||
255 | #define SDC_FIFO_CFG_WRVALIDSEL (0x1 << 24) /* RW */ | ||
256 | #define SDC_FIFO_CFG_RDVALIDSEL (0x1 << 25) /* RW */ | ||
257 | |||
231 | #define REQ_CMD_EIO (0x1 << 0) | 258 | #define REQ_CMD_EIO (0x1 << 0) |
232 | #define REQ_CMD_TMO (0x1 << 1) | 259 | #define REQ_CMD_TMO (0x1 << 1) |
233 | #define REQ_DAT_ERR (0x1 << 2) | 260 | #define REQ_DAT_ERR (0x1 << 2) |
@@ -290,9 +317,23 @@ struct msdc_save_para { | |||
290 | u32 pad_tune; | 317 | u32 pad_tune; |
291 | u32 patch_bit0; | 318 | u32 patch_bit0; |
292 | u32 patch_bit1; | 319 | u32 patch_bit1; |
320 | u32 patch_bit2; | ||
293 | u32 pad_ds_tune; | 321 | u32 pad_ds_tune; |
294 | u32 pad_cmd_tune; | 322 | u32 pad_cmd_tune; |
295 | u32 emmc50_cfg0; | 323 | u32 emmc50_cfg0; |
324 | u32 emmc50_cfg3; | ||
325 | u32 sdc_fifo_cfg; | ||
326 | }; | ||
327 | |||
328 | struct mtk_mmc_compatible { | ||
329 | u8 clk_div_bits; | ||
330 | bool hs400_tune; /* only used for MT8173 */ | ||
331 | u32 pad_tune_reg; | ||
332 | bool async_fifo; | ||
333 | bool data_tune; | ||
334 | bool busy_check; | ||
335 | bool stop_clk_fix; | ||
336 | bool enhance_rx; | ||
296 | }; | 337 | }; |
297 | 338 | ||
298 | struct msdc_tune_para { | 339 | struct msdc_tune_para { |
@@ -309,6 +350,7 @@ struct msdc_delay_phase { | |||
309 | 350 | ||
310 | struct msdc_host { | 351 | struct msdc_host { |
311 | struct device *dev; | 352 | struct device *dev; |
353 | const struct mtk_mmc_compatible *dev_comp; | ||
312 | struct mmc_host *mmc; /* mmc structure */ | 354 | struct mmc_host *mmc; /* mmc structure */ |
313 | int cmd_rsp; | 355 | int cmd_rsp; |
314 | 356 | ||
@@ -334,11 +376,13 @@ struct msdc_host { | |||
334 | 376 | ||
335 | struct clk *src_clk; /* msdc source clock */ | 377 | struct clk *src_clk; /* msdc source clock */ |
336 | struct clk *h_clk; /* msdc h_clk */ | 378 | struct clk *h_clk; /* msdc h_clk */ |
379 | struct clk *src_clk_cg; /* msdc source clock control gate */ | ||
337 | u32 mclk; /* mmc subsystem clock frequency */ | 380 | u32 mclk; /* mmc subsystem clock frequency */ |
338 | u32 src_clk_freq; /* source clock frequency */ | 381 | u32 src_clk_freq; /* source clock frequency */ |
339 | u32 sclk; /* SD/MS bus clock frequency */ | 382 | u32 sclk; /* SD/MS bus clock frequency */ |
340 | unsigned char timing; | 383 | unsigned char timing; |
341 | bool vqmmc_enabled; | 384 | bool vqmmc_enabled; |
385 | u32 latch_ck; | ||
342 | u32 hs400_ds_delay; | 386 | u32 hs400_ds_delay; |
343 | u32 hs200_cmd_int_delay; /* cmd internal delay for HS200/SDR104 */ | 387 | u32 hs200_cmd_int_delay; /* cmd internal delay for HS200/SDR104 */ |
344 | u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */ | 388 | u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */ |
@@ -350,6 +394,59 @@ struct msdc_host { | |||
350 | struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */ | 394 | struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */ |
351 | }; | 395 | }; |
352 | 396 | ||
397 | static const struct mtk_mmc_compatible mt8135_compat = { | ||
398 | .clk_div_bits = 8, | ||
399 | .hs400_tune = false, | ||
400 | .pad_tune_reg = MSDC_PAD_TUNE, | ||
401 | .async_fifo = false, | ||
402 | .data_tune = false, | ||
403 | .busy_check = false, | ||
404 | .stop_clk_fix = false, | ||
405 | .enhance_rx = false, | ||
406 | }; | ||
407 | |||
408 | static const struct mtk_mmc_compatible mt8173_compat = { | ||
409 | .clk_div_bits = 8, | ||
410 | .hs400_tune = true, | ||
411 | .pad_tune_reg = MSDC_PAD_TUNE, | ||
412 | .async_fifo = false, | ||
413 | .data_tune = false, | ||
414 | .busy_check = false, | ||
415 | .stop_clk_fix = false, | ||
416 | .enhance_rx = false, | ||
417 | }; | ||
418 | |||
419 | static const struct mtk_mmc_compatible mt2701_compat = { | ||
420 | .clk_div_bits = 12, | ||
421 | .hs400_tune = false, | ||
422 | .pad_tune_reg = MSDC_PAD_TUNE0, | ||
423 | .async_fifo = true, | ||
424 | .data_tune = true, | ||
425 | .busy_check = false, | ||
426 | .stop_clk_fix = false, | ||
427 | .enhance_rx = false, | ||
428 | }; | ||
429 | |||
430 | static const struct mtk_mmc_compatible mt2712_compat = { | ||
431 | .clk_div_bits = 12, | ||
432 | .hs400_tune = false, | ||
433 | .pad_tune_reg = MSDC_PAD_TUNE0, | ||
434 | .async_fifo = true, | ||
435 | .data_tune = true, | ||
436 | .busy_check = true, | ||
437 | .stop_clk_fix = true, | ||
438 | .enhance_rx = true, | ||
439 | }; | ||
440 | |||
441 | static const struct of_device_id msdc_of_ids[] = { | ||
442 | { .compatible = "mediatek,mt8135-mmc", .data = &mt8135_compat}, | ||
443 | { .compatible = "mediatek,mt8173-mmc", .data = &mt8173_compat}, | ||
444 | { .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat}, | ||
445 | { .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat}, | ||
446 | {} | ||
447 | }; | ||
448 | MODULE_DEVICE_TABLE(of, msdc_of_ids); | ||
449 | |||
353 | static void sdr_set_bits(void __iomem *reg, u32 bs) | 450 | static void sdr_set_bits(void __iomem *reg, u32 bs) |
354 | { | 451 | { |
355 | u32 val = readl(reg); | 452 | u32 val = readl(reg); |
@@ -509,7 +606,12 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) | |||
509 | timeout = (ns + clk_ns - 1) / clk_ns + clks; | 606 | timeout = (ns + clk_ns - 1) / clk_ns + clks; |
510 | /* in 1048576 sclk cycle unit */ | 607 | /* in 1048576 sclk cycle unit */ |
511 | timeout = (timeout + (0x1 << 20) - 1) >> 20; | 608 | timeout = (timeout + (0x1 << 20) - 1) >> 20; |
512 | sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &mode); | 609 | if (host->dev_comp->clk_div_bits == 8) |
610 | sdr_get_field(host->base + MSDC_CFG, | ||
611 | MSDC_CFG_CKMOD, &mode); | ||
612 | else | ||
613 | sdr_get_field(host->base + MSDC_CFG, | ||
614 | MSDC_CFG_CKMOD_EXTRA, &mode); | ||
513 | /*DDR mode will double the clk cycles for data timeout */ | 615 | /*DDR mode will double the clk cycles for data timeout */ |
514 | timeout = mode >= 2 ? timeout * 2 : timeout; | 616 | timeout = mode >= 2 ? timeout * 2 : timeout; |
515 | timeout = timeout > 1 ? timeout - 1 : 0; | 617 | timeout = timeout > 1 ? timeout - 1 : 0; |
@@ -520,6 +622,7 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) | |||
520 | 622 | ||
521 | static void msdc_gate_clock(struct msdc_host *host) | 623 | static void msdc_gate_clock(struct msdc_host *host) |
522 | { | 624 | { |
625 | clk_disable_unprepare(host->src_clk_cg); | ||
523 | clk_disable_unprepare(host->src_clk); | 626 | clk_disable_unprepare(host->src_clk); |
524 | clk_disable_unprepare(host->h_clk); | 627 | clk_disable_unprepare(host->h_clk); |
525 | } | 628 | } |
@@ -528,6 +631,7 @@ static void msdc_ungate_clock(struct msdc_host *host) | |||
528 | { | 631 | { |
529 | clk_prepare_enable(host->h_clk); | 632 | clk_prepare_enable(host->h_clk); |
530 | clk_prepare_enable(host->src_clk); | 633 | clk_prepare_enable(host->src_clk); |
634 | clk_prepare_enable(host->src_clk_cg); | ||
531 | while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) | 635 | while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) |
532 | cpu_relax(); | 636 | cpu_relax(); |
533 | } | 637 | } |
@@ -538,6 +642,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |||
538 | u32 flags; | 642 | u32 flags; |
539 | u32 div; | 643 | u32 div; |
540 | u32 sclk; | 644 | u32 sclk; |
645 | u32 tune_reg = host->dev_comp->pad_tune_reg; | ||
541 | 646 | ||
542 | if (!hz) { | 647 | if (!hz) { |
543 | dev_dbg(host->dev, "set mclk to 0\n"); | 648 | dev_dbg(host->dev, "set mclk to 0\n"); |
@@ -548,7 +653,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |||
548 | 653 | ||
549 | flags = readl(host->base + MSDC_INTEN); | 654 | flags = readl(host->base + MSDC_INTEN); |
550 | sdr_clr_bits(host->base + MSDC_INTEN, flags); | 655 | sdr_clr_bits(host->base + MSDC_INTEN, flags); |
551 | sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE); | 656 | if (host->dev_comp->clk_div_bits == 8) |
657 | sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE); | ||
658 | else | ||
659 | sdr_clr_bits(host->base + MSDC_CFG, | ||
660 | MSDC_CFG_HS400_CK_MODE_EXTRA); | ||
552 | if (timing == MMC_TIMING_UHS_DDR50 || | 661 | if (timing == MMC_TIMING_UHS_DDR50 || |
553 | timing == MMC_TIMING_MMC_DDR52 || | 662 | timing == MMC_TIMING_MMC_DDR52 || |
554 | timing == MMC_TIMING_MMC_HS400) { | 663 | timing == MMC_TIMING_MMC_HS400) { |
@@ -568,8 +677,12 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |||
568 | 677 | ||
569 | if (timing == MMC_TIMING_MMC_HS400 && | 678 | if (timing == MMC_TIMING_MMC_HS400 && |
570 | hz >= (host->src_clk_freq >> 1)) { | 679 | hz >= (host->src_clk_freq >> 1)) { |
571 | sdr_set_bits(host->base + MSDC_CFG, | 680 | if (host->dev_comp->clk_div_bits == 8) |
572 | MSDC_CFG_HS400_CK_MODE); | 681 | sdr_set_bits(host->base + MSDC_CFG, |
682 | MSDC_CFG_HS400_CK_MODE); | ||
683 | else | ||
684 | sdr_set_bits(host->base + MSDC_CFG, | ||
685 | MSDC_CFG_HS400_CK_MODE_EXTRA); | ||
573 | sclk = host->src_clk_freq >> 1; | 686 | sclk = host->src_clk_freq >> 1; |
574 | div = 0; /* div is ignore when bit18 is set */ | 687 | div = 0; /* div is ignore when bit18 is set */ |
575 | } | 688 | } |
@@ -587,11 +700,31 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |||
587 | sclk = (host->src_clk_freq >> 2) / div; | 700 | sclk = (host->src_clk_freq >> 2) / div; |
588 | } | 701 | } |
589 | } | 702 | } |
590 | sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV, | 703 | sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); |
591 | (mode << 8) | div); | 704 | /* |
592 | sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); | 705 | * As src_clk/HCLK use the same bit to gate/ungate, |
706 | * So if want to only gate src_clk, need gate its parent(mux). | ||
707 | */ | ||
708 | if (host->src_clk_cg) | ||
709 | clk_disable_unprepare(host->src_clk_cg); | ||
710 | else | ||
711 | clk_disable_unprepare(clk_get_parent(host->src_clk)); | ||
712 | if (host->dev_comp->clk_div_bits == 8) | ||
713 | sdr_set_field(host->base + MSDC_CFG, | ||
714 | MSDC_CFG_CKMOD | MSDC_CFG_CKDIV, | ||
715 | (mode << 8) | div); | ||
716 | else | ||
717 | sdr_set_field(host->base + MSDC_CFG, | ||
718 | MSDC_CFG_CKMOD_EXTRA | MSDC_CFG_CKDIV_EXTRA, | ||
719 | (mode << 12) | div); | ||
720 | if (host->src_clk_cg) | ||
721 | clk_prepare_enable(host->src_clk_cg); | ||
722 | else | ||
723 | clk_prepare_enable(clk_get_parent(host->src_clk)); | ||
724 | |||
593 | while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) | 725 | while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) |
594 | cpu_relax(); | 726 | cpu_relax(); |
727 | sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); | ||
595 | host->sclk = sclk; | 728 | host->sclk = sclk; |
596 | host->mclk = hz; | 729 | host->mclk = hz; |
597 | host->timing = timing; | 730 | host->timing = timing; |
@@ -605,15 +738,16 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) | |||
605 | */ | 738 | */ |
606 | if (host->sclk <= 52000000) { | 739 | if (host->sclk <= 52000000) { |
607 | writel(host->def_tune_para.iocon, host->base + MSDC_IOCON); | 740 | writel(host->def_tune_para.iocon, host->base + MSDC_IOCON); |
608 | writel(host->def_tune_para.pad_tune, host->base + MSDC_PAD_TUNE); | 741 | writel(host->def_tune_para.pad_tune, host->base + tune_reg); |
609 | } else { | 742 | } else { |
610 | writel(host->saved_tune_para.iocon, host->base + MSDC_IOCON); | 743 | writel(host->saved_tune_para.iocon, host->base + MSDC_IOCON); |
611 | writel(host->saved_tune_para.pad_tune, host->base + MSDC_PAD_TUNE); | 744 | writel(host->saved_tune_para.pad_tune, host->base + tune_reg); |
612 | writel(host->saved_tune_para.pad_cmd_tune, | 745 | writel(host->saved_tune_para.pad_cmd_tune, |
613 | host->base + PAD_CMD_TUNE); | 746 | host->base + PAD_CMD_TUNE); |
614 | } | 747 | } |
615 | 748 | ||
616 | if (timing == MMC_TIMING_MMC_HS400) | 749 | if (timing == MMC_TIMING_MMC_HS400 && |
750 | host->dev_comp->hs400_tune) | ||
617 | sdr_set_field(host->base + PAD_CMD_TUNE, | 751 | sdr_set_field(host->base + PAD_CMD_TUNE, |
618 | MSDC_PAD_TUNE_CMDRRDLY, | 752 | MSDC_PAD_TUNE_CMDRRDLY, |
619 | host->hs400_cmd_int_delay); | 753 | host->hs400_cmd_int_delay); |
@@ -1165,6 +1299,7 @@ static irqreturn_t msdc_irq(int irq, void *dev_id) | |||
1165 | static void msdc_init_hw(struct msdc_host *host) | 1299 | static void msdc_init_hw(struct msdc_host *host) |
1166 | { | 1300 | { |
1167 | u32 val; | 1301 | u32 val; |
1302 | u32 tune_reg = host->dev_comp->pad_tune_reg; | ||
1168 | 1303 | ||
1169 | /* Configure to MMC/SD mode, clock free running */ | 1304 | /* Configure to MMC/SD mode, clock free running */ |
1170 | sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN); | 1305 | sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN); |
@@ -1180,14 +1315,53 @@ static void msdc_init_hw(struct msdc_host *host) | |||
1180 | val = readl(host->base + MSDC_INT); | 1315 | val = readl(host->base + MSDC_INT); |
1181 | writel(val, host->base + MSDC_INT); | 1316 | writel(val, host->base + MSDC_INT); |
1182 | 1317 | ||
1183 | writel(0, host->base + MSDC_PAD_TUNE); | 1318 | writel(0, host->base + tune_reg); |
1184 | writel(0, host->base + MSDC_IOCON); | 1319 | writel(0, host->base + MSDC_IOCON); |
1185 | sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0); | 1320 | sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0); |
1186 | writel(0x403c0046, host->base + MSDC_PATCH_BIT); | 1321 | writel(0x403c0046, host->base + MSDC_PATCH_BIT); |
1187 | sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); | 1322 | sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); |
1188 | writel(0xffff0089, host->base + MSDC_PATCH_BIT1); | 1323 | writel(0xffff4089, host->base + MSDC_PATCH_BIT1); |
1189 | sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL); | 1324 | sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL); |
1190 | 1325 | ||
1326 | if (host->dev_comp->stop_clk_fix) { | ||
1327 | sdr_set_field(host->base + MSDC_PATCH_BIT1, | ||
1328 | MSDC_PATCH_BIT1_STOP_DLY, 3); | ||
1329 | sdr_clr_bits(host->base + SDC_FIFO_CFG, | ||
1330 | SDC_FIFO_CFG_WRVALIDSEL); | ||
1331 | sdr_clr_bits(host->base + SDC_FIFO_CFG, | ||
1332 | SDC_FIFO_CFG_RDVALIDSEL); | ||
1333 | } | ||
1334 | |||
1335 | if (host->dev_comp->busy_check) | ||
1336 | sdr_clr_bits(host->base + MSDC_PATCH_BIT1, (1 << 7)); | ||
1337 | |||
1338 | if (host->dev_comp->async_fifo) { | ||
1339 | sdr_set_field(host->base + MSDC_PATCH_BIT2, | ||
1340 | MSDC_PB2_RESPWAIT, 3); | ||
1341 | if (host->dev_comp->enhance_rx) { | ||
1342 | sdr_set_bits(host->base + SDC_ADV_CFG0, | ||
1343 | SDC_RX_ENHANCE_EN); | ||
1344 | } else { | ||
1345 | sdr_set_field(host->base + MSDC_PATCH_BIT2, | ||
1346 | MSDC_PB2_RESPSTSENSEL, 2); | ||
1347 | sdr_set_field(host->base + MSDC_PATCH_BIT2, | ||
1348 | MSDC_PB2_CRCSTSENSEL, 2); | ||
1349 | } | ||
1350 | /* use async fifo, then no need tune internal delay */ | ||
1351 | sdr_clr_bits(host->base + MSDC_PATCH_BIT2, | ||
1352 | MSDC_PATCH_BIT2_CFGRESP); | ||
1353 | sdr_set_bits(host->base + MSDC_PATCH_BIT2, | ||
1354 | MSDC_PATCH_BIT2_CFGCRCSTS); | ||
1355 | } | ||
1356 | |||
1357 | if (host->dev_comp->data_tune) { | ||
1358 | sdr_set_bits(host->base + tune_reg, | ||
1359 | MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); | ||
1360 | } else { | ||
1361 | /* choose clock tune */ | ||
1362 | sdr_set_bits(host->base + tune_reg, MSDC_PAD_TUNE_RXDLYSEL); | ||
1363 | } | ||
1364 | |||
1191 | /* Configure to enable SDIO mode. | 1365 | /* Configure to enable SDIO mode. |
1192 | * it's must otherwise sdio cmd5 failed | 1366 | * it's must otherwise sdio cmd5 failed |
1193 | */ | 1367 | */ |
@@ -1200,7 +1374,9 @@ static void msdc_init_hw(struct msdc_host *host) | |||
1200 | sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3); | 1374 | sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3); |
1201 | 1375 | ||
1202 | host->def_tune_para.iocon = readl(host->base + MSDC_IOCON); | 1376 | host->def_tune_para.iocon = readl(host->base + MSDC_IOCON); |
1203 | host->def_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE); | 1377 | host->def_tune_para.pad_tune = readl(host->base + tune_reg); |
1378 | host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON); | ||
1379 | host->saved_tune_para.pad_tune = readl(host->base + tune_reg); | ||
1204 | dev_dbg(host->dev, "init hardware done!"); | 1380 | dev_dbg(host->dev, "init hardware done!"); |
1205 | } | 1381 | } |
1206 | 1382 | ||
@@ -1343,18 +1519,19 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode) | |||
1343 | struct msdc_delay_phase internal_delay_phase; | 1519 | struct msdc_delay_phase internal_delay_phase; |
1344 | u8 final_delay, final_maxlen; | 1520 | u8 final_delay, final_maxlen; |
1345 | u32 internal_delay = 0; | 1521 | u32 internal_delay = 0; |
1522 | u32 tune_reg = host->dev_comp->pad_tune_reg; | ||
1346 | int cmd_err; | 1523 | int cmd_err; |
1347 | int i, j; | 1524 | int i, j; |
1348 | 1525 | ||
1349 | if (mmc->ios.timing == MMC_TIMING_MMC_HS200 || | 1526 | if (mmc->ios.timing == MMC_TIMING_MMC_HS200 || |
1350 | mmc->ios.timing == MMC_TIMING_UHS_SDR104) | 1527 | mmc->ios.timing == MMC_TIMING_UHS_SDR104) |
1351 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1528 | sdr_set_field(host->base + tune_reg, |
1352 | MSDC_PAD_TUNE_CMDRRDLY, | 1529 | MSDC_PAD_TUNE_CMDRRDLY, |
1353 | host->hs200_cmd_int_delay); | 1530 | host->hs200_cmd_int_delay); |
1354 | 1531 | ||
1355 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); | 1532 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); |
1356 | for (i = 0 ; i < PAD_DELAY_MAX; i++) { | 1533 | for (i = 0 ; i < PAD_DELAY_MAX; i++) { |
1357 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1534 | sdr_set_field(host->base + tune_reg, |
1358 | MSDC_PAD_TUNE_CMDRDLY, i); | 1535 | MSDC_PAD_TUNE_CMDRDLY, i); |
1359 | /* | 1536 | /* |
1360 | * Using the same parameters, it may sometimes pass the test, | 1537 | * Using the same parameters, it may sometimes pass the test, |
@@ -1373,12 +1550,13 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode) | |||
1373 | } | 1550 | } |
1374 | final_rise_delay = get_best_delay(host, rise_delay); | 1551 | final_rise_delay = get_best_delay(host, rise_delay); |
1375 | /* if rising edge has enough margin, then do not scan falling edge */ | 1552 | /* if rising edge has enough margin, then do not scan falling edge */ |
1376 | if (final_rise_delay.maxlen >= 12 && final_rise_delay.start < 4) | 1553 | if (final_rise_delay.maxlen >= 12 || |
1554 | (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4)) | ||
1377 | goto skip_fall; | 1555 | goto skip_fall; |
1378 | 1556 | ||
1379 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); | 1557 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); |
1380 | for (i = 0; i < PAD_DELAY_MAX; i++) { | 1558 | for (i = 0; i < PAD_DELAY_MAX; i++) { |
1381 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1559 | sdr_set_field(host->base + tune_reg, |
1382 | MSDC_PAD_TUNE_CMDRDLY, i); | 1560 | MSDC_PAD_TUNE_CMDRDLY, i); |
1383 | /* | 1561 | /* |
1384 | * Using the same parameters, it may sometimes pass the test, | 1562 | * Using the same parameters, it may sometimes pass the test, |
@@ -1403,20 +1581,20 @@ skip_fall: | |||
1403 | final_maxlen = final_fall_delay.maxlen; | 1581 | final_maxlen = final_fall_delay.maxlen; |
1404 | if (final_maxlen == final_rise_delay.maxlen) { | 1582 | if (final_maxlen == final_rise_delay.maxlen) { |
1405 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); | 1583 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); |
1406 | sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, | 1584 | sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRDLY, |
1407 | final_rise_delay.final_phase); | 1585 | final_rise_delay.final_phase); |
1408 | final_delay = final_rise_delay.final_phase; | 1586 | final_delay = final_rise_delay.final_phase; |
1409 | } else { | 1587 | } else { |
1410 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); | 1588 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL); |
1411 | sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY, | 1589 | sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRDLY, |
1412 | final_fall_delay.final_phase); | 1590 | final_fall_delay.final_phase); |
1413 | final_delay = final_fall_delay.final_phase; | 1591 | final_delay = final_fall_delay.final_phase; |
1414 | } | 1592 | } |
1415 | if (host->hs200_cmd_int_delay) | 1593 | if (host->dev_comp->async_fifo || host->hs200_cmd_int_delay) |
1416 | goto skip_internal; | 1594 | goto skip_internal; |
1417 | 1595 | ||
1418 | for (i = 0; i < PAD_DELAY_MAX; i++) { | 1596 | for (i = 0; i < PAD_DELAY_MAX; i++) { |
1419 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1597 | sdr_set_field(host->base + tune_reg, |
1420 | MSDC_PAD_TUNE_CMDRRDLY, i); | 1598 | MSDC_PAD_TUNE_CMDRRDLY, i); |
1421 | mmc_send_tuning(mmc, opcode, &cmd_err); | 1599 | mmc_send_tuning(mmc, opcode, &cmd_err); |
1422 | if (!cmd_err) | 1600 | if (!cmd_err) |
@@ -1424,7 +1602,7 @@ skip_fall: | |||
1424 | } | 1602 | } |
1425 | dev_dbg(host->dev, "Final internal delay: 0x%x\n", internal_delay); | 1603 | dev_dbg(host->dev, "Final internal delay: 0x%x\n", internal_delay); |
1426 | internal_delay_phase = get_best_delay(host, internal_delay); | 1604 | internal_delay_phase = get_best_delay(host, internal_delay); |
1427 | sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, | 1605 | sdr_set_field(host->base + tune_reg, MSDC_PAD_TUNE_CMDRRDLY, |
1428 | internal_delay_phase.final_phase); | 1606 | internal_delay_phase.final_phase); |
1429 | skip_internal: | 1607 | skip_internal: |
1430 | dev_dbg(host->dev, "Final cmd pad delay: %x\n", final_delay); | 1608 | dev_dbg(host->dev, "Final cmd pad delay: %x\n", final_delay); |
@@ -1486,12 +1664,15 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode) | |||
1486 | u32 rise_delay = 0, fall_delay = 0; | 1664 | u32 rise_delay = 0, fall_delay = 0; |
1487 | struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,}; | 1665 | struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,}; |
1488 | u8 final_delay, final_maxlen; | 1666 | u8 final_delay, final_maxlen; |
1667 | u32 tune_reg = host->dev_comp->pad_tune_reg; | ||
1489 | int i, ret; | 1668 | int i, ret; |
1490 | 1669 | ||
1670 | sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_INT_DAT_LATCH_CK_SEL, | ||
1671 | host->latch_ck); | ||
1491 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); | 1672 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); |
1492 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); | 1673 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); |
1493 | for (i = 0 ; i < PAD_DELAY_MAX; i++) { | 1674 | for (i = 0 ; i < PAD_DELAY_MAX; i++) { |
1494 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1675 | sdr_set_field(host->base + tune_reg, |
1495 | MSDC_PAD_TUNE_DATRRDLY, i); | 1676 | MSDC_PAD_TUNE_DATRRDLY, i); |
1496 | ret = mmc_send_tuning(mmc, opcode, NULL); | 1677 | ret = mmc_send_tuning(mmc, opcode, NULL); |
1497 | if (!ret) | 1678 | if (!ret) |
@@ -1506,7 +1687,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode) | |||
1506 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); | 1687 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); |
1507 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); | 1688 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); |
1508 | for (i = 0; i < PAD_DELAY_MAX; i++) { | 1689 | for (i = 0; i < PAD_DELAY_MAX; i++) { |
1509 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1690 | sdr_set_field(host->base + tune_reg, |
1510 | MSDC_PAD_TUNE_DATRRDLY, i); | 1691 | MSDC_PAD_TUNE_DATRRDLY, i); |
1511 | ret = mmc_send_tuning(mmc, opcode, NULL); | 1692 | ret = mmc_send_tuning(mmc, opcode, NULL); |
1512 | if (!ret) | 1693 | if (!ret) |
@@ -1519,14 +1700,14 @@ skip_fall: | |||
1519 | if (final_maxlen == final_rise_delay.maxlen) { | 1700 | if (final_maxlen == final_rise_delay.maxlen) { |
1520 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); | 1701 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); |
1521 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); | 1702 | sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); |
1522 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1703 | sdr_set_field(host->base + tune_reg, |
1523 | MSDC_PAD_TUNE_DATRRDLY, | 1704 | MSDC_PAD_TUNE_DATRRDLY, |
1524 | final_rise_delay.final_phase); | 1705 | final_rise_delay.final_phase); |
1525 | final_delay = final_rise_delay.final_phase; | 1706 | final_delay = final_rise_delay.final_phase; |
1526 | } else { | 1707 | } else { |
1527 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); | 1708 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_DSPL); |
1528 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); | 1709 | sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL); |
1529 | sdr_set_field(host->base + MSDC_PAD_TUNE, | 1710 | sdr_set_field(host->base + tune_reg, |
1530 | MSDC_PAD_TUNE_DATRRDLY, | 1711 | MSDC_PAD_TUNE_DATRRDLY, |
1531 | final_fall_delay.final_phase); | 1712 | final_fall_delay.final_phase); |
1532 | final_delay = final_fall_delay.final_phase; | 1713 | final_delay = final_fall_delay.final_phase; |
@@ -1540,8 +1721,10 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1540 | { | 1721 | { |
1541 | struct msdc_host *host = mmc_priv(mmc); | 1722 | struct msdc_host *host = mmc_priv(mmc); |
1542 | int ret; | 1723 | int ret; |
1724 | u32 tune_reg = host->dev_comp->pad_tune_reg; | ||
1543 | 1725 | ||
1544 | if (host->hs400_mode) | 1726 | if (host->hs400_mode && |
1727 | host->dev_comp->hs400_tune) | ||
1545 | ret = hs400_tune_response(mmc, opcode); | 1728 | ret = hs400_tune_response(mmc, opcode); |
1546 | else | 1729 | else |
1547 | ret = msdc_tune_response(mmc, opcode); | 1730 | ret = msdc_tune_response(mmc, opcode); |
@@ -1556,7 +1739,7 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1556 | } | 1739 | } |
1557 | 1740 | ||
1558 | host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON); | 1741 | host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON); |
1559 | host->saved_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE); | 1742 | host->saved_tune_para.pad_tune = readl(host->base + tune_reg); |
1560 | host->saved_tune_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE); | 1743 | host->saved_tune_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE); |
1561 | return ret; | 1744 | return ret; |
1562 | } | 1745 | } |
@@ -1567,6 +1750,11 @@ static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1567 | host->hs400_mode = true; | 1750 | host->hs400_mode = true; |
1568 | 1751 | ||
1569 | writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); | 1752 | writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE); |
1753 | /* hs400 mode must set it to 0 */ | ||
1754 | sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS); | ||
1755 | /* to improve read performance, set outstanding to 2 */ | ||
1756 | sdr_set_field(host->base + EMMC50_CFG3, EMMC50_CFG3_OUTS_WR, 2); | ||
1757 | |||
1570 | return 0; | 1758 | return 0; |
1571 | } | 1759 | } |
1572 | 1760 | ||
@@ -1596,6 +1784,9 @@ static const struct mmc_host_ops mt_msdc_ops = { | |||
1596 | static void msdc_of_property_parse(struct platform_device *pdev, | 1784 | static void msdc_of_property_parse(struct platform_device *pdev, |
1597 | struct msdc_host *host) | 1785 | struct msdc_host *host) |
1598 | { | 1786 | { |
1787 | of_property_read_u32(pdev->dev.of_node, "mediatek,latch-ck", | ||
1788 | &host->latch_ck); | ||
1789 | |||
1599 | of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay", | 1790 | of_property_read_u32(pdev->dev.of_node, "hs400-ds-delay", |
1600 | &host->hs400_ds_delay); | 1791 | &host->hs400_ds_delay); |
1601 | 1792 | ||
@@ -1617,12 +1808,17 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1617 | struct mmc_host *mmc; | 1808 | struct mmc_host *mmc; |
1618 | struct msdc_host *host; | 1809 | struct msdc_host *host; |
1619 | struct resource *res; | 1810 | struct resource *res; |
1811 | const struct of_device_id *of_id; | ||
1620 | int ret; | 1812 | int ret; |
1621 | 1813 | ||
1622 | if (!pdev->dev.of_node) { | 1814 | if (!pdev->dev.of_node) { |
1623 | dev_err(&pdev->dev, "No DT found\n"); | 1815 | dev_err(&pdev->dev, "No DT found\n"); |
1624 | return -EINVAL; | 1816 | return -EINVAL; |
1625 | } | 1817 | } |
1818 | |||
1819 | of_id = of_match_node(msdc_of_ids, pdev->dev.of_node); | ||
1820 | if (!of_id) | ||
1821 | return -EINVAL; | ||
1626 | /* Allocate MMC host for this device */ | 1822 | /* Allocate MMC host for this device */ |
1627 | mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); | 1823 | mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); |
1628 | if (!mmc) | 1824 | if (!mmc) |
@@ -1641,7 +1837,7 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1641 | } | 1837 | } |
1642 | 1838 | ||
1643 | ret = mmc_regulator_get_supply(mmc); | 1839 | ret = mmc_regulator_get_supply(mmc); |
1644 | if (ret == -EPROBE_DEFER) | 1840 | if (ret) |
1645 | goto host_free; | 1841 | goto host_free; |
1646 | 1842 | ||
1647 | host->src_clk = devm_clk_get(&pdev->dev, "source"); | 1843 | host->src_clk = devm_clk_get(&pdev->dev, "source"); |
@@ -1656,6 +1852,11 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1656 | goto host_free; | 1852 | goto host_free; |
1657 | } | 1853 | } |
1658 | 1854 | ||
1855 | /*source clock control gate is optional clock*/ | ||
1856 | host->src_clk_cg = devm_clk_get(&pdev->dev, "source_cg"); | ||
1857 | if (IS_ERR(host->src_clk_cg)) | ||
1858 | host->src_clk_cg = NULL; | ||
1859 | |||
1659 | host->irq = platform_get_irq(pdev, 0); | 1860 | host->irq = platform_get_irq(pdev, 0); |
1660 | if (host->irq < 0) { | 1861 | if (host->irq < 0) { |
1661 | ret = -EINVAL; | 1862 | ret = -EINVAL; |
@@ -1686,11 +1887,15 @@ static int msdc_drv_probe(struct platform_device *pdev) | |||
1686 | msdc_of_property_parse(pdev, host); | 1887 | msdc_of_property_parse(pdev, host); |
1687 | 1888 | ||
1688 | host->dev = &pdev->dev; | 1889 | host->dev = &pdev->dev; |
1890 | host->dev_comp = of_id->data; | ||
1689 | host->mmc = mmc; | 1891 | host->mmc = mmc; |
1690 | host->src_clk_freq = clk_get_rate(host->src_clk); | 1892 | host->src_clk_freq = clk_get_rate(host->src_clk); |
1691 | /* Set host parameters to mmc */ | 1893 | /* Set host parameters to mmc */ |
1692 | mmc->ops = &mt_msdc_ops; | 1894 | mmc->ops = &mt_msdc_ops; |
1693 | mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255); | 1895 | if (host->dev_comp->clk_div_bits == 8) |
1896 | mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 255); | ||
1897 | else | ||
1898 | mmc->f_min = DIV_ROUND_UP(host->src_clk_freq, 4 * 4095); | ||
1694 | 1899 | ||
1695 | mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; | 1900 | mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; |
1696 | /* MMC core transfer sizes tunable parameters */ | 1901 | /* MMC core transfer sizes tunable parameters */ |
@@ -1788,28 +1993,38 @@ static int msdc_drv_remove(struct platform_device *pdev) | |||
1788 | #ifdef CONFIG_PM | 1993 | #ifdef CONFIG_PM |
1789 | static void msdc_save_reg(struct msdc_host *host) | 1994 | static void msdc_save_reg(struct msdc_host *host) |
1790 | { | 1995 | { |
1996 | u32 tune_reg = host->dev_comp->pad_tune_reg; | ||
1997 | |||
1791 | host->save_para.msdc_cfg = readl(host->base + MSDC_CFG); | 1998 | host->save_para.msdc_cfg = readl(host->base + MSDC_CFG); |
1792 | host->save_para.iocon = readl(host->base + MSDC_IOCON); | 1999 | host->save_para.iocon = readl(host->base + MSDC_IOCON); |
1793 | host->save_para.sdc_cfg = readl(host->base + SDC_CFG); | 2000 | host->save_para.sdc_cfg = readl(host->base + SDC_CFG); |
1794 | host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE); | 2001 | host->save_para.pad_tune = readl(host->base + tune_reg); |
1795 | host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT); | 2002 | host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT); |
1796 | host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1); | 2003 | host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1); |
2004 | host->save_para.patch_bit2 = readl(host->base + MSDC_PATCH_BIT2); | ||
1797 | host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE); | 2005 | host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE); |
1798 | host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE); | 2006 | host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE); |
1799 | host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0); | 2007 | host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0); |
2008 | host->save_para.emmc50_cfg3 = readl(host->base + EMMC50_CFG3); | ||
2009 | host->save_para.sdc_fifo_cfg = readl(host->base + SDC_FIFO_CFG); | ||
1800 | } | 2010 | } |
1801 | 2011 | ||
1802 | static void msdc_restore_reg(struct msdc_host *host) | 2012 | static void msdc_restore_reg(struct msdc_host *host) |
1803 | { | 2013 | { |
2014 | u32 tune_reg = host->dev_comp->pad_tune_reg; | ||
2015 | |||
1804 | writel(host->save_para.msdc_cfg, host->base + MSDC_CFG); | 2016 | writel(host->save_para.msdc_cfg, host->base + MSDC_CFG); |
1805 | writel(host->save_para.iocon, host->base + MSDC_IOCON); | 2017 | writel(host->save_para.iocon, host->base + MSDC_IOCON); |
1806 | writel(host->save_para.sdc_cfg, host->base + SDC_CFG); | 2018 | writel(host->save_para.sdc_cfg, host->base + SDC_CFG); |
1807 | writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE); | 2019 | writel(host->save_para.pad_tune, host->base + tune_reg); |
1808 | writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT); | 2020 | writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT); |
1809 | writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1); | 2021 | writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1); |
2022 | writel(host->save_para.patch_bit2, host->base + MSDC_PATCH_BIT2); | ||
1810 | writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE); | 2023 | writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE); |
1811 | writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE); | 2024 | writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE); |
1812 | writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0); | 2025 | writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0); |
2026 | writel(host->save_para.emmc50_cfg3, host->base + EMMC50_CFG3); | ||
2027 | writel(host->save_para.sdc_fifo_cfg, host->base + SDC_FIFO_CFG); | ||
1813 | } | 2028 | } |
1814 | 2029 | ||
1815 | static int msdc_runtime_suspend(struct device *dev) | 2030 | static int msdc_runtime_suspend(struct device *dev) |
@@ -1839,12 +2054,6 @@ static const struct dev_pm_ops msdc_dev_pm_ops = { | |||
1839 | SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL) | 2054 | SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL) |
1840 | }; | 2055 | }; |
1841 | 2056 | ||
1842 | static const struct of_device_id msdc_of_ids[] = { | ||
1843 | { .compatible = "mediatek,mt8135-mmc", }, | ||
1844 | {} | ||
1845 | }; | ||
1846 | MODULE_DEVICE_TABLE(of, msdc_of_ids); | ||
1847 | |||
1848 | static struct platform_driver mt_msdc_driver = { | 2057 | static struct platform_driver mt_msdc_driver = { |
1849 | .probe = msdc_drv_probe, | 2058 | .probe = msdc_drv_probe, |
1850 | .remove = msdc_drv_remove, | 2059 | .remove = msdc_drv_remove, |
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index 58d74b8d6c79..210247b3d11a 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
@@ -508,9 +508,9 @@ static irqreturn_t mvsd_irq(int irq, void *dev) | |||
508 | return IRQ_NONE; | 508 | return IRQ_NONE; |
509 | } | 509 | } |
510 | 510 | ||
511 | static void mvsd_timeout_timer(unsigned long data) | 511 | static void mvsd_timeout_timer(struct timer_list *t) |
512 | { | 512 | { |
513 | struct mvsd_host *host = (struct mvsd_host *)data; | 513 | struct mvsd_host *host = from_timer(host, t, timer); |
514 | void __iomem *iobase = host->base; | 514 | void __iomem *iobase = host->base; |
515 | struct mmc_request *mrq; | 515 | struct mmc_request *mrq; |
516 | unsigned long flags; | 516 | unsigned long flags; |
@@ -776,7 +776,7 @@ static int mvsd_probe(struct platform_device *pdev) | |||
776 | goto out; | 776 | goto out; |
777 | } | 777 | } |
778 | 778 | ||
779 | setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host); | 779 | timer_setup(&host->timer, mvsd_timeout_timer, 0); |
780 | platform_set_drvdata(pdev, mmc); | 780 | platform_set_drvdata(pdev, mmc); |
781 | ret = mmc_add_host(mmc); | 781 | ret = mmc_add_host(mmc); |
782 | if (ret) | 782 | if (ret) |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 1d5418e4efae..5ff8ef7223cc 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -963,10 +963,9 @@ static bool filter(struct dma_chan *chan, void *param) | |||
963 | return true; | 963 | return true; |
964 | } | 964 | } |
965 | 965 | ||
966 | static void mxcmci_watchdog(unsigned long data) | 966 | static void mxcmci_watchdog(struct timer_list *t) |
967 | { | 967 | { |
968 | struct mmc_host *mmc = (struct mmc_host *)data; | 968 | struct mxcmci_host *host = from_timer(host, t, watchdog); |
969 | struct mxcmci_host *host = mmc_priv(mmc); | ||
970 | struct mmc_request *req = host->req; | 969 | struct mmc_request *req = host->req; |
971 | unsigned int stat = mxcmci_readl(host, MMC_REG_STATUS); | 970 | unsigned int stat = mxcmci_readl(host, MMC_REG_STATUS); |
972 | 971 | ||
@@ -1075,7 +1074,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1075 | dat3_card_detect = true; | 1074 | dat3_card_detect = true; |
1076 | 1075 | ||
1077 | ret = mmc_regulator_get_supply(mmc); | 1076 | ret = mmc_regulator_get_supply(mmc); |
1078 | if (ret == -EPROBE_DEFER) | 1077 | if (ret) |
1079 | goto out_free; | 1078 | goto out_free; |
1080 | 1079 | ||
1081 | if (!mmc->ocr_avail) { | 1080 | if (!mmc->ocr_avail) { |
@@ -1165,9 +1164,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
1165 | goto out_free_dma; | 1164 | goto out_free_dma; |
1166 | } | 1165 | } |
1167 | 1166 | ||
1168 | init_timer(&host->watchdog); | 1167 | timer_setup(&host->watchdog, mxcmci_watchdog, 0); |
1169 | host->watchdog.function = &mxcmci_watchdog; | ||
1170 | host->watchdog.data = (unsigned long)mmc; | ||
1171 | 1168 | ||
1172 | mmc_add_host(mmc); | 1169 | mmc_add_host(mmc); |
1173 | 1170 | ||
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index bd49f34d7654..adf32682f27a 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -625,9 +625,9 @@ static void mmc_omap_abort_command(struct work_struct *work) | |||
625 | } | 625 | } |
626 | 626 | ||
627 | static void | 627 | static void |
628 | mmc_omap_cmd_timer(unsigned long data) | 628 | mmc_omap_cmd_timer(struct timer_list *t) |
629 | { | 629 | { |
630 | struct mmc_omap_host *host = (struct mmc_omap_host *) data; | 630 | struct mmc_omap_host *host = from_timer(host, t, cmd_abort_timer); |
631 | unsigned long flags; | 631 | unsigned long flags; |
632 | 632 | ||
633 | spin_lock_irqsave(&host->slot_lock, flags); | 633 | spin_lock_irqsave(&host->slot_lock, flags); |
@@ -654,9 +654,9 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host) | |||
654 | } | 654 | } |
655 | 655 | ||
656 | static void | 656 | static void |
657 | mmc_omap_clk_timer(unsigned long data) | 657 | mmc_omap_clk_timer(struct timer_list *t) |
658 | { | 658 | { |
659 | struct mmc_omap_host *host = (struct mmc_omap_host *) data; | 659 | struct mmc_omap_host *host = from_timer(host, t, clk_timer); |
660 | 660 | ||
661 | mmc_omap_fclk_enable(host, 0); | 661 | mmc_omap_fclk_enable(host, 0); |
662 | } | 662 | } |
@@ -874,9 +874,9 @@ void omap_mmc_notify_cover_event(struct device *dev, int num, int is_closed) | |||
874 | tasklet_hi_schedule(&slot->cover_tasklet); | 874 | tasklet_hi_schedule(&slot->cover_tasklet); |
875 | } | 875 | } |
876 | 876 | ||
877 | static void mmc_omap_cover_timer(unsigned long arg) | 877 | static void mmc_omap_cover_timer(struct timer_list *t) |
878 | { | 878 | { |
879 | struct mmc_omap_slot *slot = (struct mmc_omap_slot *) arg; | 879 | struct mmc_omap_slot *slot = from_timer(slot, t, cover_timer); |
880 | tasklet_schedule(&slot->cover_tasklet); | 880 | tasklet_schedule(&slot->cover_tasklet); |
881 | } | 881 | } |
882 | 882 | ||
@@ -1264,8 +1264,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) | |||
1264 | mmc->max_seg_size = mmc->max_req_size; | 1264 | mmc->max_seg_size = mmc->max_req_size; |
1265 | 1265 | ||
1266 | if (slot->pdata->get_cover_state != NULL) { | 1266 | if (slot->pdata->get_cover_state != NULL) { |
1267 | setup_timer(&slot->cover_timer, mmc_omap_cover_timer, | 1267 | timer_setup(&slot->cover_timer, mmc_omap_cover_timer, 0); |
1268 | (unsigned long)slot); | ||
1269 | tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, | 1268 | tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, |
1270 | (unsigned long)slot); | 1269 | (unsigned long)slot); |
1271 | } | 1270 | } |
@@ -1352,11 +1351,10 @@ static int mmc_omap_probe(struct platform_device *pdev) | |||
1352 | INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work); | 1351 | INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work); |
1353 | 1352 | ||
1354 | INIT_WORK(&host->cmd_abort_work, mmc_omap_abort_command); | 1353 | INIT_WORK(&host->cmd_abort_work, mmc_omap_abort_command); |
1355 | setup_timer(&host->cmd_abort_timer, mmc_omap_cmd_timer, | 1354 | timer_setup(&host->cmd_abort_timer, mmc_omap_cmd_timer, 0); |
1356 | (unsigned long) host); | ||
1357 | 1355 | ||
1358 | spin_lock_init(&host->clk_lock); | 1356 | spin_lock_init(&host->clk_lock); |
1359 | setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host); | 1357 | timer_setup(&host->clk_timer, mmc_omap_clk_timer, 0); |
1360 | 1358 | ||
1361 | spin_lock_init(&host->dma_lock); | 1359 | spin_lock_init(&host->dma_lock); |
1362 | spin_lock_init(&host->slot_lock); | 1360 | spin_lock_init(&host->slot_lock); |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 3b5e6d11069b..071693ebfe18 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -147,10 +147,6 @@ | |||
147 | #define OMAP_MMC_MAX_CLOCK 52000000 | 147 | #define OMAP_MMC_MAX_CLOCK 52000000 |
148 | #define DRIVER_NAME "omap_hsmmc" | 148 | #define DRIVER_NAME "omap_hsmmc" |
149 | 149 | ||
150 | #define VDD_1V8 1800000 /* 180000 uV */ | ||
151 | #define VDD_3V0 3000000 /* 300000 uV */ | ||
152 | #define VDD_165_195 (ffs(MMC_VDD_165_195) - 1) | ||
153 | |||
154 | /* | 150 | /* |
155 | * One controller can have multiple slots, like on some omap boards using | 151 | * One controller can have multiple slots, like on some omap boards using |
156 | * omap.c controller driver. Luckily this is not currently done on any known | 152 | * omap.c controller driver. Luckily this is not currently done on any known |
@@ -308,8 +304,7 @@ err_set_ocr: | |||
308 | return ret; | 304 | return ret; |
309 | } | 305 | } |
310 | 306 | ||
311 | static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, | 307 | static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on) |
312 | int vdd) | ||
313 | { | 308 | { |
314 | int ret; | 309 | int ret; |
315 | 310 | ||
@@ -317,17 +312,6 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, | |||
317 | return 0; | 312 | return 0; |
318 | 313 | ||
319 | if (power_on) { | 314 | if (power_on) { |
320 | if (vdd <= VDD_165_195) | ||
321 | ret = regulator_set_voltage(host->pbias, VDD_1V8, | ||
322 | VDD_1V8); | ||
323 | else | ||
324 | ret = regulator_set_voltage(host->pbias, VDD_3V0, | ||
325 | VDD_3V0); | ||
326 | if (ret < 0) { | ||
327 | dev_err(host->dev, "pbias set voltage fail\n"); | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | if (host->pbias_enabled == 0) { | 315 | if (host->pbias_enabled == 0) { |
332 | ret = regulator_enable(host->pbias); | 316 | ret = regulator_enable(host->pbias); |
333 | if (ret) { | 317 | if (ret) { |
@@ -350,8 +334,7 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on, | |||
350 | return 0; | 334 | return 0; |
351 | } | 335 | } |
352 | 336 | ||
353 | static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on, | 337 | static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on) |
354 | int vdd) | ||
355 | { | 338 | { |
356 | struct mmc_host *mmc = host->mmc; | 339 | struct mmc_host *mmc = host->mmc; |
357 | int ret = 0; | 340 | int ret = 0; |
@@ -363,7 +346,7 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on, | |||
363 | if (IS_ERR(mmc->supply.vmmc)) | 346 | if (IS_ERR(mmc->supply.vmmc)) |
364 | return 0; | 347 | return 0; |
365 | 348 | ||
366 | ret = omap_hsmmc_set_pbias(host, false, 0); | 349 | ret = omap_hsmmc_set_pbias(host, false); |
367 | if (ret) | 350 | if (ret) |
368 | return ret; | 351 | return ret; |
369 | 352 | ||
@@ -385,7 +368,7 @@ static int omap_hsmmc_set_power(struct omap_hsmmc_host *host, int power_on, | |||
385 | if (ret) | 368 | if (ret) |
386 | return ret; | 369 | return ret; |
387 | 370 | ||
388 | ret = omap_hsmmc_set_pbias(host, true, vdd); | 371 | ret = omap_hsmmc_set_pbias(host, true); |
389 | if (ret) | 372 | if (ret) |
390 | goto err_set_voltage; | 373 | goto err_set_voltage; |
391 | } else { | 374 | } else { |
@@ -462,7 +445,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
462 | 445 | ||
463 | 446 | ||
464 | ret = mmc_regulator_get_supply(mmc); | 447 | ret = mmc_regulator_get_supply(mmc); |
465 | if (ret == -EPROBE_DEFER) | 448 | if (ret) |
466 | return ret; | 449 | return ret; |
467 | 450 | ||
468 | /* Allow an aux regulator */ | 451 | /* Allow an aux regulator */ |
@@ -1220,11 +1203,11 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) | |||
1220 | clk_disable_unprepare(host->dbclk); | 1203 | clk_disable_unprepare(host->dbclk); |
1221 | 1204 | ||
1222 | /* Turn the power off */ | 1205 | /* Turn the power off */ |
1223 | ret = omap_hsmmc_set_power(host, 0, 0); | 1206 | ret = omap_hsmmc_set_power(host, 0); |
1224 | 1207 | ||
1225 | /* Turn the power ON with given VDD 1.8 or 3.0v */ | 1208 | /* Turn the power ON with given VDD 1.8 or 3.0v */ |
1226 | if (!ret) | 1209 | if (!ret) |
1227 | ret = omap_hsmmc_set_power(host, 1, vdd); | 1210 | ret = omap_hsmmc_set_power(host, 1); |
1228 | if (host->dbclk) | 1211 | if (host->dbclk) |
1229 | clk_prepare_enable(host->dbclk); | 1212 | clk_prepare_enable(host->dbclk); |
1230 | 1213 | ||
@@ -1621,10 +1604,10 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1621 | if (ios->power_mode != host->power_mode) { | 1604 | if (ios->power_mode != host->power_mode) { |
1622 | switch (ios->power_mode) { | 1605 | switch (ios->power_mode) { |
1623 | case MMC_POWER_OFF: | 1606 | case MMC_POWER_OFF: |
1624 | omap_hsmmc_set_power(host, 0, 0); | 1607 | omap_hsmmc_set_power(host, 0); |
1625 | break; | 1608 | break; |
1626 | case MMC_POWER_UP: | 1609 | case MMC_POWER_UP: |
1627 | omap_hsmmc_set_power(host, 1, ios->vdd); | 1610 | omap_hsmmc_set_power(host, 1); |
1628 | break; | 1611 | break; |
1629 | case MMC_POWER_ON: | 1612 | case MMC_POWER_ON: |
1630 | do_send_init_stream = 1; | 1613 | do_send_init_stream = 1; |
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index 8bae88a150fd..41cbe84c1d18 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c | |||
@@ -88,6 +88,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { | |||
88 | static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = { | 88 | static const struct of_device_id renesas_sdhi_internal_dmac_of_match[] = { |
89 | { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, }, | 89 | { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, }, |
90 | { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, }, | 90 | { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, }, |
91 | { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, }, | ||
91 | {}, | 92 | {}, |
92 | }; | 93 | }; |
93 | MODULE_DEVICE_TABLE(of, renesas_sdhi_internal_dmac_of_match); | 94 | MODULE_DEVICE_TABLE(of, renesas_sdhi_internal_dmac_of_match); |
diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c index df4465439e13..9ab10436e4b8 100644 --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c | |||
@@ -91,7 +91,6 @@ static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { | |||
91 | }; | 91 | }; |
92 | 92 | ||
93 | static const struct of_device_id renesas_sdhi_sys_dmac_of_match[] = { | 93 | static const struct of_device_id renesas_sdhi_sys_dmac_of_match[] = { |
94 | { .compatible = "renesas,sdhi-shmobile" }, | ||
95 | { .compatible = "renesas,sdhi-sh73a0", .data = &of_default_cfg, }, | 94 | { .compatible = "renesas,sdhi-sh73a0", .data = &of_default_cfg, }, |
96 | { .compatible = "renesas,sdhi-r8a73a4", .data = &of_default_cfg, }, | 95 | { .compatible = "renesas,sdhi-r8a73a4", .data = &of_default_cfg, }, |
97 | { .compatible = "renesas,sdhi-r8a7740", .data = &of_default_cfg, }, | 96 | { .compatible = "renesas,sdhi-r8a7740", .data = &of_default_cfg, }, |
@@ -107,6 +106,10 @@ static const struct of_device_id renesas_sdhi_sys_dmac_of_match[] = { | |||
107 | { .compatible = "renesas,sdhi-r8a7794", .data = &of_rcar_gen2_compatible, }, | 106 | { .compatible = "renesas,sdhi-r8a7794", .data = &of_rcar_gen2_compatible, }, |
108 | { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, }, | 107 | { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_gen3_compatible, }, |
109 | { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, }, | 108 | { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, }, |
109 | { .compatible = "renesas,rcar-gen1-sdhi", .data = &of_rcar_gen1_compatible, }, | ||
110 | { .compatible = "renesas,rcar-gen2-sdhi", .data = &of_rcar_gen2_compatible, }, | ||
111 | { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, }, | ||
112 | { .compatible = "renesas,sdhi-shmobile" }, | ||
110 | {}, | 113 | {}, |
111 | }; | 114 | }; |
112 | MODULE_DEVICE_TABLE(of, renesas_sdhi_sys_dmac_of_match); | 115 | MODULE_DEVICE_TABLE(of, renesas_sdhi_sys_dmac_of_match); |
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 41b57713b620..0848dc0f882e 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -618,29 +618,22 @@ static int sd_change_phase(struct realtek_pci_sdmmc *host, | |||
618 | u8 sample_point, bool rx) | 618 | u8 sample_point, bool rx) |
619 | { | 619 | { |
620 | struct rtsx_pcr *pcr = host->pcr; | 620 | struct rtsx_pcr *pcr = host->pcr; |
621 | int err; | ||
622 | 621 | ||
623 | dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n", | 622 | dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n", |
624 | __func__, rx ? "RX" : "TX", sample_point); | 623 | __func__, rx ? "RX" : "TX", sample_point); |
625 | 624 | ||
626 | rtsx_pci_init_cmd(pcr); | 625 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, CHANGE_CLK); |
627 | |||
628 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, CHANGE_CLK); | ||
629 | if (rx) | 626 | if (rx) |
630 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | 627 | rtsx_pci_write_register(pcr, SD_VPRX_CTL, |
631 | SD_VPRX_CTL, 0x1F, sample_point); | 628 | PHASE_SELECT_MASK, sample_point); |
632 | else | 629 | else |
633 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | 630 | rtsx_pci_write_register(pcr, SD_VPTX_CTL, |
634 | SD_VPTX_CTL, 0x1F, sample_point); | 631 | PHASE_SELECT_MASK, sample_point); |
635 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); | 632 | rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); |
636 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, | 633 | rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, |
637 | PHASE_NOT_RESET, PHASE_NOT_RESET); | 634 | PHASE_NOT_RESET); |
638 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, 0); | 635 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, 0); |
639 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); | 636 | rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); |
640 | |||
641 | err = rtsx_pci_send_cmd(pcr, 100); | ||
642 | if (err < 0) | ||
643 | return err; | ||
644 | 637 | ||
645 | return 0; | 638 | return 0; |
646 | } | 639 | } |
@@ -708,10 +701,12 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, | |||
708 | { | 701 | { |
709 | int err; | 702 | int err; |
710 | struct mmc_command cmd = {}; | 703 | struct mmc_command cmd = {}; |
704 | struct rtsx_pcr *pcr = host->pcr; | ||
711 | 705 | ||
712 | err = sd_change_phase(host, sample_point, true); | 706 | sd_change_phase(host, sample_point, true); |
713 | if (err < 0) | 707 | |
714 | return err; | 708 | rtsx_pci_write_register(pcr, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, |
709 | SD_RSP_80CLK_TIMEOUT_EN); | ||
715 | 710 | ||
716 | cmd.opcode = opcode; | 711 | cmd.opcode = opcode; |
717 | err = sd_read_data(host, &cmd, 0x40, NULL, 0, 100); | 712 | err = sd_read_data(host, &cmd, 0x40, NULL, 0, 100); |
@@ -719,9 +714,12 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, | |||
719 | /* Wait till SD DATA IDLE */ | 714 | /* Wait till SD DATA IDLE */ |
720 | sd_wait_data_idle(host); | 715 | sd_wait_data_idle(host); |
721 | sd_clear_error(host); | 716 | sd_clear_error(host); |
717 | rtsx_pci_write_register(pcr, SD_CFG3, | ||
718 | SD_RSP_80CLK_TIMEOUT_EN, 0); | ||
722 | return err; | 719 | return err; |
723 | } | 720 | } |
724 | 721 | ||
722 | rtsx_pci_write_register(pcr, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); | ||
725 | return 0; | 723 | return 0; |
726 | } | 724 | } |
727 | 725 | ||
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 08ae0ff13513..b988997a1e80 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -73,6 +73,7 @@ struct sdhci_acpi_slot { | |||
73 | unsigned int caps2; | 73 | unsigned int caps2; |
74 | mmc_pm_flag_t pm_caps; | 74 | mmc_pm_flag_t pm_caps; |
75 | unsigned int flags; | 75 | unsigned int flags; |
76 | size_t priv_size; | ||
76 | int (*probe_slot)(struct platform_device *, const char *, const char *); | 77 | int (*probe_slot)(struct platform_device *, const char *, const char *); |
77 | int (*remove_slot)(struct platform_device *); | 78 | int (*remove_slot)(struct platform_device *); |
78 | }; | 79 | }; |
@@ -82,13 +83,118 @@ struct sdhci_acpi_host { | |||
82 | const struct sdhci_acpi_slot *slot; | 83 | const struct sdhci_acpi_slot *slot; |
83 | struct platform_device *pdev; | 84 | struct platform_device *pdev; |
84 | bool use_runtime_pm; | 85 | bool use_runtime_pm; |
86 | unsigned long private[0] ____cacheline_aligned; | ||
85 | }; | 87 | }; |
86 | 88 | ||
89 | static inline void *sdhci_acpi_priv(struct sdhci_acpi_host *c) | ||
90 | { | ||
91 | return (void *)c->private; | ||
92 | } | ||
93 | |||
87 | static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag) | 94 | static inline bool sdhci_acpi_flag(struct sdhci_acpi_host *c, unsigned int flag) |
88 | { | 95 | { |
89 | return c->slot && (c->slot->flags & flag); | 96 | return c->slot && (c->slot->flags & flag); |
90 | } | 97 | } |
91 | 98 | ||
99 | enum { | ||
100 | INTEL_DSM_FNS = 0, | ||
101 | INTEL_DSM_V18_SWITCH = 3, | ||
102 | INTEL_DSM_V33_SWITCH = 4, | ||
103 | }; | ||
104 | |||
105 | struct intel_host { | ||
106 | u32 dsm_fns; | ||
107 | }; | ||
108 | |||
109 | static const guid_t intel_dsm_guid = | ||
110 | GUID_INIT(0xF6C13EA5, 0x65CD, 0x461F, | ||
111 | 0xAB, 0x7A, 0x29, 0xF7, 0xE8, 0xD5, 0xBD, 0x61); | ||
112 | |||
113 | static int __intel_dsm(struct intel_host *intel_host, struct device *dev, | ||
114 | unsigned int fn, u32 *result) | ||
115 | { | ||
116 | union acpi_object *obj; | ||
117 | int err = 0; | ||
118 | |||
119 | obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &intel_dsm_guid, 0, fn, NULL); | ||
120 | if (!obj) | ||
121 | return -EOPNOTSUPP; | ||
122 | |||
123 | if (obj->type == ACPI_TYPE_INTEGER) { | ||
124 | *result = obj->integer.value; | ||
125 | } else if (obj->type == ACPI_TYPE_BUFFER && obj->buffer.length > 0) { | ||
126 | size_t len = min_t(size_t, obj->buffer.length, 4); | ||
127 | |||
128 | *result = 0; | ||
129 | memcpy(result, obj->buffer.pointer, len); | ||
130 | } else { | ||
131 | dev_err(dev, "%s DSM fn %u obj->type %d obj->buffer.length %d\n", | ||
132 | __func__, fn, obj->type, obj->buffer.length); | ||
133 | err = -EINVAL; | ||
134 | } | ||
135 | |||
136 | ACPI_FREE(obj); | ||
137 | |||
138 | return err; | ||
139 | } | ||
140 | |||
141 | static int intel_dsm(struct intel_host *intel_host, struct device *dev, | ||
142 | unsigned int fn, u32 *result) | ||
143 | { | ||
144 | if (fn > 31 || !(intel_host->dsm_fns & (1 << fn))) | ||
145 | return -EOPNOTSUPP; | ||
146 | |||
147 | return __intel_dsm(intel_host, dev, fn, result); | ||
148 | } | ||
149 | |||
150 | static void intel_dsm_init(struct intel_host *intel_host, struct device *dev, | ||
151 | struct mmc_host *mmc) | ||
152 | { | ||
153 | int err; | ||
154 | |||
155 | err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns); | ||
156 | if (err) { | ||
157 | pr_debug("%s: DSM not supported, error %d\n", | ||
158 | mmc_hostname(mmc), err); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | pr_debug("%s: DSM function mask %#x\n", | ||
163 | mmc_hostname(mmc), intel_host->dsm_fns); | ||
164 | } | ||
165 | |||
166 | static int intel_start_signal_voltage_switch(struct mmc_host *mmc, | ||
167 | struct mmc_ios *ios) | ||
168 | { | ||
169 | struct device *dev = mmc_dev(mmc); | ||
170 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); | ||
171 | struct intel_host *intel_host = sdhci_acpi_priv(c); | ||
172 | unsigned int fn; | ||
173 | u32 result = 0; | ||
174 | int err; | ||
175 | |||
176 | err = sdhci_start_signal_voltage_switch(mmc, ios); | ||
177 | if (err) | ||
178 | return err; | ||
179 | |||
180 | switch (ios->signal_voltage) { | ||
181 | case MMC_SIGNAL_VOLTAGE_330: | ||
182 | fn = INTEL_DSM_V33_SWITCH; | ||
183 | break; | ||
184 | case MMC_SIGNAL_VOLTAGE_180: | ||
185 | fn = INTEL_DSM_V18_SWITCH; | ||
186 | break; | ||
187 | default: | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | err = intel_dsm(intel_host, dev, fn, &result); | ||
192 | pr_debug("%s: %s DSM fn %u error %d result %u\n", | ||
193 | mmc_hostname(mmc), __func__, fn, err, result); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
92 | static void sdhci_acpi_int_hw_reset(struct sdhci_host *host) | 198 | static void sdhci_acpi_int_hw_reset(struct sdhci_host *host) |
93 | { | 199 | { |
94 | u8 reg; | 200 | u8 reg; |
@@ -269,56 +375,26 @@ out: | |||
269 | return ret; | 375 | return ret; |
270 | } | 376 | } |
271 | 377 | ||
272 | static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev, | 378 | static int intel_probe_slot(struct platform_device *pdev, const char *hid, |
273 | const char *hid, const char *uid) | 379 | const char *uid) |
274 | { | 380 | { |
275 | struct sdhci_acpi_host *c = platform_get_drvdata(pdev); | 381 | struct sdhci_acpi_host *c = platform_get_drvdata(pdev); |
276 | struct sdhci_host *host; | 382 | struct intel_host *intel_host = sdhci_acpi_priv(c); |
277 | 383 | struct sdhci_host *host = c->host; | |
278 | if (!c || !c->host) | ||
279 | return 0; | ||
280 | |||
281 | host = c->host; | ||
282 | |||
283 | /* Platform specific code during emmc probe slot goes here */ | ||
284 | 384 | ||
285 | if (hid && uid && !strcmp(hid, "80860F14") && !strcmp(uid, "1") && | 385 | if (hid && uid && !strcmp(hid, "80860F14") && !strcmp(uid, "1") && |
286 | sdhci_readl(host, SDHCI_CAPABILITIES) == 0x446cc8b2 && | 386 | sdhci_readl(host, SDHCI_CAPABILITIES) == 0x446cc8b2 && |
287 | sdhci_readl(host, SDHCI_CAPABILITIES_1) == 0x00000807) | 387 | sdhci_readl(host, SDHCI_CAPABILITIES_1) == 0x00000807) |
288 | host->timeout_clk = 1000; /* 1000 kHz i.e. 1 MHz */ | 388 | host->timeout_clk = 1000; /* 1000 kHz i.e. 1 MHz */ |
289 | 389 | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int sdhci_acpi_sdio_probe_slot(struct platform_device *pdev, | ||
294 | const char *hid, const char *uid) | ||
295 | { | ||
296 | struct sdhci_acpi_host *c = platform_get_drvdata(pdev); | ||
297 | |||
298 | if (!c || !c->host) | ||
299 | return 0; | ||
300 | |||
301 | /* Platform specific code during sdio probe slot goes here */ | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static int sdhci_acpi_sd_probe_slot(struct platform_device *pdev, | ||
307 | const char *hid, const char *uid) | ||
308 | { | ||
309 | struct sdhci_acpi_host *c = platform_get_drvdata(pdev); | ||
310 | struct sdhci_host *host; | ||
311 | |||
312 | if (!c || !c->host || !c->slot) | ||
313 | return 0; | ||
314 | |||
315 | host = c->host; | ||
316 | |||
317 | /* Platform specific code during sd probe slot goes here */ | ||
318 | |||
319 | if (hid && !strcmp(hid, "80865ACA")) | 390 | if (hid && !strcmp(hid, "80865ACA")) |
320 | host->mmc_host_ops.get_cd = bxt_get_cd; | 391 | host->mmc_host_ops.get_cd = bxt_get_cd; |
321 | 392 | ||
393 | intel_dsm_init(intel_host, &pdev->dev, host->mmc); | ||
394 | |||
395 | host->mmc_host_ops.start_signal_voltage_switch = | ||
396 | intel_start_signal_voltage_switch; | ||
397 | |||
322 | return 0; | 398 | return 0; |
323 | } | 399 | } |
324 | 400 | ||
@@ -332,7 +408,8 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { | |||
332 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 408 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
333 | SDHCI_QUIRK2_STOP_WITH_TC | | 409 | SDHCI_QUIRK2_STOP_WITH_TC | |
334 | SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400, | 410 | SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400, |
335 | .probe_slot = sdhci_acpi_emmc_probe_slot, | 411 | .probe_slot = intel_probe_slot, |
412 | .priv_size = sizeof(struct intel_host), | ||
336 | }; | 413 | }; |
337 | 414 | ||
338 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | 415 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { |
@@ -343,7 +420,8 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | |||
343 | MMC_CAP_WAIT_WHILE_BUSY, | 420 | MMC_CAP_WAIT_WHILE_BUSY, |
344 | .flags = SDHCI_ACPI_RUNTIME_PM, | 421 | .flags = SDHCI_ACPI_RUNTIME_PM, |
345 | .pm_caps = MMC_PM_KEEP_POWER, | 422 | .pm_caps = MMC_PM_KEEP_POWER, |
346 | .probe_slot = sdhci_acpi_sdio_probe_slot, | 423 | .probe_slot = intel_probe_slot, |
424 | .priv_size = sizeof(struct intel_host), | ||
347 | }; | 425 | }; |
348 | 426 | ||
349 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { | 427 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { |
@@ -353,7 +431,8 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { | |||
353 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | | 431 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | |
354 | SDHCI_QUIRK2_STOP_WITH_TC, | 432 | SDHCI_QUIRK2_STOP_WITH_TC, |
355 | .caps = MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_AGGRESSIVE_PM, | 433 | .caps = MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_AGGRESSIVE_PM, |
356 | .probe_slot = sdhci_acpi_sd_probe_slot, | 434 | .probe_slot = intel_probe_slot, |
435 | .priv_size = sizeof(struct intel_host), | ||
357 | }; | 436 | }; |
358 | 437 | ||
359 | static const struct sdhci_acpi_slot sdhci_acpi_slot_qcom_sd_3v = { | 438 | static const struct sdhci_acpi_slot sdhci_acpi_slot_qcom_sd_3v = { |
@@ -429,11 +508,13 @@ static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(const char *hid, | |||
429 | static int sdhci_acpi_probe(struct platform_device *pdev) | 508 | static int sdhci_acpi_probe(struct platform_device *pdev) |
430 | { | 509 | { |
431 | struct device *dev = &pdev->dev; | 510 | struct device *dev = &pdev->dev; |
511 | const struct sdhci_acpi_slot *slot; | ||
432 | struct acpi_device *device, *child; | 512 | struct acpi_device *device, *child; |
433 | struct sdhci_acpi_host *c; | 513 | struct sdhci_acpi_host *c; |
434 | struct sdhci_host *host; | 514 | struct sdhci_host *host; |
435 | struct resource *iomem; | 515 | struct resource *iomem; |
436 | resource_size_t len; | 516 | resource_size_t len; |
517 | size_t priv_size; | ||
437 | const char *hid; | 518 | const char *hid; |
438 | const char *uid; | 519 | const char *uid; |
439 | int err; | 520 | int err; |
@@ -443,7 +524,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
443 | return -ENODEV; | 524 | return -ENODEV; |
444 | 525 | ||
445 | hid = acpi_device_hid(device); | 526 | hid = acpi_device_hid(device); |
446 | uid = device->pnp.unique_id; | 527 | uid = acpi_device_uid(device); |
528 | |||
529 | slot = sdhci_acpi_get_slot(hid, uid); | ||
447 | 530 | ||
448 | /* Power on the SDHCI controller and its children */ | 531 | /* Power on the SDHCI controller and its children */ |
449 | acpi_device_fix_up_power(device); | 532 | acpi_device_fix_up_power(device); |
@@ -467,13 +550,14 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
467 | if (!devm_request_mem_region(dev, iomem->start, len, dev_name(dev))) | 550 | if (!devm_request_mem_region(dev, iomem->start, len, dev_name(dev))) |
468 | return -ENOMEM; | 551 | return -ENOMEM; |
469 | 552 | ||
470 | host = sdhci_alloc_host(dev, sizeof(struct sdhci_acpi_host)); | 553 | priv_size = slot ? slot->priv_size : 0; |
554 | host = sdhci_alloc_host(dev, sizeof(struct sdhci_acpi_host) + priv_size); | ||
471 | if (IS_ERR(host)) | 555 | if (IS_ERR(host)) |
472 | return PTR_ERR(host); | 556 | return PTR_ERR(host); |
473 | 557 | ||
474 | c = sdhci_priv(host); | 558 | c = sdhci_priv(host); |
475 | c->host = host; | 559 | c->host = host; |
476 | c->slot = sdhci_acpi_get_slot(hid, uid); | 560 | c->slot = slot; |
477 | c->pdev = pdev; | 561 | c->pdev = pdev; |
478 | c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM); | 562 | c->use_runtime_pm = sdhci_acpi_flag(c, SDHCI_ACPI_RUNTIME_PM); |
479 | 563 | ||
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 56529c3d389a..0f589e26ee63 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/bitfield.h> | ||
16 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
17 | #include <linux/iopoll.h> | 18 | #include <linux/iopoll.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -27,15 +28,14 @@ | |||
27 | #define SDHCI_CDNS_HRS04_ACK BIT(26) | 28 | #define SDHCI_CDNS_HRS04_ACK BIT(26) |
28 | #define SDHCI_CDNS_HRS04_RD BIT(25) | 29 | #define SDHCI_CDNS_HRS04_RD BIT(25) |
29 | #define SDHCI_CDNS_HRS04_WR BIT(24) | 30 | #define SDHCI_CDNS_HRS04_WR BIT(24) |
30 | #define SDHCI_CDNS_HRS04_RDATA_SHIFT 16 | 31 | #define SDHCI_CDNS_HRS04_RDATA GENMASK(23, 16) |
31 | #define SDHCI_CDNS_HRS04_WDATA_SHIFT 8 | 32 | #define SDHCI_CDNS_HRS04_WDATA GENMASK(15, 8) |
32 | #define SDHCI_CDNS_HRS04_ADDR_SHIFT 0 | 33 | #define SDHCI_CDNS_HRS04_ADDR GENMASK(5, 0) |
33 | 34 | ||
34 | #define SDHCI_CDNS_HRS06 0x18 /* eMMC control */ | 35 | #define SDHCI_CDNS_HRS06 0x18 /* eMMC control */ |
35 | #define SDHCI_CDNS_HRS06_TUNE_UP BIT(15) | 36 | #define SDHCI_CDNS_HRS06_TUNE_UP BIT(15) |
36 | #define SDHCI_CDNS_HRS06_TUNE_SHIFT 8 | 37 | #define SDHCI_CDNS_HRS06_TUNE GENMASK(13, 8) |
37 | #define SDHCI_CDNS_HRS06_TUNE_MASK 0x3f | 38 | #define SDHCI_CDNS_HRS06_MODE GENMASK(2, 0) |
38 | #define SDHCI_CDNS_HRS06_MODE_MASK 0x7 | ||
39 | #define SDHCI_CDNS_HRS06_MODE_SD 0x0 | 39 | #define SDHCI_CDNS_HRS06_MODE_SD 0x0 |
40 | #define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2 | 40 | #define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2 |
41 | #define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3 | 41 | #define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3 |
@@ -105,8 +105,8 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, | |||
105 | u32 tmp; | 105 | u32 tmp; |
106 | int ret; | 106 | int ret; |
107 | 107 | ||
108 | tmp = (data << SDHCI_CDNS_HRS04_WDATA_SHIFT) | | 108 | tmp = FIELD_PREP(SDHCI_CDNS_HRS04_WDATA, data) | |
109 | (addr << SDHCI_CDNS_HRS04_ADDR_SHIFT); | 109 | FIELD_PREP(SDHCI_CDNS_HRS04_ADDR, addr); |
110 | writel(tmp, reg); | 110 | writel(tmp, reg); |
111 | 111 | ||
112 | tmp |= SDHCI_CDNS_HRS04_WR; | 112 | tmp |= SDHCI_CDNS_HRS04_WR; |
@@ -189,8 +189,8 @@ static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode) | |||
189 | 189 | ||
190 | /* The speed mode for eMMC is selected by HRS06 register */ | 190 | /* The speed mode for eMMC is selected by HRS06 register */ |
191 | tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06); | 191 | tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06); |
192 | tmp &= ~SDHCI_CDNS_HRS06_MODE_MASK; | 192 | tmp &= ~SDHCI_CDNS_HRS06_MODE; |
193 | tmp |= mode; | 193 | tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_MODE, mode); |
194 | writel(tmp, priv->hrs_addr + SDHCI_CDNS_HRS06); | 194 | writel(tmp, priv->hrs_addr + SDHCI_CDNS_HRS06); |
195 | } | 195 | } |
196 | 196 | ||
@@ -199,7 +199,7 @@ static u32 sdhci_cdns_get_emmc_mode(struct sdhci_cdns_priv *priv) | |||
199 | u32 tmp; | 199 | u32 tmp; |
200 | 200 | ||
201 | tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06); | 201 | tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06); |
202 | return tmp & SDHCI_CDNS_HRS06_MODE_MASK; | 202 | return FIELD_GET(SDHCI_CDNS_HRS06_MODE, tmp); |
203 | } | 203 | } |
204 | 204 | ||
205 | static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host, | 205 | static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host, |
@@ -254,12 +254,12 @@ static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) | |||
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 | 256 | ||
257 | if (WARN_ON(val > SDHCI_CDNS_HRS06_TUNE_MASK)) | 257 | if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val))) |
258 | return -EINVAL; | 258 | return -EINVAL; |
259 | 259 | ||
260 | tmp = readl(reg); | 260 | tmp = readl(reg); |
261 | tmp &= ~(SDHCI_CDNS_HRS06_TUNE_MASK << SDHCI_CDNS_HRS06_TUNE_SHIFT); | 261 | tmp &= ~SDHCI_CDNS_HRS06_TUNE; |
262 | tmp |= val << SDHCI_CDNS_HRS06_TUNE_SHIFT; | 262 | tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_TUNE, val); |
263 | tmp |= SDHCI_CDNS_HRS06_TUNE_UP; | 263 | tmp |= SDHCI_CDNS_HRS06_TUNE_UP; |
264 | writel(tmp, reg); | 264 | writel(tmp, reg); |
265 | 265 | ||
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index fc73e56eb1e2..3fb7d2eec93f 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c | |||
@@ -123,14 +123,17 @@ | |||
123 | #define CMUX_SHIFT_PHASE_MASK (7 << CMUX_SHIFT_PHASE_SHIFT) | 123 | #define CMUX_SHIFT_PHASE_MASK (7 << CMUX_SHIFT_PHASE_SHIFT) |
124 | 124 | ||
125 | #define MSM_MMC_AUTOSUSPEND_DELAY_MS 50 | 125 | #define MSM_MMC_AUTOSUSPEND_DELAY_MS 50 |
126 | |||
127 | /* Timeout value to avoid infinite waiting for pwr_irq */ | ||
128 | #define MSM_PWR_IRQ_TIMEOUT_MS 5000 | ||
129 | |||
126 | struct sdhci_msm_host { | 130 | struct sdhci_msm_host { |
127 | struct platform_device *pdev; | 131 | struct platform_device *pdev; |
128 | void __iomem *core_mem; /* MSM SDCC mapped address */ | 132 | void __iomem *core_mem; /* MSM SDCC mapped address */ |
129 | int pwr_irq; /* power irq */ | 133 | int pwr_irq; /* power irq */ |
130 | struct clk *clk; /* main SD/MMC bus clock */ | ||
131 | struct clk *pclk; /* SDHC peripheral bus clock */ | ||
132 | struct clk *bus_clk; /* SDHC bus voter clock */ | 134 | struct clk *bus_clk; /* SDHC bus voter clock */ |
133 | struct clk *xo_clk; /* TCXO clk needed for FLL feature of cm_dll*/ | 135 | struct clk *xo_clk; /* TCXO clk needed for FLL feature of cm_dll*/ |
136 | struct clk_bulk_data bulk_clks[4]; /* core, iface, cal, sleep clocks */ | ||
134 | unsigned long clk_rate; | 137 | unsigned long clk_rate; |
135 | struct mmc_host *mmc; | 138 | struct mmc_host *mmc; |
136 | bool use_14lpp_dll_reset; | 139 | bool use_14lpp_dll_reset; |
@@ -138,6 +141,10 @@ struct sdhci_msm_host { | |||
138 | bool calibration_done; | 141 | bool calibration_done; |
139 | u8 saved_tuning_phase; | 142 | u8 saved_tuning_phase; |
140 | bool use_cdclp533; | 143 | bool use_cdclp533; |
144 | u32 curr_pwr_state; | ||
145 | u32 curr_io_level; | ||
146 | wait_queue_head_t pwr_irq_wait; | ||
147 | bool pwr_irq_flag; | ||
141 | }; | 148 | }; |
142 | 149 | ||
143 | static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, | 150 | static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, |
@@ -164,10 +171,11 @@ static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host, | |||
164 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 171 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
165 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 172 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
166 | struct mmc_ios curr_ios = host->mmc->ios; | 173 | struct mmc_ios curr_ios = host->mmc->ios; |
174 | struct clk *core_clk = msm_host->bulk_clks[0].clk; | ||
167 | int rc; | 175 | int rc; |
168 | 176 | ||
169 | clock = msm_get_clock_rate_for_bus_mode(host, clock); | 177 | clock = msm_get_clock_rate_for_bus_mode(host, clock); |
170 | rc = clk_set_rate(msm_host->clk, clock); | 178 | rc = clk_set_rate(core_clk, clock); |
171 | if (rc) { | 179 | if (rc) { |
172 | pr_err("%s: Failed to set clock at rate %u at timing %d\n", | 180 | pr_err("%s: Failed to set clock at rate %u at timing %d\n", |
173 | mmc_hostname(host->mmc), clock, | 181 | mmc_hostname(host->mmc), clock, |
@@ -176,7 +184,7 @@ static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host, | |||
176 | } | 184 | } |
177 | msm_host->clk_rate = clock; | 185 | msm_host->clk_rate = clock; |
178 | pr_debug("%s: Setting clock at rate %lu at timing %d\n", | 186 | pr_debug("%s: Setting clock at rate %lu at timing %d\n", |
179 | mmc_hostname(host->mmc), clk_get_rate(msm_host->clk), | 187 | mmc_hostname(host->mmc), clk_get_rate(core_clk), |
180 | curr_ios.timing); | 188 | curr_ios.timing); |
181 | } | 189 | } |
182 | 190 | ||
@@ -995,21 +1003,142 @@ static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, | |||
995 | sdhci_msm_hs400(host, &mmc->ios); | 1003 | sdhci_msm_hs400(host, &mmc->ios); |
996 | } | 1004 | } |
997 | 1005 | ||
998 | static void sdhci_msm_voltage_switch(struct sdhci_host *host) | 1006 | static inline void sdhci_msm_init_pwr_irq_wait(struct sdhci_msm_host *msm_host) |
1007 | { | ||
1008 | init_waitqueue_head(&msm_host->pwr_irq_wait); | ||
1009 | } | ||
1010 | |||
1011 | static inline void sdhci_msm_complete_pwr_irq_wait( | ||
1012 | struct sdhci_msm_host *msm_host) | ||
1013 | { | ||
1014 | wake_up(&msm_host->pwr_irq_wait); | ||
1015 | } | ||
1016 | |||
1017 | /* | ||
1018 | * sdhci_msm_check_power_status API should be called when registers writes | ||
1019 | * which can toggle sdhci IO bus ON/OFF or change IO lines HIGH/LOW happens. | ||
1020 | * To what state the register writes will change the IO lines should be passed | ||
1021 | * as the argument req_type. This API will check whether the IO line's state | ||
1022 | * is already the expected state and will wait for power irq only if | ||
1023 | * power irq is expected to be trigerred based on the current IO line state | ||
1024 | * and expected IO line state. | ||
1025 | */ | ||
1026 | static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type) | ||
1027 | { | ||
1028 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
1029 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
1030 | bool done = false; | ||
1031 | |||
1032 | pr_debug("%s: %s: request %d curr_pwr_state %x curr_io_level %x\n", | ||
1033 | mmc_hostname(host->mmc), __func__, req_type, | ||
1034 | msm_host->curr_pwr_state, msm_host->curr_io_level); | ||
1035 | |||
1036 | /* | ||
1037 | * The IRQ for request type IO High/LOW will be generated when - | ||
1038 | * there is a state change in 1.8V enable bit (bit 3) of | ||
1039 | * SDHCI_HOST_CONTROL2 register. The reset state of that bit is 0 | ||
1040 | * which indicates 3.3V IO voltage. So, when MMC core layer tries | ||
1041 | * to set it to 3.3V before card detection happens, the | ||
1042 | * IRQ doesn't get triggered as there is no state change in this bit. | ||
1043 | * The driver already handles this case by changing the IO voltage | ||
1044 | * level to high as part of controller power up sequence. Hence, check | ||
1045 | * for host->pwr to handle a case where IO voltage high request is | ||
1046 | * issued even before controller power up. | ||
1047 | */ | ||
1048 | if ((req_type & REQ_IO_HIGH) && !host->pwr) { | ||
1049 | pr_debug("%s: do not wait for power IRQ that never comes, req_type: %d\n", | ||
1050 | mmc_hostname(host->mmc), req_type); | ||
1051 | return; | ||
1052 | } | ||
1053 | if ((req_type & msm_host->curr_pwr_state) || | ||
1054 | (req_type & msm_host->curr_io_level)) | ||
1055 | done = true; | ||
1056 | /* | ||
1057 | * This is needed here to handle cases where register writes will | ||
1058 | * not change the current bus state or io level of the controller. | ||
1059 | * In this case, no power irq will be triggerred and we should | ||
1060 | * not wait. | ||
1061 | */ | ||
1062 | if (!done) { | ||
1063 | if (!wait_event_timeout(msm_host->pwr_irq_wait, | ||
1064 | msm_host->pwr_irq_flag, | ||
1065 | msecs_to_jiffies(MSM_PWR_IRQ_TIMEOUT_MS))) | ||
1066 | dev_warn(&msm_host->pdev->dev, | ||
1067 | "%s: pwr_irq for req: (%d) timed out\n", | ||
1068 | mmc_hostname(host->mmc), req_type); | ||
1069 | } | ||
1070 | pr_debug("%s: %s: request %d done\n", mmc_hostname(host->mmc), | ||
1071 | __func__, req_type); | ||
1072 | } | ||
1073 | |||
1074 | static void sdhci_msm_dump_pwr_ctrl_regs(struct sdhci_host *host) | ||
1075 | { | ||
1076 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
1077 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
1078 | |||
1079 | pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x\n", | ||
1080 | mmc_hostname(host->mmc), | ||
1081 | readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS), | ||
1082 | readl_relaxed(msm_host->core_mem + CORE_PWRCTL_MASK), | ||
1083 | readl_relaxed(msm_host->core_mem + CORE_PWRCTL_CTL)); | ||
1084 | } | ||
1085 | |||
1086 | static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) | ||
999 | { | 1087 | { |
1000 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 1088 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1001 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 1089 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
1002 | u32 irq_status, irq_ack = 0; | 1090 | u32 irq_status, irq_ack = 0; |
1091 | int retry = 10; | ||
1092 | int pwr_state = 0, io_level = 0; | ||
1093 | |||
1003 | 1094 | ||
1004 | irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); | 1095 | irq_status = readl_relaxed(msm_host->core_mem + CORE_PWRCTL_STATUS); |
1005 | irq_status &= INT_MASK; | 1096 | irq_status &= INT_MASK; |
1006 | 1097 | ||
1007 | writel_relaxed(irq_status, msm_host->core_mem + CORE_PWRCTL_CLEAR); | 1098 | writel_relaxed(irq_status, msm_host->core_mem + CORE_PWRCTL_CLEAR); |
1008 | 1099 | ||
1009 | if (irq_status & (CORE_PWRCTL_BUS_ON | CORE_PWRCTL_BUS_OFF)) | 1100 | /* |
1101 | * There is a rare HW scenario where the first clear pulse could be | ||
1102 | * lost when actual reset and clear/read of status register is | ||
1103 | * happening at a time. Hence, retry for at least 10 times to make | ||
1104 | * sure status register is cleared. Otherwise, this will result in | ||
1105 | * a spurious power IRQ resulting in system instability. | ||
1106 | */ | ||
1107 | while (irq_status & readl_relaxed(msm_host->core_mem + | ||
1108 | CORE_PWRCTL_STATUS)) { | ||
1109 | if (retry == 0) { | ||
1110 | pr_err("%s: Timedout clearing (0x%x) pwrctl status register\n", | ||
1111 | mmc_hostname(host->mmc), irq_status); | ||
1112 | sdhci_msm_dump_pwr_ctrl_regs(host); | ||
1113 | WARN_ON(1); | ||
1114 | break; | ||
1115 | } | ||
1116 | writel_relaxed(irq_status, | ||
1117 | msm_host->core_mem + CORE_PWRCTL_CLEAR); | ||
1118 | retry--; | ||
1119 | udelay(10); | ||
1120 | } | ||
1121 | |||
1122 | /* Handle BUS ON/OFF*/ | ||
1123 | if (irq_status & CORE_PWRCTL_BUS_ON) { | ||
1124 | pwr_state = REQ_BUS_ON; | ||
1125 | io_level = REQ_IO_HIGH; | ||
1126 | irq_ack |= CORE_PWRCTL_BUS_SUCCESS; | ||
1127 | } | ||
1128 | if (irq_status & CORE_PWRCTL_BUS_OFF) { | ||
1129 | pwr_state = REQ_BUS_OFF; | ||
1130 | io_level = REQ_IO_LOW; | ||
1010 | irq_ack |= CORE_PWRCTL_BUS_SUCCESS; | 1131 | irq_ack |= CORE_PWRCTL_BUS_SUCCESS; |
1011 | if (irq_status & (CORE_PWRCTL_IO_LOW | CORE_PWRCTL_IO_HIGH)) | 1132 | } |
1133 | /* Handle IO LOW/HIGH */ | ||
1134 | if (irq_status & CORE_PWRCTL_IO_LOW) { | ||
1135 | io_level = REQ_IO_LOW; | ||
1136 | irq_ack |= CORE_PWRCTL_IO_SUCCESS; | ||
1137 | } | ||
1138 | if (irq_status & CORE_PWRCTL_IO_HIGH) { | ||
1139 | io_level = REQ_IO_HIGH; | ||
1012 | irq_ack |= CORE_PWRCTL_IO_SUCCESS; | 1140 | irq_ack |= CORE_PWRCTL_IO_SUCCESS; |
1141 | } | ||
1013 | 1142 | ||
1014 | /* | 1143 | /* |
1015 | * The driver has to acknowledge the interrupt, switch voltages and | 1144 | * The driver has to acknowledge the interrupt, switch voltages and |
@@ -1017,13 +1146,27 @@ static void sdhci_msm_voltage_switch(struct sdhci_host *host) | |||
1017 | * switches are handled by the sdhci core, so just report success. | 1146 | * switches are handled by the sdhci core, so just report success. |
1018 | */ | 1147 | */ |
1019 | writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); | 1148 | writel_relaxed(irq_ack, msm_host->core_mem + CORE_PWRCTL_CTL); |
1149 | |||
1150 | if (pwr_state) | ||
1151 | msm_host->curr_pwr_state = pwr_state; | ||
1152 | if (io_level) | ||
1153 | msm_host->curr_io_level = io_level; | ||
1154 | |||
1155 | pr_debug("%s: %s: Handled IRQ(%d), irq_status=0x%x, ack=0x%x\n", | ||
1156 | mmc_hostname(msm_host->mmc), __func__, irq, irq_status, | ||
1157 | irq_ack); | ||
1020 | } | 1158 | } |
1021 | 1159 | ||
1022 | static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) | 1160 | static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) |
1023 | { | 1161 | { |
1024 | struct sdhci_host *host = (struct sdhci_host *)data; | 1162 | struct sdhci_host *host = (struct sdhci_host *)data; |
1163 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
1164 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
1165 | |||
1166 | sdhci_msm_handle_pwr_irq(host, irq); | ||
1167 | msm_host->pwr_irq_flag = 1; | ||
1168 | sdhci_msm_complete_pwr_irq_wait(msm_host); | ||
1025 | 1169 | ||
1026 | sdhci_msm_voltage_switch(host); | ||
1027 | 1170 | ||
1028 | return IRQ_HANDLED; | 1171 | return IRQ_HANDLED; |
1029 | } | 1172 | } |
@@ -1032,8 +1175,9 @@ static unsigned int sdhci_msm_get_max_clock(struct sdhci_host *host) | |||
1032 | { | 1175 | { |
1033 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 1176 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1034 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 1177 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
1178 | struct clk *core_clk = msm_host->bulk_clks[0].clk; | ||
1035 | 1179 | ||
1036 | return clk_round_rate(msm_host->clk, ULONG_MAX); | 1180 | return clk_round_rate(core_clk, ULONG_MAX); |
1037 | } | 1181 | } |
1038 | 1182 | ||
1039 | static unsigned int sdhci_msm_get_min_clock(struct sdhci_host *host) | 1183 | static unsigned int sdhci_msm_get_min_clock(struct sdhci_host *host) |
@@ -1092,6 +1236,69 @@ out: | |||
1092 | __sdhci_msm_set_clock(host, clock); | 1236 | __sdhci_msm_set_clock(host, clock); |
1093 | } | 1237 | } |
1094 | 1238 | ||
1239 | /* | ||
1240 | * Platform specific register write functions. This is so that, if any | ||
1241 | * register write needs to be followed up by platform specific actions, | ||
1242 | * they can be added here. These functions can go to sleep when writes | ||
1243 | * to certain registers are done. | ||
1244 | * These functions are relying on sdhci_set_ios not using spinlock. | ||
1245 | */ | ||
1246 | static int __sdhci_msm_check_write(struct sdhci_host *host, u16 val, int reg) | ||
1247 | { | ||
1248 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
1249 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
1250 | u32 req_type = 0; | ||
1251 | |||
1252 | switch (reg) { | ||
1253 | case SDHCI_HOST_CONTROL2: | ||
1254 | req_type = (val & SDHCI_CTRL_VDD_180) ? REQ_IO_LOW : | ||
1255 | REQ_IO_HIGH; | ||
1256 | break; | ||
1257 | case SDHCI_SOFTWARE_RESET: | ||
1258 | if (host->pwr && (val & SDHCI_RESET_ALL)) | ||
1259 | req_type = REQ_BUS_OFF; | ||
1260 | break; | ||
1261 | case SDHCI_POWER_CONTROL: | ||
1262 | req_type = !val ? REQ_BUS_OFF : REQ_BUS_ON; | ||
1263 | break; | ||
1264 | } | ||
1265 | |||
1266 | if (req_type) { | ||
1267 | msm_host->pwr_irq_flag = 0; | ||
1268 | /* | ||
1269 | * Since this register write may trigger a power irq, ensure | ||
1270 | * all previous register writes are complete by this point. | ||
1271 | */ | ||
1272 | mb(); | ||
1273 | } | ||
1274 | return req_type; | ||
1275 | } | ||
1276 | |||
1277 | /* This function may sleep*/ | ||
1278 | static void sdhci_msm_writew(struct sdhci_host *host, u16 val, int reg) | ||
1279 | { | ||
1280 | u32 req_type = 0; | ||
1281 | |||
1282 | req_type = __sdhci_msm_check_write(host, val, reg); | ||
1283 | writew_relaxed(val, host->ioaddr + reg); | ||
1284 | |||
1285 | if (req_type) | ||
1286 | sdhci_msm_check_power_status(host, req_type); | ||
1287 | } | ||
1288 | |||
1289 | /* This function may sleep*/ | ||
1290 | static void sdhci_msm_writeb(struct sdhci_host *host, u8 val, int reg) | ||
1291 | { | ||
1292 | u32 req_type = 0; | ||
1293 | |||
1294 | req_type = __sdhci_msm_check_write(host, val, reg); | ||
1295 | |||
1296 | writeb_relaxed(val, host->ioaddr + reg); | ||
1297 | |||
1298 | if (req_type) | ||
1299 | sdhci_msm_check_power_status(host, req_type); | ||
1300 | } | ||
1301 | |||
1095 | static const struct of_device_id sdhci_msm_dt_match[] = { | 1302 | static const struct of_device_id sdhci_msm_dt_match[] = { |
1096 | { .compatible = "qcom,sdhci-msm-v4" }, | 1303 | { .compatible = "qcom,sdhci-msm-v4" }, |
1097 | {}, | 1304 | {}, |
@@ -1106,7 +1313,8 @@ static const struct sdhci_ops sdhci_msm_ops = { | |||
1106 | .get_max_clock = sdhci_msm_get_max_clock, | 1313 | .get_max_clock = sdhci_msm_get_max_clock, |
1107 | .set_bus_width = sdhci_set_bus_width, | 1314 | .set_bus_width = sdhci_set_bus_width, |
1108 | .set_uhs_signaling = sdhci_msm_set_uhs_signaling, | 1315 | .set_uhs_signaling = sdhci_msm_set_uhs_signaling, |
1109 | .voltage_switch = sdhci_msm_voltage_switch, | 1316 | .write_w = sdhci_msm_writew, |
1317 | .write_b = sdhci_msm_writeb, | ||
1110 | }; | 1318 | }; |
1111 | 1319 | ||
1112 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { | 1320 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { |
@@ -1124,6 +1332,7 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1124 | struct sdhci_pltfm_host *pltfm_host; | 1332 | struct sdhci_pltfm_host *pltfm_host; |
1125 | struct sdhci_msm_host *msm_host; | 1333 | struct sdhci_msm_host *msm_host; |
1126 | struct resource *core_memres; | 1334 | struct resource *core_memres; |
1335 | struct clk *clk; | ||
1127 | int ret; | 1336 | int ret; |
1128 | u16 host_version, core_minor; | 1337 | u16 host_version, core_minor; |
1129 | u32 core_version, config; | 1338 | u32 core_version, config; |
@@ -1160,24 +1369,42 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1160 | } | 1369 | } |
1161 | 1370 | ||
1162 | /* Setup main peripheral bus clock */ | 1371 | /* Setup main peripheral bus clock */ |
1163 | msm_host->pclk = devm_clk_get(&pdev->dev, "iface"); | 1372 | clk = devm_clk_get(&pdev->dev, "iface"); |
1164 | if (IS_ERR(msm_host->pclk)) { | 1373 | if (IS_ERR(clk)) { |
1165 | ret = PTR_ERR(msm_host->pclk); | 1374 | ret = PTR_ERR(clk); |
1166 | dev_err(&pdev->dev, "Peripheral clk setup failed (%d)\n", ret); | 1375 | dev_err(&pdev->dev, "Peripheral clk setup failed (%d)\n", ret); |
1167 | goto bus_clk_disable; | 1376 | goto bus_clk_disable; |
1168 | } | 1377 | } |
1169 | 1378 | msm_host->bulk_clks[1].clk = clk; | |
1170 | ret = clk_prepare_enable(msm_host->pclk); | ||
1171 | if (ret) | ||
1172 | goto bus_clk_disable; | ||
1173 | 1379 | ||
1174 | /* Setup SDC MMC clock */ | 1380 | /* Setup SDC MMC clock */ |
1175 | msm_host->clk = devm_clk_get(&pdev->dev, "core"); | 1381 | clk = devm_clk_get(&pdev->dev, "core"); |
1176 | if (IS_ERR(msm_host->clk)) { | 1382 | if (IS_ERR(clk)) { |
1177 | ret = PTR_ERR(msm_host->clk); | 1383 | ret = PTR_ERR(clk); |
1178 | dev_err(&pdev->dev, "SDC MMC clk setup failed (%d)\n", ret); | 1384 | dev_err(&pdev->dev, "SDC MMC clk setup failed (%d)\n", ret); |
1179 | goto pclk_disable; | 1385 | goto bus_clk_disable; |
1180 | } | 1386 | } |
1387 | msm_host->bulk_clks[0].clk = clk; | ||
1388 | |||
1389 | /* Vote for maximum clock rate for maximum performance */ | ||
1390 | ret = clk_set_rate(clk, INT_MAX); | ||
1391 | if (ret) | ||
1392 | dev_warn(&pdev->dev, "core clock boost failed\n"); | ||
1393 | |||
1394 | clk = devm_clk_get(&pdev->dev, "cal"); | ||
1395 | if (IS_ERR(clk)) | ||
1396 | clk = NULL; | ||
1397 | msm_host->bulk_clks[2].clk = clk; | ||
1398 | |||
1399 | clk = devm_clk_get(&pdev->dev, "sleep"); | ||
1400 | if (IS_ERR(clk)) | ||
1401 | clk = NULL; | ||
1402 | msm_host->bulk_clks[3].clk = clk; | ||
1403 | |||
1404 | ret = clk_bulk_prepare_enable(ARRAY_SIZE(msm_host->bulk_clks), | ||
1405 | msm_host->bulk_clks); | ||
1406 | if (ret) | ||
1407 | goto bus_clk_disable; | ||
1181 | 1408 | ||
1182 | /* | 1409 | /* |
1183 | * xo clock is needed for FLL feature of cm_dll. | 1410 | * xo clock is needed for FLL feature of cm_dll. |
@@ -1189,15 +1416,6 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1189 | dev_warn(&pdev->dev, "TCXO clk not present (%d)\n", ret); | 1416 | dev_warn(&pdev->dev, "TCXO clk not present (%d)\n", ret); |
1190 | } | 1417 | } |
1191 | 1418 | ||
1192 | /* Vote for maximum clock rate for maximum performance */ | ||
1193 | ret = clk_set_rate(msm_host->clk, INT_MAX); | ||
1194 | if (ret) | ||
1195 | dev_warn(&pdev->dev, "core clock boost failed\n"); | ||
1196 | |||
1197 | ret = clk_prepare_enable(msm_host->clk); | ||
1198 | if (ret) | ||
1199 | goto pclk_disable; | ||
1200 | |||
1201 | core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1419 | core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1202 | msm_host->core_mem = devm_ioremap_resource(&pdev->dev, core_memres); | 1420 | msm_host->core_mem = devm_ioremap_resource(&pdev->dev, core_memres); |
1203 | 1421 | ||
@@ -1251,6 +1469,21 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1251 | CORE_VENDOR_SPEC_CAPABILITIES0); | 1469 | CORE_VENDOR_SPEC_CAPABILITIES0); |
1252 | } | 1470 | } |
1253 | 1471 | ||
1472 | /* | ||
1473 | * Power on reset state may trigger power irq if previous status of | ||
1474 | * PWRCTL was either BUS_ON or IO_HIGH_V. So before enabling pwr irq | ||
1475 | * interrupt in GIC, any pending power irq interrupt should be | ||
1476 | * acknowledged. Otherwise power irq interrupt handler would be | ||
1477 | * fired prematurely. | ||
1478 | */ | ||
1479 | sdhci_msm_handle_pwr_irq(host, 0); | ||
1480 | |||
1481 | /* | ||
1482 | * Ensure that above writes are propogated before interrupt enablement | ||
1483 | * in GIC. | ||
1484 | */ | ||
1485 | mb(); | ||
1486 | |||
1254 | /* Setup IRQ for handling power/voltage tasks with PMIC */ | 1487 | /* Setup IRQ for handling power/voltage tasks with PMIC */ |
1255 | msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq"); | 1488 | msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq"); |
1256 | if (msm_host->pwr_irq < 0) { | 1489 | if (msm_host->pwr_irq < 0) { |
@@ -1260,6 +1493,10 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1260 | goto clk_disable; | 1493 | goto clk_disable; |
1261 | } | 1494 | } |
1262 | 1495 | ||
1496 | sdhci_msm_init_pwr_irq_wait(msm_host); | ||
1497 | /* Enable pwr irq interrupts */ | ||
1498 | writel_relaxed(INT_MASK, msm_host->core_mem + CORE_PWRCTL_MASK); | ||
1499 | |||
1263 | ret = devm_request_threaded_irq(&pdev->dev, msm_host->pwr_irq, NULL, | 1500 | ret = devm_request_threaded_irq(&pdev->dev, msm_host->pwr_irq, NULL, |
1264 | sdhci_msm_pwr_irq, IRQF_ONESHOT, | 1501 | sdhci_msm_pwr_irq, IRQF_ONESHOT, |
1265 | dev_name(&pdev->dev), host); | 1502 | dev_name(&pdev->dev), host); |
@@ -1290,9 +1527,8 @@ pm_runtime_disable: | |||
1290 | pm_runtime_set_suspended(&pdev->dev); | 1527 | pm_runtime_set_suspended(&pdev->dev); |
1291 | pm_runtime_put_noidle(&pdev->dev); | 1528 | pm_runtime_put_noidle(&pdev->dev); |
1292 | clk_disable: | 1529 | clk_disable: |
1293 | clk_disable_unprepare(msm_host->clk); | 1530 | clk_bulk_disable_unprepare(ARRAY_SIZE(msm_host->bulk_clks), |
1294 | pclk_disable: | 1531 | msm_host->bulk_clks); |
1295 | clk_disable_unprepare(msm_host->pclk); | ||
1296 | bus_clk_disable: | 1532 | bus_clk_disable: |
1297 | if (!IS_ERR(msm_host->bus_clk)) | 1533 | if (!IS_ERR(msm_host->bus_clk)) |
1298 | clk_disable_unprepare(msm_host->bus_clk); | 1534 | clk_disable_unprepare(msm_host->bus_clk); |
@@ -1315,8 +1551,8 @@ static int sdhci_msm_remove(struct platform_device *pdev) | |||
1315 | pm_runtime_disable(&pdev->dev); | 1551 | pm_runtime_disable(&pdev->dev); |
1316 | pm_runtime_put_noidle(&pdev->dev); | 1552 | pm_runtime_put_noidle(&pdev->dev); |
1317 | 1553 | ||
1318 | clk_disable_unprepare(msm_host->clk); | 1554 | clk_bulk_disable_unprepare(ARRAY_SIZE(msm_host->bulk_clks), |
1319 | clk_disable_unprepare(msm_host->pclk); | 1555 | msm_host->bulk_clks); |
1320 | if (!IS_ERR(msm_host->bus_clk)) | 1556 | if (!IS_ERR(msm_host->bus_clk)) |
1321 | clk_disable_unprepare(msm_host->bus_clk); | 1557 | clk_disable_unprepare(msm_host->bus_clk); |
1322 | sdhci_pltfm_free(pdev); | 1558 | sdhci_pltfm_free(pdev); |
@@ -1330,8 +1566,8 @@ static int sdhci_msm_runtime_suspend(struct device *dev) | |||
1330 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 1566 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1331 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 1567 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
1332 | 1568 | ||
1333 | clk_disable_unprepare(msm_host->clk); | 1569 | clk_bulk_disable_unprepare(ARRAY_SIZE(msm_host->bulk_clks), |
1334 | clk_disable_unprepare(msm_host->pclk); | 1570 | msm_host->bulk_clks); |
1335 | 1571 | ||
1336 | return 0; | 1572 | return 0; |
1337 | } | 1573 | } |
@@ -1341,21 +1577,9 @@ static int sdhci_msm_runtime_resume(struct device *dev) | |||
1341 | struct sdhci_host *host = dev_get_drvdata(dev); | 1577 | struct sdhci_host *host = dev_get_drvdata(dev); |
1342 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 1578 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1343 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 1579 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
1344 | int ret; | ||
1345 | 1580 | ||
1346 | ret = clk_prepare_enable(msm_host->clk); | 1581 | return clk_bulk_prepare_enable(ARRAY_SIZE(msm_host->bulk_clks), |
1347 | if (ret) { | 1582 | msm_host->bulk_clks); |
1348 | dev_err(dev, "clk_enable failed for core_clk: %d\n", ret); | ||
1349 | return ret; | ||
1350 | } | ||
1351 | ret = clk_prepare_enable(msm_host->pclk); | ||
1352 | if (ret) { | ||
1353 | dev_err(dev, "clk_enable failed for iface_clk: %d\n", ret); | ||
1354 | clk_disable_unprepare(msm_host->clk); | ||
1355 | return ret; | ||
1356 | } | ||
1357 | |||
1358 | return 0; | ||
1359 | } | 1583 | } |
1360 | #endif | 1584 | #endif |
1361 | 1585 | ||
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c index 4e47ed6bc716..682c573e20a7 100644 --- a/drivers/mmc/host/sdhci-of-at91.c +++ b/drivers/mmc/host/sdhci-of-at91.c | |||
@@ -114,7 +114,8 @@ static void sdhci_at91_set_power(struct sdhci_host *host, unsigned char mode, | |||
114 | sdhci_set_power_noreg(host, mode, vdd); | 114 | sdhci_set_power_noreg(host, mode, vdd); |
115 | } | 115 | } |
116 | 116 | ||
117 | void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) | 117 | static void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, |
118 | unsigned int timing) | ||
118 | { | 119 | { |
119 | if (timing == MMC_TIMING_MMC_DDR52) | 120 | if (timing == MMC_TIMING_MMC_DDR52) |
120 | sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R); | 121 | sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R); |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index d96a057a7db8..1f424374bbbb 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -458,6 +458,33 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host) | |||
458 | return clock / 256 / 16; | 458 | return clock / 256 / 16; |
459 | } | 459 | } |
460 | 460 | ||
461 | static void esdhc_clock_enable(struct sdhci_host *host, bool enable) | ||
462 | { | ||
463 | u32 val; | ||
464 | ktime_t timeout; | ||
465 | |||
466 | val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); | ||
467 | |||
468 | if (enable) | ||
469 | val |= ESDHC_CLOCK_SDCLKEN; | ||
470 | else | ||
471 | val &= ~ESDHC_CLOCK_SDCLKEN; | ||
472 | |||
473 | sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL); | ||
474 | |||
475 | /* Wait max 20 ms */ | ||
476 | timeout = ktime_add_ms(ktime_get(), 20); | ||
477 | val = ESDHC_CLOCK_STABLE; | ||
478 | while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) { | ||
479 | if (ktime_after(ktime_get(), timeout)) { | ||
480 | pr_err("%s: Internal clock never stabilised.\n", | ||
481 | mmc_hostname(host->mmc)); | ||
482 | break; | ||
483 | } | ||
484 | udelay(10); | ||
485 | } | ||
486 | } | ||
487 | |||
461 | static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) | 488 | static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) |
462 | { | 489 | { |
463 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 490 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
@@ -469,8 +496,10 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) | |||
469 | 496 | ||
470 | host->mmc->actual_clock = 0; | 497 | host->mmc->actual_clock = 0; |
471 | 498 | ||
472 | if (clock == 0) | 499 | if (clock == 0) { |
500 | esdhc_clock_enable(host, false); | ||
473 | return; | 501 | return; |
502 | } | ||
474 | 503 | ||
475 | /* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */ | 504 | /* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */ |
476 | if (esdhc->vendor_ver < VENDOR_V_23) | 505 | if (esdhc->vendor_ver < VENDOR_V_23) |
@@ -558,33 +587,6 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) | |||
558 | sdhci_writel(host, ctrl, ESDHC_PROCTL); | 587 | sdhci_writel(host, ctrl, ESDHC_PROCTL); |
559 | } | 588 | } |
560 | 589 | ||
561 | static void esdhc_clock_enable(struct sdhci_host *host, bool enable) | ||
562 | { | ||
563 | u32 val; | ||
564 | ktime_t timeout; | ||
565 | |||
566 | val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); | ||
567 | |||
568 | if (enable) | ||
569 | val |= ESDHC_CLOCK_SDCLKEN; | ||
570 | else | ||
571 | val &= ~ESDHC_CLOCK_SDCLKEN; | ||
572 | |||
573 | sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL); | ||
574 | |||
575 | /* Wait max 20 ms */ | ||
576 | timeout = ktime_add_ms(ktime_get(), 20); | ||
577 | val = ESDHC_CLOCK_STABLE; | ||
578 | while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) { | ||
579 | if (ktime_after(ktime_get(), timeout)) { | ||
580 | pr_err("%s: Internal clock never stabilised.\n", | ||
581 | mmc_hostname(host->mmc)); | ||
582 | break; | ||
583 | } | ||
584 | udelay(10); | ||
585 | } | ||
586 | } | ||
587 | |||
588 | static void esdhc_reset(struct sdhci_host *host, u8 mask) | 590 | static void esdhc_reset(struct sdhci_host *host, u8 mask) |
589 | { | 591 | { |
590 | sdhci_reset(host, mask); | 592 | sdhci_reset(host, mask); |
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c new file mode 100644 index 000000000000..628bfe9a3d17 --- /dev/null +++ b/drivers/mmc/host/sdhci-omap.c | |||
@@ -0,0 +1,607 @@ | |||
1 | /** | ||
2 | * SDHCI Controller driver for TI's OMAP SoCs | ||
3 | * | ||
4 | * Copyright (C) 2017 Texas Instruments | ||
5 | * Author: Kishon Vijay Abraham I <kishon@ti.com> | ||
6 | * | ||
7 | * This program is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 of | ||
9 | * the License as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/mmc/slot-gpio.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/of_device.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/pm_runtime.h> | ||
27 | #include <linux/regulator/consumer.h> | ||
28 | |||
29 | #include "sdhci-pltfm.h" | ||
30 | |||
31 | #define SDHCI_OMAP_CON 0x12c | ||
32 | #define CON_DW8 BIT(5) | ||
33 | #define CON_DMA_MASTER BIT(20) | ||
34 | #define CON_INIT BIT(1) | ||
35 | #define CON_OD BIT(0) | ||
36 | |||
37 | #define SDHCI_OMAP_CMD 0x20c | ||
38 | |||
39 | #define SDHCI_OMAP_HCTL 0x228 | ||
40 | #define HCTL_SDBP BIT(8) | ||
41 | #define HCTL_SDVS_SHIFT 9 | ||
42 | #define HCTL_SDVS_MASK (0x7 << HCTL_SDVS_SHIFT) | ||
43 | #define HCTL_SDVS_33 (0x7 << HCTL_SDVS_SHIFT) | ||
44 | #define HCTL_SDVS_30 (0x6 << HCTL_SDVS_SHIFT) | ||
45 | #define HCTL_SDVS_18 (0x5 << HCTL_SDVS_SHIFT) | ||
46 | |||
47 | #define SDHCI_OMAP_SYSCTL 0x22c | ||
48 | #define SYSCTL_CEN BIT(2) | ||
49 | #define SYSCTL_CLKD_SHIFT 6 | ||
50 | #define SYSCTL_CLKD_MASK 0x3ff | ||
51 | |||
52 | #define SDHCI_OMAP_STAT 0x230 | ||
53 | |||
54 | #define SDHCI_OMAP_IE 0x234 | ||
55 | #define INT_CC_EN BIT(0) | ||
56 | |||
57 | #define SDHCI_OMAP_AC12 0x23c | ||
58 | #define AC12_V1V8_SIGEN BIT(19) | ||
59 | |||
60 | #define SDHCI_OMAP_CAPA 0x240 | ||
61 | #define CAPA_VS33 BIT(24) | ||
62 | #define CAPA_VS30 BIT(25) | ||
63 | #define CAPA_VS18 BIT(26) | ||
64 | |||
65 | #define SDHCI_OMAP_TIMEOUT 1 /* 1 msec */ | ||
66 | |||
67 | #define SYSCTL_CLKD_MAX 0x3FF | ||
68 | |||
69 | #define IOV_1V8 1800000 /* 180000 uV */ | ||
70 | #define IOV_3V0 3000000 /* 300000 uV */ | ||
71 | #define IOV_3V3 3300000 /* 330000 uV */ | ||
72 | |||
73 | struct sdhci_omap_data { | ||
74 | u32 offset; | ||
75 | }; | ||
76 | |||
77 | struct sdhci_omap_host { | ||
78 | void __iomem *base; | ||
79 | struct device *dev; | ||
80 | struct regulator *pbias; | ||
81 | bool pbias_enabled; | ||
82 | struct sdhci_host *host; | ||
83 | u8 bus_mode; | ||
84 | u8 power_mode; | ||
85 | }; | ||
86 | |||
87 | static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host, | ||
88 | unsigned int offset) | ||
89 | { | ||
90 | return readl(host->base + offset); | ||
91 | } | ||
92 | |||
93 | static inline void sdhci_omap_writel(struct sdhci_omap_host *host, | ||
94 | unsigned int offset, u32 data) | ||
95 | { | ||
96 | writel(data, host->base + offset); | ||
97 | } | ||
98 | |||
99 | static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host, | ||
100 | bool power_on, unsigned int iov) | ||
101 | { | ||
102 | int ret; | ||
103 | struct device *dev = omap_host->dev; | ||
104 | |||
105 | if (IS_ERR(omap_host->pbias)) | ||
106 | return 0; | ||
107 | |||
108 | if (power_on) { | ||
109 | ret = regulator_set_voltage(omap_host->pbias, iov, iov); | ||
110 | if (ret) { | ||
111 | dev_err(dev, "pbias set voltage failed\n"); | ||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | if (omap_host->pbias_enabled) | ||
116 | return 0; | ||
117 | |||
118 | ret = regulator_enable(omap_host->pbias); | ||
119 | if (ret) { | ||
120 | dev_err(dev, "pbias reg enable fail\n"); | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | omap_host->pbias_enabled = true; | ||
125 | } else { | ||
126 | if (!omap_host->pbias_enabled) | ||
127 | return 0; | ||
128 | |||
129 | ret = regulator_disable(omap_host->pbias); | ||
130 | if (ret) { | ||
131 | dev_err(dev, "pbias reg disable fail\n"); | ||
132 | return ret; | ||
133 | } | ||
134 | omap_host->pbias_enabled = false; | ||
135 | } | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host, | ||
141 | unsigned int iov) | ||
142 | { | ||
143 | int ret; | ||
144 | struct sdhci_host *host = omap_host->host; | ||
145 | struct mmc_host *mmc = host->mmc; | ||
146 | |||
147 | ret = sdhci_omap_set_pbias(omap_host, false, 0); | ||
148 | if (ret) | ||
149 | return ret; | ||
150 | |||
151 | if (!IS_ERR(mmc->supply.vqmmc)) { | ||
152 | ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov); | ||
153 | if (ret) { | ||
154 | dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n"); | ||
155 | return ret; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | ret = sdhci_omap_set_pbias(omap_host, true, iov); | ||
160 | if (ret) | ||
161 | return ret; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host, | ||
167 | unsigned char signal_voltage) | ||
168 | { | ||
169 | u32 reg; | ||
170 | ktime_t timeout; | ||
171 | |||
172 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL); | ||
173 | reg &= ~HCTL_SDVS_MASK; | ||
174 | |||
175 | if (signal_voltage == MMC_SIGNAL_VOLTAGE_330) | ||
176 | reg |= HCTL_SDVS_33; | ||
177 | else | ||
178 | reg |= HCTL_SDVS_18; | ||
179 | |||
180 | sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg); | ||
181 | |||
182 | reg |= HCTL_SDBP; | ||
183 | sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg); | ||
184 | |||
185 | /* wait 1ms */ | ||
186 | timeout = ktime_add_ms(ktime_get(), SDHCI_OMAP_TIMEOUT); | ||
187 | while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) { | ||
188 | if (WARN_ON(ktime_after(ktime_get(), timeout))) | ||
189 | return; | ||
190 | usleep_range(5, 10); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc, | ||
195 | struct mmc_ios *ios) | ||
196 | { | ||
197 | u32 reg; | ||
198 | int ret; | ||
199 | unsigned int iov; | ||
200 | struct sdhci_host *host = mmc_priv(mmc); | ||
201 | struct sdhci_pltfm_host *pltfm_host; | ||
202 | struct sdhci_omap_host *omap_host; | ||
203 | struct device *dev; | ||
204 | |||
205 | pltfm_host = sdhci_priv(host); | ||
206 | omap_host = sdhci_pltfm_priv(pltfm_host); | ||
207 | dev = omap_host->dev; | ||
208 | |||
209 | if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { | ||
210 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); | ||
211 | if (!(reg & CAPA_VS33)) | ||
212 | return -EOPNOTSUPP; | ||
213 | |||
214 | sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage); | ||
215 | |||
216 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12); | ||
217 | reg &= ~AC12_V1V8_SIGEN; | ||
218 | sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg); | ||
219 | |||
220 | iov = IOV_3V3; | ||
221 | } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { | ||
222 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); | ||
223 | if (!(reg & CAPA_VS18)) | ||
224 | return -EOPNOTSUPP; | ||
225 | |||
226 | sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage); | ||
227 | |||
228 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12); | ||
229 | reg |= AC12_V1V8_SIGEN; | ||
230 | sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg); | ||
231 | |||
232 | iov = IOV_1V8; | ||
233 | } else { | ||
234 | return -EOPNOTSUPP; | ||
235 | } | ||
236 | |||
237 | ret = sdhci_omap_enable_iov(omap_host, iov); | ||
238 | if (ret) { | ||
239 | dev_err(dev, "failed to switch IO voltage to %dmV\n", iov); | ||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | dev_dbg(dev, "IO voltage switched to %dmV\n", iov); | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host, | ||
248 | unsigned int mode) | ||
249 | { | ||
250 | u32 reg; | ||
251 | |||
252 | if (omap_host->bus_mode == mode) | ||
253 | return; | ||
254 | |||
255 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); | ||
256 | if (mode == MMC_BUSMODE_OPENDRAIN) | ||
257 | reg |= CON_OD; | ||
258 | else | ||
259 | reg &= ~CON_OD; | ||
260 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); | ||
261 | |||
262 | omap_host->bus_mode = mode; | ||
263 | } | ||
264 | |||
265 | static void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | ||
266 | { | ||
267 | struct sdhci_host *host = mmc_priv(mmc); | ||
268 | struct sdhci_pltfm_host *pltfm_host; | ||
269 | struct sdhci_omap_host *omap_host; | ||
270 | |||
271 | pltfm_host = sdhci_priv(host); | ||
272 | omap_host = sdhci_pltfm_priv(pltfm_host); | ||
273 | |||
274 | sdhci_omap_set_bus_mode(omap_host, ios->bus_mode); | ||
275 | sdhci_set_ios(mmc, ios); | ||
276 | } | ||
277 | |||
278 | static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host, | ||
279 | unsigned int clock) | ||
280 | { | ||
281 | u16 dsor; | ||
282 | |||
283 | dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock); | ||
284 | if (dsor > SYSCTL_CLKD_MAX) | ||
285 | dsor = SYSCTL_CLKD_MAX; | ||
286 | |||
287 | return dsor; | ||
288 | } | ||
289 | |||
290 | static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host) | ||
291 | { | ||
292 | u32 reg; | ||
293 | |||
294 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL); | ||
295 | reg |= SYSCTL_CEN; | ||
296 | sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg); | ||
297 | } | ||
298 | |||
299 | static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host) | ||
300 | { | ||
301 | u32 reg; | ||
302 | |||
303 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL); | ||
304 | reg &= ~SYSCTL_CEN; | ||
305 | sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg); | ||
306 | } | ||
307 | |||
308 | static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock) | ||
309 | { | ||
310 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
311 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | ||
312 | unsigned long clkdiv; | ||
313 | |||
314 | sdhci_omap_stop_clock(omap_host); | ||
315 | |||
316 | if (!clock) | ||
317 | return; | ||
318 | |||
319 | clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock); | ||
320 | clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT; | ||
321 | sdhci_enable_clk(host, clkdiv); | ||
322 | |||
323 | sdhci_omap_start_clock(omap_host); | ||
324 | } | ||
325 | |||
326 | static void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode, | ||
327 | unsigned short vdd) | ||
328 | { | ||
329 | struct mmc_host *mmc = host->mmc; | ||
330 | |||
331 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); | ||
332 | } | ||
333 | |||
334 | static int sdhci_omap_enable_dma(struct sdhci_host *host) | ||
335 | { | ||
336 | u32 reg; | ||
337 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
338 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | ||
339 | |||
340 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); | ||
341 | reg |= CON_DMA_MASTER; | ||
342 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host) | ||
348 | { | ||
349 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
350 | |||
351 | return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX; | ||
352 | } | ||
353 | |||
354 | static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width) | ||
355 | { | ||
356 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
357 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | ||
358 | u32 reg; | ||
359 | |||
360 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); | ||
361 | if (width == MMC_BUS_WIDTH_8) | ||
362 | reg |= CON_DW8; | ||
363 | else | ||
364 | reg &= ~CON_DW8; | ||
365 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); | ||
366 | |||
367 | sdhci_set_bus_width(host, width); | ||
368 | } | ||
369 | |||
370 | static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode) | ||
371 | { | ||
372 | u32 reg; | ||
373 | ktime_t timeout; | ||
374 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
375 | struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); | ||
376 | |||
377 | if (omap_host->power_mode == power_mode) | ||
378 | return; | ||
379 | |||
380 | if (power_mode != MMC_POWER_ON) | ||
381 | return; | ||
382 | |||
383 | disable_irq(host->irq); | ||
384 | |||
385 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); | ||
386 | reg |= CON_INIT; | ||
387 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); | ||
388 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0); | ||
389 | |||
390 | /* wait 1ms */ | ||
391 | timeout = ktime_add_ms(ktime_get(), SDHCI_OMAP_TIMEOUT); | ||
392 | while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) { | ||
393 | if (WARN_ON(ktime_after(ktime_get(), timeout))) | ||
394 | return; | ||
395 | usleep_range(5, 10); | ||
396 | } | ||
397 | |||
398 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); | ||
399 | reg &= ~CON_INIT; | ||
400 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg); | ||
401 | sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN); | ||
402 | |||
403 | enable_irq(host->irq); | ||
404 | |||
405 | omap_host->power_mode = power_mode; | ||
406 | } | ||
407 | |||
408 | static struct sdhci_ops sdhci_omap_ops = { | ||
409 | .set_clock = sdhci_omap_set_clock, | ||
410 | .set_power = sdhci_omap_set_power, | ||
411 | .enable_dma = sdhci_omap_enable_dma, | ||
412 | .get_max_clock = sdhci_pltfm_clk_get_max_clock, | ||
413 | .get_min_clock = sdhci_omap_get_min_clock, | ||
414 | .set_bus_width = sdhci_omap_set_bus_width, | ||
415 | .platform_send_init_74_clocks = sdhci_omap_init_74_clocks, | ||
416 | .reset = sdhci_reset, | ||
417 | .set_uhs_signaling = sdhci_set_uhs_signaling, | ||
418 | }; | ||
419 | |||
420 | static int sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host) | ||
421 | { | ||
422 | u32 reg; | ||
423 | int ret = 0; | ||
424 | struct device *dev = omap_host->dev; | ||
425 | struct regulator *vqmmc; | ||
426 | |||
427 | vqmmc = regulator_get(dev, "vqmmc"); | ||
428 | if (IS_ERR(vqmmc)) { | ||
429 | ret = PTR_ERR(vqmmc); | ||
430 | goto reg_put; | ||
431 | } | ||
432 | |||
433 | /* voltage capabilities might be set by boot loader, clear it */ | ||
434 | reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); | ||
435 | reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33); | ||
436 | |||
437 | if (regulator_is_supported_voltage(vqmmc, IOV_3V3, IOV_3V3)) | ||
438 | reg |= CAPA_VS33; | ||
439 | if (regulator_is_supported_voltage(vqmmc, IOV_1V8, IOV_1V8)) | ||
440 | reg |= CAPA_VS18; | ||
441 | |||
442 | sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg); | ||
443 | |||
444 | reg_put: | ||
445 | regulator_put(vqmmc); | ||
446 | |||
447 | return ret; | ||
448 | } | ||
449 | |||
450 | static const struct sdhci_pltfm_data sdhci_omap_pdata = { | ||
451 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | | ||
452 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | | ||
453 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | | ||
454 | SDHCI_QUIRK_NO_HISPD_BIT | | ||
455 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, | ||
456 | .quirks2 = SDHCI_QUIRK2_NO_1_8_V | | ||
457 | SDHCI_QUIRK2_ACMD23_BROKEN | | ||
458 | SDHCI_QUIRK2_RSP_136_HAS_CRC, | ||
459 | .ops = &sdhci_omap_ops, | ||
460 | }; | ||
461 | |||
462 | static const struct sdhci_omap_data dra7_data = { | ||
463 | .offset = 0x200, | ||
464 | }; | ||
465 | |||
466 | static const struct of_device_id omap_sdhci_match[] = { | ||
467 | { .compatible = "ti,dra7-sdhci", .data = &dra7_data }, | ||
468 | {}, | ||
469 | }; | ||
470 | MODULE_DEVICE_TABLE(of, omap_sdhci_match); | ||
471 | |||
472 | static int sdhci_omap_probe(struct platform_device *pdev) | ||
473 | { | ||
474 | int ret; | ||
475 | u32 offset; | ||
476 | struct device *dev = &pdev->dev; | ||
477 | struct sdhci_host *host; | ||
478 | struct sdhci_pltfm_host *pltfm_host; | ||
479 | struct sdhci_omap_host *omap_host; | ||
480 | struct mmc_host *mmc; | ||
481 | const struct of_device_id *match; | ||
482 | struct sdhci_omap_data *data; | ||
483 | |||
484 | match = of_match_device(omap_sdhci_match, dev); | ||
485 | if (!match) | ||
486 | return -EINVAL; | ||
487 | |||
488 | data = (struct sdhci_omap_data *)match->data; | ||
489 | if (!data) { | ||
490 | dev_err(dev, "no sdhci omap data\n"); | ||
491 | return -EINVAL; | ||
492 | } | ||
493 | offset = data->offset; | ||
494 | |||
495 | host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata, | ||
496 | sizeof(*omap_host)); | ||
497 | if (IS_ERR(host)) { | ||
498 | dev_err(dev, "Failed sdhci_pltfm_init\n"); | ||
499 | return PTR_ERR(host); | ||
500 | } | ||
501 | |||
502 | pltfm_host = sdhci_priv(host); | ||
503 | omap_host = sdhci_pltfm_priv(pltfm_host); | ||
504 | omap_host->host = host; | ||
505 | omap_host->base = host->ioaddr; | ||
506 | omap_host->dev = dev; | ||
507 | host->ioaddr += offset; | ||
508 | |||
509 | mmc = host->mmc; | ||
510 | ret = mmc_of_parse(mmc); | ||
511 | if (ret) | ||
512 | goto err_pltfm_free; | ||
513 | |||
514 | pltfm_host->clk = devm_clk_get(dev, "fck"); | ||
515 | if (IS_ERR(pltfm_host->clk)) { | ||
516 | ret = PTR_ERR(pltfm_host->clk); | ||
517 | goto err_pltfm_free; | ||
518 | } | ||
519 | |||
520 | ret = clk_set_rate(pltfm_host->clk, mmc->f_max); | ||
521 | if (ret) { | ||
522 | dev_err(dev, "failed to set clock to %d\n", mmc->f_max); | ||
523 | goto err_pltfm_free; | ||
524 | } | ||
525 | |||
526 | omap_host->pbias = devm_regulator_get_optional(dev, "pbias"); | ||
527 | if (IS_ERR(omap_host->pbias)) { | ||
528 | ret = PTR_ERR(omap_host->pbias); | ||
529 | if (ret != -ENODEV) | ||
530 | goto err_pltfm_free; | ||
531 | dev_dbg(dev, "unable to get pbias regulator %d\n", ret); | ||
532 | } | ||
533 | omap_host->pbias_enabled = false; | ||
534 | |||
535 | /* | ||
536 | * omap_device_pm_domain has callbacks to enable the main | ||
537 | * functional clock, interface clock and also configure the | ||
538 | * SYSCONFIG register of omap devices. The callback will be invoked | ||
539 | * as part of pm_runtime_get_sync. | ||
540 | */ | ||
541 | pm_runtime_enable(dev); | ||
542 | ret = pm_runtime_get_sync(dev); | ||
543 | if (ret < 0) { | ||
544 | dev_err(dev, "pm_runtime_get_sync failed\n"); | ||
545 | pm_runtime_put_noidle(dev); | ||
546 | goto err_rpm_disable; | ||
547 | } | ||
548 | |||
549 | ret = sdhci_omap_set_capabilities(omap_host); | ||
550 | if (ret) { | ||
551 | dev_err(dev, "failed to set system capabilities\n"); | ||
552 | goto err_put_sync; | ||
553 | } | ||
554 | |||
555 | host->mmc_host_ops.get_ro = mmc_gpio_get_ro; | ||
556 | host->mmc_host_ops.start_signal_voltage_switch = | ||
557 | sdhci_omap_start_signal_voltage_switch; | ||
558 | host->mmc_host_ops.set_ios = sdhci_omap_set_ios; | ||
559 | |||
560 | sdhci_read_caps(host); | ||
561 | host->caps |= SDHCI_CAN_DO_ADMA2; | ||
562 | |||
563 | ret = sdhci_add_host(host); | ||
564 | if (ret) | ||
565 | goto err_put_sync; | ||
566 | |||
567 | return 0; | ||
568 | |||
569 | err_put_sync: | ||
570 | pm_runtime_put_sync(dev); | ||
571 | |||
572 | err_rpm_disable: | ||
573 | pm_runtime_disable(dev); | ||
574 | |||
575 | err_pltfm_free: | ||
576 | sdhci_pltfm_free(pdev); | ||
577 | return ret; | ||
578 | } | ||
579 | |||
580 | static int sdhci_omap_remove(struct platform_device *pdev) | ||
581 | { | ||
582 | struct device *dev = &pdev->dev; | ||
583 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
584 | |||
585 | sdhci_remove_host(host, true); | ||
586 | pm_runtime_put_sync(dev); | ||
587 | pm_runtime_disable(dev); | ||
588 | sdhci_pltfm_free(pdev); | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static struct platform_driver sdhci_omap_driver = { | ||
594 | .probe = sdhci_omap_probe, | ||
595 | .remove = sdhci_omap_remove, | ||
596 | .driver = { | ||
597 | .name = "sdhci-omap", | ||
598 | .of_match_table = omap_sdhci_match, | ||
599 | }, | ||
600 | }; | ||
601 | |||
602 | module_platform_driver(sdhci_omap_driver); | ||
603 | |||
604 | MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs"); | ||
605 | MODULE_AUTHOR("Texas Instruments Inc."); | ||
606 | MODULE_LICENSE("GPL v2"); | ||
607 | MODULE_ALIAS("platform:sdhci_omap"); | ||
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 67d787fa3306..3e4f04fd5175 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | #include "sdhci.h" | 33 | #include "sdhci.h" |
34 | #include "sdhci-pci.h" | 34 | #include "sdhci-pci.h" |
35 | #include "sdhci-pci-o2micro.h" | ||
36 | 35 | ||
37 | static int sdhci_pci_enable_dma(struct sdhci_host *host); | 36 | static int sdhci_pci_enable_dma(struct sdhci_host *host); |
38 | static void sdhci_pci_hw_reset(struct sdhci_host *host); | 37 | static void sdhci_pci_hw_reset(struct sdhci_host *host); |
@@ -798,15 +797,6 @@ static const struct sdhci_pci_fixes sdhci_intel_mrfld_mmc = { | |||
798 | .probe_slot = intel_mrfld_mmc_probe_slot, | 797 | .probe_slot = intel_mrfld_mmc_probe_slot, |
799 | }; | 798 | }; |
800 | 799 | ||
801 | /* O2Micro extra registers */ | ||
802 | #define O2_SD_LOCK_WP 0xD3 | ||
803 | #define O2_SD_MULTI_VCC3V 0xEE | ||
804 | #define O2_SD_CLKREQ 0xEC | ||
805 | #define O2_SD_CAPS 0xE0 | ||
806 | #define O2_SD_ADMA1 0xE2 | ||
807 | #define O2_SD_ADMA2 0xE7 | ||
808 | #define O2_SD_INF_MOD 0xF1 | ||
809 | |||
810 | static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) | 800 | static int jmicron_pmos(struct sdhci_pci_chip *chip, int on) |
811 | { | 801 | { |
812 | u8 scratch; | 802 | u8 scratch; |
@@ -1290,6 +1280,7 @@ static const struct pci_device_id pci_ids[] = { | |||
1290 | SDHCI_PCI_DEVICE(INTEL, SPT_SDIO, intel_byt_sdio), | 1280 | SDHCI_PCI_DEVICE(INTEL, SPT_SDIO, intel_byt_sdio), |
1291 | SDHCI_PCI_DEVICE(INTEL, SPT_SD, intel_byt_sd), | 1281 | SDHCI_PCI_DEVICE(INTEL, SPT_SD, intel_byt_sd), |
1292 | SDHCI_PCI_DEVICE(INTEL, DNV_EMMC, intel_byt_emmc), | 1282 | SDHCI_PCI_DEVICE(INTEL, DNV_EMMC, intel_byt_emmc), |
1283 | SDHCI_PCI_DEVICE(INTEL, CDF_EMMC, intel_glk_emmc), | ||
1293 | SDHCI_PCI_DEVICE(INTEL, BXT_EMMC, intel_byt_emmc), | 1284 | SDHCI_PCI_DEVICE(INTEL, BXT_EMMC, intel_byt_emmc), |
1294 | SDHCI_PCI_DEVICE(INTEL, BXT_SDIO, intel_byt_sdio), | 1285 | SDHCI_PCI_DEVICE(INTEL, BXT_SDIO, intel_byt_sdio), |
1295 | SDHCI_PCI_DEVICE(INTEL, BXT_SD, intel_byt_sd), | 1286 | SDHCI_PCI_DEVICE(INTEL, BXT_SD, intel_byt_sd), |
diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c index 14273ca00641..555970a29c94 100644 --- a/drivers/mmc/host/sdhci-pci-o2micro.c +++ b/drivers/mmc/host/sdhci-pci-o2micro.c | |||
@@ -19,7 +19,40 @@ | |||
19 | 19 | ||
20 | #include "sdhci.h" | 20 | #include "sdhci.h" |
21 | #include "sdhci-pci.h" | 21 | #include "sdhci-pci.h" |
22 | #include "sdhci-pci-o2micro.h" | 22 | |
23 | /* | ||
24 | * O2Micro device registers | ||
25 | */ | ||
26 | |||
27 | #define O2_SD_MISC_REG5 0x64 | ||
28 | #define O2_SD_LD0_CTRL 0x68 | ||
29 | #define O2_SD_DEV_CTRL 0x88 | ||
30 | #define O2_SD_LOCK_WP 0xD3 | ||
31 | #define O2_SD_TEST_REG 0xD4 | ||
32 | #define O2_SD_FUNC_REG0 0xDC | ||
33 | #define O2_SD_MULTI_VCC3V 0xEE | ||
34 | #define O2_SD_CLKREQ 0xEC | ||
35 | #define O2_SD_CAPS 0xE0 | ||
36 | #define O2_SD_ADMA1 0xE2 | ||
37 | #define O2_SD_ADMA2 0xE7 | ||
38 | #define O2_SD_INF_MOD 0xF1 | ||
39 | #define O2_SD_MISC_CTRL4 0xFC | ||
40 | #define O2_SD_TUNING_CTRL 0x300 | ||
41 | #define O2_SD_PLL_SETTING 0x304 | ||
42 | #define O2_SD_CLK_SETTING 0x328 | ||
43 | #define O2_SD_CAP_REG2 0x330 | ||
44 | #define O2_SD_CAP_REG0 0x334 | ||
45 | #define O2_SD_UHS1_CAP_SETTING 0x33C | ||
46 | #define O2_SD_DELAY_CTRL 0x350 | ||
47 | #define O2_SD_UHS2_L1_CTRL 0x35C | ||
48 | #define O2_SD_FUNC_REG3 0x3E0 | ||
49 | #define O2_SD_FUNC_REG4 0x3E4 | ||
50 | #define O2_SD_LED_ENABLE BIT(6) | ||
51 | #define O2_SD_FREG0_LEDOFF BIT(13) | ||
52 | #define O2_SD_FREG4_ENABLE_CLK_SET BIT(22) | ||
53 | |||
54 | #define O2_SD_VENDOR_SETTING 0x110 | ||
55 | #define O2_SD_VENDOR_SETTING2 0x1C8 | ||
23 | 56 | ||
24 | static void o2_pci_set_baseclk(struct sdhci_pci_chip *chip, u32 value) | 57 | static void o2_pci_set_baseclk(struct sdhci_pci_chip *chip, u32 value) |
25 | { | 58 | { |
diff --git a/drivers/mmc/host/sdhci-pci-o2micro.h b/drivers/mmc/host/sdhci-pci-o2micro.h deleted file mode 100644 index 770f53857211..000000000000 --- a/drivers/mmc/host/sdhci-pci-o2micro.h +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 BayHub Technology Ltd. | ||
3 | * | ||
4 | * Authors: Peter Guo <peter.guo@bayhubtech.com> | ||
5 | * Adam Lee <adam.lee@canonical.com> | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifndef __SDHCI_PCI_O2MICRO_H | ||
19 | #define __SDHCI_PCI_O2MICRO_H | ||
20 | |||
21 | #include "sdhci-pci.h" | ||
22 | |||
23 | /* | ||
24 | * O2Micro device IDs | ||
25 | */ | ||
26 | |||
27 | #define PCI_DEVICE_ID_O2_SDS0 0x8420 | ||
28 | #define PCI_DEVICE_ID_O2_SDS1 0x8421 | ||
29 | #define PCI_DEVICE_ID_O2_FUJIN2 0x8520 | ||
30 | #define PCI_DEVICE_ID_O2_SEABIRD0 0x8620 | ||
31 | #define PCI_DEVICE_ID_O2_SEABIRD1 0x8621 | ||
32 | |||
33 | /* | ||
34 | * O2Micro device registers | ||
35 | */ | ||
36 | |||
37 | #define O2_SD_MISC_REG5 0x64 | ||
38 | #define O2_SD_LD0_CTRL 0x68 | ||
39 | #define O2_SD_DEV_CTRL 0x88 | ||
40 | #define O2_SD_LOCK_WP 0xD3 | ||
41 | #define O2_SD_TEST_REG 0xD4 | ||
42 | #define O2_SD_FUNC_REG0 0xDC | ||
43 | #define O2_SD_MULTI_VCC3V 0xEE | ||
44 | #define O2_SD_CLKREQ 0xEC | ||
45 | #define O2_SD_CAPS 0xE0 | ||
46 | #define O2_SD_ADMA1 0xE2 | ||
47 | #define O2_SD_ADMA2 0xE7 | ||
48 | #define O2_SD_INF_MOD 0xF1 | ||
49 | #define O2_SD_MISC_CTRL4 0xFC | ||
50 | #define O2_SD_TUNING_CTRL 0x300 | ||
51 | #define O2_SD_PLL_SETTING 0x304 | ||
52 | #define O2_SD_CLK_SETTING 0x328 | ||
53 | #define O2_SD_CAP_REG2 0x330 | ||
54 | #define O2_SD_CAP_REG0 0x334 | ||
55 | #define O2_SD_UHS1_CAP_SETTING 0x33C | ||
56 | #define O2_SD_DELAY_CTRL 0x350 | ||
57 | #define O2_SD_UHS2_L1_CTRL 0x35C | ||
58 | #define O2_SD_FUNC_REG3 0x3E0 | ||
59 | #define O2_SD_FUNC_REG4 0x3E4 | ||
60 | #define O2_SD_LED_ENABLE BIT(6) | ||
61 | #define O2_SD_FREG0_LEDOFF BIT(13) | ||
62 | #define O2_SD_FREG4_ENABLE_CLK_SET BIT(22) | ||
63 | |||
64 | #define O2_SD_VENDOR_SETTING 0x110 | ||
65 | #define O2_SD_VENDOR_SETTING2 0x1C8 | ||
66 | |||
67 | extern int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot); | ||
68 | |||
69 | extern int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip); | ||
70 | |||
71 | extern int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip); | ||
72 | |||
73 | #endif /* __SDHCI_PCI_O2MICRO_H */ | ||
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 3e8ea3e566f6..0056f08a29cc 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
@@ -6,6 +6,12 @@ | |||
6 | * PCI device IDs, sub IDs | 6 | * PCI device IDs, sub IDs |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define PCI_DEVICE_ID_O2_SDS0 0x8420 | ||
10 | #define PCI_DEVICE_ID_O2_SDS1 0x8421 | ||
11 | #define PCI_DEVICE_ID_O2_FUJIN2 0x8520 | ||
12 | #define PCI_DEVICE_ID_O2_SEABIRD0 0x8620 | ||
13 | #define PCI_DEVICE_ID_O2_SEABIRD1 0x8621 | ||
14 | |||
9 | #define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809 | 15 | #define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809 |
10 | #define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a | 16 | #define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a |
11 | #define PCI_DEVICE_ID_INTEL_BYT_EMMC 0x0f14 | 17 | #define PCI_DEVICE_ID_INTEL_BYT_EMMC 0x0f14 |
@@ -26,6 +32,7 @@ | |||
26 | #define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c | 32 | #define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c |
27 | #define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d | 33 | #define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d |
28 | #define PCI_DEVICE_ID_INTEL_DNV_EMMC 0x19db | 34 | #define PCI_DEVICE_ID_INTEL_DNV_EMMC 0x19db |
35 | #define PCI_DEVICE_ID_INTEL_CDF_EMMC 0x18db | ||
29 | #define PCI_DEVICE_ID_INTEL_BXT_SD 0x0aca | 36 | #define PCI_DEVICE_ID_INTEL_BXT_SD 0x0aca |
30 | #define PCI_DEVICE_ID_INTEL_BXT_EMMC 0x0acc | 37 | #define PCI_DEVICE_ID_INTEL_BXT_EMMC 0x0acc |
31 | #define PCI_DEVICE_ID_INTEL_BXT_SDIO 0x0ad0 | 38 | #define PCI_DEVICE_ID_INTEL_BXT_SDIO 0x0ad0 |
@@ -164,4 +171,10 @@ static inline void *sdhci_pci_priv(struct sdhci_pci_slot *slot) | |||
164 | int sdhci_pci_resume_host(struct sdhci_pci_chip *chip); | 171 | int sdhci_pci_resume_host(struct sdhci_pci_chip *chip); |
165 | #endif | 172 | #endif |
166 | 173 | ||
174 | int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot); | ||
175 | int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip); | ||
176 | #ifdef CONFIG_PM_SLEEP | ||
177 | int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip); | ||
178 | #endif | ||
179 | |||
167 | #endif /* __SDHCI_PCI_H */ | 180 | #endif /* __SDHCI_PCI_H */ |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index d328fcf284d1..cda83ccb2702 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -761,32 +761,24 @@ static const struct dev_pm_ops sdhci_s3c_pmops = { | |||
761 | NULL) | 761 | NULL) |
762 | }; | 762 | }; |
763 | 763 | ||
764 | #if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) | ||
765 | static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = { | ||
766 | .no_divider = true, | ||
767 | }; | ||
768 | #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data) | ||
769 | #else | ||
770 | #define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL) | ||
771 | #endif | ||
772 | |||
773 | static const struct platform_device_id sdhci_s3c_driver_ids[] = { | 764 | static const struct platform_device_id sdhci_s3c_driver_ids[] = { |
774 | { | 765 | { |
775 | .name = "s3c-sdhci", | 766 | .name = "s3c-sdhci", |
776 | .driver_data = (kernel_ulong_t)NULL, | 767 | .driver_data = (kernel_ulong_t)NULL, |
777 | }, { | ||
778 | .name = "exynos4-sdhci", | ||
779 | .driver_data = EXYNOS4_SDHCI_DRV_DATA, | ||
780 | }, | 768 | }, |
781 | { } | 769 | { } |
782 | }; | 770 | }; |
783 | MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids); | 771 | MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids); |
784 | 772 | ||
785 | #ifdef CONFIG_OF | 773 | #ifdef CONFIG_OF |
774 | static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = { | ||
775 | .no_divider = true, | ||
776 | }; | ||
777 | |||
786 | static const struct of_device_id sdhci_s3c_dt_match[] = { | 778 | static const struct of_device_id sdhci_s3c_dt_match[] = { |
787 | { .compatible = "samsung,s3c6410-sdhci", }, | 779 | { .compatible = "samsung,s3c6410-sdhci", }, |
788 | { .compatible = "samsung,exynos4210-sdhci", | 780 | { .compatible = "samsung,exynos4210-sdhci", |
789 | .data = (void *)EXYNOS4_SDHCI_DRV_DATA }, | 781 | .data = &exynos4_sdhci_drv_data }, |
790 | {}, | 782 | {}, |
791 | }; | 783 | }; |
792 | MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match); | 784 | MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match); |
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 0cd6fa80db66..b877c13184c2 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -422,7 +422,15 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { | |||
422 | SDHCI_QUIRK_NO_HISPD_BIT | | 422 | SDHCI_QUIRK_NO_HISPD_BIT | |
423 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | | 423 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | |
424 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | 424 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
425 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, | 425 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | |
426 | /* SDHCI controllers on Tegra186 support 40-bit addressing. | ||
427 | * IOVA addresses are 48-bit wide on Tegra186. | ||
428 | * With 64-bit dma mask used for SDHCI, accesses can | ||
429 | * be broken. Disable 64-bit dma, which would fall back | ||
430 | * to 32-bit dma mask. Ideally 40-bit dma mask would work, | ||
431 | * But it is not supported as of now. | ||
432 | */ | ||
433 | SDHCI_QUIRK2_BROKEN_64_BIT_DMA, | ||
426 | .ops = &tegra114_sdhci_ops, | 434 | .ops = &tegra114_sdhci_ops, |
427 | }; | 435 | }; |
428 | 436 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0d5fcca18c9e..2f14334e42df 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -2407,12 +2407,12 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
2407 | ; | 2407 | ; |
2408 | } | 2408 | } |
2409 | 2409 | ||
2410 | static void sdhci_timeout_timer(unsigned long data) | 2410 | static void sdhci_timeout_timer(struct timer_list *t) |
2411 | { | 2411 | { |
2412 | struct sdhci_host *host; | 2412 | struct sdhci_host *host; |
2413 | unsigned long flags; | 2413 | unsigned long flags; |
2414 | 2414 | ||
2415 | host = (struct sdhci_host*)data; | 2415 | host = from_timer(host, t, timer); |
2416 | 2416 | ||
2417 | spin_lock_irqsave(&host->lock, flags); | 2417 | spin_lock_irqsave(&host->lock, flags); |
2418 | 2418 | ||
@@ -2429,12 +2429,12 @@ static void sdhci_timeout_timer(unsigned long data) | |||
2429 | spin_unlock_irqrestore(&host->lock, flags); | 2429 | spin_unlock_irqrestore(&host->lock, flags); |
2430 | } | 2430 | } |
2431 | 2431 | ||
2432 | static void sdhci_timeout_data_timer(unsigned long data) | 2432 | static void sdhci_timeout_data_timer(struct timer_list *t) |
2433 | { | 2433 | { |
2434 | struct sdhci_host *host; | 2434 | struct sdhci_host *host; |
2435 | unsigned long flags; | 2435 | unsigned long flags; |
2436 | 2436 | ||
2437 | host = (struct sdhci_host *)data; | 2437 | host = from_timer(host, t, data_timer); |
2438 | 2438 | ||
2439 | spin_lock_irqsave(&host->lock, flags); | 2439 | spin_lock_irqsave(&host->lock, flags); |
2440 | 2440 | ||
@@ -3238,7 +3238,7 @@ int sdhci_setup_host(struct sdhci_host *host) | |||
3238 | * available. | 3238 | * available. |
3239 | */ | 3239 | */ |
3240 | ret = mmc_regulator_get_supply(mmc); | 3240 | ret = mmc_regulator_get_supply(mmc); |
3241 | if (ret == -EPROBE_DEFER) | 3241 | if (ret) |
3242 | return ret; | 3242 | return ret; |
3243 | 3243 | ||
3244 | DBG("Version: 0x%08x | Present: 0x%08x\n", | 3244 | DBG("Version: 0x%08x | Present: 0x%08x\n", |
@@ -3749,9 +3749,8 @@ int __sdhci_add_host(struct sdhci_host *host) | |||
3749 | tasklet_init(&host->finish_tasklet, | 3749 | tasklet_init(&host->finish_tasklet, |
3750 | sdhci_tasklet_finish, (unsigned long)host); | 3750 | sdhci_tasklet_finish, (unsigned long)host); |
3751 | 3751 | ||
3752 | setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); | 3752 | timer_setup(&host->timer, sdhci_timeout_timer, 0); |
3753 | setup_timer(&host->data_timer, sdhci_timeout_data_timer, | 3753 | timer_setup(&host->data_timer, sdhci_timeout_data_timer, 0); |
3754 | (unsigned long)host); | ||
3755 | 3754 | ||
3756 | init_waitqueue_head(&host->buf_ready_int); | 3755 | init_waitqueue_head(&host->buf_ready_int); |
3757 | 3756 | ||
diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c index 111b66f5439b..04ca0d33a521 100644 --- a/drivers/mmc/host/sdhci_f_sdh30.c +++ b/drivers/mmc/host/sdhci_f_sdh30.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/property.h> | ||
16 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
17 | 18 | ||
18 | #include "sdhci-pltfm.h" | 19 | #include "sdhci-pltfm.h" |
@@ -47,6 +48,7 @@ struct f_sdhost_priv { | |||
47 | struct clk *clk; | 48 | struct clk *clk; |
48 | u32 vendor_hs200; | 49 | u32 vendor_hs200; |
49 | struct device *dev; | 50 | struct device *dev; |
51 | bool enable_cmd_dat_delay; | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host) | 54 | static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host) |
@@ -84,10 +86,19 @@ static unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host) | |||
84 | 86 | ||
85 | static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask) | 87 | static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask) |
86 | { | 88 | { |
89 | struct f_sdhost_priv *priv = sdhci_priv(host); | ||
90 | u32 ctl; | ||
91 | |||
87 | if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0) | 92 | if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0) |
88 | sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL); | 93 | sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL); |
89 | 94 | ||
90 | sdhci_reset(host, mask); | 95 | sdhci_reset(host, mask); |
96 | |||
97 | if (priv->enable_cmd_dat_delay) { | ||
98 | ctl = sdhci_readl(host, F_SDH30_ESD_CONTROL); | ||
99 | ctl |= F_SDH30_CMD_DAT_DELAY; | ||
100 | sdhci_writel(host, ctl, F_SDH30_ESD_CONTROL); | ||
101 | } | ||
91 | } | 102 | } |
92 | 103 | ||
93 | static const struct sdhci_ops sdhci_f_sdh30_ops = { | 104 | static const struct sdhci_ops sdhci_f_sdh30_ops = { |
@@ -126,6 +137,9 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev) | |||
126 | host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | | 137 | host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | |
127 | SDHCI_QUIRK2_TUNING_WORK_AROUND; | 138 | SDHCI_QUIRK2_TUNING_WORK_AROUND; |
128 | 139 | ||
140 | priv->enable_cmd_dat_delay = device_property_read_bool(dev, | ||
141 | "fujitsu,cmd-dat-delay-select"); | ||
142 | |||
129 | ret = mmc_of_parse(host->mmc); | 143 | ret = mmc_of_parse(host->mmc); |
130 | if (ret) | 144 | if (ret) |
131 | goto err; | 145 | goto err; |
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 53c970fe0873..cc98355dbdb9 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c | |||
@@ -1175,11 +1175,8 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, | |||
1175 | return -EINVAL; | 1175 | return -EINVAL; |
1176 | 1176 | ||
1177 | ret = mmc_regulator_get_supply(host->mmc); | 1177 | ret = mmc_regulator_get_supply(host->mmc); |
1178 | if (ret) { | 1178 | if (ret) |
1179 | if (ret != -EPROBE_DEFER) | ||
1180 | dev_err(&pdev->dev, "Could not get vmmc supply\n"); | ||
1181 | return ret; | 1179 | return ret; |
1182 | } | ||
1183 | 1180 | ||
1184 | host->reg_base = devm_ioremap_resource(&pdev->dev, | 1181 | host->reg_base = devm_ioremap_resource(&pdev->dev, |
1185 | platform_get_resource(pdev, IORESOURCE_MEM, 0)); | 1182 | platform_get_resource(pdev, IORESOURCE_MEM, 0)); |
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 93c4b40df90a..a3d8380ab480 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c | |||
@@ -783,9 +783,9 @@ static void tifm_sd_end_cmd(unsigned long data) | |||
783 | mmc_request_done(mmc, mrq); | 783 | mmc_request_done(mmc, mrq); |
784 | } | 784 | } |
785 | 785 | ||
786 | static void tifm_sd_abort(unsigned long data) | 786 | static void tifm_sd_abort(struct timer_list *t) |
787 | { | 787 | { |
788 | struct tifm_sd *host = (struct tifm_sd*)data; | 788 | struct tifm_sd *host = from_timer(host, t, timer); |
789 | 789 | ||
790 | pr_err("%s : card failed to respond for a long period of time " | 790 | pr_err("%s : card failed to respond for a long period of time " |
791 | "(%x, %x)\n", | 791 | "(%x, %x)\n", |
@@ -968,7 +968,7 @@ static int tifm_sd_probe(struct tifm_dev *sock) | |||
968 | 968 | ||
969 | tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd, | 969 | tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd, |
970 | (unsigned long)host); | 970 | (unsigned long)host); |
971 | setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); | 971 | timer_setup(&host->timer, tifm_sd_abort, 0); |
972 | 972 | ||
973 | mmc->ops = &tifm_sd_ops; | 973 | mmc->ops = &tifm_sd_ops; |
974 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 974 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index 9c4e6199b854..583bf3262df5 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c | |||
@@ -167,11 +167,11 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host) | |||
167 | 167 | ||
168 | /* HW engineers overrode docs: no sleep needed on R-Car2+ */ | 168 | /* HW engineers overrode docs: no sleep needed on R-Car2+ */ |
169 | if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) | 169 | if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) |
170 | msleep(10); | 170 | usleep_range(10000, 11000); |
171 | 171 | ||
172 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { | 172 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { |
173 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); | 173 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100); |
174 | msleep(10); | 174 | usleep_range(10000, 11000); |
175 | } | 175 | } |
176 | } | 176 | } |
177 | 177 | ||
@@ -179,7 +179,7 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) | |||
179 | { | 179 | { |
180 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { | 180 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { |
181 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); | 181 | sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); |
182 | msleep(10); | 182 | usleep_range(10000, 11000); |
183 | } | 183 | } |
184 | 184 | ||
185 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & | 185 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & |
@@ -187,7 +187,7 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) | |||
187 | 187 | ||
188 | /* HW engineers overrode docs: no sleep needed on R-Car2+ */ | 188 | /* HW engineers overrode docs: no sleep needed on R-Car2+ */ |
189 | if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) | 189 | if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) |
190 | msleep(10); | 190 | usleep_range(10000, 11000); |
191 | } | 191 | } |
192 | 192 | ||
193 | static void tmio_mmc_set_clock(struct tmio_mmc_host *host, | 193 | static void tmio_mmc_set_clock(struct tmio_mmc_host *host, |
@@ -219,7 +219,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, | |||
219 | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); | 219 | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); |
220 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); | 220 | sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK); |
221 | if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) | 221 | if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2)) |
222 | msleep(10); | 222 | usleep_range(10000, 11000); |
223 | 223 | ||
224 | tmio_mmc_clk_start(host); | 224 | tmio_mmc_clk_start(host); |
225 | } | 225 | } |
@@ -230,11 +230,11 @@ static void tmio_mmc_reset(struct tmio_mmc_host *host) | |||
230 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); | 230 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); |
231 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) | 231 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) |
232 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); | 232 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000); |
233 | msleep(10); | 233 | usleep_range(10000, 11000); |
234 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); | 234 | sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); |
235 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) | 235 | if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) |
236 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); | 236 | sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001); |
237 | msleep(10); | 237 | usleep_range(10000, 11000); |
238 | 238 | ||
239 | if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) { | 239 | if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) { |
240 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); | 240 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); |
@@ -1113,8 +1113,11 @@ static int tmio_mmc_init_ocr(struct tmio_mmc_host *host) | |||
1113 | { | 1113 | { |
1114 | struct tmio_mmc_data *pdata = host->pdata; | 1114 | struct tmio_mmc_data *pdata = host->pdata; |
1115 | struct mmc_host *mmc = host->mmc; | 1115 | struct mmc_host *mmc = host->mmc; |
1116 | int err; | ||
1116 | 1117 | ||
1117 | mmc_regulator_get_supply(mmc); | 1118 | err = mmc_regulator_get_supply(mmc); |
1119 | if (err) | ||
1120 | return err; | ||
1118 | 1121 | ||
1119 | /* use ocr_mask if no regulator */ | 1122 | /* use ocr_mask if no regulator */ |
1120 | if (!mmc->ocr_avail) | 1123 | if (!mmc->ocr_avail) |
@@ -1299,23 +1302,24 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | |||
1299 | pm_runtime_enable(&pdev->dev); | 1302 | pm_runtime_enable(&pdev->dev); |
1300 | 1303 | ||
1301 | ret = mmc_add_host(mmc); | 1304 | ret = mmc_add_host(mmc); |
1302 | if (ret < 0) { | 1305 | if (ret) |
1303 | tmio_mmc_host_remove(_host); | 1306 | goto remove_host; |
1304 | return ret; | ||
1305 | } | ||
1306 | 1307 | ||
1307 | dev_pm_qos_expose_latency_limit(&pdev->dev, 100); | 1308 | dev_pm_qos_expose_latency_limit(&pdev->dev, 100); |
1308 | 1309 | ||
1309 | if (pdata->flags & TMIO_MMC_USE_GPIO_CD) { | 1310 | if (pdata->flags & TMIO_MMC_USE_GPIO_CD) { |
1310 | ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio, 0); | 1311 | ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio, 0); |
1311 | if (ret < 0) { | 1312 | if (ret) |
1312 | tmio_mmc_host_remove(_host); | 1313 | goto remove_host; |
1313 | return ret; | 1314 | |
1314 | } | ||
1315 | mmc_gpiod_request_cd_irq(mmc); | 1315 | mmc_gpiod_request_cd_irq(mmc); |
1316 | } | 1316 | } |
1317 | 1317 | ||
1318 | return 0; | 1318 | return 0; |
1319 | |||
1320 | remove_host: | ||
1321 | tmio_mmc_host_remove(_host); | ||
1322 | return ret; | ||
1319 | } | 1323 | } |
1320 | EXPORT_SYMBOL_GPL(tmio_mmc_host_probe); | 1324 | EXPORT_SYMBOL_GPL(tmio_mmc_host_probe); |
1321 | 1325 | ||
diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index 64da6a88cfb9..cdfeb15b6f05 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c | |||
@@ -1757,7 +1757,7 @@ static int usdhi6_probe(struct platform_device *pdev) | |||
1757 | return -ENOMEM; | 1757 | return -ENOMEM; |
1758 | 1758 | ||
1759 | ret = mmc_regulator_get_supply(mmc); | 1759 | ret = mmc_regulator_get_supply(mmc); |
1760 | if (ret == -EPROBE_DEFER) | 1760 | if (ret) |
1761 | goto e_free_mmc; | 1761 | goto e_free_mmc; |
1762 | 1762 | ||
1763 | ret = mmc_of_parse(mmc); | 1763 | ret = mmc_of_parse(mmc); |
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index a838bf5480d8..32c4211506fc 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c | |||
@@ -932,12 +932,12 @@ out: | |||
932 | return result; | 932 | return result; |
933 | } | 933 | } |
934 | 934 | ||
935 | static void via_sdc_timeout(unsigned long ulongdata) | 935 | static void via_sdc_timeout(struct timer_list *t) |
936 | { | 936 | { |
937 | struct via_crdr_mmc_host *sdhost; | 937 | struct via_crdr_mmc_host *sdhost; |
938 | unsigned long flags; | 938 | unsigned long flags; |
939 | 939 | ||
940 | sdhost = (struct via_crdr_mmc_host *)ulongdata; | 940 | sdhost = from_timer(sdhost, t, timer); |
941 | 941 | ||
942 | spin_lock_irqsave(&sdhost->lock, flags); | 942 | spin_lock_irqsave(&sdhost->lock, flags); |
943 | 943 | ||
@@ -1036,9 +1036,7 @@ static void via_init_mmc_host(struct via_crdr_mmc_host *host) | |||
1036 | u32 lenreg; | 1036 | u32 lenreg; |
1037 | u32 status; | 1037 | u32 status; |
1038 | 1038 | ||
1039 | init_timer(&host->timer); | 1039 | timer_setup(&host->timer, via_sdc_timeout, 0); |
1040 | host->timer.data = (unsigned long)host; | ||
1041 | host->timer.function = via_sdc_timeout; | ||
1042 | 1040 | ||
1043 | spin_lock_init(&host->lock); | 1041 | spin_lock_init(&host->lock); |
1044 | 1042 | ||
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index 8f569d257405..1fe68137a30f 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c | |||
@@ -741,9 +741,10 @@ static void vub300_deadwork_thread(struct work_struct *work) | |||
741 | kref_put(&vub300->kref, vub300_delete); | 741 | kref_put(&vub300->kref, vub300_delete); |
742 | } | 742 | } |
743 | 743 | ||
744 | static void vub300_inactivity_timer_expired(unsigned long data) | 744 | static void vub300_inactivity_timer_expired(struct timer_list *t) |
745 | { /* softirq */ | 745 | { /* softirq */ |
746 | struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)data; | 746 | struct vub300_mmc_host *vub300 = from_timer(vub300, t, |
747 | inactivity_timer); | ||
747 | if (!vub300->interface) { | 748 | if (!vub300->interface) { |
748 | kref_put(&vub300->kref, vub300_delete); | 749 | kref_put(&vub300->kref, vub300_delete); |
749 | } else if (vub300->cmd) { | 750 | } else if (vub300->cmd) { |
@@ -1180,9 +1181,10 @@ static void send_command(struct vub300_mmc_host *vub300) | |||
1180 | * timer callback runs in atomic mode | 1181 | * timer callback runs in atomic mode |
1181 | * so it cannot call usb_kill_urb() | 1182 | * so it cannot call usb_kill_urb() |
1182 | */ | 1183 | */ |
1183 | static void vub300_sg_timed_out(unsigned long data) | 1184 | static void vub300_sg_timed_out(struct timer_list *t) |
1184 | { | 1185 | { |
1185 | struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)data; | 1186 | struct vub300_mmc_host *vub300 = from_timer(vub300, t, |
1187 | sg_transfer_timer); | ||
1186 | vub300->usb_timed_out = 1; | 1188 | vub300->usb_timed_out = 1; |
1187 | usb_sg_cancel(&vub300->sg_request); | 1189 | usb_sg_cancel(&vub300->sg_request); |
1188 | usb_unlink_urb(vub300->command_out_urb); | 1190 | usb_unlink_urb(vub300->command_out_urb); |
@@ -1244,12 +1246,8 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300, | |||
1244 | USB_RECIP_DEVICE, 0x0000, 0x0000, | 1246 | USB_RECIP_DEVICE, 0x0000, 0x0000, |
1245 | xfer_buffer, xfer_length, HZ); | 1247 | xfer_buffer, xfer_length, HZ); |
1246 | kfree(xfer_buffer); | 1248 | kfree(xfer_buffer); |
1247 | if (retval < 0) { | 1249 | if (retval < 0) |
1248 | strncpy(vub300->vub_name, | 1250 | goto copy_error_message; |
1249 | "SDIO pseudocode download failed", | ||
1250 | sizeof(vub300->vub_name)); | ||
1251 | return; | ||
1252 | } | ||
1253 | } else { | 1251 | } else { |
1254 | dev_err(&vub300->udev->dev, | 1252 | dev_err(&vub300->udev->dev, |
1255 | "not enough memory for xfer buffer to send" | 1253 | "not enough memory for xfer buffer to send" |
@@ -1291,12 +1289,8 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300, | |||
1291 | USB_RECIP_DEVICE, 0x0000, 0x0000, | 1289 | USB_RECIP_DEVICE, 0x0000, 0x0000, |
1292 | xfer_buffer, xfer_length, HZ); | 1290 | xfer_buffer, xfer_length, HZ); |
1293 | kfree(xfer_buffer); | 1291 | kfree(xfer_buffer); |
1294 | if (retval < 0) { | 1292 | if (retval < 0) |
1295 | strncpy(vub300->vub_name, | 1293 | goto copy_error_message; |
1296 | "SDIO pseudocode download failed", | ||
1297 | sizeof(vub300->vub_name)); | ||
1298 | return; | ||
1299 | } | ||
1300 | } else { | 1294 | } else { |
1301 | dev_err(&vub300->udev->dev, | 1295 | dev_err(&vub300->udev->dev, |
1302 | "not enough memory for xfer buffer to send" | 1296 | "not enough memory for xfer buffer to send" |
@@ -1349,6 +1343,12 @@ static void __download_offload_pseudocode(struct vub300_mmc_host *vub300, | |||
1349 | sizeof(vub300->vub_name)); | 1343 | sizeof(vub300->vub_name)); |
1350 | return; | 1344 | return; |
1351 | } | 1345 | } |
1346 | |||
1347 | return; | ||
1348 | |||
1349 | copy_error_message: | ||
1350 | strncpy(vub300->vub_name, "SDIO pseudocode download failed", | ||
1351 | sizeof(vub300->vub_name)); | ||
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | /* | 1354 | /* |
@@ -2323,13 +2323,10 @@ static int vub300_probe(struct usb_interface *interface, | |||
2323 | INIT_WORK(&vub300->cmndwork, vub300_cmndwork_thread); | 2323 | INIT_WORK(&vub300->cmndwork, vub300_cmndwork_thread); |
2324 | INIT_WORK(&vub300->deadwork, vub300_deadwork_thread); | 2324 | INIT_WORK(&vub300->deadwork, vub300_deadwork_thread); |
2325 | kref_init(&vub300->kref); | 2325 | kref_init(&vub300->kref); |
2326 | init_timer(&vub300->sg_transfer_timer); | 2326 | timer_setup(&vub300->sg_transfer_timer, vub300_sg_timed_out, 0); |
2327 | vub300->sg_transfer_timer.data = (unsigned long)vub300; | ||
2328 | vub300->sg_transfer_timer.function = vub300_sg_timed_out; | ||
2329 | kref_get(&vub300->kref); | 2327 | kref_get(&vub300->kref); |
2330 | init_timer(&vub300->inactivity_timer); | 2328 | timer_setup(&vub300->inactivity_timer, |
2331 | vub300->inactivity_timer.data = (unsigned long)vub300; | 2329 | vub300_inactivity_timer_expired, 0); |
2332 | vub300->inactivity_timer.function = vub300_inactivity_timer_expired; | ||
2333 | vub300->inactivity_timer.expires = jiffies + HZ; | 2330 | vub300->inactivity_timer.expires = jiffies + HZ; |
2334 | add_timer(&vub300->inactivity_timer); | 2331 | add_timer(&vub300->inactivity_timer); |
2335 | if (vub300->card_present) | 2332 | if (vub300->card_present) |
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 546aaf8d1507..f4233576153b 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -956,9 +956,9 @@ static const struct mmc_host_ops wbsd_ops = { | |||
956 | * Helper function to reset detection ignore | 956 | * Helper function to reset detection ignore |
957 | */ | 957 | */ |
958 | 958 | ||
959 | static void wbsd_reset_ignore(unsigned long data) | 959 | static void wbsd_reset_ignore(struct timer_list *t) |
960 | { | 960 | { |
961 | struct wbsd_host *host = (struct wbsd_host *)data; | 961 | struct wbsd_host *host = from_timer(host, t, ignore_timer); |
962 | 962 | ||
963 | BUG_ON(host == NULL); | 963 | BUG_ON(host == NULL); |
964 | 964 | ||
@@ -1224,9 +1224,7 @@ static int wbsd_alloc_mmc(struct device *dev) | |||
1224 | /* | 1224 | /* |
1225 | * Set up timers | 1225 | * Set up timers |
1226 | */ | 1226 | */ |
1227 | init_timer(&host->ignore_timer); | 1227 | timer_setup(&host->ignore_timer, wbsd_reset_ignore, 0); |
1228 | host->ignore_timer.data = (unsigned long)host; | ||
1229 | host->ignore_timer.function = wbsd_reset_ignore; | ||
1230 | 1228 | ||
1231 | /* | 1229 | /* |
1232 | * Maximum number of segments. Worst case is one sector per segment | 1230 | * Maximum number of segments. Worst case is one sector per segment |
diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index 0cb76ba29e84..8f782d22fdbe 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c | |||
@@ -34,6 +34,8 @@ struct pbias_reg_info { | |||
34 | u32 vmode; | 34 | u32 vmode; |
35 | unsigned int enable_time; | 35 | unsigned int enable_time; |
36 | char *name; | 36 | char *name; |
37 | const unsigned int *pbias_volt_table; | ||
38 | int n_voltages; | ||
37 | }; | 39 | }; |
38 | 40 | ||
39 | struct pbias_regulator_data { | 41 | struct pbias_regulator_data { |
@@ -49,11 +51,16 @@ struct pbias_of_data { | |||
49 | unsigned int offset; | 51 | unsigned int offset; |
50 | }; | 52 | }; |
51 | 53 | ||
52 | static const unsigned int pbias_volt_table[] = { | 54 | static const unsigned int pbias_volt_table_3_0V[] = { |
53 | 1800000, | 55 | 1800000, |
54 | 3000000 | 56 | 3000000 |
55 | }; | 57 | }; |
56 | 58 | ||
59 | static const unsigned int pbias_volt_table_3_3V[] = { | ||
60 | 1800000, | ||
61 | 3300000 | ||
62 | }; | ||
63 | |||
57 | static const struct regulator_ops pbias_regulator_voltage_ops = { | 64 | static const struct regulator_ops pbias_regulator_voltage_ops = { |
58 | .list_voltage = regulator_list_voltage_table, | 65 | .list_voltage = regulator_list_voltage_table, |
59 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 66 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
@@ -69,6 +76,8 @@ static const struct pbias_reg_info pbias_mmc_omap2430 = { | |||
69 | .vmode = BIT(0), | 76 | .vmode = BIT(0), |
70 | .disable_val = 0, | 77 | .disable_val = 0, |
71 | .enable_time = 100, | 78 | .enable_time = 100, |
79 | .pbias_volt_table = pbias_volt_table_3_0V, | ||
80 | .n_voltages = 2, | ||
72 | .name = "pbias_mmc_omap2430" | 81 | .name = "pbias_mmc_omap2430" |
73 | }; | 82 | }; |
74 | 83 | ||
@@ -77,6 +86,8 @@ static const struct pbias_reg_info pbias_sim_omap3 = { | |||
77 | .enable_mask = BIT(9), | 86 | .enable_mask = BIT(9), |
78 | .vmode = BIT(8), | 87 | .vmode = BIT(8), |
79 | .enable_time = 100, | 88 | .enable_time = 100, |
89 | .pbias_volt_table = pbias_volt_table_3_0V, | ||
90 | .n_voltages = 2, | ||
80 | .name = "pbias_sim_omap3" | 91 | .name = "pbias_sim_omap3" |
81 | }; | 92 | }; |
82 | 93 | ||
@@ -86,6 +97,8 @@ static const struct pbias_reg_info pbias_mmc_omap4 = { | |||
86 | .disable_val = BIT(25), | 97 | .disable_val = BIT(25), |
87 | .vmode = BIT(21), | 98 | .vmode = BIT(21), |
88 | .enable_time = 100, | 99 | .enable_time = 100, |
100 | .pbias_volt_table = pbias_volt_table_3_0V, | ||
101 | .n_voltages = 2, | ||
89 | .name = "pbias_mmc_omap4" | 102 | .name = "pbias_mmc_omap4" |
90 | }; | 103 | }; |
91 | 104 | ||
@@ -95,6 +108,8 @@ static const struct pbias_reg_info pbias_mmc_omap5 = { | |||
95 | .disable_val = BIT(25), | 108 | .disable_val = BIT(25), |
96 | .vmode = BIT(21), | 109 | .vmode = BIT(21), |
97 | .enable_time = 100, | 110 | .enable_time = 100, |
111 | .pbias_volt_table = pbias_volt_table_3_3V, | ||
112 | .n_voltages = 2, | ||
98 | .name = "pbias_mmc_omap5" | 113 | .name = "pbias_mmc_omap5" |
99 | }; | 114 | }; |
100 | 115 | ||
@@ -199,8 +214,8 @@ static int pbias_regulator_probe(struct platform_device *pdev) | |||
199 | drvdata[data_idx].desc.owner = THIS_MODULE; | 214 | drvdata[data_idx].desc.owner = THIS_MODULE; |
200 | drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; | 215 | drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; |
201 | drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; | 216 | drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; |
202 | drvdata[data_idx].desc.volt_table = pbias_volt_table; | 217 | drvdata[data_idx].desc.volt_table = info->pbias_volt_table; |
203 | drvdata[data_idx].desc.n_voltages = 2; | 218 | drvdata[data_idx].desc.n_voltages = info->n_voltages; |
204 | drvdata[data_idx].desc.enable_time = info->enable_time; | 219 | drvdata[data_idx].desc.enable_time = info->enable_time; |
205 | drvdata[data_idx].desc.vsel_reg = offset; | 220 | drvdata[data_idx].desc.vsel_reg = offset; |
206 | drvdata[data_idx].desc.vsel_mask = info->vmode; | 221 | drvdata[data_idx].desc.vsel_mask = info->vmode; |
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 116816fb9110..7815d8db7eca 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h | |||
@@ -334,6 +334,7 @@ | |||
334 | #define DCM_DRP_RD_DATA_H 0xFC29 | 334 | #define DCM_DRP_RD_DATA_H 0xFC29 |
335 | #define SD_VPCLK0_CTL 0xFC2A | 335 | #define SD_VPCLK0_CTL 0xFC2A |
336 | #define SD_VPCLK1_CTL 0xFC2B | 336 | #define SD_VPCLK1_CTL 0xFC2B |
337 | #define PHASE_SELECT_MASK 0x1F | ||
337 | #define SD_DCMPS0_CTL 0xFC2C | 338 | #define SD_DCMPS0_CTL 0xFC2C |
338 | #define SD_DCMPS1_CTL 0xFC2D | 339 | #define SD_DCMPS1_CTL 0xFC2D |
339 | #define SD_VPTX_CTL SD_VPCLK0_CTL | 340 | #define SD_VPTX_CTL SD_VPCLK0_CTL |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 9a43763a68ad..e7743eca1021 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -255,6 +255,10 @@ struct mmc_supply { | |||
255 | struct regulator *vqmmc; /* Optional Vccq supply */ | 255 | struct regulator *vqmmc; /* Optional Vccq supply */ |
256 | }; | 256 | }; |
257 | 257 | ||
258 | struct mmc_ctx { | ||
259 | struct task_struct *task; | ||
260 | }; | ||
261 | |||
258 | struct mmc_host { | 262 | struct mmc_host { |
259 | struct device *parent; | 263 | struct device *parent; |
260 | struct device class_dev; | 264 | struct device class_dev; |
@@ -350,6 +354,8 @@ struct mmc_host { | |||
350 | #define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */ | 354 | #define MMC_CAP2_CQE (1 << 23) /* Has eMMC command queue engine */ |
351 | #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ | 355 | #define MMC_CAP2_CQE_DCMD (1 << 24) /* CQE can issue a direct command */ |
352 | 356 | ||
357 | int fixed_drv_type; /* fixed driver type for non-removable media */ | ||
358 | |||
353 | mmc_pm_flag_t pm_caps; /* supported pm features */ | 359 | mmc_pm_flag_t pm_caps; /* supported pm features */ |
354 | 360 | ||
355 | /* host specific block data */ | 361 | /* host specific block data */ |
@@ -388,8 +394,9 @@ struct mmc_host { | |||
388 | struct mmc_card *card; /* device attached to this host */ | 394 | struct mmc_card *card; /* device attached to this host */ |
389 | 395 | ||
390 | wait_queue_head_t wq; | 396 | wait_queue_head_t wq; |
391 | struct task_struct *claimer; /* task that has host claimed */ | 397 | struct mmc_ctx *claimer; /* context that has host claimed */ |
392 | int claim_cnt; /* "claim" nesting count */ | 398 | int claim_cnt; /* "claim" nesting count */ |
399 | struct mmc_ctx default_ctx; /* default context */ | ||
393 | 400 | ||
394 | struct delayed_work detect; | 401 | struct delayed_work detect; |
395 | int detect_change; /* card detect flag */ | 402 | int detect_change; /* card detect flag */ |
@@ -469,6 +476,8 @@ void mmc_detect_change(struct mmc_host *, unsigned long delay); | |||
469 | void mmc_request_done(struct mmc_host *, struct mmc_request *); | 476 | void mmc_request_done(struct mmc_host *, struct mmc_request *); |
470 | void mmc_command_done(struct mmc_host *host, struct mmc_request *mrq); | 477 | void mmc_command_done(struct mmc_host *host, struct mmc_request *mrq); |
471 | 478 | ||
479 | void mmc_cqe_request_done(struct mmc_host *host, struct mmc_request *mrq); | ||
480 | |||
472 | static inline void mmc_signal_sdio_irq(struct mmc_host *host) | 481 | static inline void mmc_signal_sdio_irq(struct mmc_host *host) |
473 | { | 482 | { |
474 | host->ops->enable_sdio_irq(host, 0); | 483 | host->ops->enable_sdio_irq(host, 0); |
diff --git a/include/linux/mmc/sdhci-pci-data.h b/include/linux/mmc/sdhci-pci-data.h index 36f986d4a59a..1d42872d22f3 100644 --- a/include/linux/mmc/sdhci-pci-data.h +++ b/include/linux/mmc/sdhci-pci-data.h | |||
@@ -15,7 +15,4 @@ struct sdhci_pci_data { | |||
15 | 15 | ||
16 | extern struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, | 16 | extern struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, |
17 | int slotno); | 17 | int slotno); |
18 | |||
19 | extern int sdhci_pci_spt_drive_strength; | ||
20 | |||
21 | #endif | 18 | #endif |