diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-09 11:39:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-09 11:39:39 -0400 |
commit | 97e18dc007546fce8e99098480b921a02ebb3037 (patch) | |
tree | f38c022d034e0172e83f6972983577f790f24dac | |
parent | 042f7b7cbd1e531278a09c449563165ba1f07673 (diff) | |
parent | c67480173f72e883235dd0ad09d90156c8f87600 (diff) |
Merge tag 'mmc-updates-for-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
Pull MMC updates from Chris Ball:
"MMC highlights for 3.15:
Core:
- CONFIG_MMC_UNSAFE_RESUME=y is now default behavior
- DT bindings for SDHCI UHS, eMMC HS200, high-speed DDR, at 1.8/1.2V
- Add GPIO descriptor based slot-gpio card detect API
Drivers:
- dw_mmc: Refactor SOCFPGA support as a variant inside dw_mmc-pltfm.c
- mmci: Support HW busy detection on ux500
- omap: Support MMC_ERASE
- omap_hsmmc: Support MMC_PM_KEEP_POWER, MMC_PM_WAKE_SDIO_IRQ, (a)cmd23
- rtsx: Support pre-req/post-req async
- sdhci: Add support for Realtek RTS5250 controllers
- sdhci-acpi: Add support for 80860F16, fix 80860F14/SDIO card detect
- sdhci-msm: Add new driver for Qualcomm SDHCI chipset support
- sdhci-pxav3: Add support for Marvell Armada 380 and 385 SoCs"
* tag 'mmc-updates-for-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (102 commits)
mmc: sdhci-acpi: Intel SDIO has broken card detect
mmc: sdhci-pxav3: add support for the Armada 38x SDHCI controller
mmc: sdhci-msm: Add platform_execute_tuning implementation
mmc: sdhci-msm: Initial support for Qualcomm chipsets
mmc: sdhci-msm: Qualcomm SDHCI binding documentation
sdhci: only reprogram retuning timer when flag is set
mmc: rename ARCH_BCM to ARCH_BCM_MOBILE
mmc: sdhci: Allow for irq being shared
mmc: sdhci-acpi: Add device id 80860F16
mmc: sdhci-acpi: Fix broken card detect for ACPI HID 80860F14
mmc: slot-gpio: Add GPIO descriptor based CD GPIO API
mmc: slot-gpio: Split out CD IRQ request into a separate function
mmc: slot-gpio: Record GPIO descriptors instead of GPIO numbers
Revert "dts: socfpga: Add support for SD/MMC on the SOCFPGA platform"
mmc: sdhci-spear: use generic card detection gpio support
mmc: sdhci-spear: remove support for power gpio
mmc: sdhci-spear: simplify resource handling
mmc: sdhci-spear: fix platform_data usage
mmc: sdhci-spear: fix error handling paths for DT
mmc: sdhci-bcm-kona: fix build errors when built-in
...
63 files changed, 2577 insertions, 1166 deletions
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index 458b57f199af..9dce540771fb 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt | |||
@@ -26,9 +26,18 @@ Optional properties: | |||
26 | this system, even if the controller claims it is. | 26 | this system, even if the controller claims it is. |
27 | - cap-sd-highspeed: SD high-speed timing is supported | 27 | - cap-sd-highspeed: SD high-speed timing is supported |
28 | - cap-mmc-highspeed: MMC high-speed timing is supported | 28 | - cap-mmc-highspeed: MMC high-speed timing is supported |
29 | - sd-uhs-sdr12: SD UHS SDR12 speed is supported | ||
30 | - sd-uhs-sdr25: SD UHS SDR25 speed is supported | ||
31 | - sd-uhs-sdr50: SD UHS SDR50 speed is supported | ||
32 | - sd-uhs-sdr104: SD UHS SDR104 speed is supported | ||
33 | - sd-uhs-ddr50: SD UHS DDR50 speed is supported | ||
29 | - cap-power-off-card: powering off the card is safe | 34 | - cap-power-off-card: powering off the card is safe |
30 | - cap-sdio-irq: enable SDIO IRQ signalling on this interface | 35 | - cap-sdio-irq: enable SDIO IRQ signalling on this interface |
31 | - full-pwr-cycle: full power cycle of the card is supported | 36 | - full-pwr-cycle: full power cycle of the card is supported |
37 | - mmc-highspeed-ddr-1_8v: eMMC high-speed DDR mode(1.8V I/O) is supported | ||
38 | - mmc-highspeed-ddr-1_2v: eMMC high-speed DDR mode(1.2V I/O) is supported | ||
39 | - mmc-hs200-1_8v: eMMC HS200 mode(1.8V I/O) is supported | ||
40 | - mmc-hs200-1_2v: eMMC HS200 mode(1.2V I/O) is supported | ||
32 | 41 | ||
33 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line | 42 | *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line |
34 | polarity properties, we have to fix the meaning of the "normal" and "inverted" | 43 | polarity properties, we have to fix the meaning of the "normal" and "inverted" |
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt new file mode 100644 index 000000000000..81b33b5b20fc --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt | |||
@@ -0,0 +1,55 @@ | |||
1 | * Qualcomm SDHCI controller (sdhci-msm) | ||
2 | |||
3 | This file documents differences between the core properties in mmc.txt | ||
4 | and the properties used by the sdhci-msm driver. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: Should contain "qcom,sdhci-msm-v4". | ||
8 | - reg: Base address and length of the register in the following order: | ||
9 | - Host controller register map (required) | ||
10 | - SD Core register map (required) | ||
11 | - interrupts: Should contain an interrupt-specifiers for the interrupts: | ||
12 | - Host controller interrupt (required) | ||
13 | - pinctrl-names: Should contain only one value - "default". | ||
14 | - pinctrl-0: Should specify pin control groups used for this controller. | ||
15 | - clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock-names. | ||
16 | - clock-names: Should contain the following: | ||
17 | "iface" - Main peripheral bus clock (PCLK/HCLK - AHB Bus clock) (required) | ||
18 | "core" - SDC MMC clock (MCLK) (required) | ||
19 | "bus" - SDCC bus voter clock (optional) | ||
20 | |||
21 | Example: | ||
22 | |||
23 | sdhc_1: sdhci@f9824900 { | ||
24 | compatible = "qcom,sdhci-msm-v4"; | ||
25 | reg = <0xf9824900 0x11c>, <0xf9824000 0x800>; | ||
26 | interrupts = <0 123 0>; | ||
27 | bus-width = <8>; | ||
28 | non-removable; | ||
29 | |||
30 | vmmc = <&pm8941_l20>; | ||
31 | vqmmc = <&pm8941_s3>; | ||
32 | |||
33 | pinctrl-names = "default"; | ||
34 | pinctrl-0 = <&sdc1_clk &sdc1_cmd &sdc1_data>; | ||
35 | |||
36 | clocks = <&gcc GCC_SDCC1_APPS_CLK>, <&gcc GCC_SDCC1_AHB_CLK>; | ||
37 | clock-names = "core", "iface"; | ||
38 | }; | ||
39 | |||
40 | sdhc_2: sdhci@f98a4900 { | ||
41 | compatible = "qcom,sdhci-msm-v4"; | ||
42 | reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; | ||
43 | interrupts = <0 125 0>; | ||
44 | bus-width = <4>; | ||
45 | cd-gpios = <&msmgpio 62 0x1>; | ||
46 | |||
47 | vmmc = <&pm8941_l21>; | ||
48 | vqmmc = <&pm8941_l13>; | ||
49 | |||
50 | pinctrl-names = "default"; | ||
51 | pinctrl-0 = <&sdc2_clk &sdc2_cmd &sdc2_data>; | ||
52 | |||
53 | clocks = <&gcc GCC_SDCC2_APPS_CLK>, <&gcc GCC_SDCC2_AHB_CLK>; | ||
54 | clock-names = "core", "iface"; | ||
55 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt index dbe98a3c183a..86223c3eda90 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt | |||
@@ -4,7 +4,14 @@ This file documents differences between the core properties in mmc.txt | |||
4 | and the properties used by the sdhci-pxav2 and sdhci-pxav3 drivers. | 4 | and the properties used by the sdhci-pxav2 and sdhci-pxav3 drivers. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible: Should be "mrvl,pxav2-mmc" or "mrvl,pxav3-mmc". | 7 | - compatible: Should be "mrvl,pxav2-mmc", "mrvl,pxav3-mmc" or |
8 | "marvell,armada-380-sdhci". | ||
9 | - reg: | ||
10 | * for "mrvl,pxav2-mmc" and "mrvl,pxav3-mmc", one register area for | ||
11 | the SDHCI registers. | ||
12 | * for "marvell,armada-380-sdhci", two register areas. The first one | ||
13 | for the SDHCI registers themselves, and the second one for the | ||
14 | AXI/Mbus bridge registers of the SDHCI unit. | ||
8 | 15 | ||
9 | Optional properties: | 16 | Optional properties: |
10 | - mrvl,clk-delay-cycles: Specify a number of cycles to delay for tuning. | 17 | - mrvl,clk-delay-cycles: Specify a number of cycles to delay for tuning. |
@@ -19,3 +26,11 @@ sdhci@d4280800 { | |||
19 | non-removable; | 26 | non-removable; |
20 | mrvl,clk-delay-cycles = <31>; | 27 | mrvl,clk-delay-cycles = <31>; |
21 | }; | 28 | }; |
29 | |||
30 | sdhci@d8000 { | ||
31 | compatible = "marvell,armada-380-sdhci"; | ||
32 | reg = <0xd8000 0x1000>, <0xdc000 0x100>; | ||
33 | interrupts = <0 25 0x4>; | ||
34 | clocks = <&gateclk 17>; | ||
35 | mrvl,clk-delay-cycles = <0x1F>; | ||
36 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index 8c8908ab84ba..ce8056116fb0 100644 --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | |||
@@ -10,6 +10,7 @@ Required properties: | |||
10 | - compatible: | 10 | - compatible: |
11 | Should be "ti,omap2-hsmmc", for OMAP2 controllers | 11 | Should be "ti,omap2-hsmmc", for OMAP2 controllers |
12 | Should be "ti,omap3-hsmmc", for OMAP3 controllers | 12 | Should be "ti,omap3-hsmmc", for OMAP3 controllers |
13 | Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0 | ||
13 | Should be "ti,omap4-hsmmc", for OMAP4 controllers | 14 | Should be "ti,omap4-hsmmc", for OMAP4 controllers |
14 | - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1 | 15 | - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1 |
15 | 16 | ||
diff --git a/Documentation/devicetree/bindings/regulator/pbias-regulator.txt b/Documentation/devicetree/bindings/regulator/pbias-regulator.txt new file mode 100644 index 000000000000..32aa26f1e434 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/pbias-regulator.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | PBIAS internal regulator for SD card dual voltage i/o pads on OMAP SoCs. | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: | ||
5 | - "ti,pbias-omap" for OMAP2, OMAP3, OMAP4, OMAP5, DRA7. | ||
6 | - reg: pbias register offset from syscon base and size of pbias register. | ||
7 | - syscon : phandle of the system control module | ||
8 | - regulator-name : should be | ||
9 | pbias_mmc_omap2430 for OMAP2430, OMAP3 SoCs | ||
10 | pbias_sim_omap3 for OMAP3 SoCs | ||
11 | pbias_mmc_omap4 for OMAP4 SoCs | ||
12 | pbias_mmc_omap5 for OMAP5 and DRA7 SoC | ||
13 | |||
14 | Optional properties: | ||
15 | - Any optional property defined in bindings/regulator/regulator.txt | ||
16 | |||
17 | Example: | ||
18 | |||
19 | pbias_regulator: pbias_regulator { | ||
20 | compatible = "ti,pbias-omap"; | ||
21 | reg = <0 0x4>; | ||
22 | syscon = <&omap5_padconf_global>; | ||
23 | pbias_mmc_reg: pbias_mmc_omap5 { | ||
24 | regulator-name = "pbias_mmc_omap5"; | ||
25 | regulator-min-microvolt = <1800000>; | ||
26 | regulator-max-microvolt = <3000000>; | ||
27 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 7faf31001437..a769432bddbe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5930,6 +5930,7 @@ F: include/linux/mfd/ | |||
5930 | 5930 | ||
5931 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM | 5931 | MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM |
5932 | M: Chris Ball <chris@printf.net> | 5932 | M: Chris Ball <chris@printf.net> |
5933 | M: Ulf Hansson <ulf.hansson@linaro.org> | ||
5933 | L: linux-mmc@vger.kernel.org | 5934 | L: linux-mmc@vger.kernel.org |
5934 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git | 5935 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git |
5935 | S: Maintained | 5936 | S: Maintained |
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 9e3caf3d19fb..1c0f8e1893ae 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi | |||
@@ -154,6 +154,22 @@ | |||
154 | ti,hwmods = "counter_32k"; | 154 | ti,hwmods = "counter_32k"; |
155 | }; | 155 | }; |
156 | 156 | ||
157 | dra7_ctrl_general: tisyscon@4a002e00 { | ||
158 | compatible = "syscon"; | ||
159 | reg = <0x4a002e00 0x7c>; | ||
160 | }; | ||
161 | |||
162 | pbias_regulator: pbias_regulator { | ||
163 | compatible = "ti,pbias-omap"; | ||
164 | reg = <0 0x4>; | ||
165 | syscon = <&dra7_ctrl_general>; | ||
166 | pbias_mmc_reg: pbias_mmc_omap5 { | ||
167 | regulator-name = "pbias_mmc_omap5"; | ||
168 | regulator-min-microvolt = <1800000>; | ||
169 | regulator-max-microvolt = <3000000>; | ||
170 | }; | ||
171 | }; | ||
172 | |||
157 | dra7_pmx_core: pinmux@4a003400 { | 173 | dra7_pmx_core: pinmux@4a003400 { |
158 | compatible = "pinctrl-single"; | 174 | compatible = "pinctrl-single"; |
159 | reg = <0x4a003400 0x0464>; | 175 | reg = <0x4a003400 0x0464>; |
@@ -543,6 +559,7 @@ | |||
543 | dmas = <&sdma 61>, <&sdma 62>; | 559 | dmas = <&sdma 61>, <&sdma 62>; |
544 | dma-names = "tx", "rx"; | 560 | dma-names = "tx", "rx"; |
545 | status = "disabled"; | 561 | status = "disabled"; |
562 | pbias-supply = <&pbias_mmc_reg>; | ||
546 | }; | 563 | }; |
547 | 564 | ||
548 | mmc2: mmc@480b4000 { | 565 | mmc2: mmc@480b4000 { |
diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi index 9d2f028fd687..d09697dab55e 100644 --- a/arch/arm/boot/dts/omap2430.dtsi +++ b/arch/arm/boot/dts/omap2430.dtsi | |||
@@ -29,6 +29,22 @@ | |||
29 | pinctrl-single,function-mask = <0x3f>; | 29 | pinctrl-single,function-mask = <0x3f>; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | omap2_scm_general: tisyscon@49002270 { | ||
33 | compatible = "syscon"; | ||
34 | reg = <0x49002270 0x240>; | ||
35 | }; | ||
36 | |||
37 | pbias_regulator: pbias_regulator { | ||
38 | compatible = "ti,pbias-omap"; | ||
39 | reg = <0x230 0x4>; | ||
40 | syscon = <&omap2_scm_general>; | ||
41 | pbias_mmc_reg: pbias_mmc_omap2430 { | ||
42 | regulator-name = "pbias_mmc_omap2430"; | ||
43 | regulator-min-microvolt = <1800000>; | ||
44 | regulator-max-microvolt = <3000000>; | ||
45 | }; | ||
46 | }; | ||
47 | |||
32 | gpio1: gpio@4900c000 { | 48 | gpio1: gpio@4900c000 { |
33 | compatible = "ti,omap2-gpio"; | 49 | compatible = "ti,omap2-gpio"; |
34 | reg = <0x4900c000 0x200>; | 50 | reg = <0x4900c000 0x200>; |
@@ -188,6 +204,7 @@ | |||
188 | ti,dual-volt; | 204 | ti,dual-volt; |
189 | dmas = <&sdma 61>, <&sdma 62>; | 205 | dmas = <&sdma 61>, <&sdma 62>; |
190 | dma-names = "tx", "rx"; | 206 | dma-names = "tx", "rx"; |
207 | pbias-supply = <&pbias_mmc_reg>; | ||
191 | }; | 208 | }; |
192 | 209 | ||
193 | mmc2: mmc@480b4000 { | 210 | mmc2: mmc@480b4000 { |
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts index ddce0d807f70..0abe986a4ecc 100644 --- a/arch/arm/boot/dts/omap3-ldp.dts +++ b/arch/arm/boot/dts/omap3-ldp.dts | |||
@@ -174,8 +174,20 @@ | |||
174 | }; | 174 | }; |
175 | 175 | ||
176 | &mmc1 { | 176 | &mmc1 { |
177 | /* See 35xx errata 2.1.1.128 in SPRZ278F */ | ||
178 | compatible = "ti,omap3-pre-es3-hsmmc"; | ||
177 | vmmc-supply = <&vmmc1>; | 179 | vmmc-supply = <&vmmc1>; |
178 | bus-width = <4>; | 180 | bus-width = <4>; |
181 | pinctrl-names = "default"; | ||
182 | pinctrl-0 = <&mmc1_pins>; | ||
183 | }; | ||
184 | |||
185 | &mmc2 { | ||
186 | status="disabled"; | ||
187 | }; | ||
188 | |||
189 | &mmc3 { | ||
190 | status="disabled"; | ||
179 | }; | 191 | }; |
180 | 192 | ||
181 | &omap3_pmx_core { | 193 | &omap3_pmx_core { |
@@ -209,6 +221,17 @@ | |||
209 | 0x174 (PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */ | 221 | 0x174 (PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */ |
210 | >; | 222 | >; |
211 | }; | 223 | }; |
224 | |||
225 | mmc1_pins: pinmux_mmc1_pins { | ||
226 | pinctrl-single,pins = < | ||
227 | OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.mmc1_clk */ | ||
228 | OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.mmc1_cmd */ | ||
229 | OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.mmc1_dat0 */ | ||
230 | OMAP3_CORE1_IOPAD(0x214A, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.mmc1_dat1 */ | ||
231 | OMAP3_CORE1_IOPAD(0x214C, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.mmc1_dat2 */ | ||
232 | OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 */ | ||
233 | >; | ||
234 | }; | ||
212 | }; | 235 | }; |
213 | 236 | ||
214 | &usb_otg_hs { | 237 | &usb_otg_hs { |
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 3d05eff67e25..5e5790f631eb 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi | |||
@@ -181,6 +181,22 @@ | |||
181 | pinctrl-single,function-mask = <0xff1f>; | 181 | pinctrl-single,function-mask = <0xff1f>; |
182 | }; | 182 | }; |
183 | 183 | ||
184 | omap3_scm_general: tisyscon@48002270 { | ||
185 | compatible = "syscon"; | ||
186 | reg = <0x48002270 0x2f0>; | ||
187 | }; | ||
188 | |||
189 | pbias_regulator: pbias_regulator { | ||
190 | compatible = "ti,pbias-omap"; | ||
191 | reg = <0x2b0 0x4>; | ||
192 | syscon = <&omap3_scm_general>; | ||
193 | pbias_mmc_reg: pbias_mmc_omap2430 { | ||
194 | regulator-name = "pbias_mmc_omap2430"; | ||
195 | regulator-min-microvolt = <1800000>; | ||
196 | regulator-max-microvolt = <3000000>; | ||
197 | }; | ||
198 | }; | ||
199 | |||
184 | gpio1: gpio@48310000 { | 200 | gpio1: gpio@48310000 { |
185 | compatible = "ti,omap3-gpio"; | 201 | compatible = "ti,omap3-gpio"; |
186 | reg = <0x48310000 0x200>; | 202 | reg = <0x48310000 0x200>; |
@@ -395,6 +411,7 @@ | |||
395 | ti,dual-volt; | 411 | ti,dual-volt; |
396 | dmas = <&sdma 61>, <&sdma 62>; | 412 | dmas = <&sdma 61>, <&sdma 62>; |
397 | dma-names = "tx", "rx"; | 413 | dma-names = "tx", "rx"; |
414 | pbias-supply = <&pbias_mmc_reg>; | ||
398 | }; | 415 | }; |
399 | 416 | ||
400 | mmc2: mmc@480b4000 { | 417 | mmc2: mmc@480b4000 { |
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 2b4c1cbbce33..27fcac874742 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi | |||
@@ -191,6 +191,22 @@ | |||
191 | pinctrl-single,function-mask = <0x7fff>; | 191 | pinctrl-single,function-mask = <0x7fff>; |
192 | }; | 192 | }; |
193 | 193 | ||
194 | omap4_padconf_global: tisyscon@4a1005a0 { | ||
195 | compatible = "syscon"; | ||
196 | reg = <0x4a1005a0 0x170>; | ||
197 | }; | ||
198 | |||
199 | pbias_regulator: pbias_regulator { | ||
200 | compatible = "ti,pbias-omap"; | ||
201 | reg = <0x60 0x4>; | ||
202 | syscon = <&omap4_padconf_global>; | ||
203 | pbias_mmc_reg: pbias_mmc_omap4 { | ||
204 | regulator-name = "pbias_mmc_omap4"; | ||
205 | regulator-min-microvolt = <1800000>; | ||
206 | regulator-max-microvolt = <3000000>; | ||
207 | }; | ||
208 | }; | ||
209 | |||
194 | sdma: dma-controller@4a056000 { | 210 | sdma: dma-controller@4a056000 { |
195 | compatible = "ti,omap4430-sdma"; | 211 | compatible = "ti,omap4430-sdma"; |
196 | reg = <0x4a056000 0x1000>; | 212 | reg = <0x4a056000 0x1000>; |
@@ -427,6 +443,7 @@ | |||
427 | ti,needs-special-reset; | 443 | ti,needs-special-reset; |
428 | dmas = <&sdma 61>, <&sdma 62>; | 444 | dmas = <&sdma 61>, <&sdma 62>; |
429 | dma-names = "tx", "rx"; | 445 | dma-names = "tx", "rx"; |
446 | pbias-supply = <&pbias_mmc_reg>; | ||
430 | }; | 447 | }; |
431 | 448 | ||
432 | mmc2: mmc@480b4000 { | 449 | mmc2: mmc@480b4000 { |
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 19155bb84835..6f3de22fb266 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi | |||
@@ -198,6 +198,22 @@ | |||
198 | pinctrl-single,function-mask = <0x7fff>; | 198 | pinctrl-single,function-mask = <0x7fff>; |
199 | }; | 199 | }; |
200 | 200 | ||
201 | omap5_padconf_global: tisyscon@4a002da0 { | ||
202 | compatible = "syscon"; | ||
203 | reg = <0x4A002da0 0xec>; | ||
204 | }; | ||
205 | |||
206 | pbias_regulator: pbias_regulator { | ||
207 | compatible = "ti,pbias-omap"; | ||
208 | reg = <0x60 0x4>; | ||
209 | syscon = <&omap5_padconf_global>; | ||
210 | pbias_mmc_reg: pbias_mmc_omap5 { | ||
211 | regulator-name = "pbias_mmc_omap5"; | ||
212 | regulator-min-microvolt = <1800000>; | ||
213 | regulator-max-microvolt = <3000000>; | ||
214 | }; | ||
215 | }; | ||
216 | |||
201 | sdma: dma-controller@4a056000 { | 217 | sdma: dma-controller@4a056000 { |
202 | compatible = "ti,omap4430-sdma"; | 218 | compatible = "ti,omap4430-sdma"; |
203 | reg = <0x4a056000 0x1000>; | 219 | reg = <0x4a056000 0x1000>; |
@@ -480,6 +496,7 @@ | |||
480 | ti,needs-special-reset; | 496 | ti,needs-special-reset; |
481 | dmas = <&sdma 61>, <&sdma 62>; | 497 | dmas = <&sdma 61>, <&sdma 62>; |
482 | dma-names = "tx", "rx"; | 498 | dma-names = "tx", "rx"; |
499 | pbias-supply = <&pbias_mmc_reg>; | ||
483 | }; | 500 | }; |
484 | 501 | ||
485 | mmc2: mmc@480b4000 { | 502 | mmc2: mmc@480b4000 { |
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 364ba38e40f3..a9667957b757 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig | |||
@@ -170,6 +170,7 @@ CONFIG_DRA752_THERMAL=y | |||
170 | CONFIG_WATCHDOG=y | 170 | CONFIG_WATCHDOG=y |
171 | CONFIG_OMAP_WATCHDOG=y | 171 | CONFIG_OMAP_WATCHDOG=y |
172 | CONFIG_TWL4030_WATCHDOG=y | 172 | CONFIG_TWL4030_WATCHDOG=y |
173 | CONFIG_MFD_SYSCON=y | ||
173 | CONFIG_MFD_PALMAS=y | 174 | CONFIG_MFD_PALMAS=y |
174 | CONFIG_MFD_TPS65217=y | 175 | CONFIG_MFD_TPS65217=y |
175 | CONFIG_MFD_TPS65910=y | 176 | CONFIG_MFD_TPS65910=y |
@@ -181,6 +182,7 @@ CONFIG_REGULATOR_TPS6507X=y | |||
181 | CONFIG_REGULATOR_TPS65217=y | 182 | CONFIG_REGULATOR_TPS65217=y |
182 | CONFIG_REGULATOR_TPS65910=y | 183 | CONFIG_REGULATOR_TPS65910=y |
183 | CONFIG_REGULATOR_TWL4030=y | 184 | CONFIG_REGULATOR_TWL4030=y |
185 | CONFIG_REGULATOR_PBIAS=y | ||
184 | CONFIG_FB=y | 186 | CONFIG_FB=y |
185 | CONFIG_FIRMWARE_EDID=y | 187 | CONFIG_FIRMWARE_EDID=y |
186 | CONFIG_FB_MODE_HELPERS=y | 188 | CONFIG_FB_MODE_HELPERS=y |
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 1d15735f9ef9..c9de3d598ea5 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -338,58 +338,28 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | |||
338 | int num_sg, bool read, int timeout) | 338 | int num_sg, bool read, int timeout) |
339 | { | 339 | { |
340 | struct completion trans_done; | 340 | struct completion trans_done; |
341 | u8 dir; | 341 | int err = 0, count; |
342 | int err = 0, i, count; | ||
343 | long timeleft; | 342 | long timeleft; |
344 | unsigned long flags; | 343 | unsigned long flags; |
345 | struct scatterlist *sg; | ||
346 | enum dma_data_direction dma_dir; | ||
347 | u32 val; | ||
348 | dma_addr_t addr; | ||
349 | unsigned int len; | ||
350 | |||
351 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); | ||
352 | |||
353 | /* don't transfer data during abort processing */ | ||
354 | if (pcr->remove_pci) | ||
355 | return -EINVAL; | ||
356 | |||
357 | if ((sglist == NULL) || (num_sg <= 0)) | ||
358 | return -EINVAL; | ||
359 | 344 | ||
360 | if (read) { | 345 | count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read); |
361 | dir = DEVICE_TO_HOST; | ||
362 | dma_dir = DMA_FROM_DEVICE; | ||
363 | } else { | ||
364 | dir = HOST_TO_DEVICE; | ||
365 | dma_dir = DMA_TO_DEVICE; | ||
366 | } | ||
367 | |||
368 | count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | ||
369 | if (count < 1) { | 346 | if (count < 1) { |
370 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); | 347 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); |
371 | return -EINVAL; | 348 | return -EINVAL; |
372 | } | 349 | } |
373 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | 350 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); |
374 | 351 | ||
375 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
376 | pcr->sgi = 0; | ||
377 | for_each_sg(sglist, sg, count, i) { | ||
378 | addr = sg_dma_address(sg); | ||
379 | len = sg_dma_len(sg); | ||
380 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1); | ||
381 | } | ||
382 | 352 | ||
383 | spin_lock_irqsave(&pcr->lock, flags); | 353 | spin_lock_irqsave(&pcr->lock, flags); |
384 | 354 | ||
385 | pcr->done = &trans_done; | 355 | pcr->done = &trans_done; |
386 | pcr->trans_result = TRANS_NOT_READY; | 356 | pcr->trans_result = TRANS_NOT_READY; |
387 | init_completion(&trans_done); | 357 | init_completion(&trans_done); |
388 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
389 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
390 | 358 | ||
391 | spin_unlock_irqrestore(&pcr->lock, flags); | 359 | spin_unlock_irqrestore(&pcr->lock, flags); |
392 | 360 | ||
361 | rtsx_pci_dma_transfer(pcr, sglist, count, read); | ||
362 | |||
393 | timeleft = wait_for_completion_interruptible_timeout( | 363 | timeleft = wait_for_completion_interruptible_timeout( |
394 | &trans_done, msecs_to_jiffies(timeout)); | 364 | &trans_done, msecs_to_jiffies(timeout)); |
395 | if (timeleft <= 0) { | 365 | if (timeleft <= 0) { |
@@ -413,7 +383,7 @@ out: | |||
413 | pcr->done = NULL; | 383 | pcr->done = NULL; |
414 | spin_unlock_irqrestore(&pcr->lock, flags); | 384 | spin_unlock_irqrestore(&pcr->lock, flags); |
415 | 385 | ||
416 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | 386 | rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read); |
417 | 387 | ||
418 | if ((err < 0) && (err != -ENODEV)) | 388 | if ((err < 0) && (err != -ENODEV)) |
419 | rtsx_pci_stop_cmd(pcr); | 389 | rtsx_pci_stop_cmd(pcr); |
@@ -425,6 +395,73 @@ out: | |||
425 | } | 395 | } |
426 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | 396 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); |
427 | 397 | ||
398 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
399 | int num_sg, bool read) | ||
400 | { | ||
401 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
402 | |||
403 | if (pcr->remove_pci) | ||
404 | return -EINVAL; | ||
405 | |||
406 | if ((sglist == NULL) || num_sg < 1) | ||
407 | return -EINVAL; | ||
408 | |||
409 | return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
410 | } | ||
411 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg); | ||
412 | |||
413 | int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
414 | int num_sg, bool read) | ||
415 | { | ||
416 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
417 | |||
418 | if (pcr->remove_pci) | ||
419 | return -EINVAL; | ||
420 | |||
421 | if (sglist == NULL || num_sg < 1) | ||
422 | return -EINVAL; | ||
423 | |||
424 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
425 | return num_sg; | ||
426 | } | ||
427 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg); | ||
428 | |||
429 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
430 | int sg_count, bool read) | ||
431 | { | ||
432 | struct scatterlist *sg; | ||
433 | dma_addr_t addr; | ||
434 | unsigned int len; | ||
435 | int i; | ||
436 | u32 val; | ||
437 | u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE; | ||
438 | unsigned long flags; | ||
439 | |||
440 | if (pcr->remove_pci) | ||
441 | return -EINVAL; | ||
442 | |||
443 | if ((sglist == NULL) || (sg_count < 1)) | ||
444 | return -EINVAL; | ||
445 | |||
446 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
447 | pcr->sgi = 0; | ||
448 | for_each_sg(sglist, sg, sg_count, i) { | ||
449 | addr = sg_dma_address(sg); | ||
450 | len = sg_dma_len(sg); | ||
451 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == sg_count - 1); | ||
452 | } | ||
453 | |||
454 | spin_lock_irqsave(&pcr->lock, flags); | ||
455 | |||
456 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
457 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
458 | |||
459 | spin_unlock_irqrestore(&pcr->lock, flags); | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer); | ||
464 | |||
428 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) | 465 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) |
429 | { | 466 | { |
430 | int err; | 467 | int err; |
@@ -836,6 +873,8 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
836 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); | 873 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); |
837 | /* Clear interrupt flag */ | 874 | /* Clear interrupt flag */ |
838 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); | 875 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); |
876 | dev_dbg(&pcr->pci->dev, "=========== BIPR 0x%8x ==========\n", int_reg); | ||
877 | |||
839 | if ((int_reg & pcr->bier) == 0) { | 878 | if ((int_reg & pcr->bier) == 0) { |
840 | spin_unlock(&pcr->lock); | 879 | spin_unlock(&pcr->lock); |
841 | return IRQ_NONE; | 880 | return IRQ_NONE; |
@@ -866,17 +905,28 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
866 | } | 905 | } |
867 | 906 | ||
868 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { | 907 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { |
869 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { | 908 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) |
870 | pcr->trans_result = TRANS_RESULT_FAIL; | 909 | pcr->trans_result = TRANS_RESULT_FAIL; |
871 | if (pcr->done) | 910 | else if (int_reg & TRANS_OK_INT) |
872 | complete(pcr->done); | ||
873 | } else if (int_reg & TRANS_OK_INT) { | ||
874 | pcr->trans_result = TRANS_RESULT_OK; | 911 | pcr->trans_result = TRANS_RESULT_OK; |
875 | if (pcr->done) | 912 | |
876 | complete(pcr->done); | 913 | if (pcr->done) |
914 | complete(pcr->done); | ||
915 | |||
916 | if (int_reg & SD_EXIST) { | ||
917 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
918 | if (slot && slot->done_transfer) | ||
919 | slot->done_transfer(slot->p_dev); | ||
920 | } | ||
921 | |||
922 | if (int_reg & MS_EXIST) { | ||
923 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
924 | if (slot && slot->done_transfer) | ||
925 | slot->done_transfer(slot->p_dev); | ||
877 | } | 926 | } |
878 | } | 927 | } |
879 | 928 | ||
929 | |||
880 | if (pcr->card_inserted || pcr->card_removed) | 930 | if (pcr->card_inserted || pcr->card_removed) |
881 | schedule_delayed_work(&pcr->carddet_work, | 931 | schedule_delayed_work(&pcr->carddet_work, |
882 | msecs_to_jiffies(200)); | 932 | msecs_to_jiffies(200)); |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 7b5424f398ac..452782bffebc 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -415,8 +415,7 @@ static int ioctl_do_sanitize(struct mmc_card *card) | |||
415 | { | 415 | { |
416 | int err; | 416 | int err; |
417 | 417 | ||
418 | if (!(mmc_can_sanitize(card) && | 418 | if (!mmc_can_sanitize(card)) { |
419 | (card->host->caps2 & MMC_CAP2_SANITIZE))) { | ||
420 | pr_warn("%s: %s - SANITIZE is not supported\n", | 419 | pr_warn("%s: %s - SANITIZE is not supported\n", |
421 | mmc_hostname(card->host), __func__); | 420 | mmc_hostname(card->host), __func__); |
422 | err = -EOPNOTSUPP; | 421 | err = -EOPNOTSUPP; |
@@ -722,19 +721,6 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | |||
722 | return result; | 721 | return result; |
723 | } | 722 | } |
724 | 723 | ||
725 | static int send_stop(struct mmc_card *card, u32 *status) | ||
726 | { | ||
727 | struct mmc_command cmd = {0}; | ||
728 | int err; | ||
729 | |||
730 | cmd.opcode = MMC_STOP_TRANSMISSION; | ||
731 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | ||
732 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | ||
733 | if (err == 0) | ||
734 | *status = cmd.resp[0]; | ||
735 | return err; | ||
736 | } | ||
737 | |||
738 | static int get_card_status(struct mmc_card *card, u32 *status, int retries) | 724 | static int get_card_status(struct mmc_card *card, u32 *status, int retries) |
739 | { | 725 | { |
740 | struct mmc_command cmd = {0}; | 726 | struct mmc_command cmd = {0}; |
@@ -750,6 +736,99 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) | |||
750 | return err; | 736 | return err; |
751 | } | 737 | } |
752 | 738 | ||
739 | static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, | ||
740 | bool hw_busy_detect, struct request *req, int *gen_err) | ||
741 | { | ||
742 | unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); | ||
743 | int err = 0; | ||
744 | u32 status; | ||
745 | |||
746 | do { | ||
747 | err = get_card_status(card, &status, 5); | ||
748 | if (err) { | ||
749 | pr_err("%s: error %d requesting status\n", | ||
750 | req->rq_disk->disk_name, err); | ||
751 | return err; | ||
752 | } | ||
753 | |||
754 | if (status & R1_ERROR) { | ||
755 | pr_err("%s: %s: error sending status cmd, status %#x\n", | ||
756 | req->rq_disk->disk_name, __func__, status); | ||
757 | *gen_err = 1; | ||
758 | } | ||
759 | |||
760 | /* We may rely on the host hw to handle busy detection.*/ | ||
761 | if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && | ||
762 | hw_busy_detect) | ||
763 | break; | ||
764 | |||
765 | /* | ||
766 | * Timeout if the device never becomes ready for data and never | ||
767 | * leaves the program state. | ||
768 | */ | ||
769 | if (time_after(jiffies, timeout)) { | ||
770 | pr_err("%s: Card stuck in programming state! %s %s\n", | ||
771 | mmc_hostname(card->host), | ||
772 | req->rq_disk->disk_name, __func__); | ||
773 | return -ETIMEDOUT; | ||
774 | } | ||
775 | |||
776 | /* | ||
777 | * Some cards mishandle the status bits, | ||
778 | * so make sure to check both the busy | ||
779 | * indication and the card state. | ||
780 | */ | ||
781 | } while (!(status & R1_READY_FOR_DATA) || | ||
782 | (R1_CURRENT_STATE(status) == R1_STATE_PRG)); | ||
783 | |||
784 | return err; | ||
785 | } | ||
786 | |||
787 | static int send_stop(struct mmc_card *card, unsigned int timeout_ms, | ||
788 | struct request *req, int *gen_err, u32 *stop_status) | ||
789 | { | ||
790 | struct mmc_host *host = card->host; | ||
791 | struct mmc_command cmd = {0}; | ||
792 | int err; | ||
793 | bool use_r1b_resp = rq_data_dir(req) == WRITE; | ||
794 | |||
795 | /* | ||
796 | * Normally we use R1B responses for WRITE, but in cases where the host | ||
797 | * has specified a max_busy_timeout we need to validate it. A failure | ||
798 | * means we need to prevent the host from doing hw busy detection, which | ||
799 | * is done by converting to a R1 response instead. | ||
800 | */ | ||
801 | if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) | ||
802 | use_r1b_resp = false; | ||
803 | |||
804 | cmd.opcode = MMC_STOP_TRANSMISSION; | ||
805 | if (use_r1b_resp) { | ||
806 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | ||
807 | cmd.busy_timeout = timeout_ms; | ||
808 | } else { | ||
809 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; | ||
810 | } | ||
811 | |||
812 | err = mmc_wait_for_cmd(host, &cmd, 5); | ||
813 | if (err) | ||
814 | return err; | ||
815 | |||
816 | *stop_status = cmd.resp[0]; | ||
817 | |||
818 | /* No need to check card status in case of READ. */ | ||
819 | if (rq_data_dir(req) == READ) | ||
820 | return 0; | ||
821 | |||
822 | if (!mmc_host_is_spi(host) && | ||
823 | (*stop_status & R1_ERROR)) { | ||
824 | pr_err("%s: %s: general error sending stop command, resp %#x\n", | ||
825 | req->rq_disk->disk_name, __func__, *stop_status); | ||
826 | *gen_err = 1; | ||
827 | } | ||
828 | |||
829 | return card_busy_detect(card, timeout_ms, use_r1b_resp, req, gen_err); | ||
830 | } | ||
831 | |||
753 | #define ERR_NOMEDIUM 3 | 832 | #define ERR_NOMEDIUM 3 |
754 | #define ERR_RETRY 2 | 833 | #define ERR_RETRY 2 |
755 | #define ERR_ABORT 1 | 834 | #define ERR_ABORT 1 |
@@ -866,26 +945,21 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
866 | */ | 945 | */ |
867 | if (R1_CURRENT_STATE(status) == R1_STATE_DATA || | 946 | if (R1_CURRENT_STATE(status) == R1_STATE_DATA || |
868 | R1_CURRENT_STATE(status) == R1_STATE_RCV) { | 947 | R1_CURRENT_STATE(status) == R1_STATE_RCV) { |
869 | err = send_stop(card, &stop_status); | 948 | err = send_stop(card, |
870 | if (err) | 949 | DIV_ROUND_UP(brq->data.timeout_ns, 1000000), |
950 | req, gen_err, &stop_status); | ||
951 | if (err) { | ||
871 | pr_err("%s: error %d sending stop command\n", | 952 | pr_err("%s: error %d sending stop command\n", |
872 | req->rq_disk->disk_name, err); | 953 | req->rq_disk->disk_name, err); |
873 | 954 | /* | |
874 | /* | 955 | * If the stop cmd also timed out, the card is probably |
875 | * If the stop cmd also timed out, the card is probably | 956 | * not present, so abort. Other errors are bad news too. |
876 | * not present, so abort. Other errors are bad news too. | 957 | */ |
877 | */ | ||
878 | if (err) | ||
879 | return ERR_ABORT; | 958 | return ERR_ABORT; |
959 | } | ||
960 | |||
880 | if (stop_status & R1_CARD_ECC_FAILED) | 961 | if (stop_status & R1_CARD_ECC_FAILED) |
881 | *ecc_err = 1; | 962 | *ecc_err = 1; |
882 | if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) | ||
883 | if (stop_status & R1_ERROR) { | ||
884 | pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n", | ||
885 | req->rq_disk->disk_name, __func__, | ||
886 | stop_status); | ||
887 | *gen_err = 1; | ||
888 | } | ||
889 | } | 963 | } |
890 | 964 | ||
891 | /* Check for set block count errors */ | 965 | /* Check for set block count errors */ |
@@ -1157,8 +1231,7 @@ static int mmc_blk_err_check(struct mmc_card *card, | |||
1157 | * program mode, which we have to wait for it to complete. | 1231 | * program mode, which we have to wait for it to complete. |
1158 | */ | 1232 | */ |
1159 | if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { | 1233 | if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { |
1160 | u32 status; | 1234 | int err; |
1161 | unsigned long timeout; | ||
1162 | 1235 | ||
1163 | /* Check stop command response */ | 1236 | /* Check stop command response */ |
1164 | if (brq->stop.resp[0] & R1_ERROR) { | 1237 | if (brq->stop.resp[0] & R1_ERROR) { |
@@ -1168,39 +1241,10 @@ static int mmc_blk_err_check(struct mmc_card *card, | |||
1168 | gen_err = 1; | 1241 | gen_err = 1; |
1169 | } | 1242 | } |
1170 | 1243 | ||
1171 | timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS); | 1244 | err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, false, req, |
1172 | do { | 1245 | &gen_err); |
1173 | int err = get_card_status(card, &status, 5); | 1246 | if (err) |
1174 | if (err) { | 1247 | return MMC_BLK_CMD_ERR; |
1175 | pr_err("%s: error %d requesting status\n", | ||
1176 | req->rq_disk->disk_name, err); | ||
1177 | return MMC_BLK_CMD_ERR; | ||
1178 | } | ||
1179 | |||
1180 | if (status & R1_ERROR) { | ||
1181 | pr_err("%s: %s: general error sending status command, card status %#x\n", | ||
1182 | req->rq_disk->disk_name, __func__, | ||
1183 | status); | ||
1184 | gen_err = 1; | ||
1185 | } | ||
1186 | |||
1187 | /* Timeout if the device never becomes ready for data | ||
1188 | * and never leaves the program state. | ||
1189 | */ | ||
1190 | if (time_after(jiffies, timeout)) { | ||
1191 | pr_err("%s: Card stuck in programming state!"\ | ||
1192 | " %s %s\n", mmc_hostname(card->host), | ||
1193 | req->rq_disk->disk_name, __func__); | ||
1194 | |||
1195 | return MMC_BLK_CMD_ERR; | ||
1196 | } | ||
1197 | /* | ||
1198 | * Some cards mishandle the status bits, | ||
1199 | * so make sure to check both the busy | ||
1200 | * indication and the card state. | ||
1201 | */ | ||
1202 | } while (!(status & R1_READY_FOR_DATA) || | ||
1203 | (R1_CURRENT_STATE(status) == R1_STATE_PRG)); | ||
1204 | } | 1248 | } |
1205 | 1249 | ||
1206 | /* if general error occurs, retry the write operation. */ | 1250 | /* if general error occurs, retry the write operation. */ |
@@ -1335,7 +1379,6 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, | |||
1335 | brq->data.blksz = 512; | 1379 | brq->data.blksz = 512; |
1336 | brq->stop.opcode = MMC_STOP_TRANSMISSION; | 1380 | brq->stop.opcode = MMC_STOP_TRANSMISSION; |
1337 | brq->stop.arg = 0; | 1381 | brq->stop.arg = 0; |
1338 | brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | ||
1339 | brq->data.blocks = blk_rq_sectors(req); | 1382 | brq->data.blocks = blk_rq_sectors(req); |
1340 | 1383 | ||
1341 | /* | 1384 | /* |
@@ -1378,9 +1421,15 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, | |||
1378 | if (rq_data_dir(req) == READ) { | 1421 | if (rq_data_dir(req) == READ) { |
1379 | brq->cmd.opcode = readcmd; | 1422 | brq->cmd.opcode = readcmd; |
1380 | brq->data.flags |= MMC_DATA_READ; | 1423 | brq->data.flags |= MMC_DATA_READ; |
1424 | if (brq->mrq.stop) | ||
1425 | brq->stop.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | | ||
1426 | MMC_CMD_AC; | ||
1381 | } else { | 1427 | } else { |
1382 | brq->cmd.opcode = writecmd; | 1428 | brq->cmd.opcode = writecmd; |
1383 | brq->data.flags |= MMC_DATA_WRITE; | 1429 | brq->data.flags |= MMC_DATA_WRITE; |
1430 | if (brq->mrq.stop) | ||
1431 | brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | | ||
1432 | MMC_CMD_AC; | ||
1384 | } | 1433 | } |
1385 | 1434 | ||
1386 | if (do_rel_wr) | 1435 | if (do_rel_wr) |
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index 269d072ef55e..9ebee72d9c3f 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig | |||
@@ -2,21 +2,6 @@ | |||
2 | # MMC core configuration | 2 | # MMC core configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | config MMC_UNSAFE_RESUME | ||
6 | bool "Assume MMC/SD cards are non-removable (DANGEROUS)" | ||
7 | help | ||
8 | If you say Y here, the MMC layer will assume that all cards | ||
9 | stayed in their respective slots during the suspend. The | ||
10 | normal behaviour is to remove them at suspend and | ||
11 | redetecting them at resume. Breaking this assumption will | ||
12 | in most cases result in data corruption. | ||
13 | |||
14 | This option is usually just for embedded systems which use | ||
15 | a MMC/SD card for rootfs. Most people should say N here. | ||
16 | |||
17 | This option sets a default which can be overridden by the | ||
18 | module parameter "removable=0" or "removable=1". | ||
19 | |||
20 | config MMC_CLKGATE | 5 | config MMC_CLKGATE |
21 | bool "MMC host clock gating" | 6 | bool "MMC host clock gating" |
22 | help | 7 | help |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 64145a32b917..824644875d41 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -185,24 +185,16 @@ static int mmc_runtime_suspend(struct device *dev) | |||
185 | { | 185 | { |
186 | struct mmc_card *card = mmc_dev_to_card(dev); | 186 | struct mmc_card *card = mmc_dev_to_card(dev); |
187 | struct mmc_host *host = card->host; | 187 | struct mmc_host *host = card->host; |
188 | int ret = 0; | ||
189 | 188 | ||
190 | if (host->bus_ops->runtime_suspend) | 189 | return host->bus_ops->runtime_suspend(host); |
191 | ret = host->bus_ops->runtime_suspend(host); | ||
192 | |||
193 | return ret; | ||
194 | } | 190 | } |
195 | 191 | ||
196 | static int mmc_runtime_resume(struct device *dev) | 192 | static int mmc_runtime_resume(struct device *dev) |
197 | { | 193 | { |
198 | struct mmc_card *card = mmc_dev_to_card(dev); | 194 | struct mmc_card *card = mmc_dev_to_card(dev); |
199 | struct mmc_host *host = card->host; | 195 | struct mmc_host *host = card->host; |
200 | int ret = 0; | ||
201 | 196 | ||
202 | if (host->bus_ops->runtime_resume) | 197 | return host->bus_ops->runtime_resume(host); |
203 | ret = host->bus_ops->runtime_resume(host); | ||
204 | |||
205 | return ret; | ||
206 | } | 198 | } |
207 | 199 | ||
208 | static int mmc_runtime_idle(struct device *dev) | 200 | static int mmc_runtime_idle(struct device *dev) |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 098374b1ab2b..acbc3f2aaaf9 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mmc/host.h> | 34 | #include <linux/mmc/host.h> |
35 | #include <linux/mmc/mmc.h> | 35 | #include <linux/mmc/mmc.h> |
36 | #include <linux/mmc/sd.h> | 36 | #include <linux/mmc/sd.h> |
37 | #include <linux/mmc/slot-gpio.h> | ||
37 | 38 | ||
38 | #include "core.h" | 39 | #include "core.h" |
39 | #include "bus.h" | 40 | #include "bus.h" |
@@ -65,23 +66,6 @@ bool use_spi_crc = 1; | |||
65 | module_param(use_spi_crc, bool, 0); | 66 | module_param(use_spi_crc, bool, 0); |
66 | 67 | ||
67 | /* | 68 | /* |
68 | * We normally treat cards as removed during suspend if they are not | ||
69 | * known to be on a non-removable bus, to avoid the risk of writing | ||
70 | * back data to a different card after resume. Allow this to be | ||
71 | * overridden if necessary. | ||
72 | */ | ||
73 | #ifdef CONFIG_MMC_UNSAFE_RESUME | ||
74 | bool mmc_assume_removable; | ||
75 | #else | ||
76 | bool mmc_assume_removable = 1; | ||
77 | #endif | ||
78 | EXPORT_SYMBOL(mmc_assume_removable); | ||
79 | module_param_named(removable, mmc_assume_removable, bool, 0644); | ||
80 | MODULE_PARM_DESC( | ||
81 | removable, | ||
82 | "MMC/SD cards are removable and may be removed during suspend"); | ||
83 | |||
84 | /* | ||
85 | * Internal function. Schedule delayed work in the MMC work queue. | 69 | * Internal function. Schedule delayed work in the MMC work queue. |
86 | */ | 70 | */ |
87 | static int mmc_schedule_delayed_work(struct delayed_work *work, | 71 | static int mmc_schedule_delayed_work(struct delayed_work *work, |
@@ -302,7 +286,8 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) | |||
302 | } | 286 | } |
303 | 287 | ||
304 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 288 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
305 | EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal, true); | 289 | EXT_CSD_BKOPS_START, 1, timeout, |
290 | use_busy_signal, true, false); | ||
306 | if (err) { | 291 | if (err) { |
307 | pr_warn("%s: Error %d starting bkops\n", | 292 | pr_warn("%s: Error %d starting bkops\n", |
308 | mmc_hostname(card->host), err); | 293 | mmc_hostname(card->host), err); |
@@ -1950,7 +1935,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, | |||
1950 | cmd.opcode = MMC_ERASE; | 1935 | cmd.opcode = MMC_ERASE; |
1951 | cmd.arg = arg; | 1936 | cmd.arg = arg; |
1952 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; | 1937 | cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; |
1953 | cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty); | 1938 | cmd.busy_timeout = mmc_erase_timeout(card, arg, qty); |
1954 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | 1939 | err = mmc_wait_for_cmd(card->host, &cmd, 0); |
1955 | if (err) { | 1940 | if (err) { |
1956 | pr_err("mmc_erase: erase error %d, status %#x\n", | 1941 | pr_err("mmc_erase: erase error %d, status %#x\n", |
@@ -2137,7 +2122,7 @@ static unsigned int mmc_do_calc_max_discard(struct mmc_card *card, | |||
2137 | y = 0; | 2122 | y = 0; |
2138 | for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) { | 2123 | for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) { |
2139 | timeout = mmc_erase_timeout(card, arg, qty + x); | 2124 | timeout = mmc_erase_timeout(card, arg, qty + x); |
2140 | if (timeout > host->max_discard_to) | 2125 | if (timeout > host->max_busy_timeout) |
2141 | break; | 2126 | break; |
2142 | if (timeout < last_timeout) | 2127 | if (timeout < last_timeout) |
2143 | break; | 2128 | break; |
@@ -2169,7 +2154,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card) | |||
2169 | struct mmc_host *host = card->host; | 2154 | struct mmc_host *host = card->host; |
2170 | unsigned int max_discard, max_trim; | 2155 | unsigned int max_discard, max_trim; |
2171 | 2156 | ||
2172 | if (!host->max_discard_to) | 2157 | if (!host->max_busy_timeout) |
2173 | return UINT_MAX; | 2158 | return UINT_MAX; |
2174 | 2159 | ||
2175 | /* | 2160 | /* |
@@ -2189,7 +2174,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card) | |||
2189 | max_discard = 0; | 2174 | max_discard = 0; |
2190 | } | 2175 | } |
2191 | pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n", | 2176 | pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n", |
2192 | mmc_hostname(host), max_discard, host->max_discard_to); | 2177 | mmc_hostname(host), max_discard, host->max_busy_timeout); |
2193 | return max_discard; | 2178 | return max_discard; |
2194 | } | 2179 | } |
2195 | EXPORT_SYMBOL(mmc_calc_max_discard); | 2180 | EXPORT_SYMBOL(mmc_calc_max_discard); |
@@ -2248,9 +2233,6 @@ static int mmc_do_hw_reset(struct mmc_host *host, int check) | |||
2248 | { | 2233 | { |
2249 | struct mmc_card *card = host->card; | 2234 | struct mmc_card *card = host->card; |
2250 | 2235 | ||
2251 | if (!host->bus_ops->power_restore) | ||
2252 | return -EOPNOTSUPP; | ||
2253 | |||
2254 | if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) | 2236 | if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) |
2255 | return -EOPNOTSUPP; | 2237 | return -EOPNOTSUPP; |
2256 | 2238 | ||
@@ -2352,7 +2334,7 @@ int _mmc_detect_card_removed(struct mmc_host *host) | |||
2352 | { | 2334 | { |
2353 | int ret; | 2335 | int ret; |
2354 | 2336 | ||
2355 | if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive) | 2337 | if (host->caps & MMC_CAP_NONREMOVABLE) |
2356 | return 0; | 2338 | return 0; |
2357 | 2339 | ||
2358 | if (!host->card || mmc_card_removed(host->card)) | 2340 | if (!host->card || mmc_card_removed(host->card)) |
@@ -2435,7 +2417,7 @@ void mmc_rescan(struct work_struct *work) | |||
2435 | * if there is a _removable_ card registered, check whether it is | 2417 | * if there is a _removable_ card registered, check whether it is |
2436 | * still present | 2418 | * still present |
2437 | */ | 2419 | */ |
2438 | if (host->bus_ops && host->bus_ops->detect && !host->bus_dead | 2420 | if (host->bus_ops && !host->bus_dead |
2439 | && !(host->caps & MMC_CAP_NONREMOVABLE)) | 2421 | && !(host->caps & MMC_CAP_NONREMOVABLE)) |
2440 | host->bus_ops->detect(host); | 2422 | host->bus_ops->detect(host); |
2441 | 2423 | ||
@@ -2490,6 +2472,7 @@ void mmc_start_host(struct mmc_host *host) | |||
2490 | mmc_power_off(host); | 2472 | mmc_power_off(host); |
2491 | else | 2473 | else |
2492 | mmc_power_up(host, host->ocr_avail); | 2474 | mmc_power_up(host, host->ocr_avail); |
2475 | mmc_gpiod_request_cd_irq(host); | ||
2493 | _mmc_detect_change(host, 0, false); | 2476 | _mmc_detect_change(host, 0, false); |
2494 | } | 2477 | } |
2495 | 2478 | ||
@@ -2501,6 +2484,8 @@ void mmc_stop_host(struct mmc_host *host) | |||
2501 | host->removed = 1; | 2484 | host->removed = 1; |
2502 | spin_unlock_irqrestore(&host->lock, flags); | 2485 | spin_unlock_irqrestore(&host->lock, flags); |
2503 | #endif | 2486 | #endif |
2487 | if (host->slot.cd_irq >= 0) | ||
2488 | disable_irq(host->slot.cd_irq); | ||
2504 | 2489 | ||
2505 | host->rescan_disable = 1; | 2490 | host->rescan_disable = 1; |
2506 | cancel_delayed_work_sync(&host->detect); | 2491 | cancel_delayed_work_sync(&host->detect); |
@@ -2537,7 +2522,7 @@ int mmc_power_save_host(struct mmc_host *host) | |||
2537 | 2522 | ||
2538 | mmc_bus_get(host); | 2523 | mmc_bus_get(host); |
2539 | 2524 | ||
2540 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { | 2525 | if (!host->bus_ops || host->bus_dead) { |
2541 | mmc_bus_put(host); | 2526 | mmc_bus_put(host); |
2542 | return -EINVAL; | 2527 | return -EINVAL; |
2543 | } | 2528 | } |
@@ -2563,7 +2548,7 @@ int mmc_power_restore_host(struct mmc_host *host) | |||
2563 | 2548 | ||
2564 | mmc_bus_get(host); | 2549 | mmc_bus_get(host); |
2565 | 2550 | ||
2566 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) { | 2551 | if (!host->bus_ops || host->bus_dead) { |
2567 | mmc_bus_put(host); | 2552 | mmc_bus_put(host); |
2568 | return -EINVAL; | 2553 | return -EINVAL; |
2569 | } | 2554 | } |
@@ -2582,12 +2567,8 @@ EXPORT_SYMBOL(mmc_power_restore_host); | |||
2582 | */ | 2567 | */ |
2583 | int mmc_flush_cache(struct mmc_card *card) | 2568 | int mmc_flush_cache(struct mmc_card *card) |
2584 | { | 2569 | { |
2585 | struct mmc_host *host = card->host; | ||
2586 | int err = 0; | 2570 | int err = 0; |
2587 | 2571 | ||
2588 | if (!(host->caps2 & MMC_CAP2_CACHE_CTRL)) | ||
2589 | return err; | ||
2590 | |||
2591 | if (mmc_card_mmc(card) && | 2572 | if (mmc_card_mmc(card) && |
2592 | (card->ext_csd.cache_size > 0) && | 2573 | (card->ext_csd.cache_size > 0) && |
2593 | (card->ext_csd.cache_ctrl & 1)) { | 2574 | (card->ext_csd.cache_ctrl & 1)) { |
@@ -2602,44 +2583,6 @@ int mmc_flush_cache(struct mmc_card *card) | |||
2602 | } | 2583 | } |
2603 | EXPORT_SYMBOL(mmc_flush_cache); | 2584 | EXPORT_SYMBOL(mmc_flush_cache); |
2604 | 2585 | ||
2605 | /* | ||
2606 | * Turn the cache ON/OFF. | ||
2607 | * Turning the cache OFF shall trigger flushing of the data | ||
2608 | * to the non-volatile storage. | ||
2609 | * This function should be called with host claimed | ||
2610 | */ | ||
2611 | int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | ||
2612 | { | ||
2613 | struct mmc_card *card = host->card; | ||
2614 | unsigned int timeout; | ||
2615 | int err = 0; | ||
2616 | |||
2617 | if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) || | ||
2618 | mmc_card_is_removable(host)) | ||
2619 | return err; | ||
2620 | |||
2621 | if (card && mmc_card_mmc(card) && | ||
2622 | (card->ext_csd.cache_size > 0)) { | ||
2623 | enable = !!enable; | ||
2624 | |||
2625 | if (card->ext_csd.cache_ctrl ^ enable) { | ||
2626 | timeout = enable ? card->ext_csd.generic_cmd6_time : 0; | ||
2627 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
2628 | EXT_CSD_CACHE_CTRL, enable, timeout); | ||
2629 | if (err) | ||
2630 | pr_err("%s: cache %s error %d\n", | ||
2631 | mmc_hostname(card->host), | ||
2632 | enable ? "on" : "off", | ||
2633 | err); | ||
2634 | else | ||
2635 | card->ext_csd.cache_ctrl = enable; | ||
2636 | } | ||
2637 | } | ||
2638 | |||
2639 | return err; | ||
2640 | } | ||
2641 | EXPORT_SYMBOL(mmc_cache_ctrl); | ||
2642 | |||
2643 | #ifdef CONFIG_PM | 2586 | #ifdef CONFIG_PM |
2644 | 2587 | ||
2645 | /* Do the card removal on suspend if card is assumed removeable | 2588 | /* Do the card removal on suspend if card is assumed removeable |
@@ -2668,7 +2611,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, | |||
2668 | /* Validate prerequisites for suspend */ | 2611 | /* Validate prerequisites for suspend */ |
2669 | if (host->bus_ops->pre_suspend) | 2612 | if (host->bus_ops->pre_suspend) |
2670 | err = host->bus_ops->pre_suspend(host); | 2613 | err = host->bus_ops->pre_suspend(host); |
2671 | if (!err && host->bus_ops->suspend) | 2614 | if (!err) |
2672 | break; | 2615 | break; |
2673 | 2616 | ||
2674 | /* Calling bus_ops->remove() with a claimed host can deadlock */ | 2617 | /* Calling bus_ops->remove() with a claimed host can deadlock */ |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 114f6bdfbef3..fdea825dbb24 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -419,6 +419,16 @@ int mmc_of_parse(struct mmc_host *host) | |||
419 | host->caps |= MMC_CAP_SD_HIGHSPEED; | 419 | host->caps |= MMC_CAP_SD_HIGHSPEED; |
420 | if (of_find_property(np, "cap-mmc-highspeed", &len)) | 420 | if (of_find_property(np, "cap-mmc-highspeed", &len)) |
421 | host->caps |= MMC_CAP_MMC_HIGHSPEED; | 421 | host->caps |= MMC_CAP_MMC_HIGHSPEED; |
422 | if (of_find_property(np, "sd-uhs-sdr12", &len)) | ||
423 | host->caps |= MMC_CAP_UHS_SDR12; | ||
424 | if (of_find_property(np, "sd-uhs-sdr25", &len)) | ||
425 | host->caps |= MMC_CAP_UHS_SDR25; | ||
426 | if (of_find_property(np, "sd-uhs-sdr50", &len)) | ||
427 | host->caps |= MMC_CAP_UHS_SDR50; | ||
428 | if (of_find_property(np, "sd-uhs-sdr104", &len)) | ||
429 | host->caps |= MMC_CAP_UHS_SDR104; | ||
430 | if (of_find_property(np, "sd-uhs-ddr50", &len)) | ||
431 | host->caps |= MMC_CAP_UHS_DDR50; | ||
422 | if (of_find_property(np, "cap-power-off-card", &len)) | 432 | if (of_find_property(np, "cap-power-off-card", &len)) |
423 | host->caps |= MMC_CAP_POWER_OFF_CARD; | 433 | host->caps |= MMC_CAP_POWER_OFF_CARD; |
424 | if (of_find_property(np, "cap-sdio-irq", &len)) | 434 | if (of_find_property(np, "cap-sdio-irq", &len)) |
@@ -429,6 +439,14 @@ int mmc_of_parse(struct mmc_host *host) | |||
429 | host->pm_caps |= MMC_PM_KEEP_POWER; | 439 | host->pm_caps |= MMC_PM_KEEP_POWER; |
430 | if (of_find_property(np, "enable-sdio-wakeup", &len)) | 440 | if (of_find_property(np, "enable-sdio-wakeup", &len)) |
431 | host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; | 441 | host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; |
442 | if (of_find_property(np, "mmc-ddr-1_8v", &len)) | ||
443 | host->caps |= MMC_CAP_1_8V_DDR; | ||
444 | if (of_find_property(np, "mmc-ddr-1_2v", &len)) | ||
445 | host->caps |= MMC_CAP_1_2V_DDR; | ||
446 | if (of_find_property(np, "mmc-hs200-1_8v", &len)) | ||
447 | host->caps2 |= MMC_CAP2_HS200_1_8V_SDR; | ||
448 | if (of_find_property(np, "mmc-hs200-1_2v", &len)) | ||
449 | host->caps2 |= MMC_CAP2_HS200_1_2V_SDR; | ||
432 | 450 | ||
433 | return 0; | 451 | return 0; |
434 | 452 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 98e9eb0f6643..1ab5f3a0af5b 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -856,8 +856,10 @@ static int mmc_select_hs200(struct mmc_card *card) | |||
856 | 856 | ||
857 | /* switch to HS200 mode if bus width set successfully */ | 857 | /* switch to HS200 mode if bus width set successfully */ |
858 | if (!err) | 858 | if (!err) |
859 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 859 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
860 | EXT_CSD_HS_TIMING, 2, 0); | 860 | EXT_CSD_HS_TIMING, 2, |
861 | card->ext_csd.generic_cmd6_time, | ||
862 | true, true, true); | ||
861 | err: | 863 | err: |
862 | return err; | 864 | return err; |
863 | } | 865 | } |
@@ -1074,9 +1076,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1074 | host->caps2 & MMC_CAP2_HS200) | 1076 | host->caps2 & MMC_CAP2_HS200) |
1075 | err = mmc_select_hs200(card); | 1077 | err = mmc_select_hs200(card); |
1076 | else if (host->caps & MMC_CAP_MMC_HIGHSPEED) | 1078 | else if (host->caps & MMC_CAP_MMC_HIGHSPEED) |
1077 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1079 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1078 | EXT_CSD_HS_TIMING, 1, | 1080 | EXT_CSD_HS_TIMING, 1, |
1079 | card->ext_csd.generic_cmd6_time); | 1081 | card->ext_csd.generic_cmd6_time, |
1082 | true, true, true); | ||
1080 | 1083 | ||
1081 | if (err && err != -EBADMSG) | 1084 | if (err && err != -EBADMSG) |
1082 | goto free_card; | 1085 | goto free_card; |
@@ -1287,8 +1290,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1287 | * If cache size is higher than 0, this indicates | 1290 | * If cache size is higher than 0, this indicates |
1288 | * the existence of cache and it can be turned on. | 1291 | * the existence of cache and it can be turned on. |
1289 | */ | 1292 | */ |
1290 | if ((host->caps2 & MMC_CAP2_CACHE_CTRL) && | 1293 | if (card->ext_csd.cache_size > 0) { |
1291 | card->ext_csd.cache_size > 0) { | ||
1292 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1294 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1293 | EXT_CSD_CACHE_CTRL, 1, | 1295 | EXT_CSD_CACHE_CTRL, 1, |
1294 | card->ext_csd.generic_cmd6_time); | 1296 | card->ext_csd.generic_cmd6_time); |
@@ -1356,11 +1358,9 @@ static int mmc_sleep(struct mmc_host *host) | |||
1356 | { | 1358 | { |
1357 | struct mmc_command cmd = {0}; | 1359 | struct mmc_command cmd = {0}; |
1358 | struct mmc_card *card = host->card; | 1360 | struct mmc_card *card = host->card; |
1361 | unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); | ||
1359 | int err; | 1362 | int err; |
1360 | 1363 | ||
1361 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
1362 | return 0; | ||
1363 | |||
1364 | err = mmc_deselect_cards(host); | 1364 | err = mmc_deselect_cards(host); |
1365 | if (err) | 1365 | if (err) |
1366 | return err; | 1366 | return err; |
@@ -1369,7 +1369,19 @@ static int mmc_sleep(struct mmc_host *host) | |||
1369 | cmd.arg = card->rca << 16; | 1369 | cmd.arg = card->rca << 16; |
1370 | cmd.arg |= 1 << 15; | 1370 | cmd.arg |= 1 << 15; |
1371 | 1371 | ||
1372 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | 1372 | /* |
1373 | * If the max_busy_timeout of the host is specified, validate it against | ||
1374 | * the sleep cmd timeout. A failure means we need to prevent the host | ||
1375 | * from doing hw busy detection, which is done by converting to a R1 | ||
1376 | * response instead of a R1B. | ||
1377 | */ | ||
1378 | if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { | ||
1379 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | ||
1380 | } else { | ||
1381 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
1382 | cmd.busy_timeout = timeout_ms; | ||
1383 | } | ||
1384 | |||
1373 | err = mmc_wait_for_cmd(host, &cmd, 0); | 1385 | err = mmc_wait_for_cmd(host, &cmd, 0); |
1374 | if (err) | 1386 | if (err) |
1375 | return err; | 1387 | return err; |
@@ -1380,8 +1392,8 @@ static int mmc_sleep(struct mmc_host *host) | |||
1380 | * SEND_STATUS command to poll the status because that command (and most | 1392 | * SEND_STATUS command to poll the status because that command (and most |
1381 | * others) is invalid while the card sleeps. | 1393 | * others) is invalid while the card sleeps. |
1382 | */ | 1394 | */ |
1383 | if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) | 1395 | if (!cmd.busy_timeout || !(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) |
1384 | mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000)); | 1396 | mmc_delay(timeout_ms); |
1385 | 1397 | ||
1386 | return err; | 1398 | return err; |
1387 | } | 1399 | } |
@@ -1404,7 +1416,7 @@ static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type) | |||
1404 | 1416 | ||
1405 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1417 | err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1406 | EXT_CSD_POWER_OFF_NOTIFICATION, | 1418 | EXT_CSD_POWER_OFF_NOTIFICATION, |
1407 | notify_type, timeout, true, false); | 1419 | notify_type, timeout, true, false, false); |
1408 | if (err) | 1420 | if (err) |
1409 | pr_err("%s: Power Off Notification timed out, %u\n", | 1421 | pr_err("%s: Power Off Notification timed out, %u\n", |
1410 | mmc_hostname(card->host), timeout); | 1422 | mmc_hostname(card->host), timeout); |
@@ -1484,7 +1496,7 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) | |||
1484 | goto out; | 1496 | goto out; |
1485 | } | 1497 | } |
1486 | 1498 | ||
1487 | err = mmc_cache_ctrl(host, 0); | 1499 | err = mmc_flush_cache(host->card); |
1488 | if (err) | 1500 | if (err) |
1489 | goto out; | 1501 | goto out; |
1490 | 1502 | ||
@@ -1636,16 +1648,6 @@ static int mmc_power_restore(struct mmc_host *host) | |||
1636 | static const struct mmc_bus_ops mmc_ops = { | 1648 | static const struct mmc_bus_ops mmc_ops = { |
1637 | .remove = mmc_remove, | 1649 | .remove = mmc_remove, |
1638 | .detect = mmc_detect, | 1650 | .detect = mmc_detect, |
1639 | .suspend = NULL, | ||
1640 | .resume = NULL, | ||
1641 | .power_restore = mmc_power_restore, | ||
1642 | .alive = mmc_alive, | ||
1643 | .shutdown = mmc_shutdown, | ||
1644 | }; | ||
1645 | |||
1646 | static const struct mmc_bus_ops mmc_ops_unsafe = { | ||
1647 | .remove = mmc_remove, | ||
1648 | .detect = mmc_detect, | ||
1649 | .suspend = mmc_suspend, | 1651 | .suspend = mmc_suspend, |
1650 | .resume = mmc_resume, | 1652 | .resume = mmc_resume, |
1651 | .runtime_suspend = mmc_runtime_suspend, | 1653 | .runtime_suspend = mmc_runtime_suspend, |
@@ -1655,17 +1657,6 @@ static const struct mmc_bus_ops mmc_ops_unsafe = { | |||
1655 | .shutdown = mmc_shutdown, | 1657 | .shutdown = mmc_shutdown, |
1656 | }; | 1658 | }; |
1657 | 1659 | ||
1658 | static void mmc_attach_bus_ops(struct mmc_host *host) | ||
1659 | { | ||
1660 | const struct mmc_bus_ops *bus_ops; | ||
1661 | |||
1662 | if (!mmc_card_is_removable(host)) | ||
1663 | bus_ops = &mmc_ops_unsafe; | ||
1664 | else | ||
1665 | bus_ops = &mmc_ops; | ||
1666 | mmc_attach_bus(host, bus_ops); | ||
1667 | } | ||
1668 | |||
1669 | /* | 1660 | /* |
1670 | * Starting point for MMC card init. | 1661 | * Starting point for MMC card init. |
1671 | */ | 1662 | */ |
@@ -1685,7 +1676,7 @@ int mmc_attach_mmc(struct mmc_host *host) | |||
1685 | if (err) | 1676 | if (err) |
1686 | return err; | 1677 | return err; |
1687 | 1678 | ||
1688 | mmc_attach_bus_ops(host); | 1679 | mmc_attach_bus(host, &mmc_ops); |
1689 | if (host->ocr_avail_mmc) | 1680 | if (host->ocr_avail_mmc) |
1690 | host->ocr_avail = host->ocr_avail_mmc; | 1681 | host->ocr_avail = host->ocr_avail_mmc; |
1691 | 1682 | ||
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index e5b5eeb548d1..f51b5ba3bbea 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -405,20 +405,30 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc) | |||
405 | * timeout of zero implies maximum possible timeout | 405 | * timeout of zero implies maximum possible timeout |
406 | * @use_busy_signal: use the busy signal as response type | 406 | * @use_busy_signal: use the busy signal as response type |
407 | * @send_status: send status cmd to poll for busy | 407 | * @send_status: send status cmd to poll for busy |
408 | * @ignore_crc: ignore CRC errors when sending status cmd to poll for busy | ||
408 | * | 409 | * |
409 | * Modifies the EXT_CSD register for selected card. | 410 | * Modifies the EXT_CSD register for selected card. |
410 | */ | 411 | */ |
411 | int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | 412 | int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, |
412 | unsigned int timeout_ms, bool use_busy_signal, bool send_status) | 413 | unsigned int timeout_ms, bool use_busy_signal, bool send_status, |
414 | bool ignore_crc) | ||
413 | { | 415 | { |
416 | struct mmc_host *host = card->host; | ||
414 | int err; | 417 | int err; |
415 | struct mmc_command cmd = {0}; | 418 | struct mmc_command cmd = {0}; |
416 | unsigned long timeout; | 419 | unsigned long timeout; |
417 | u32 status = 0; | 420 | u32 status = 0; |
418 | bool ignore_crc = false; | 421 | bool use_r1b_resp = use_busy_signal; |
419 | 422 | ||
420 | BUG_ON(!card); | 423 | /* |
421 | BUG_ON(!card->host); | 424 | * If the cmd timeout and the max_busy_timeout of the host are both |
425 | * specified, let's validate them. A failure means we need to prevent | ||
426 | * the host from doing hw busy detection, which is done by converting | ||
427 | * to a R1 response instead of a R1B. | ||
428 | */ | ||
429 | if (timeout_ms && host->max_busy_timeout && | ||
430 | (timeout_ms > host->max_busy_timeout)) | ||
431 | use_r1b_resp = false; | ||
422 | 432 | ||
423 | cmd.opcode = MMC_SWITCH; | 433 | cmd.opcode = MMC_SWITCH; |
424 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | 434 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | |
@@ -426,17 +436,21 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | |||
426 | (value << 8) | | 436 | (value << 8) | |
427 | set; | 437 | set; |
428 | cmd.flags = MMC_CMD_AC; | 438 | cmd.flags = MMC_CMD_AC; |
429 | if (use_busy_signal) | 439 | if (use_r1b_resp) { |
430 | cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; | 440 | cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; |
431 | else | 441 | /* |
442 | * A busy_timeout of zero means the host can decide to use | ||
443 | * whatever value it finds suitable. | ||
444 | */ | ||
445 | cmd.busy_timeout = timeout_ms; | ||
446 | } else { | ||
432 | cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; | 447 | cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; |
448 | } | ||
433 | 449 | ||
434 | |||
435 | cmd.cmd_timeout_ms = timeout_ms; | ||
436 | if (index == EXT_CSD_SANITIZE_START) | 450 | if (index == EXT_CSD_SANITIZE_START) |
437 | cmd.sanitize_busy = true; | 451 | cmd.sanitize_busy = true; |
438 | 452 | ||
439 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 453 | err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); |
440 | if (err) | 454 | if (err) |
441 | return err; | 455 | return err; |
442 | 456 | ||
@@ -445,24 +459,27 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | |||
445 | return 0; | 459 | return 0; |
446 | 460 | ||
447 | /* | 461 | /* |
448 | * Must check status to be sure of no errors | 462 | * CRC errors shall only be ignored in cases were CMD13 is used to poll |
449 | * If CMD13 is to check the busy completion of the timing change, | 463 | * to detect busy completion. |
450 | * disable the check of CRC error. | ||
451 | */ | 464 | */ |
452 | if (index == EXT_CSD_HS_TIMING && | 465 | if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) |
453 | !(card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)) | 466 | ignore_crc = false; |
454 | ignore_crc = true; | 467 | |
468 | /* We have an unspecified cmd timeout, use the fallback value. */ | ||
469 | if (!timeout_ms) | ||
470 | timeout_ms = MMC_OPS_TIMEOUT_MS; | ||
455 | 471 | ||
456 | timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS); | 472 | /* Must check status to be sure of no errors. */ |
473 | timeout = jiffies + msecs_to_jiffies(timeout_ms); | ||
457 | do { | 474 | do { |
458 | if (send_status) { | 475 | if (send_status) { |
459 | err = __mmc_send_status(card, &status, ignore_crc); | 476 | err = __mmc_send_status(card, &status, ignore_crc); |
460 | if (err) | 477 | if (err) |
461 | return err; | 478 | return err; |
462 | } | 479 | } |
463 | if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) | 480 | if ((host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp) |
464 | break; | 481 | break; |
465 | if (mmc_host_is_spi(card->host)) | 482 | if (mmc_host_is_spi(host)) |
466 | break; | 483 | break; |
467 | 484 | ||
468 | /* | 485 | /* |
@@ -478,18 +495,18 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | |||
478 | /* Timeout if the device never leaves the program state. */ | 495 | /* Timeout if the device never leaves the program state. */ |
479 | if (time_after(jiffies, timeout)) { | 496 | if (time_after(jiffies, timeout)) { |
480 | pr_err("%s: Card stuck in programming state! %s\n", | 497 | pr_err("%s: Card stuck in programming state! %s\n", |
481 | mmc_hostname(card->host), __func__); | 498 | mmc_hostname(host), __func__); |
482 | return -ETIMEDOUT; | 499 | return -ETIMEDOUT; |
483 | } | 500 | } |
484 | } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); | 501 | } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); |
485 | 502 | ||
486 | if (mmc_host_is_spi(card->host)) { | 503 | if (mmc_host_is_spi(host)) { |
487 | if (status & R1_SPI_ILLEGAL_COMMAND) | 504 | if (status & R1_SPI_ILLEGAL_COMMAND) |
488 | return -EBADMSG; | 505 | return -EBADMSG; |
489 | } else { | 506 | } else { |
490 | if (status & 0xFDFFA000) | 507 | if (status & 0xFDFFA000) |
491 | pr_warning("%s: unexpected status %#x after " | 508 | pr_warn("%s: unexpected status %#x after switch\n", |
492 | "switch", mmc_hostname(card->host), status); | 509 | mmc_hostname(host), status); |
493 | if (status & R1_SWITCH_ERROR) | 510 | if (status & R1_SWITCH_ERROR) |
494 | return -EBADMSG; | 511 | return -EBADMSG; |
495 | } | 512 | } |
@@ -501,7 +518,8 @@ EXPORT_SYMBOL_GPL(__mmc_switch); | |||
501 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | 518 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, |
502 | unsigned int timeout_ms) | 519 | unsigned int timeout_ms) |
503 | { | 520 | { |
504 | return __mmc_switch(card, set, index, value, timeout_ms, true, true); | 521 | return __mmc_switch(card, set, index, value, timeout_ms, true, true, |
522 | false); | ||
505 | } | 523 | } |
506 | EXPORT_SYMBOL_GPL(mmc_switch); | 524 | EXPORT_SYMBOL_GPL(mmc_switch); |
507 | 525 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 692fdb177294..2dd359d2242f 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -1209,16 +1209,6 @@ static int mmc_sd_power_restore(struct mmc_host *host) | |||
1209 | static const struct mmc_bus_ops mmc_sd_ops = { | 1209 | static const struct mmc_bus_ops mmc_sd_ops = { |
1210 | .remove = mmc_sd_remove, | 1210 | .remove = mmc_sd_remove, |
1211 | .detect = mmc_sd_detect, | 1211 | .detect = mmc_sd_detect, |
1212 | .suspend = NULL, | ||
1213 | .resume = NULL, | ||
1214 | .power_restore = mmc_sd_power_restore, | ||
1215 | .alive = mmc_sd_alive, | ||
1216 | .shutdown = mmc_sd_suspend, | ||
1217 | }; | ||
1218 | |||
1219 | static const struct mmc_bus_ops mmc_sd_ops_unsafe = { | ||
1220 | .remove = mmc_sd_remove, | ||
1221 | .detect = mmc_sd_detect, | ||
1222 | .runtime_suspend = mmc_sd_runtime_suspend, | 1212 | .runtime_suspend = mmc_sd_runtime_suspend, |
1223 | .runtime_resume = mmc_sd_runtime_resume, | 1213 | .runtime_resume = mmc_sd_runtime_resume, |
1224 | .suspend = mmc_sd_suspend, | 1214 | .suspend = mmc_sd_suspend, |
@@ -1228,17 +1218,6 @@ static const struct mmc_bus_ops mmc_sd_ops_unsafe = { | |||
1228 | .shutdown = mmc_sd_suspend, | 1218 | .shutdown = mmc_sd_suspend, |
1229 | }; | 1219 | }; |
1230 | 1220 | ||
1231 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) | ||
1232 | { | ||
1233 | const struct mmc_bus_ops *bus_ops; | ||
1234 | |||
1235 | if (!mmc_card_is_removable(host)) | ||
1236 | bus_ops = &mmc_sd_ops_unsafe; | ||
1237 | else | ||
1238 | bus_ops = &mmc_sd_ops; | ||
1239 | mmc_attach_bus(host, bus_ops); | ||
1240 | } | ||
1241 | |||
1242 | /* | 1221 | /* |
1243 | * Starting point for SD card init. | 1222 | * Starting point for SD card init. |
1244 | */ | 1223 | */ |
@@ -1254,7 +1233,7 @@ int mmc_attach_sd(struct mmc_host *host) | |||
1254 | if (err) | 1233 | if (err) |
1255 | return err; | 1234 | return err; |
1256 | 1235 | ||
1257 | mmc_sd_attach_bus_ops(host); | 1236 | mmc_attach_bus(host, &mmc_sd_ops); |
1258 | if (host->ocr_avail_sd) | 1237 | if (host->ocr_avail_sd) |
1259 | host->ocr_avail = host->ocr_avail_sd; | 1238 | host->ocr_avail = host->ocr_avail_sd; |
1260 | 1239 | ||
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 46596b71a32f..f7650b899e3d 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/err.h> | 11 | #include <linux/err.h> |
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/gpio/consumer.h> | ||
13 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
14 | #include <linux/jiffies.h> | 15 | #include <linux/jiffies.h> |
15 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
@@ -18,8 +19,10 @@ | |||
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | 20 | ||
20 | struct mmc_gpio { | 21 | struct mmc_gpio { |
21 | int ro_gpio; | 22 | struct gpio_desc *ro_gpio; |
22 | int cd_gpio; | 23 | struct gpio_desc *cd_gpio; |
24 | bool override_ro_active_level; | ||
25 | bool override_cd_active_level; | ||
23 | char *ro_label; | 26 | char *ro_label; |
24 | char cd_label[0]; | 27 | char cd_label[0]; |
25 | }; | 28 | }; |
@@ -57,8 +60,6 @@ static int mmc_gpio_alloc(struct mmc_host *host) | |||
57 | ctx->ro_label = ctx->cd_label + len; | 60 | ctx->ro_label = ctx->cd_label + len; |
58 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); | 61 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); |
59 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); | 62 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); |
60 | ctx->cd_gpio = -EINVAL; | ||
61 | ctx->ro_gpio = -EINVAL; | ||
62 | host->slot.handler_priv = ctx; | 63 | host->slot.handler_priv = ctx; |
63 | } | 64 | } |
64 | } | 65 | } |
@@ -72,11 +73,14 @@ int mmc_gpio_get_ro(struct mmc_host *host) | |||
72 | { | 73 | { |
73 | struct mmc_gpio *ctx = host->slot.handler_priv; | 74 | struct mmc_gpio *ctx = host->slot.handler_priv; |
74 | 75 | ||
75 | if (!ctx || !gpio_is_valid(ctx->ro_gpio)) | 76 | if (!ctx || !ctx->ro_gpio) |
76 | return -ENOSYS; | 77 | return -ENOSYS; |
77 | 78 | ||
78 | return !gpio_get_value_cansleep(ctx->ro_gpio) ^ | 79 | if (ctx->override_ro_active_level) |
79 | !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); | 80 | return !gpiod_get_raw_value_cansleep(ctx->ro_gpio) ^ |
81 | !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); | ||
82 | |||
83 | return gpiod_get_value_cansleep(ctx->ro_gpio); | ||
80 | } | 84 | } |
81 | EXPORT_SYMBOL(mmc_gpio_get_ro); | 85 | EXPORT_SYMBOL(mmc_gpio_get_ro); |
82 | 86 | ||
@@ -84,11 +88,14 @@ int mmc_gpio_get_cd(struct mmc_host *host) | |||
84 | { | 88 | { |
85 | struct mmc_gpio *ctx = host->slot.handler_priv; | 89 | struct mmc_gpio *ctx = host->slot.handler_priv; |
86 | 90 | ||
87 | if (!ctx || !gpio_is_valid(ctx->cd_gpio)) | 91 | if (!ctx || !ctx->cd_gpio) |
88 | return -ENOSYS; | 92 | return -ENOSYS; |
89 | 93 | ||
90 | return !gpio_get_value_cansleep(ctx->cd_gpio) ^ | 94 | if (ctx->override_cd_active_level) |
91 | !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); | 95 | return !gpiod_get_raw_value_cansleep(ctx->cd_gpio) ^ |
96 | !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); | ||
97 | |||
98 | return gpiod_get_value_cansleep(ctx->cd_gpio); | ||
92 | } | 99 | } |
93 | EXPORT_SYMBOL(mmc_gpio_get_cd); | 100 | EXPORT_SYMBOL(mmc_gpio_get_cd); |
94 | 101 | ||
@@ -125,12 +132,47 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) | |||
125 | if (ret < 0) | 132 | if (ret < 0) |
126 | return ret; | 133 | return ret; |
127 | 134 | ||
128 | ctx->ro_gpio = gpio; | 135 | ctx->override_ro_active_level = true; |
136 | ctx->ro_gpio = gpio_to_desc(gpio); | ||
129 | 137 | ||
130 | return 0; | 138 | return 0; |
131 | } | 139 | } |
132 | EXPORT_SYMBOL(mmc_gpio_request_ro); | 140 | EXPORT_SYMBOL(mmc_gpio_request_ro); |
133 | 141 | ||
142 | void mmc_gpiod_request_cd_irq(struct mmc_host *host) | ||
143 | { | ||
144 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
145 | int ret, irq; | ||
146 | |||
147 | if (host->slot.cd_irq >= 0 || !ctx || !ctx->cd_gpio) | ||
148 | return; | ||
149 | |||
150 | irq = gpiod_to_irq(ctx->cd_gpio); | ||
151 | |||
152 | /* | ||
153 | * Even if gpiod_to_irq() returns a valid IRQ number, the platform might | ||
154 | * still prefer to poll, e.g., because that IRQ number is already used | ||
155 | * by another unit and cannot be shared. | ||
156 | */ | ||
157 | if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) | ||
158 | irq = -EINVAL; | ||
159 | |||
160 | if (irq >= 0) { | ||
161 | ret = devm_request_threaded_irq(&host->class_dev, irq, | ||
162 | NULL, mmc_gpio_cd_irqt, | ||
163 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
164 | ctx->cd_label, host); | ||
165 | if (ret < 0) | ||
166 | irq = ret; | ||
167 | } | ||
168 | |||
169 | host->slot.cd_irq = irq; | ||
170 | |||
171 | if (irq < 0) | ||
172 | host->caps |= MMC_CAP_NEEDS_POLL; | ||
173 | } | ||
174 | EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); | ||
175 | |||
134 | /** | 176 | /** |
135 | * mmc_gpio_request_cd - request a gpio for card-detection | 177 | * mmc_gpio_request_cd - request a gpio for card-detection |
136 | * @host: mmc host | 178 | * @host: mmc host |
@@ -154,7 +196,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | |||
154 | unsigned int debounce) | 196 | unsigned int debounce) |
155 | { | 197 | { |
156 | struct mmc_gpio *ctx; | 198 | struct mmc_gpio *ctx; |
157 | int irq = gpio_to_irq(gpio); | ||
158 | int ret; | 199 | int ret; |
159 | 200 | ||
160 | ret = mmc_gpio_alloc(host); | 201 | ret = mmc_gpio_alloc(host); |
@@ -179,29 +220,10 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | |||
179 | return ret; | 220 | return ret; |
180 | } | 221 | } |
181 | 222 | ||
182 | /* | 223 | ctx->override_cd_active_level = true; |
183 | * Even if gpio_to_irq() returns a valid IRQ number, the platform might | 224 | ctx->cd_gpio = gpio_to_desc(gpio); |
184 | * still prefer to poll, e.g., because that IRQ number is already used | ||
185 | * by another unit and cannot be shared. | ||
186 | */ | ||
187 | if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) | ||
188 | irq = -EINVAL; | ||
189 | |||
190 | if (irq >= 0) { | ||
191 | ret = devm_request_threaded_irq(&host->class_dev, irq, | ||
192 | NULL, mmc_gpio_cd_irqt, | ||
193 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
194 | ctx->cd_label, host); | ||
195 | if (ret < 0) | ||
196 | irq = ret; | ||
197 | } | ||
198 | |||
199 | host->slot.cd_irq = irq; | ||
200 | |||
201 | if (irq < 0) | ||
202 | host->caps |= MMC_CAP_NEEDS_POLL; | ||
203 | 225 | ||
204 | ctx->cd_gpio = gpio; | 226 | mmc_gpiod_request_cd_irq(host); |
205 | 227 | ||
206 | return 0; | 228 | return 0; |
207 | } | 229 | } |
@@ -219,11 +241,11 @@ void mmc_gpio_free_ro(struct mmc_host *host) | |||
219 | struct mmc_gpio *ctx = host->slot.handler_priv; | 241 | struct mmc_gpio *ctx = host->slot.handler_priv; |
220 | int gpio; | 242 | int gpio; |
221 | 243 | ||
222 | if (!ctx || !gpio_is_valid(ctx->ro_gpio)) | 244 | if (!ctx || !ctx->ro_gpio) |
223 | return; | 245 | return; |
224 | 246 | ||
225 | gpio = ctx->ro_gpio; | 247 | gpio = desc_to_gpio(ctx->ro_gpio); |
226 | ctx->ro_gpio = -EINVAL; | 248 | ctx->ro_gpio = NULL; |
227 | 249 | ||
228 | devm_gpio_free(&host->class_dev, gpio); | 250 | devm_gpio_free(&host->class_dev, gpio); |
229 | } | 251 | } |
@@ -241,7 +263,7 @@ void mmc_gpio_free_cd(struct mmc_host *host) | |||
241 | struct mmc_gpio *ctx = host->slot.handler_priv; | 263 | struct mmc_gpio *ctx = host->slot.handler_priv; |
242 | int gpio; | 264 | int gpio; |
243 | 265 | ||
244 | if (!ctx || !gpio_is_valid(ctx->cd_gpio)) | 266 | if (!ctx || !ctx->cd_gpio) |
245 | return; | 267 | return; |
246 | 268 | ||
247 | if (host->slot.cd_irq >= 0) { | 269 | if (host->slot.cd_irq >= 0) { |
@@ -249,9 +271,87 @@ void mmc_gpio_free_cd(struct mmc_host *host) | |||
249 | host->slot.cd_irq = -EINVAL; | 271 | host->slot.cd_irq = -EINVAL; |
250 | } | 272 | } |
251 | 273 | ||
252 | gpio = ctx->cd_gpio; | 274 | gpio = desc_to_gpio(ctx->cd_gpio); |
253 | ctx->cd_gpio = -EINVAL; | 275 | ctx->cd_gpio = NULL; |
254 | 276 | ||
255 | devm_gpio_free(&host->class_dev, gpio); | 277 | devm_gpio_free(&host->class_dev, gpio); |
256 | } | 278 | } |
257 | EXPORT_SYMBOL(mmc_gpio_free_cd); | 279 | EXPORT_SYMBOL(mmc_gpio_free_cd); |
280 | |||
281 | /** | ||
282 | * mmc_gpiod_request_cd - request a gpio descriptor for card-detection | ||
283 | * @host: mmc host | ||
284 | * @con_id: function within the GPIO consumer | ||
285 | * @idx: index of the GPIO to obtain in the consumer | ||
286 | * @override_active_level: ignore %GPIO_ACTIVE_LOW flag | ||
287 | * @debounce: debounce time in microseconds | ||
288 | * | ||
289 | * Use this function in place of mmc_gpio_request_cd() to use the GPIO | ||
290 | * descriptor API. Note that it is paired with mmc_gpiod_free_cd() not | ||
291 | * mmc_gpio_free_cd(). Note also that it must be called prior to mmc_add_host() | ||
292 | * otherwise the caller must also call mmc_gpiod_request_cd_irq(). | ||
293 | * | ||
294 | * Returns zero on success, else an error. | ||
295 | */ | ||
296 | int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | ||
297 | unsigned int idx, bool override_active_level, | ||
298 | unsigned int debounce) | ||
299 | { | ||
300 | struct mmc_gpio *ctx; | ||
301 | struct gpio_desc *desc; | ||
302 | int ret; | ||
303 | |||
304 | ret = mmc_gpio_alloc(host); | ||
305 | if (ret < 0) | ||
306 | return ret; | ||
307 | |||
308 | ctx = host->slot.handler_priv; | ||
309 | |||
310 | if (!con_id) | ||
311 | con_id = ctx->cd_label; | ||
312 | |||
313 | desc = devm_gpiod_get_index(host->parent, con_id, idx); | ||
314 | if (IS_ERR(desc)) | ||
315 | return PTR_ERR(desc); | ||
316 | |||
317 | ret = gpiod_direction_input(desc); | ||
318 | if (ret < 0) | ||
319 | return ret; | ||
320 | |||
321 | if (debounce) { | ||
322 | ret = gpiod_set_debounce(desc, debounce); | ||
323 | if (ret < 0) | ||
324 | return ret; | ||
325 | } | ||
326 | |||
327 | ctx->override_cd_active_level = override_active_level; | ||
328 | ctx->cd_gpio = desc; | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | EXPORT_SYMBOL(mmc_gpiod_request_cd); | ||
333 | |||
334 | /** | ||
335 | * mmc_gpiod_free_cd - free the card-detection gpio descriptor | ||
336 | * @host: mmc host | ||
337 | * | ||
338 | * It's provided only for cases that client drivers need to manually free | ||
339 | * up the card-detection gpio requested by mmc_gpiod_request_cd(). | ||
340 | */ | ||
341 | void mmc_gpiod_free_cd(struct mmc_host *host) | ||
342 | { | ||
343 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
344 | |||
345 | if (!ctx || !ctx->cd_gpio) | ||
346 | return; | ||
347 | |||
348 | if (host->slot.cd_irq >= 0) { | ||
349 | devm_free_irq(&host->class_dev, host->slot.cd_irq, host); | ||
350 | host->slot.cd_irq = -EINVAL; | ||
351 | } | ||
352 | |||
353 | devm_gpiod_put(&host->class_dev, ctx->cd_gpio); | ||
354 | |||
355 | ctx->cd_gpio = NULL; | ||
356 | } | ||
357 | EXPORT_SYMBOL(mmc_gpiod_free_cd); | ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 1384f67abe21..8aaf8c1f3f63 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -263,7 +263,7 @@ config MMC_SDHCI_S3C_DMA | |||
263 | 263 | ||
264 | config MMC_SDHCI_BCM_KONA | 264 | config MMC_SDHCI_BCM_KONA |
265 | tristate "SDHCI support on Broadcom KONA platform" | 265 | tristate "SDHCI support on Broadcom KONA platform" |
266 | depends on ARCH_BCM | 266 | depends on ARCH_BCM_MOBILE |
267 | select MMC_SDHCI_PLTFM | 267 | select MMC_SDHCI_PLTFM |
268 | help | 268 | help |
269 | This selects the Broadcom Kona Secure Digital Host Controller | 269 | This selects the Broadcom Kona Secure Digital Host Controller |
@@ -334,6 +334,19 @@ config MMC_ATMELMCI | |||
334 | 334 | ||
335 | If unsure, say N. | 335 | If unsure, say N. |
336 | 336 | ||
337 | config MMC_SDHCI_MSM | ||
338 | tristate "Qualcomm SDHCI Controller Support" | ||
339 | depends on ARCH_QCOM | ||
340 | depends on MMC_SDHCI_PLTFM | ||
341 | help | ||
342 | This selects the Secure Digital Host Controller Interface (SDHCI) | ||
343 | support present in Qualcomm SOCs. The controller supports | ||
344 | SD/MMC/SDIO devices. | ||
345 | |||
346 | If you have a controller with this interface, say Y or M here. | ||
347 | |||
348 | If unsure, say N. | ||
349 | |||
337 | config MMC_MSM | 350 | config MMC_MSM |
338 | tristate "Qualcomm SDCC Controller Support" | 351 | tristate "Qualcomm SDCC Controller Support" |
339 | depends on MMC && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50) | 352 | depends on MMC && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50) |
@@ -580,14 +593,6 @@ config MMC_DW_EXYNOS | |||
580 | Synopsys DesignWare Memory Card Interface driver. Select this option | 593 | Synopsys DesignWare Memory Card Interface driver. Select this option |
581 | for platforms based on Exynos4 and Exynos5 SoC's. | 594 | for platforms based on Exynos4 and Exynos5 SoC's. |
582 | 595 | ||
583 | config MMC_DW_SOCFPGA | ||
584 | tristate "SOCFPGA specific extensions for Synopsys DW Memory Card Interface" | ||
585 | depends on MMC_DW && MFD_SYSCON | ||
586 | select MMC_DW_PLTFM | ||
587 | help | ||
588 | This selects support for Altera SoCFPGA specific extensions to the | ||
589 | Synopsys DesignWare Memory Card Interface driver. | ||
590 | |||
591 | config MMC_DW_K3 | 596 | config MMC_DW_K3 |
592 | tristate "K3 specific extensions for Synopsys DW Memory Card Interface" | 597 | tristate "K3 specific extensions for Synopsys DW Memory Card Interface" |
593 | depends on MMC_DW | 598 | depends on MMC_DW |
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 3483b6b6b880..0c8aa5e1e304 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -43,7 +43,6 @@ obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o | |||
43 | obj-$(CONFIG_MMC_DW) += dw_mmc.o | 43 | obj-$(CONFIG_MMC_DW) += dw_mmc.o |
44 | obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o | 44 | obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o |
45 | obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o | 45 | obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o |
46 | obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o | ||
47 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o | 46 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o |
48 | obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o | 47 | obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o |
49 | obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o | 48 | obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o |
@@ -64,6 +63,7 @@ obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o | |||
64 | obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o | 63 | obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o |
65 | obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o | 64 | obj-$(CONFIG_MMC_SDHCI_BCM_KONA) += sdhci-bcm-kona.o |
66 | obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o | 65 | obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o |
66 | obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-msm.o | ||
67 | 67 | ||
68 | ifeq ($(CONFIG_CB710_DEBUG),y) | 68 | ifeq ($(CONFIG_CB710_DEBUG),y) |
69 | CFLAGS-cb710-mmc += -DDEBUG | 69 | CFLAGS-cb710-mmc += -DDEBUG |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index d6153740b77f..5d4c5e0fba2f 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c | |||
@@ -1192,7 +1192,7 @@ static struct davinci_mmc_config | |||
1192 | struct device_node *np; | 1192 | struct device_node *np; |
1193 | struct davinci_mmc_config *pdata = pdev->dev.platform_data; | 1193 | struct davinci_mmc_config *pdata = pdev->dev.platform_data; |
1194 | const struct of_device_id *match = | 1194 | const struct of_device_id *match = |
1195 | of_match_device(of_match_ptr(davinci_mmc_dt_ids), &pdev->dev); | 1195 | of_match_device(davinci_mmc_dt_ids, &pdev->dev); |
1196 | u32 data; | 1196 | u32 data; |
1197 | 1197 | ||
1198 | np = pdev->dev.of_node; | 1198 | np = pdev->dev.of_node; |
@@ -1468,7 +1468,7 @@ static struct platform_driver davinci_mmcsd_driver = { | |||
1468 | .name = "davinci_mmc", | 1468 | .name = "davinci_mmc", |
1469 | .owner = THIS_MODULE, | 1469 | .owner = THIS_MODULE, |
1470 | .pm = davinci_mmcsd_pm_ops, | 1470 | .pm = davinci_mmcsd_pm_ops, |
1471 | .of_match_table = of_match_ptr(davinci_mmc_dt_ids), | 1471 | .of_match_table = davinci_mmc_dt_ids, |
1472 | }, | 1472 | }, |
1473 | .remove = __exit_p(davinci_mmcsd_remove), | 1473 | .remove = __exit_p(davinci_mmcsd_remove), |
1474 | .id_table = davinci_mmc_devtype, | 1474 | .id_table = davinci_mmc_devtype, |
diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index f567c219cff4..650f9cc3f7a6 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c | |||
@@ -50,6 +50,7 @@ static int dw_mci_k3_probe(struct platform_device *pdev) | |||
50 | return dw_mci_pltfm_register(pdev, drv_data); | 50 | return dw_mci_pltfm_register(pdev, drv_data); |
51 | } | 51 | } |
52 | 52 | ||
53 | #ifdef CONFIG_PM_SLEEP | ||
53 | static int dw_mci_k3_suspend(struct device *dev) | 54 | static int dw_mci_k3_suspend(struct device *dev) |
54 | { | 55 | { |
55 | struct dw_mci *host = dev_get_drvdata(dev); | 56 | struct dw_mci *host = dev_get_drvdata(dev); |
@@ -75,6 +76,7 @@ static int dw_mci_k3_resume(struct device *dev) | |||
75 | 76 | ||
76 | return dw_mci_resume(host); | 77 | return dw_mci_resume(host); |
77 | } | 78 | } |
79 | #endif /* CONFIG_PM_SLEEP */ | ||
78 | 80 | ||
79 | static SIMPLE_DEV_PM_OPS(dw_mci_k3_pmops, dw_mci_k3_suspend, dw_mci_k3_resume); | 81 | static SIMPLE_DEV_PM_OPS(dw_mci_k3_pmops, dw_mci_k3_suspend, dw_mci_k3_resume); |
80 | 82 | ||
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 5c4965655297..d4a47a9f5584 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c | |||
@@ -25,13 +25,17 @@ | |||
25 | #include "dw_mmc.h" | 25 | #include "dw_mmc.h" |
26 | #include "dw_mmc-pltfm.h" | 26 | #include "dw_mmc-pltfm.h" |
27 | 27 | ||
28 | static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr) | 28 | static void dw_mci_pltfm_prepare_command(struct dw_mci *host, u32 *cmdr) |
29 | { | 29 | { |
30 | *cmdr |= SDMMC_CMD_USE_HOLD_REG; | 30 | *cmdr |= SDMMC_CMD_USE_HOLD_REG; |
31 | } | 31 | } |
32 | 32 | ||
33 | static const struct dw_mci_drv_data rockchip_drv_data = { | 33 | static const struct dw_mci_drv_data rockchip_drv_data = { |
34 | .prepare_command = dw_mci_rockchip_prepare_command, | 34 | .prepare_command = dw_mci_pltfm_prepare_command, |
35 | }; | ||
36 | |||
37 | static const struct dw_mci_drv_data socfpga_drv_data = { | ||
38 | .prepare_command = dw_mci_pltfm_prepare_command, | ||
35 | }; | 39 | }; |
36 | 40 | ||
37 | int dw_mci_pltfm_register(struct platform_device *pdev, | 41 | int dw_mci_pltfm_register(struct platform_device *pdev, |
@@ -92,6 +96,8 @@ static const struct of_device_id dw_mci_pltfm_match[] = { | |||
92 | { .compatible = "snps,dw-mshc", }, | 96 | { .compatible = "snps,dw-mshc", }, |
93 | { .compatible = "rockchip,rk2928-dw-mshc", | 97 | { .compatible = "rockchip,rk2928-dw-mshc", |
94 | .data = &rockchip_drv_data }, | 98 | .data = &rockchip_drv_data }, |
99 | { .compatible = "altr,socfpga-dw-mshc", | ||
100 | .data = &socfpga_drv_data }, | ||
95 | {}, | 101 | {}, |
96 | }; | 102 | }; |
97 | MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); | 103 | MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); |
@@ -123,7 +129,7 @@ static struct platform_driver dw_mci_pltfm_driver = { | |||
123 | .remove = dw_mci_pltfm_remove, | 129 | .remove = dw_mci_pltfm_remove, |
124 | .driver = { | 130 | .driver = { |
125 | .name = "dw_mmc", | 131 | .name = "dw_mmc", |
126 | .of_match_table = of_match_ptr(dw_mci_pltfm_match), | 132 | .of_match_table = dw_mci_pltfm_match, |
127 | .pm = &dw_mci_pltfm_pmops, | 133 | .pm = &dw_mci_pltfm_pmops, |
128 | }, | 134 | }, |
129 | }; | 135 | }; |
diff --git a/drivers/mmc/host/dw_mmc-socfpga.c b/drivers/mmc/host/dw_mmc-socfpga.c deleted file mode 100644 index 3e8e53ae3302..000000000000 --- a/drivers/mmc/host/dw_mmc-socfpga.c +++ /dev/null | |||
@@ -1,138 +0,0 @@ | |||
1 | /* | ||
2 | * Altera SoCFPGA Specific Extensions for Synopsys DW Multimedia Card Interface | ||
3 | * driver | ||
4 | * | ||
5 | * Copyright (C) 2012, Samsung Electronics Co., Ltd. | ||
6 | * Copyright (C) 2013 Altera Corporation | ||
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 | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * Taken from dw_mmc-exynos.c | ||
14 | */ | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/mfd/syscon.h> | ||
17 | #include <linux/mmc/host.h> | ||
18 | #include <linux/mmc/dw_mmc.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/regmap.h> | ||
23 | |||
24 | #include "dw_mmc.h" | ||
25 | #include "dw_mmc-pltfm.h" | ||
26 | |||
27 | #define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x108 | ||
28 | #define DRV_CLK_PHASE_SHIFT_SEL_MASK 0x7 | ||
29 | #define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \ | ||
30 | ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0)) | ||
31 | |||
32 | /* SOCFPGA implementation specific driver private data */ | ||
33 | struct dw_mci_socfpga_priv_data { | ||
34 | u8 ciu_div; /* card interface unit divisor */ | ||
35 | u32 hs_timing; /* bitmask for CIU clock phase shift */ | ||
36 | struct regmap *sysreg; /* regmap for system manager register */ | ||
37 | }; | ||
38 | |||
39 | static int dw_mci_socfpga_priv_init(struct dw_mci *host) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int dw_mci_socfpga_setup_clock(struct dw_mci *host) | ||
45 | { | ||
46 | struct dw_mci_socfpga_priv_data *priv = host->priv; | ||
47 | |||
48 | clk_disable_unprepare(host->ciu_clk); | ||
49 | regmap_write(priv->sysreg, SYSMGR_SDMMCGRP_CTRL_OFFSET, | ||
50 | priv->hs_timing); | ||
51 | clk_prepare_enable(host->ciu_clk); | ||
52 | |||
53 | host->bus_hz /= (priv->ciu_div + 1); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static void dw_mci_socfpga_prepare_command(struct dw_mci *host, u32 *cmdr) | ||
58 | { | ||
59 | struct dw_mci_socfpga_priv_data *priv = host->priv; | ||
60 | |||
61 | if (priv->hs_timing & DRV_CLK_PHASE_SHIFT_SEL_MASK) | ||
62 | *cmdr |= SDMMC_CMD_USE_HOLD_REG; | ||
63 | } | ||
64 | |||
65 | static int dw_mci_socfpga_parse_dt(struct dw_mci *host) | ||
66 | { | ||
67 | struct dw_mci_socfpga_priv_data *priv; | ||
68 | struct device_node *np = host->dev->of_node; | ||
69 | u32 timing[2]; | ||
70 | u32 div = 0; | ||
71 | int ret; | ||
72 | |||
73 | priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); | ||
74 | if (!priv) { | ||
75 | dev_err(host->dev, "mem alloc failed for private data\n"); | ||
76 | return -ENOMEM; | ||
77 | } | ||
78 | |||
79 | priv->sysreg = syscon_regmap_lookup_by_compatible("altr,sys-mgr"); | ||
80 | if (IS_ERR(priv->sysreg)) { | ||
81 | dev_err(host->dev, "regmap for altr,sys-mgr lookup failed.\n"); | ||
82 | return PTR_ERR(priv->sysreg); | ||
83 | } | ||
84 | |||
85 | ret = of_property_read_u32(np, "altr,dw-mshc-ciu-div", &div); | ||
86 | if (ret) | ||
87 | dev_info(host->dev, "No dw-mshc-ciu-div specified, assuming 1"); | ||
88 | priv->ciu_div = div; | ||
89 | |||
90 | ret = of_property_read_u32_array(np, | ||
91 | "altr,dw-mshc-sdr-timing", timing, 2); | ||
92 | if (ret) | ||
93 | return ret; | ||
94 | |||
95 | priv->hs_timing = SYSMGR_SDMMC_CTRL_SET(timing[0], timing[1]); | ||
96 | host->priv = priv; | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static const struct dw_mci_drv_data socfpga_drv_data = { | ||
101 | .init = dw_mci_socfpga_priv_init, | ||
102 | .setup_clock = dw_mci_socfpga_setup_clock, | ||
103 | .prepare_command = dw_mci_socfpga_prepare_command, | ||
104 | .parse_dt = dw_mci_socfpga_parse_dt, | ||
105 | }; | ||
106 | |||
107 | static const struct of_device_id dw_mci_socfpga_match[] = { | ||
108 | { .compatible = "altr,socfpga-dw-mshc", | ||
109 | .data = &socfpga_drv_data, }, | ||
110 | {}, | ||
111 | }; | ||
112 | MODULE_DEVICE_TABLE(of, dw_mci_socfpga_match); | ||
113 | |||
114 | static int dw_mci_socfpga_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | const struct dw_mci_drv_data *drv_data; | ||
117 | const struct of_device_id *match; | ||
118 | |||
119 | match = of_match_node(dw_mci_socfpga_match, pdev->dev.of_node); | ||
120 | drv_data = match->data; | ||
121 | return dw_mci_pltfm_register(pdev, drv_data); | ||
122 | } | ||
123 | |||
124 | static struct platform_driver dw_mci_socfpga_pltfm_driver = { | ||
125 | .probe = dw_mci_socfpga_probe, | ||
126 | .remove = __exit_p(dw_mci_pltfm_remove), | ||
127 | .driver = { | ||
128 | .name = "dwmmc_socfpga", | ||
129 | .of_match_table = dw_mci_socfpga_match, | ||
130 | .pm = &dw_mci_pltfm_pmops, | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | module_platform_driver(dw_mci_socfpga_pltfm_driver); | ||
135 | |||
136 | MODULE_DESCRIPTION("Altera SOCFPGA Specific DW-MSHC Driver Extension"); | ||
137 | MODULE_LICENSE("GPL v2"); | ||
138 | MODULE_ALIAS("platform:dwmmc-socfpga"); | ||
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index c204b7d1532c..cced599d5aeb 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -1345,7 +1345,7 @@ static void dw_mci_tasklet_func(unsigned long priv) | |||
1345 | 1345 | ||
1346 | if (!err) { | 1346 | if (!err) { |
1347 | if (!data->stop || mrq->sbc) { | 1347 | if (!data->stop || mrq->sbc) { |
1348 | if (mrq->sbc) | 1348 | if (mrq->sbc && data->stop) |
1349 | data->stop->error = 0; | 1349 | data->stop->error = 0; |
1350 | dw_mci_request_end(host, mrq); | 1350 | dw_mci_request_end(host, mrq); |
1351 | goto unlock; | 1351 | goto unlock; |
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 6bf24ab917e6..68349779c396 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
@@ -185,7 +185,7 @@ | |||
185 | 185 | ||
186 | extern int dw_mci_probe(struct dw_mci *host); | 186 | extern int dw_mci_probe(struct dw_mci *host); |
187 | extern void dw_mci_remove(struct dw_mci *host); | 187 | extern void dw_mci_remove(struct dw_mci *host); |
188 | #ifdef CONFIG_PM | 188 | #ifdef CONFIG_PM_SLEEP |
189 | extern int dw_mci_suspend(struct dw_mci *host); | 189 | extern int dw_mci_suspend(struct dw_mci *host); |
190 | extern int dw_mci_resume(struct dw_mci *host); | 190 | extern int dw_mci_resume(struct dw_mci *host); |
191 | #endif | 191 | #endif |
@@ -244,6 +244,7 @@ struct dw_mci_tuning_data { | |||
244 | * @prepare_command: handle CMD register extensions. | 244 | * @prepare_command: handle CMD register extensions. |
245 | * @set_ios: handle bus specific extensions. | 245 | * @set_ios: handle bus specific extensions. |
246 | * @parse_dt: parse implementation specific device tree properties. | 246 | * @parse_dt: parse implementation specific device tree properties. |
247 | * @execute_tuning: implementation specific tuning procedure. | ||
247 | * | 248 | * |
248 | * Provide controller implementation specific extensions. The usage of this | 249 | * Provide controller implementation specific extensions. The usage of this |
249 | * data structure is fully optional and usage of each member in this structure | 250 | * data structure is fully optional and usage of each member in this structure |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b93122636531..771c60ab4a32 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -921,6 +921,29 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, | |||
921 | { | 921 | { |
922 | void __iomem *base = host->base; | 922 | void __iomem *base = host->base; |
923 | bool sbc = (cmd == host->mrq->sbc); | 923 | bool sbc = (cmd == host->mrq->sbc); |
924 | bool busy_resp = host->variant->busy_detect && | ||
925 | (cmd->flags & MMC_RSP_BUSY); | ||
926 | |||
927 | /* Check if we need to wait for busy completion. */ | ||
928 | if (host->busy_status && (status & MCI_ST_CARDBUSY)) | ||
929 | return; | ||
930 | |||
931 | /* Enable busy completion if needed and supported. */ | ||
932 | if (!host->busy_status && busy_resp && | ||
933 | !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && | ||
934 | (readl(base + MMCISTATUS) & MCI_ST_CARDBUSY)) { | ||
935 | writel(readl(base + MMCIMASK0) | MCI_ST_BUSYEND, | ||
936 | base + MMCIMASK0); | ||
937 | host->busy_status = status & (MCI_CMDSENT|MCI_CMDRESPEND); | ||
938 | return; | ||
939 | } | ||
940 | |||
941 | /* At busy completion, mask the IRQ and complete the request. */ | ||
942 | if (host->busy_status) { | ||
943 | writel(readl(base + MMCIMASK0) & ~MCI_ST_BUSYEND, | ||
944 | base + MMCIMASK0); | ||
945 | host->busy_status = 0; | ||
946 | } | ||
924 | 947 | ||
925 | host->cmd = NULL; | 948 | host->cmd = NULL; |
926 | 949 | ||
@@ -1139,20 +1162,30 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) | |||
1139 | status &= ~MCI_IRQ1MASK; | 1162 | status &= ~MCI_IRQ1MASK; |
1140 | } | 1163 | } |
1141 | 1164 | ||
1165 | /* | ||
1166 | * We intentionally clear the MCI_ST_CARDBUSY IRQ here (if it's | ||
1167 | * enabled) since the HW seems to be triggering the IRQ on both | ||
1168 | * edges while monitoring DAT0 for busy completion. | ||
1169 | */ | ||
1142 | status &= readl(host->base + MMCIMASK0); | 1170 | status &= readl(host->base + MMCIMASK0); |
1143 | writel(status, host->base + MMCICLEAR); | 1171 | writel(status, host->base + MMCICLEAR); |
1144 | 1172 | ||
1145 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); | 1173 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); |
1146 | 1174 | ||
1175 | cmd = host->cmd; | ||
1176 | if ((status|host->busy_status) & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT| | ||
1177 | MCI_CMDSENT|MCI_CMDRESPEND) && cmd) | ||
1178 | mmci_cmd_irq(host, cmd, status); | ||
1179 | |||
1147 | data = host->data; | 1180 | data = host->data; |
1148 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| | 1181 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| |
1149 | MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| | 1182 | MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| |
1150 | MCI_DATABLOCKEND) && data) | 1183 | MCI_DATABLOCKEND) && data) |
1151 | mmci_data_irq(host, data, status); | 1184 | mmci_data_irq(host, data, status); |
1152 | 1185 | ||
1153 | cmd = host->cmd; | 1186 | /* Don't poll for busy completion in irq context. */ |
1154 | if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd) | 1187 | if (host->busy_status) |
1155 | mmci_cmd_irq(host, cmd, status); | 1188 | status &= ~MCI_ST_CARDBUSY; |
1156 | 1189 | ||
1157 | ret = 1; | 1190 | ret = 1; |
1158 | } while (status); | 1191 | } while (status); |
@@ -1503,12 +1536,6 @@ static int mmci_probe(struct amba_device *dev, | |||
1503 | goto clk_disable; | 1536 | goto clk_disable; |
1504 | } | 1537 | } |
1505 | 1538 | ||
1506 | if (variant->busy_detect) { | ||
1507 | mmci_ops.card_busy = mmci_card_busy; | ||
1508 | mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE); | ||
1509 | } | ||
1510 | |||
1511 | mmc->ops = &mmci_ops; | ||
1512 | /* | 1539 | /* |
1513 | * The ARM and ST versions of the block have slightly different | 1540 | * The ARM and ST versions of the block have slightly different |
1514 | * clock divider equations which means that the minimum divider | 1541 | * clock divider equations which means that the minimum divider |
@@ -1542,6 +1569,15 @@ static int mmci_probe(struct amba_device *dev, | |||
1542 | mmc->caps = plat->capabilities; | 1569 | mmc->caps = plat->capabilities; |
1543 | mmc->caps2 = plat->capabilities2; | 1570 | mmc->caps2 = plat->capabilities2; |
1544 | 1571 | ||
1572 | if (variant->busy_detect) { | ||
1573 | mmci_ops.card_busy = mmci_card_busy; | ||
1574 | mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE); | ||
1575 | mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; | ||
1576 | mmc->max_busy_timeout = 0; | ||
1577 | } | ||
1578 | |||
1579 | mmc->ops = &mmci_ops; | ||
1580 | |||
1545 | /* We support these PM capabilities. */ | 1581 | /* We support these PM capabilities. */ |
1546 | mmc->pm_caps = MMC_PM_KEEP_POWER; | 1582 | mmc->pm_caps = MMC_PM_KEEP_POWER; |
1547 | 1583 | ||
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 84c0e59b792a..58b1b8896bf2 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -140,6 +140,7 @@ | |||
140 | /* Extended status bits for the ST Micro variants */ | 140 | /* Extended status bits for the ST Micro variants */ |
141 | #define MCI_ST_SDIOITMASK (1 << 22) | 141 | #define MCI_ST_SDIOITMASK (1 << 22) |
142 | #define MCI_ST_CEATAENDMASK (1 << 23) | 142 | #define MCI_ST_CEATAENDMASK (1 << 23) |
143 | #define MCI_ST_BUSYEND (1 << 24) | ||
143 | 144 | ||
144 | #define MMCIMASK1 0x040 | 145 | #define MMCIMASK1 0x040 |
145 | #define MMCIFIFOCNT 0x048 | 146 | #define MMCIFIFOCNT 0x048 |
@@ -187,6 +188,7 @@ struct mmci_host { | |||
187 | u32 pwr_reg; | 188 | u32 pwr_reg; |
188 | u32 clk_reg; | 189 | u32 clk_reg; |
189 | u32 datactrl_reg; | 190 | u32 datactrl_reg; |
191 | u32 busy_status; | ||
190 | bool vqmmc_enabled; | 192 | bool vqmmc_enabled; |
191 | struct mmci_platform_data *plat; | 193 | struct mmci_platform_data *plat; |
192 | struct variant_data *variant; | 194 | struct variant_data *variant; |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 98b6b6ef7e5c..5c2e58b29305 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/omap-dma.h> | 26 | #include <linux/omap-dma.h> |
27 | #include <linux/mmc/host.h> | 27 | #include <linux/mmc/host.h> |
28 | #include <linux/mmc/card.h> | 28 | #include <linux/mmc/card.h> |
29 | #include <linux/mmc/mmc.h> | ||
29 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
30 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
@@ -130,7 +131,6 @@ struct mmc_omap_host { | |||
130 | u32 dma_rx_burst; | 131 | u32 dma_rx_burst; |
131 | struct dma_chan *dma_tx; | 132 | struct dma_chan *dma_tx; |
132 | u32 dma_tx_burst; | 133 | u32 dma_tx_burst; |
133 | struct resource *mem_res; | ||
134 | void __iomem *virt_base; | 134 | void __iomem *virt_base; |
135 | unsigned int phys_base; | 135 | unsigned int phys_base; |
136 | int irq; | 136 | int irq; |
@@ -153,7 +153,6 @@ struct mmc_omap_host { | |||
153 | u32 total_bytes_left; | 153 | u32 total_bytes_left; |
154 | 154 | ||
155 | unsigned features; | 155 | unsigned features; |
156 | unsigned use_dma:1; | ||
157 | unsigned brs_received:1, dma_done:1; | 156 | unsigned brs_received:1, dma_done:1; |
158 | unsigned dma_in_use:1; | 157 | unsigned dma_in_use:1; |
159 | spinlock_t dma_lock; | 158 | spinlock_t dma_lock; |
@@ -338,6 +337,7 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) | |||
338 | u32 cmdreg; | 337 | u32 cmdreg; |
339 | u32 resptype; | 338 | u32 resptype; |
340 | u32 cmdtype; | 339 | u32 cmdtype; |
340 | u16 irq_mask; | ||
341 | 341 | ||
342 | host->cmd = cmd; | 342 | host->cmd = cmd; |
343 | 343 | ||
@@ -390,12 +390,14 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) | |||
390 | OMAP_MMC_WRITE(host, CTO, 200); | 390 | OMAP_MMC_WRITE(host, CTO, 200); |
391 | OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff); | 391 | OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff); |
392 | OMAP_MMC_WRITE(host, ARGH, cmd->arg >> 16); | 392 | OMAP_MMC_WRITE(host, ARGH, cmd->arg >> 16); |
393 | OMAP_MMC_WRITE(host, IE, | 393 | irq_mask = OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL | |
394 | OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL | | 394 | OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT | |
395 | OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT | | 395 | OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT | |
396 | OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT | | 396 | OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR | |
397 | OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR | | 397 | OMAP_MMC_STAT_END_OF_DATA; |
398 | OMAP_MMC_STAT_END_OF_DATA); | 398 | if (cmd->opcode == MMC_ERASE) |
399 | irq_mask &= ~OMAP_MMC_STAT_DATA_TOUT; | ||
400 | OMAP_MMC_WRITE(host, IE, irq_mask); | ||
399 | OMAP_MMC_WRITE(host, CMD, cmdreg); | 401 | OMAP_MMC_WRITE(host, CMD, cmdreg); |
400 | } | 402 | } |
401 | 403 | ||
@@ -945,7 +947,7 @@ static void | |||
945 | mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) | 947 | mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) |
946 | { | 948 | { |
947 | struct mmc_data *data = req->data; | 949 | struct mmc_data *data = req->data; |
948 | int i, use_dma, block_size; | 950 | int i, use_dma = 1, block_size; |
949 | unsigned sg_len; | 951 | unsigned sg_len; |
950 | 952 | ||
951 | host->data = data; | 953 | host->data = data; |
@@ -970,13 +972,10 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) | |||
970 | sg_len = (data->blocks == 1) ? 1 : data->sg_len; | 972 | sg_len = (data->blocks == 1) ? 1 : data->sg_len; |
971 | 973 | ||
972 | /* Only do DMA for entire blocks */ | 974 | /* Only do DMA for entire blocks */ |
973 | use_dma = host->use_dma; | 975 | for (i = 0; i < sg_len; i++) { |
974 | if (use_dma) { | 976 | if ((data->sg[i].length % block_size) != 0) { |
975 | for (i = 0; i < sg_len; i++) { | 977 | use_dma = 0; |
976 | if ((data->sg[i].length % block_size) != 0) { | 978 | break; |
977 | use_dma = 0; | ||
978 | break; | ||
979 | } | ||
980 | } | 979 | } |
981 | } | 980 | } |
982 | 981 | ||
@@ -1239,7 +1238,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) | |||
1239 | 1238 | ||
1240 | mmc->caps = 0; | 1239 | mmc->caps = 0; |
1241 | if (host->pdata->slots[id].wires >= 4) | 1240 | if (host->pdata->slots[id].wires >= 4) |
1242 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 1241 | mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_ERASE; |
1243 | 1242 | ||
1244 | mmc->ops = &mmc_omap_ops; | 1243 | mmc->ops = &mmc_omap_ops; |
1245 | mmc->f_min = 400000; | 1244 | mmc->f_min = 400000; |
@@ -1262,6 +1261,13 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) | |||
1262 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 1261 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
1263 | mmc->max_seg_size = mmc->max_req_size; | 1262 | mmc->max_seg_size = mmc->max_req_size; |
1264 | 1263 | ||
1264 | if (slot->pdata->get_cover_state != NULL) { | ||
1265 | setup_timer(&slot->cover_timer, mmc_omap_cover_timer, | ||
1266 | (unsigned long)slot); | ||
1267 | tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, | ||
1268 | (unsigned long)slot); | ||
1269 | } | ||
1270 | |||
1265 | r = mmc_add_host(mmc); | 1271 | r = mmc_add_host(mmc); |
1266 | if (r < 0) | 1272 | if (r < 0) |
1267 | goto err_remove_host; | 1273 | goto err_remove_host; |
@@ -1278,11 +1284,6 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) | |||
1278 | &dev_attr_cover_switch); | 1284 | &dev_attr_cover_switch); |
1279 | if (r < 0) | 1285 | if (r < 0) |
1280 | goto err_remove_slot_name; | 1286 | goto err_remove_slot_name; |
1281 | |||
1282 | setup_timer(&slot->cover_timer, mmc_omap_cover_timer, | ||
1283 | (unsigned long)slot); | ||
1284 | tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, | ||
1285 | (unsigned long)slot); | ||
1286 | tasklet_schedule(&slot->cover_tasklet); | 1287 | tasklet_schedule(&slot->cover_tasklet); |
1287 | } | 1288 | } |
1288 | 1289 | ||
@@ -1333,21 +1334,19 @@ static int mmc_omap_probe(struct platform_device *pdev) | |||
1333 | return -EPROBE_DEFER; | 1334 | return -EPROBE_DEFER; |
1334 | } | 1335 | } |
1335 | 1336 | ||
1336 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1337 | host = devm_kzalloc(&pdev->dev, sizeof(struct mmc_omap_host), |
1338 | GFP_KERNEL); | ||
1339 | if (host == NULL) | ||
1340 | return -ENOMEM; | ||
1341 | |||
1337 | irq = platform_get_irq(pdev, 0); | 1342 | irq = platform_get_irq(pdev, 0); |
1338 | if (res == NULL || irq < 0) | 1343 | if (irq < 0) |
1339 | return -ENXIO; | 1344 | return -ENXIO; |
1340 | 1345 | ||
1341 | res = request_mem_region(res->start, resource_size(res), | 1346 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1342 | pdev->name); | 1347 | host->virt_base = devm_ioremap_resource(&pdev->dev, res); |
1343 | if (res == NULL) | 1348 | if (IS_ERR(host->virt_base)) |
1344 | return -EBUSY; | 1349 | return PTR_ERR(host->virt_base); |
1345 | |||
1346 | host = kzalloc(sizeof(struct mmc_omap_host), GFP_KERNEL); | ||
1347 | if (host == NULL) { | ||
1348 | ret = -ENOMEM; | ||
1349 | goto err_free_mem_region; | ||
1350 | } | ||
1351 | 1350 | ||
1352 | INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work); | 1351 | INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work); |
1353 | INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work); | 1352 | INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work); |
@@ -1369,20 +1368,11 @@ static int mmc_omap_probe(struct platform_device *pdev) | |||
1369 | platform_set_drvdata(pdev, host); | 1368 | platform_set_drvdata(pdev, host); |
1370 | 1369 | ||
1371 | host->id = pdev->id; | 1370 | host->id = pdev->id; |
1372 | host->mem_res = res; | ||
1373 | host->irq = irq; | ||
1374 | host->use_dma = 1; | ||
1375 | host->irq = irq; | 1371 | host->irq = irq; |
1376 | host->phys_base = host->mem_res->start; | 1372 | host->phys_base = res->start; |
1377 | host->virt_base = ioremap(res->start, resource_size(res)); | ||
1378 | if (!host->virt_base) | ||
1379 | goto err_ioremap; | ||
1380 | |||
1381 | host->iclk = clk_get(&pdev->dev, "ick"); | 1373 | host->iclk = clk_get(&pdev->dev, "ick"); |
1382 | if (IS_ERR(host->iclk)) { | 1374 | if (IS_ERR(host->iclk)) |
1383 | ret = PTR_ERR(host->iclk); | 1375 | return PTR_ERR(host->iclk); |
1384 | goto err_free_mmc_host; | ||
1385 | } | ||
1386 | clk_enable(host->iclk); | 1376 | clk_enable(host->iclk); |
1387 | 1377 | ||
1388 | host->fclk = clk_get(&pdev->dev, "fck"); | 1378 | host->fclk = clk_get(&pdev->dev, "fck"); |
@@ -1460,12 +1450,6 @@ err_free_dma: | |||
1460 | err_free_iclk: | 1450 | err_free_iclk: |
1461 | clk_disable(host->iclk); | 1451 | clk_disable(host->iclk); |
1462 | clk_put(host->iclk); | 1452 | clk_put(host->iclk); |
1463 | err_free_mmc_host: | ||
1464 | iounmap(host->virt_base); | ||
1465 | err_ioremap: | ||
1466 | kfree(host); | ||
1467 | err_free_mem_region: | ||
1468 | release_mem_region(res->start, resource_size(res)); | ||
1469 | return ret; | 1453 | return ret; |
1470 | } | 1454 | } |
1471 | 1455 | ||
@@ -1493,13 +1477,8 @@ static int mmc_omap_remove(struct platform_device *pdev) | |||
1493 | if (host->dma_rx) | 1477 | if (host->dma_rx) |
1494 | dma_release_channel(host->dma_rx); | 1478 | dma_release_channel(host->dma_rx); |
1495 | 1479 | ||
1496 | iounmap(host->virt_base); | ||
1497 | release_mem_region(pdev->resource[0].start, | ||
1498 | pdev->resource[0].end - pdev->resource[0].start + 1); | ||
1499 | destroy_workqueue(host->mmc_omap_wq); | 1480 | destroy_workqueue(host->mmc_omap_wq); |
1500 | 1481 | ||
1501 | kfree(host); | ||
1502 | |||
1503 | return 0; | 1482 | return 0; |
1504 | } | 1483 | } |
1505 | 1484 | ||
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index dbd32ad3b749..e91ee21549d0 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -45,6 +45,7 @@ | |||
45 | /* OMAP HSMMC Host Controller Registers */ | 45 | /* OMAP HSMMC Host Controller Registers */ |
46 | #define OMAP_HSMMC_SYSSTATUS 0x0014 | 46 | #define OMAP_HSMMC_SYSSTATUS 0x0014 |
47 | #define OMAP_HSMMC_CON 0x002C | 47 | #define OMAP_HSMMC_CON 0x002C |
48 | #define OMAP_HSMMC_SDMASA 0x0100 | ||
48 | #define OMAP_HSMMC_BLK 0x0104 | 49 | #define OMAP_HSMMC_BLK 0x0104 |
49 | #define OMAP_HSMMC_ARG 0x0108 | 50 | #define OMAP_HSMMC_ARG 0x0108 |
50 | #define OMAP_HSMMC_CMD 0x010C | 51 | #define OMAP_HSMMC_CMD 0x010C |
@@ -58,6 +59,7 @@ | |||
58 | #define OMAP_HSMMC_STAT 0x0130 | 59 | #define OMAP_HSMMC_STAT 0x0130 |
59 | #define OMAP_HSMMC_IE 0x0134 | 60 | #define OMAP_HSMMC_IE 0x0134 |
60 | #define OMAP_HSMMC_ISE 0x0138 | 61 | #define OMAP_HSMMC_ISE 0x0138 |
62 | #define OMAP_HSMMC_AC12 0x013C | ||
61 | #define OMAP_HSMMC_CAPA 0x0140 | 63 | #define OMAP_HSMMC_CAPA 0x0140 |
62 | 64 | ||
63 | #define VS18 (1 << 26) | 65 | #define VS18 (1 << 26) |
@@ -81,6 +83,7 @@ | |||
81 | #define DTO_MASK 0x000F0000 | 83 | #define DTO_MASK 0x000F0000 |
82 | #define DTO_SHIFT 16 | 84 | #define DTO_SHIFT 16 |
83 | #define INIT_STREAM (1 << 1) | 85 | #define INIT_STREAM (1 << 1) |
86 | #define ACEN_ACMD23 (2 << 2) | ||
84 | #define DP_SELECT (1 << 21) | 87 | #define DP_SELECT (1 << 21) |
85 | #define DDIR (1 << 4) | 88 | #define DDIR (1 << 4) |
86 | #define DMAE 0x1 | 89 | #define DMAE 0x1 |
@@ -97,7 +100,6 @@ | |||
97 | #define SRC (1 << 25) | 100 | #define SRC (1 << 25) |
98 | #define SRD (1 << 26) | 101 | #define SRD (1 << 26) |
99 | #define SOFTRESET (1 << 1) | 102 | #define SOFTRESET (1 << 1) |
100 | #define RESETDONE (1 << 0) | ||
101 | 103 | ||
102 | /* Interrupt masks for IE and ISE register */ | 104 | /* Interrupt masks for IE and ISE register */ |
103 | #define CC_EN (1 << 0) | 105 | #define CC_EN (1 << 0) |
@@ -112,13 +114,21 @@ | |||
112 | #define DTO_EN (1 << 20) | 114 | #define DTO_EN (1 << 20) |
113 | #define DCRC_EN (1 << 21) | 115 | #define DCRC_EN (1 << 21) |
114 | #define DEB_EN (1 << 22) | 116 | #define DEB_EN (1 << 22) |
117 | #define ACE_EN (1 << 24) | ||
115 | #define CERR_EN (1 << 28) | 118 | #define CERR_EN (1 << 28) |
116 | #define BADA_EN (1 << 29) | 119 | #define BADA_EN (1 << 29) |
117 | 120 | ||
118 | #define INT_EN_MASK (BADA_EN | CERR_EN | DEB_EN | DCRC_EN |\ | 121 | #define INT_EN_MASK (BADA_EN | CERR_EN | ACE_EN | DEB_EN | DCRC_EN |\ |
119 | DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \ | 122 | DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \ |
120 | BRR_EN | BWR_EN | TC_EN | CC_EN) | 123 | BRR_EN | BWR_EN | TC_EN | CC_EN) |
121 | 124 | ||
125 | #define CNI (1 << 7) | ||
126 | #define ACIE (1 << 4) | ||
127 | #define ACEB (1 << 3) | ||
128 | #define ACCE (1 << 2) | ||
129 | #define ACTO (1 << 1) | ||
130 | #define ACNE (1 << 0) | ||
131 | |||
122 | #define MMC_AUTOSUSPEND_DELAY 100 | 132 | #define MMC_AUTOSUSPEND_DELAY 100 |
123 | #define MMC_TIMEOUT_MS 20 /* 20 mSec */ | 133 | #define MMC_TIMEOUT_MS 20 /* 20 mSec */ |
124 | #define MMC_TIMEOUT_US 20000 /* 20000 micro Sec */ | 134 | #define MMC_TIMEOUT_US 20000 /* 20000 micro Sec */ |
@@ -126,6 +136,11 @@ | |||
126 | #define OMAP_MMC_MAX_CLOCK 52000000 | 136 | #define OMAP_MMC_MAX_CLOCK 52000000 |
127 | #define DRIVER_NAME "omap_hsmmc" | 137 | #define DRIVER_NAME "omap_hsmmc" |
128 | 138 | ||
139 | #define VDD_1V8 1800000 /* 180000 uV */ | ||
140 | #define VDD_3V0 3000000 /* 300000 uV */ | ||
141 | #define VDD_165_195 (ffs(MMC_VDD_165_195) - 1) | ||
142 | |||
143 | #define AUTO_CMD23 (1 << 1) /* Auto CMD23 support */ | ||
129 | /* | 144 | /* |
130 | * One controller can have multiple slots, like on some omap boards using | 145 | * One controller can have multiple slots, like on some omap boards using |
131 | * omap.c controller driver. Luckily this is not currently done on any known | 146 | * omap.c controller driver. Luckily this is not currently done on any known |
@@ -164,7 +179,8 @@ struct omap_hsmmc_host { | |||
164 | */ | 179 | */ |
165 | struct regulator *vcc; | 180 | struct regulator *vcc; |
166 | struct regulator *vcc_aux; | 181 | struct regulator *vcc_aux; |
167 | int pbias_disable; | 182 | struct regulator *pbias; |
183 | bool pbias_enabled; | ||
168 | void __iomem *base; | 184 | void __iomem *base; |
169 | resource_size_t mapbase; | 185 | resource_size_t mapbase; |
170 | spinlock_t irq_lock; /* Prevent races with irq handler */ | 186 | spinlock_t irq_lock; /* Prevent races with irq handler */ |
@@ -188,10 +204,19 @@ struct omap_hsmmc_host { | |||
188 | int reqs_blocked; | 204 | int reqs_blocked; |
189 | int use_reg; | 205 | int use_reg; |
190 | int req_in_progress; | 206 | int req_in_progress; |
207 | unsigned long clk_rate; | ||
208 | unsigned int flags; | ||
191 | struct omap_hsmmc_next next_data; | 209 | struct omap_hsmmc_next next_data; |
192 | struct omap_mmc_platform_data *pdata; | 210 | struct omap_mmc_platform_data *pdata; |
193 | }; | 211 | }; |
194 | 212 | ||
213 | struct omap_mmc_of_data { | ||
214 | u32 reg_offset; | ||
215 | u8 controller_flags; | ||
216 | }; | ||
217 | |||
218 | static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); | ||
219 | |||
195 | static int omap_hsmmc_card_detect(struct device *dev, int slot) | 220 | static int omap_hsmmc_card_detect(struct device *dev, int slot) |
196 | { | 221 | { |
197 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 222 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
@@ -261,17 +286,19 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
261 | */ | 286 | */ |
262 | if (!host->vcc) | 287 | if (!host->vcc) |
263 | return 0; | 288 | return 0; |
264 | /* | ||
265 | * With DT, never turn OFF the regulator for MMC1. This is because | ||
266 | * the pbias cell programming support is still missing when | ||
267 | * booting with Device tree | ||
268 | */ | ||
269 | if (host->pbias_disable && !vdd) | ||
270 | return 0; | ||
271 | 289 | ||
272 | if (mmc_slot(host).before_set_reg) | 290 | if (mmc_slot(host).before_set_reg) |
273 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); | 291 | mmc_slot(host).before_set_reg(dev, slot, power_on, vdd); |
274 | 292 | ||
293 | if (host->pbias) { | ||
294 | if (host->pbias_enabled == 1) { | ||
295 | ret = regulator_disable(host->pbias); | ||
296 | if (!ret) | ||
297 | host->pbias_enabled = 0; | ||
298 | } | ||
299 | regulator_set_voltage(host->pbias, VDD_3V0, VDD_3V0); | ||
300 | } | ||
301 | |||
275 | /* | 302 | /* |
276 | * Assume Vcc regulator is used only to power the card ... OMAP | 303 | * Assume Vcc regulator is used only to power the card ... OMAP |
277 | * VDDS is used to power the pins, optionally with a transceiver to | 304 | * VDDS is used to power the pins, optionally with a transceiver to |
@@ -286,11 +313,12 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
286 | * chips/cards need an interface voltage rail too. | 313 | * chips/cards need an interface voltage rail too. |
287 | */ | 314 | */ |
288 | if (power_on) { | 315 | if (power_on) { |
289 | ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); | 316 | if (host->vcc) |
317 | ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); | ||
290 | /* Enable interface voltage rail, if needed */ | 318 | /* Enable interface voltage rail, if needed */ |
291 | if (ret == 0 && host->vcc_aux) { | 319 | if (ret == 0 && host->vcc_aux) { |
292 | ret = regulator_enable(host->vcc_aux); | 320 | ret = regulator_enable(host->vcc_aux); |
293 | if (ret < 0) | 321 | if (ret < 0 && host->vcc) |
294 | ret = mmc_regulator_set_ocr(host->mmc, | 322 | ret = mmc_regulator_set_ocr(host->mmc, |
295 | host->vcc, 0); | 323 | host->vcc, 0); |
296 | } | 324 | } |
@@ -298,16 +326,34 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, | |||
298 | /* Shut down the rail */ | 326 | /* Shut down the rail */ |
299 | if (host->vcc_aux) | 327 | if (host->vcc_aux) |
300 | ret = regulator_disable(host->vcc_aux); | 328 | ret = regulator_disable(host->vcc_aux); |
301 | if (!ret) { | 329 | if (host->vcc) { |
302 | /* Then proceed to shut down the local regulator */ | 330 | /* Then proceed to shut down the local regulator */ |
303 | ret = mmc_regulator_set_ocr(host->mmc, | 331 | ret = mmc_regulator_set_ocr(host->mmc, |
304 | host->vcc, 0); | 332 | host->vcc, 0); |
305 | } | 333 | } |
306 | } | 334 | } |
307 | 335 | ||
336 | if (host->pbias) { | ||
337 | if (vdd <= VDD_165_195) | ||
338 | ret = regulator_set_voltage(host->pbias, VDD_1V8, | ||
339 | VDD_1V8); | ||
340 | else | ||
341 | ret = regulator_set_voltage(host->pbias, VDD_3V0, | ||
342 | VDD_3V0); | ||
343 | if (ret < 0) | ||
344 | goto error_set_power; | ||
345 | |||
346 | if (host->pbias_enabled == 0) { | ||
347 | ret = regulator_enable(host->pbias); | ||
348 | if (!ret) | ||
349 | host->pbias_enabled = 1; | ||
350 | } | ||
351 | } | ||
352 | |||
308 | if (mmc_slot(host).after_set_reg) | 353 | if (mmc_slot(host).after_set_reg) |
309 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); | 354 | mmc_slot(host).after_set_reg(dev, slot, power_on, vdd); |
310 | 355 | ||
356 | error_set_power: | ||
311 | return ret; | 357 | return ret; |
312 | } | 358 | } |
313 | 359 | ||
@@ -316,12 +362,12 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
316 | struct regulator *reg; | 362 | struct regulator *reg; |
317 | int ocr_value = 0; | 363 | int ocr_value = 0; |
318 | 364 | ||
319 | reg = regulator_get(host->dev, "vmmc"); | 365 | reg = devm_regulator_get(host->dev, "vmmc"); |
320 | if (IS_ERR(reg)) { | 366 | if (IS_ERR(reg)) { |
321 | dev_err(host->dev, "vmmc regulator missing\n"); | 367 | dev_err(host->dev, "unable to get vmmc regulator %ld\n", |
368 | PTR_ERR(reg)); | ||
322 | return PTR_ERR(reg); | 369 | return PTR_ERR(reg); |
323 | } else { | 370 | } else { |
324 | mmc_slot(host).set_power = omap_hsmmc_set_power; | ||
325 | host->vcc = reg; | 371 | host->vcc = reg; |
326 | ocr_value = mmc_regulator_get_ocrmask(reg); | 372 | ocr_value = mmc_regulator_get_ocrmask(reg); |
327 | if (!mmc_slot(host).ocr_mask) { | 373 | if (!mmc_slot(host).ocr_mask) { |
@@ -334,31 +380,29 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
334 | return -EINVAL; | 380 | return -EINVAL; |
335 | } | 381 | } |
336 | } | 382 | } |
383 | } | ||
384 | mmc_slot(host).set_power = omap_hsmmc_set_power; | ||
337 | 385 | ||
338 | /* Allow an aux regulator */ | 386 | /* Allow an aux regulator */ |
339 | reg = regulator_get(host->dev, "vmmc_aux"); | 387 | reg = devm_regulator_get_optional(host->dev, "vmmc_aux"); |
340 | host->vcc_aux = IS_ERR(reg) ? NULL : reg; | 388 | host->vcc_aux = IS_ERR(reg) ? NULL : reg; |
341 | 389 | ||
342 | /* For eMMC do not power off when not in sleep state */ | 390 | reg = devm_regulator_get_optional(host->dev, "pbias"); |
343 | if (mmc_slot(host).no_regulator_off_init) | 391 | host->pbias = IS_ERR(reg) ? NULL : reg; |
344 | return 0; | ||
345 | /* | ||
346 | * UGLY HACK: workaround regulator framework bugs. | ||
347 | * When the bootloader leaves a supply active, it's | ||
348 | * initialized with zero usecount ... and we can't | ||
349 | * disable it without first enabling it. Until the | ||
350 | * framework is fixed, we need a workaround like this | ||
351 | * (which is safe for MMC, but not in general). | ||
352 | */ | ||
353 | if (regulator_is_enabled(host->vcc) > 0 || | ||
354 | (host->vcc_aux && regulator_is_enabled(host->vcc_aux))) { | ||
355 | int vdd = ffs(mmc_slot(host).ocr_mask) - 1; | ||
356 | 392 | ||
357 | mmc_slot(host).set_power(host->dev, host->slot_id, | 393 | /* For eMMC do not power off when not in sleep state */ |
358 | 1, vdd); | 394 | if (mmc_slot(host).no_regulator_off_init) |
359 | mmc_slot(host).set_power(host->dev, host->slot_id, | 395 | return 0; |
360 | 0, 0); | 396 | /* |
361 | } | 397 | * To disable boot_on regulator, enable regulator |
398 | * to increase usecount and then disable it. | ||
399 | */ | ||
400 | if ((host->vcc && regulator_is_enabled(host->vcc) > 0) || | ||
401 | (host->vcc_aux && regulator_is_enabled(host->vcc_aux))) { | ||
402 | int vdd = ffs(mmc_slot(host).ocr_mask) - 1; | ||
403 | |||
404 | mmc_slot(host).set_power(host->dev, host->slot_id, 1, vdd); | ||
405 | mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); | ||
362 | } | 406 | } |
363 | 407 | ||
364 | return 0; | 408 | return 0; |
@@ -366,8 +410,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
366 | 410 | ||
367 | static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) | 411 | static void omap_hsmmc_reg_put(struct omap_hsmmc_host *host) |
368 | { | 412 | { |
369 | regulator_put(host->vcc); | ||
370 | regulator_put(host->vcc_aux); | ||
371 | mmc_slot(host).set_power = NULL; | 413 | mmc_slot(host).set_power = NULL; |
372 | } | 414 | } |
373 | 415 | ||
@@ -605,9 +647,6 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) | |||
605 | u32 hctl, capa; | 647 | u32 hctl, capa; |
606 | unsigned long timeout; | 648 | unsigned long timeout; |
607 | 649 | ||
608 | if (!OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) | ||
609 | return 1; | ||
610 | |||
611 | if (host->con == OMAP_HSMMC_READ(host->base, CON) && | 650 | if (host->con == OMAP_HSMMC_READ(host->base, CON) && |
612 | host->hctl == OMAP_HSMMC_READ(host->base, HCTL) && | 651 | host->hctl == OMAP_HSMMC_READ(host->base, HCTL) && |
613 | host->sysctl == OMAP_HSMMC_READ(host->base, SYSCTL) && | 652 | host->sysctl == OMAP_HSMMC_READ(host->base, SYSCTL) && |
@@ -787,6 +826,11 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, | |||
787 | 826 | ||
788 | cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); | 827 | cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); |
789 | 828 | ||
829 | if ((host->flags & AUTO_CMD23) && mmc_op_multi(cmd->opcode) && | ||
830 | host->mrq->sbc) { | ||
831 | cmdreg |= ACEN_ACMD23; | ||
832 | OMAP_HSMMC_WRITE(host->base, SDMASA, host->mrq->sbc->arg); | ||
833 | } | ||
790 | if (data) { | 834 | if (data) { |
791 | cmdreg |= DP_SELECT | MSBS | BCE; | 835 | cmdreg |= DP_SELECT | MSBS | BCE; |
792 | if (data->flags & MMC_DATA_READ) | 836 | if (data->flags & MMC_DATA_READ) |
@@ -864,11 +908,10 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) | |||
864 | else | 908 | else |
865 | data->bytes_xfered = 0; | 909 | data->bytes_xfered = 0; |
866 | 910 | ||
867 | if (!data->stop) { | 911 | if (data->stop && (data->error || !host->mrq->sbc)) |
912 | omap_hsmmc_start_command(host, data->stop, NULL); | ||
913 | else | ||
868 | omap_hsmmc_request_done(host, data->mrq); | 914 | omap_hsmmc_request_done(host, data->mrq); |
869 | return; | ||
870 | } | ||
871 | omap_hsmmc_start_command(host, data->stop, NULL); | ||
872 | } | 915 | } |
873 | 916 | ||
874 | /* | 917 | /* |
@@ -879,6 +922,14 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) | |||
879 | { | 922 | { |
880 | host->cmd = NULL; | 923 | host->cmd = NULL; |
881 | 924 | ||
925 | if (host->mrq->sbc && (host->cmd == host->mrq->sbc) && | ||
926 | !host->mrq->sbc->error && !(host->flags & AUTO_CMD23)) { | ||
927 | omap_hsmmc_start_dma_transfer(host); | ||
928 | omap_hsmmc_start_command(host, host->mrq->cmd, | ||
929 | host->mrq->data); | ||
930 | return; | ||
931 | } | ||
932 | |||
882 | if (cmd->flags & MMC_RSP_PRESENT) { | 933 | if (cmd->flags & MMC_RSP_PRESENT) { |
883 | if (cmd->flags & MMC_RSP_136) { | 934 | if (cmd->flags & MMC_RSP_136) { |
884 | /* response type 2 */ | 935 | /* response type 2 */ |
@@ -892,7 +943,7 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) | |||
892 | } | 943 | } |
893 | } | 944 | } |
894 | if ((host->data == NULL && !host->response_busy) || cmd->error) | 945 | if ((host->data == NULL && !host->response_busy) || cmd->error) |
895 | omap_hsmmc_request_done(host, cmd->mrq); | 946 | omap_hsmmc_request_done(host, host->mrq); |
896 | } | 947 | } |
897 | 948 | ||
898 | /* | 949 | /* |
@@ -1015,6 +1066,7 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) | |||
1015 | { | 1066 | { |
1016 | struct mmc_data *data; | 1067 | struct mmc_data *data; |
1017 | int end_cmd = 0, end_trans = 0; | 1068 | int end_cmd = 0, end_trans = 0; |
1069 | int error = 0; | ||
1018 | 1070 | ||
1019 | data = host->data; | 1071 | data = host->data; |
1020 | dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); | 1072 | dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); |
@@ -1029,6 +1081,20 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) | |||
1029 | else if (status & (CCRC_EN | DCRC_EN)) | 1081 | else if (status & (CCRC_EN | DCRC_EN)) |
1030 | hsmmc_command_incomplete(host, -EILSEQ, end_cmd); | 1082 | hsmmc_command_incomplete(host, -EILSEQ, end_cmd); |
1031 | 1083 | ||
1084 | if (status & ACE_EN) { | ||
1085 | u32 ac12; | ||
1086 | ac12 = OMAP_HSMMC_READ(host->base, AC12); | ||
1087 | if (!(ac12 & ACNE) && host->mrq->sbc) { | ||
1088 | end_cmd = 1; | ||
1089 | if (ac12 & ACTO) | ||
1090 | error = -ETIMEDOUT; | ||
1091 | else if (ac12 & (ACCE | ACEB | ACIE)) | ||
1092 | error = -EILSEQ; | ||
1093 | host->mrq->sbc->error = error; | ||
1094 | hsmmc_command_incomplete(host, error, end_cmd); | ||
1095 | } | ||
1096 | dev_dbg(mmc_dev(host->mmc), "AC12 err: 0x%x\n", ac12); | ||
1097 | } | ||
1032 | if (host->data || host->response_busy) { | 1098 | if (host->data || host->response_busy) { |
1033 | end_trans = !end_cmd; | 1099 | end_trans = !end_cmd; |
1034 | host->response_busy = 0; | 1100 | host->response_busy = 0; |
@@ -1236,8 +1302,7 @@ static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host, | |||
1236 | } | 1302 | } |
1237 | 1303 | ||
1238 | /* Check if next job is already prepared */ | 1304 | /* Check if next job is already prepared */ |
1239 | if (next || | 1305 | if (next || data->host_cookie != host->next_data.cookie) { |
1240 | (!next && data->host_cookie != host->next_data.cookie)) { | ||
1241 | dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len, | 1306 | dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len, |
1242 | omap_hsmmc_get_dma_dir(host, data)); | 1307 | omap_hsmmc_get_dma_dir(host, data)); |
1243 | 1308 | ||
@@ -1262,7 +1327,7 @@ static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host, | |||
1262 | /* | 1327 | /* |
1263 | * Routine to configure and start DMA for the MMC card | 1328 | * Routine to configure and start DMA for the MMC card |
1264 | */ | 1329 | */ |
1265 | static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, | 1330 | static int omap_hsmmc_setup_dma_transfer(struct omap_hsmmc_host *host, |
1266 | struct mmc_request *req) | 1331 | struct mmc_request *req) |
1267 | { | 1332 | { |
1268 | struct dma_slave_config cfg; | 1333 | struct dma_slave_config cfg; |
@@ -1321,8 +1386,6 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, | |||
1321 | 1386 | ||
1322 | host->dma_ch = 1; | 1387 | host->dma_ch = 1; |
1323 | 1388 | ||
1324 | dma_async_issue_pending(chan); | ||
1325 | |||
1326 | return 0; | 1389 | return 0; |
1327 | } | 1390 | } |
1328 | 1391 | ||
@@ -1338,7 +1401,7 @@ static void set_data_timeout(struct omap_hsmmc_host *host, | |||
1338 | if (clkd == 0) | 1401 | if (clkd == 0) |
1339 | clkd = 1; | 1402 | clkd = 1; |
1340 | 1403 | ||
1341 | cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd); | 1404 | cycle_ns = 1000000000 / (host->clk_rate / clkd); |
1342 | timeout = timeout_ns / cycle_ns; | 1405 | timeout = timeout_ns / cycle_ns; |
1343 | timeout += timeout_clks; | 1406 | timeout += timeout_clks; |
1344 | if (timeout) { | 1407 | if (timeout) { |
@@ -1363,6 +1426,21 @@ static void set_data_timeout(struct omap_hsmmc_host *host, | |||
1363 | OMAP_HSMMC_WRITE(host->base, SYSCTL, reg); | 1426 | OMAP_HSMMC_WRITE(host->base, SYSCTL, reg); |
1364 | } | 1427 | } |
1365 | 1428 | ||
1429 | static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host) | ||
1430 | { | ||
1431 | struct mmc_request *req = host->mrq; | ||
1432 | struct dma_chan *chan; | ||
1433 | |||
1434 | if (!req->data) | ||
1435 | return; | ||
1436 | OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) | ||
1437 | | (req->data->blocks << 16)); | ||
1438 | set_data_timeout(host, req->data->timeout_ns, | ||
1439 | req->data->timeout_clks); | ||
1440 | chan = omap_hsmmc_get_dma_chan(host, req->data); | ||
1441 | dma_async_issue_pending(chan); | ||
1442 | } | ||
1443 | |||
1366 | /* | 1444 | /* |
1367 | * Configure block length for MMC/SD cards and initiate the transfer. | 1445 | * Configure block length for MMC/SD cards and initiate the transfer. |
1368 | */ | 1446 | */ |
@@ -1383,12 +1461,8 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) | |||
1383 | return 0; | 1461 | return 0; |
1384 | } | 1462 | } |
1385 | 1463 | ||
1386 | OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) | ||
1387 | | (req->data->blocks << 16)); | ||
1388 | set_data_timeout(host, req->data->timeout_ns, req->data->timeout_clks); | ||
1389 | |||
1390 | if (host->use_dma) { | 1464 | if (host->use_dma) { |
1391 | ret = omap_hsmmc_start_dma_transfer(host, req); | 1465 | ret = omap_hsmmc_setup_dma_transfer(host, req); |
1392 | if (ret != 0) { | 1466 | if (ret != 0) { |
1393 | dev_err(mmc_dev(host->mmc), "MMC start dma failure\n"); | 1467 | dev_err(mmc_dev(host->mmc), "MMC start dma failure\n"); |
1394 | return ret; | 1468 | return ret; |
@@ -1462,6 +1536,7 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) | |||
1462 | host->reqs_blocked = 0; | 1536 | host->reqs_blocked = 0; |
1463 | WARN_ON(host->mrq != NULL); | 1537 | WARN_ON(host->mrq != NULL); |
1464 | host->mrq = req; | 1538 | host->mrq = req; |
1539 | host->clk_rate = clk_get_rate(host->fclk); | ||
1465 | err = omap_hsmmc_prepare_data(host, req); | 1540 | err = omap_hsmmc_prepare_data(host, req); |
1466 | if (err) { | 1541 | if (err) { |
1467 | req->cmd->error = err; | 1542 | req->cmd->error = err; |
@@ -1471,7 +1546,12 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) | |||
1471 | mmc_request_done(mmc, req); | 1546 | mmc_request_done(mmc, req); |
1472 | return; | 1547 | return; |
1473 | } | 1548 | } |
1549 | if (req->sbc && !(host->flags & AUTO_CMD23)) { | ||
1550 | omap_hsmmc_start_command(host, req->sbc, NULL); | ||
1551 | return; | ||
1552 | } | ||
1474 | 1553 | ||
1554 | omap_hsmmc_start_dma_transfer(host); | ||
1475 | omap_hsmmc_start_command(host, req->cmd, req->data); | 1555 | omap_hsmmc_start_command(host, req->cmd, req->data); |
1476 | } | 1556 | } |
1477 | 1557 | ||
@@ -1509,13 +1589,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1509 | * of external transceiver; but they all handle 1.8V. | 1589 | * of external transceiver; but they all handle 1.8V. |
1510 | */ | 1590 | */ |
1511 | if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) && | 1591 | if ((OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET) && |
1512 | (ios->vdd == DUAL_VOLT_OCR_BIT) && | 1592 | (ios->vdd == DUAL_VOLT_OCR_BIT)) { |
1513 | /* | ||
1514 | * With pbias cell programming missing, this | ||
1515 | * can't be allowed on MMC1 when booting with device | ||
1516 | * tree. | ||
1517 | */ | ||
1518 | !host->pbias_disable) { | ||
1519 | /* | 1593 | /* |
1520 | * The mmc_select_voltage fn of the core does | 1594 | * The mmc_select_voltage fn of the core does |
1521 | * not seem to set the power_mode to | 1595 | * not seem to set the power_mode to |
@@ -1678,18 +1752,29 @@ static void omap_hsmmc_debugfs(struct mmc_host *mmc) | |||
1678 | #endif | 1752 | #endif |
1679 | 1753 | ||
1680 | #ifdef CONFIG_OF | 1754 | #ifdef CONFIG_OF |
1681 | static u16 omap4_reg_offset = 0x100; | 1755 | static const struct omap_mmc_of_data omap3_pre_es3_mmc_of_data = { |
1756 | /* See 35xx errata 2.1.1.128 in SPRZ278F */ | ||
1757 | .controller_flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ, | ||
1758 | }; | ||
1759 | |||
1760 | static const struct omap_mmc_of_data omap4_mmc_of_data = { | ||
1761 | .reg_offset = 0x100, | ||
1762 | }; | ||
1682 | 1763 | ||
1683 | static const struct of_device_id omap_mmc_of_match[] = { | 1764 | static const struct of_device_id omap_mmc_of_match[] = { |
1684 | { | 1765 | { |
1685 | .compatible = "ti,omap2-hsmmc", | 1766 | .compatible = "ti,omap2-hsmmc", |
1686 | }, | 1767 | }, |
1687 | { | 1768 | { |
1769 | .compatible = "ti,omap3-pre-es3-hsmmc", | ||
1770 | .data = &omap3_pre_es3_mmc_of_data, | ||
1771 | }, | ||
1772 | { | ||
1688 | .compatible = "ti,omap3-hsmmc", | 1773 | .compatible = "ti,omap3-hsmmc", |
1689 | }, | 1774 | }, |
1690 | { | 1775 | { |
1691 | .compatible = "ti,omap4-hsmmc", | 1776 | .compatible = "ti,omap4-hsmmc", |
1692 | .data = &omap4_reg_offset, | 1777 | .data = &omap4_mmc_of_data, |
1693 | }, | 1778 | }, |
1694 | {}, | 1779 | {}, |
1695 | }; | 1780 | }; |
@@ -1709,7 +1794,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1709 | 1794 | ||
1710 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 1795 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
1711 | if (!pdata) | 1796 | if (!pdata) |
1712 | return NULL; /* out of memory */ | 1797 | return ERR_PTR(-ENOMEM); /* out of memory */ |
1713 | 1798 | ||
1714 | if (of_find_property(np, "ti,dual-volt", NULL)) | 1799 | if (of_find_property(np, "ti,dual-volt", NULL)) |
1715 | pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; | 1800 | pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; |
@@ -1738,13 +1823,19 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1738 | if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) | 1823 | if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) |
1739 | pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT; | 1824 | pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT; |
1740 | 1825 | ||
1826 | if (of_find_property(np, "keep-power-in-suspend", NULL)) | ||
1827 | pdata->slots[0].pm_caps |= MMC_PM_KEEP_POWER; | ||
1828 | |||
1829 | if (of_find_property(np, "enable-sdio-wakeup", NULL)) | ||
1830 | pdata->slots[0].pm_caps |= MMC_PM_WAKE_SDIO_IRQ; | ||
1831 | |||
1741 | return pdata; | 1832 | return pdata; |
1742 | } | 1833 | } |
1743 | #else | 1834 | #else |
1744 | static inline struct omap_mmc_platform_data | 1835 | static inline struct omap_mmc_platform_data |
1745 | *of_get_hsmmc_pdata(struct device *dev) | 1836 | *of_get_hsmmc_pdata(struct device *dev) |
1746 | { | 1837 | { |
1747 | return NULL; | 1838 | return ERR_PTR(-EINVAL); |
1748 | } | 1839 | } |
1749 | #endif | 1840 | #endif |
1750 | 1841 | ||
@@ -1759,6 +1850,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
1759 | dma_cap_mask_t mask; | 1850 | dma_cap_mask_t mask; |
1760 | unsigned tx_req, rx_req; | 1851 | unsigned tx_req, rx_req; |
1761 | struct pinctrl *pinctrl; | 1852 | struct pinctrl *pinctrl; |
1853 | const struct omap_mmc_of_data *data; | ||
1762 | 1854 | ||
1763 | match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); | 1855 | match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); |
1764 | if (match) { | 1856 | if (match) { |
@@ -1768,8 +1860,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
1768 | return PTR_ERR(pdata); | 1860 | return PTR_ERR(pdata); |
1769 | 1861 | ||
1770 | if (match->data) { | 1862 | if (match->data) { |
1771 | const u16 *offsetp = match->data; | 1863 | data = match->data; |
1772 | pdata->reg_offset = *offsetp; | 1864 | pdata->reg_offset = data->reg_offset; |
1865 | pdata->controller_flags |= data->controller_flags; | ||
1773 | } | 1866 | } |
1774 | } | 1867 | } |
1775 | 1868 | ||
@@ -1814,6 +1907,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
1814 | host->base = ioremap(host->mapbase, SZ_4K); | 1907 | host->base = ioremap(host->mapbase, SZ_4K); |
1815 | host->power_mode = MMC_POWER_OFF; | 1908 | host->power_mode = MMC_POWER_OFF; |
1816 | host->next_data.cookie = 1; | 1909 | host->next_data.cookie = 1; |
1910 | host->pbias_enabled = 0; | ||
1817 | 1911 | ||
1818 | platform_set_drvdata(pdev, host); | 1912 | platform_set_drvdata(pdev, host); |
1819 | 1913 | ||
@@ -1847,10 +1941,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
1847 | 1941 | ||
1848 | omap_hsmmc_context_save(host); | 1942 | omap_hsmmc_context_save(host); |
1849 | 1943 | ||
1850 | /* This can be removed once we support PBIAS with DT */ | ||
1851 | if (host->dev->of_node && res->start == 0x4809c000) | ||
1852 | host->pbias_disable = 1; | ||
1853 | |||
1854 | host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); | 1944 | host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); |
1855 | /* | 1945 | /* |
1856 | * MMC can still work without debounce clock. | 1946 | * MMC can still work without debounce clock. |
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index c46feda07d56..5fb994f9a653 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -31,14 +31,9 @@ | |||
31 | #include <linux/mfd/rtsx_pci.h> | 31 | #include <linux/mfd/rtsx_pci.h> |
32 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
33 | 33 | ||
34 | /* SD Tuning Data Structure | 34 | struct realtek_next { |
35 | * Record continuous timing phase path | 35 | unsigned int sg_count; |
36 | */ | 36 | s32 cookie; |
37 | struct timing_phase_path { | ||
38 | int start; | ||
39 | int end; | ||
40 | int mid; | ||
41 | int len; | ||
42 | }; | 37 | }; |
43 | 38 | ||
44 | struct realtek_pci_sdmmc { | 39 | struct realtek_pci_sdmmc { |
@@ -46,9 +41,18 @@ struct realtek_pci_sdmmc { | |||
46 | struct rtsx_pcr *pcr; | 41 | struct rtsx_pcr *pcr; |
47 | struct mmc_host *mmc; | 42 | struct mmc_host *mmc; |
48 | struct mmc_request *mrq; | 43 | struct mmc_request *mrq; |
49 | 44 | struct mmc_command *cmd; | |
50 | struct mutex host_mutex; | 45 | struct mmc_data *data; |
51 | 46 | ||
47 | spinlock_t lock; | ||
48 | struct timer_list timer; | ||
49 | struct tasklet_struct cmd_tasklet; | ||
50 | struct tasklet_struct data_tasklet; | ||
51 | struct tasklet_struct finish_tasklet; | ||
52 | |||
53 | u8 rsp_type; | ||
54 | u8 rsp_len; | ||
55 | int sg_count; | ||
52 | u8 ssc_depth; | 56 | u8 ssc_depth; |
53 | unsigned int clock; | 57 | unsigned int clock; |
54 | bool vpclk; | 58 | bool vpclk; |
@@ -58,8 +62,13 @@ struct realtek_pci_sdmmc { | |||
58 | int power_state; | 62 | int power_state; |
59 | #define SDMMC_POWER_ON 1 | 63 | #define SDMMC_POWER_ON 1 |
60 | #define SDMMC_POWER_OFF 0 | 64 | #define SDMMC_POWER_OFF 0 |
65 | |||
66 | struct realtek_next next_data; | ||
61 | }; | 67 | }; |
62 | 68 | ||
69 | static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | ||
70 | struct mmc_request *mrq); | ||
71 | |||
63 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) | 72 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) |
64 | { | 73 | { |
65 | return &(host->pdev->dev); | 74 | return &(host->pdev->dev); |
@@ -96,6 +105,95 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) | |||
96 | #define sd_print_debug_regs(host) | 105 | #define sd_print_debug_regs(host) |
97 | #endif /* DEBUG */ | 106 | #endif /* DEBUG */ |
98 | 107 | ||
108 | static void sd_isr_done_transfer(struct platform_device *pdev) | ||
109 | { | ||
110 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | ||
111 | |||
112 | spin_lock(&host->lock); | ||
113 | if (host->cmd) | ||
114 | tasklet_schedule(&host->cmd_tasklet); | ||
115 | if (host->data) | ||
116 | tasklet_schedule(&host->data_tasklet); | ||
117 | spin_unlock(&host->lock); | ||
118 | } | ||
119 | |||
120 | static void sd_request_timeout(unsigned long host_addr) | ||
121 | { | ||
122 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
123 | unsigned long flags; | ||
124 | |||
125 | spin_lock_irqsave(&host->lock, flags); | ||
126 | |||
127 | if (!host->mrq) { | ||
128 | dev_err(sdmmc_dev(host), "error: no request exist\n"); | ||
129 | goto out; | ||
130 | } | ||
131 | |||
132 | if (host->cmd) | ||
133 | host->cmd->error = -ETIMEDOUT; | ||
134 | if (host->data) | ||
135 | host->data->error = -ETIMEDOUT; | ||
136 | |||
137 | dev_dbg(sdmmc_dev(host), "timeout for request\n"); | ||
138 | |||
139 | out: | ||
140 | tasklet_schedule(&host->finish_tasklet); | ||
141 | spin_unlock_irqrestore(&host->lock, flags); | ||
142 | } | ||
143 | |||
144 | static void sd_finish_request(unsigned long host_addr) | ||
145 | { | ||
146 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
147 | struct rtsx_pcr *pcr = host->pcr; | ||
148 | struct mmc_request *mrq; | ||
149 | struct mmc_command *cmd; | ||
150 | struct mmc_data *data; | ||
151 | unsigned long flags; | ||
152 | bool any_error; | ||
153 | |||
154 | spin_lock_irqsave(&host->lock, flags); | ||
155 | |||
156 | del_timer(&host->timer); | ||
157 | mrq = host->mrq; | ||
158 | if (!mrq) { | ||
159 | dev_err(sdmmc_dev(host), "error: no request need finish\n"); | ||
160 | goto out; | ||
161 | } | ||
162 | |||
163 | cmd = mrq->cmd; | ||
164 | data = mrq->data; | ||
165 | |||
166 | any_error = (mrq->sbc && mrq->sbc->error) || | ||
167 | (mrq->stop && mrq->stop->error) || | ||
168 | (cmd && cmd->error) || (data && data->error); | ||
169 | |||
170 | if (any_error) { | ||
171 | rtsx_pci_stop_cmd(pcr); | ||
172 | sd_clear_error(host); | ||
173 | } | ||
174 | |||
175 | if (data) { | ||
176 | if (any_error) | ||
177 | data->bytes_xfered = 0; | ||
178 | else | ||
179 | data->bytes_xfered = data->blocks * data->blksz; | ||
180 | |||
181 | if (!data->host_cookie) | ||
182 | rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, | ||
183 | data->flags & MMC_DATA_READ); | ||
184 | |||
185 | } | ||
186 | |||
187 | host->mrq = NULL; | ||
188 | host->cmd = NULL; | ||
189 | host->data = NULL; | ||
190 | |||
191 | out: | ||
192 | spin_unlock_irqrestore(&host->lock, flags); | ||
193 | mutex_unlock(&pcr->pcr_mutex); | ||
194 | mmc_request_done(host->mmc, mrq); | ||
195 | } | ||
196 | |||
99 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | 197 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, |
100 | u8 *buf, int buf_len, int timeout) | 198 | u8 *buf, int buf_len, int timeout) |
101 | { | 199 | { |
@@ -213,8 +311,7 @@ static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | |||
213 | return 0; | 311 | return 0; |
214 | } | 312 | } |
215 | 313 | ||
216 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | 314 | static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) |
217 | struct mmc_command *cmd) | ||
218 | { | 315 | { |
219 | struct rtsx_pcr *pcr = host->pcr; | 316 | struct rtsx_pcr *pcr = host->pcr; |
220 | u8 cmd_idx = (u8)cmd->opcode; | 317 | u8 cmd_idx = (u8)cmd->opcode; |
@@ -222,11 +319,14 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
222 | int err = 0; | 319 | int err = 0; |
223 | int timeout = 100; | 320 | int timeout = 100; |
224 | int i; | 321 | int i; |
225 | u8 *ptr; | ||
226 | int stat_idx = 0; | ||
227 | u8 rsp_type; | 322 | u8 rsp_type; |
228 | int rsp_len = 5; | 323 | int rsp_len = 5; |
229 | bool clock_toggled = false; | 324 | unsigned long flags; |
325 | |||
326 | if (host->cmd) | ||
327 | dev_err(sdmmc_dev(host), "error: cmd already exist\n"); | ||
328 | |||
329 | host->cmd = cmd; | ||
230 | 330 | ||
231 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | 331 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
232 | __func__, cmd_idx, arg); | 332 | __func__, cmd_idx, arg); |
@@ -261,6 +361,8 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
261 | err = -EINVAL; | 361 | err = -EINVAL; |
262 | goto out; | 362 | goto out; |
263 | } | 363 | } |
364 | host->rsp_type = rsp_type; | ||
365 | host->rsp_len = rsp_len; | ||
264 | 366 | ||
265 | if (rsp_type == SD_RSP_TYPE_R1b) | 367 | if (rsp_type == SD_RSP_TYPE_R1b) |
266 | timeout = 3000; | 368 | timeout = 3000; |
@@ -270,8 +372,6 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
270 | 0xFF, SD_CLK_TOGGLE_EN); | 372 | 0xFF, SD_CLK_TOGGLE_EN); |
271 | if (err < 0) | 373 | if (err < 0) |
272 | goto out; | 374 | goto out; |
273 | |||
274 | clock_toggled = true; | ||
275 | } | 375 | } |
276 | 376 | ||
277 | rtsx_pci_init_cmd(pcr); | 377 | rtsx_pci_init_cmd(pcr); |
@@ -295,25 +395,60 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
295 | /* Read data from ping-pong buffer */ | 395 | /* Read data from ping-pong buffer */ |
296 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) | 396 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) |
297 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 397 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
298 | stat_idx = 16; | ||
299 | } else if (rsp_type != SD_RSP_TYPE_R0) { | 398 | } else if (rsp_type != SD_RSP_TYPE_R0) { |
300 | /* Read data from SD_CMDx registers */ | 399 | /* Read data from SD_CMDx registers */ |
301 | for (i = SD_CMD0; i <= SD_CMD4; i++) | 400 | for (i = SD_CMD0; i <= SD_CMD4; i++) |
302 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 401 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
303 | stat_idx = 5; | ||
304 | } | 402 | } |
305 | 403 | ||
306 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); | 404 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); |
307 | 405 | ||
308 | err = rtsx_pci_send_cmd(pcr, timeout); | 406 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout)); |
309 | if (err < 0) { | 407 | |
310 | sd_print_debug_regs(host); | 408 | spin_lock_irqsave(&pcr->lock, flags); |
311 | sd_clear_error(host); | 409 | pcr->trans_result = TRANS_NOT_READY; |
312 | dev_dbg(sdmmc_dev(host), | 410 | rtsx_pci_send_cmd_no_wait(pcr); |
313 | "rtsx_pci_send_cmd error (err = %d)\n", err); | 411 | spin_unlock_irqrestore(&pcr->lock, flags); |
412 | |||
413 | return; | ||
414 | |||
415 | out: | ||
416 | cmd->error = err; | ||
417 | tasklet_schedule(&host->finish_tasklet); | ||
418 | } | ||
419 | |||
420 | static void sd_get_rsp(unsigned long host_addr) | ||
421 | { | ||
422 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
423 | struct rtsx_pcr *pcr = host->pcr; | ||
424 | struct mmc_command *cmd; | ||
425 | int i, err = 0, stat_idx; | ||
426 | u8 *ptr, rsp_type; | ||
427 | unsigned long flags; | ||
428 | |||
429 | spin_lock_irqsave(&host->lock, flags); | ||
430 | |||
431 | cmd = host->cmd; | ||
432 | host->cmd = NULL; | ||
433 | |||
434 | if (!cmd) { | ||
435 | dev_err(sdmmc_dev(host), "error: cmd not exist\n"); | ||
314 | goto out; | 436 | goto out; |
315 | } | 437 | } |
316 | 438 | ||
439 | spin_lock(&pcr->lock); | ||
440 | if (pcr->trans_result == TRANS_NO_DEVICE) | ||
441 | err = -ENODEV; | ||
442 | else if (pcr->trans_result != TRANS_RESULT_OK) | ||
443 | err = -EINVAL; | ||
444 | spin_unlock(&pcr->lock); | ||
445 | |||
446 | if (err < 0) | ||
447 | goto out; | ||
448 | |||
449 | rsp_type = host->rsp_type; | ||
450 | stat_idx = host->rsp_len; | ||
451 | |||
317 | if (rsp_type == SD_RSP_TYPE_R0) { | 452 | if (rsp_type == SD_RSP_TYPE_R0) { |
318 | err = 0; | 453 | err = 0; |
319 | goto out; | 454 | goto out; |
@@ -350,26 +485,106 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
350 | cmd->resp[0]); | 485 | cmd->resp[0]); |
351 | } | 486 | } |
352 | 487 | ||
488 | if (cmd == host->mrq->sbc) { | ||
489 | sd_send_cmd(host, host->mrq->cmd); | ||
490 | spin_unlock_irqrestore(&host->lock, flags); | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | if (cmd == host->mrq->stop) | ||
495 | goto out; | ||
496 | |||
497 | if (cmd->data) { | ||
498 | sd_start_multi_rw(host, host->mrq); | ||
499 | spin_unlock_irqrestore(&host->lock, flags); | ||
500 | return; | ||
501 | } | ||
502 | |||
353 | out: | 503 | out: |
354 | cmd->error = err; | 504 | cmd->error = err; |
355 | 505 | ||
356 | if (err && clock_toggled) | 506 | tasklet_schedule(&host->finish_tasklet); |
357 | rtsx_pci_write_register(pcr, SD_BUS_STAT, | 507 | spin_unlock_irqrestore(&host->lock, flags); |
358 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); | ||
359 | } | 508 | } |
360 | 509 | ||
361 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | 510 | static int sd_pre_dma_transfer(struct realtek_pci_sdmmc *host, |
511 | struct mmc_data *data, struct realtek_next *next) | ||
512 | { | ||
513 | struct rtsx_pcr *pcr = host->pcr; | ||
514 | int read = data->flags & MMC_DATA_READ; | ||
515 | int sg_count = 0; | ||
516 | |||
517 | if (!next && data->host_cookie && | ||
518 | data->host_cookie != host->next_data.cookie) { | ||
519 | dev_err(sdmmc_dev(host), | ||
520 | "error: invalid cookie data[%d] host[%d]\n", | ||
521 | data->host_cookie, host->next_data.cookie); | ||
522 | data->host_cookie = 0; | ||
523 | } | ||
524 | |||
525 | if (next || (!next && data->host_cookie != host->next_data.cookie)) | ||
526 | sg_count = rtsx_pci_dma_map_sg(pcr, | ||
527 | data->sg, data->sg_len, read); | ||
528 | else | ||
529 | sg_count = host->next_data.sg_count; | ||
530 | |||
531 | if (next) { | ||
532 | next->sg_count = sg_count; | ||
533 | if (++next->cookie < 0) | ||
534 | next->cookie = 1; | ||
535 | data->host_cookie = next->cookie; | ||
536 | } | ||
537 | |||
538 | return sg_count; | ||
539 | } | ||
540 | |||
541 | static void sdmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
542 | bool is_first_req) | ||
543 | { | ||
544 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
545 | struct mmc_data *data = mrq->data; | ||
546 | |||
547 | if (data->host_cookie) { | ||
548 | dev_err(sdmmc_dev(host), | ||
549 | "error: descard already cookie data[%d]\n", | ||
550 | data->host_cookie); | ||
551 | data->host_cookie = 0; | ||
552 | } | ||
553 | |||
554 | dev_dbg(sdmmc_dev(host), "dma sg prepared: %d\n", | ||
555 | sd_pre_dma_transfer(host, data, &host->next_data)); | ||
556 | } | ||
557 | |||
558 | static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
559 | int err) | ||
560 | { | ||
561 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
562 | struct rtsx_pcr *pcr = host->pcr; | ||
563 | struct mmc_data *data = mrq->data; | ||
564 | int read = data->flags & MMC_DATA_READ; | ||
565 | |||
566 | rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, read); | ||
567 | data->host_cookie = 0; | ||
568 | } | ||
569 | |||
570 | static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | ||
571 | struct mmc_request *mrq) | ||
362 | { | 572 | { |
363 | struct rtsx_pcr *pcr = host->pcr; | 573 | struct rtsx_pcr *pcr = host->pcr; |
364 | struct mmc_host *mmc = host->mmc; | 574 | struct mmc_host *mmc = host->mmc; |
365 | struct mmc_card *card = mmc->card; | 575 | struct mmc_card *card = mmc->card; |
366 | struct mmc_data *data = mrq->data; | 576 | struct mmc_data *data = mrq->data; |
367 | int uhs = mmc_card_uhs(card); | 577 | int uhs = mmc_card_uhs(card); |
368 | int read = (data->flags & MMC_DATA_READ) ? 1 : 0; | 578 | int read = data->flags & MMC_DATA_READ; |
369 | u8 cfg2, trans_mode; | 579 | u8 cfg2, trans_mode; |
370 | int err; | 580 | int err; |
371 | size_t data_len = data->blksz * data->blocks; | 581 | size_t data_len = data->blksz * data->blocks; |
372 | 582 | ||
583 | if (host->data) | ||
584 | dev_err(sdmmc_dev(host), "error: data already exist\n"); | ||
585 | |||
586 | host->data = data; | ||
587 | |||
373 | if (read) { | 588 | if (read) { |
374 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 589 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | |
375 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; | 590 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; |
@@ -420,17 +635,56 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | |||
420 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | 635 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, |
421 | SD_TRANSFER_END, SD_TRANSFER_END); | 636 | SD_TRANSFER_END, SD_TRANSFER_END); |
422 | 637 | ||
638 | mod_timer(&host->timer, jiffies + 10 * HZ); | ||
423 | rtsx_pci_send_cmd_no_wait(pcr); | 639 | rtsx_pci_send_cmd_no_wait(pcr); |
424 | 640 | ||
425 | err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000); | 641 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read); |
426 | if (err < 0) { | 642 | if (err < 0) { |
427 | sd_clear_error(host); | 643 | data->error = err; |
428 | return err; | 644 | tasklet_schedule(&host->finish_tasklet); |
429 | } | 645 | } |
430 | |||
431 | return 0; | 646 | return 0; |
432 | } | 647 | } |
433 | 648 | ||
649 | static void sd_finish_multi_rw(unsigned long host_addr) | ||
650 | { | ||
651 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
652 | struct rtsx_pcr *pcr = host->pcr; | ||
653 | struct mmc_data *data; | ||
654 | int err = 0; | ||
655 | unsigned long flags; | ||
656 | |||
657 | spin_lock_irqsave(&host->lock, flags); | ||
658 | |||
659 | if (!host->data) { | ||
660 | dev_err(sdmmc_dev(host), "error: no data exist\n"); | ||
661 | goto out; | ||
662 | } | ||
663 | |||
664 | data = host->data; | ||
665 | host->data = NULL; | ||
666 | |||
667 | if (pcr->trans_result == TRANS_NO_DEVICE) | ||
668 | err = -ENODEV; | ||
669 | else if (pcr->trans_result != TRANS_RESULT_OK) | ||
670 | err = -EINVAL; | ||
671 | |||
672 | if (err < 0) { | ||
673 | data->error = err; | ||
674 | goto out; | ||
675 | } | ||
676 | |||
677 | if (!host->mrq->sbc && data->stop) { | ||
678 | sd_send_cmd(host, data->stop); | ||
679 | spin_unlock_irqrestore(&host->lock, flags); | ||
680 | return; | ||
681 | } | ||
682 | |||
683 | out: | ||
684 | tasklet_schedule(&host->finish_tasklet); | ||
685 | spin_unlock_irqrestore(&host->lock, flags); | ||
686 | } | ||
687 | |||
434 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) | 688 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) |
435 | { | 689 | { |
436 | rtsx_pci_write_register(host->pcr, SD_CFG1, | 690 | rtsx_pci_write_register(host->pcr, SD_CFG1, |
@@ -511,85 +765,47 @@ static int sd_change_phase(struct realtek_pci_sdmmc *host, | |||
511 | return 0; | 765 | return 0; |
512 | } | 766 | } |
513 | 767 | ||
514 | static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map) | 768 | static inline u32 test_phase_bit(u32 phase_map, unsigned int bit) |
515 | { | 769 | { |
516 | struct timing_phase_path path[MAX_PHASE + 1]; | 770 | bit %= RTSX_PHASE_MAX; |
517 | int i, j, cont_path_cnt; | 771 | return phase_map & (1 << bit); |
518 | int new_block, max_len, final_path_idx; | 772 | } |
519 | u8 final_phase = 0xFF; | ||
520 | 773 | ||
521 | /* Parse phase_map, take it as a bit-ring */ | 774 | static int sd_get_phase_len(u32 phase_map, unsigned int start_bit) |
522 | cont_path_cnt = 0; | 775 | { |
523 | new_block = 1; | 776 | int i; |
524 | j = 0; | ||
525 | for (i = 0; i < MAX_PHASE + 1; i++) { | ||
526 | if (phase_map & (1 << i)) { | ||
527 | if (new_block) { | ||
528 | new_block = 0; | ||
529 | j = cont_path_cnt++; | ||
530 | path[j].start = i; | ||
531 | path[j].end = i; | ||
532 | } else { | ||
533 | path[j].end = i; | ||
534 | } | ||
535 | } else { | ||
536 | new_block = 1; | ||
537 | if (cont_path_cnt) { | ||
538 | /* Calculate path length and middle point */ | ||
539 | int idx = cont_path_cnt - 1; | ||
540 | path[idx].len = | ||
541 | path[idx].end - path[idx].start + 1; | ||
542 | path[idx].mid = | ||
543 | path[idx].start + path[idx].len / 2; | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | 777 | ||
548 | if (cont_path_cnt == 0) { | 778 | for (i = 0; i < RTSX_PHASE_MAX; i++) { |
549 | dev_dbg(sdmmc_dev(host), "No continuous phase path\n"); | 779 | if (test_phase_bit(phase_map, start_bit + i) == 0) |
550 | goto finish; | 780 | return i; |
551 | } else { | ||
552 | /* Calculate last continuous path length and middle point */ | ||
553 | int idx = cont_path_cnt - 1; | ||
554 | path[idx].len = path[idx].end - path[idx].start + 1; | ||
555 | path[idx].mid = path[idx].start + path[idx].len / 2; | ||
556 | } | 781 | } |
782 | return RTSX_PHASE_MAX; | ||
783 | } | ||
784 | |||
785 | static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map) | ||
786 | { | ||
787 | int start = 0, len = 0; | ||
788 | int start_final = 0, len_final = 0; | ||
789 | u8 final_phase = 0xFF; | ||
557 | 790 | ||
558 | /* Connect the first and last continuous paths if they are adjacent */ | 791 | if (phase_map == 0) { |
559 | if (!path[0].start && (path[cont_path_cnt - 1].end == MAX_PHASE)) { | 792 | dev_err(sdmmc_dev(host), "phase error: [map:%x]\n", phase_map); |
560 | /* Using negative index */ | 793 | return final_phase; |
561 | path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; | ||
562 | path[0].len += path[cont_path_cnt - 1].len; | ||
563 | path[0].mid = path[0].start + path[0].len / 2; | ||
564 | /* Convert negative middle point index to positive one */ | ||
565 | if (path[0].mid < 0) | ||
566 | path[0].mid += MAX_PHASE + 1; | ||
567 | cont_path_cnt--; | ||
568 | } | 794 | } |
569 | 795 | ||
570 | /* Choose the longest continuous phase path */ | 796 | while (start < RTSX_PHASE_MAX) { |
571 | max_len = 0; | 797 | len = sd_get_phase_len(phase_map, start); |
572 | final_phase = 0; | 798 | if (len_final < len) { |
573 | final_path_idx = 0; | 799 | start_final = start; |
574 | for (i = 0; i < cont_path_cnt; i++) { | 800 | len_final = len; |
575 | if (path[i].len > max_len) { | ||
576 | max_len = path[i].len; | ||
577 | final_phase = (u8)path[i].mid; | ||
578 | final_path_idx = i; | ||
579 | } | 801 | } |
580 | 802 | start += len ? len : 1; | |
581 | dev_dbg(sdmmc_dev(host), "path[%d].start = %d\n", | ||
582 | i, path[i].start); | ||
583 | dev_dbg(sdmmc_dev(host), "path[%d].end = %d\n", | ||
584 | i, path[i].end); | ||
585 | dev_dbg(sdmmc_dev(host), "path[%d].len = %d\n", | ||
586 | i, path[i].len); | ||
587 | dev_dbg(sdmmc_dev(host), "path[%d].mid = %d\n", | ||
588 | i, path[i].mid); | ||
589 | } | 803 | } |
590 | 804 | ||
591 | finish: | 805 | final_phase = (start_final + len_final / 2) % RTSX_PHASE_MAX; |
592 | dev_dbg(sdmmc_dev(host), "Final chosen phase: %d\n", final_phase); | 806 | dev_dbg(sdmmc_dev(host), "phase: [map:%x] [maxlen:%d] [final:%d]\n", |
807 | phase_map, len_final, final_phase); | ||
808 | |||
593 | return final_phase; | 809 | return final_phase; |
594 | } | 810 | } |
595 | 811 | ||
@@ -635,7 +851,7 @@ static int sd_tuning_phase(struct realtek_pci_sdmmc *host, | |||
635 | int err, i; | 851 | int err, i; |
636 | u32 raw_phase_map = 0; | 852 | u32 raw_phase_map = 0; |
637 | 853 | ||
638 | for (i = MAX_PHASE; i >= 0; i--) { | 854 | for (i = 0; i < RTSX_PHASE_MAX; i++) { |
639 | err = sd_tuning_rx_cmd(host, opcode, (u8)i); | 855 | err = sd_tuning_rx_cmd(host, opcode, (u8)i); |
640 | if (err == 0) | 856 | if (err == 0) |
641 | raw_phase_map |= 1 << i; | 857 | raw_phase_map |= 1 << i; |
@@ -685,6 +901,13 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) | |||
685 | return 0; | 901 | return 0; |
686 | } | 902 | } |
687 | 903 | ||
904 | static inline bool sd_use_muti_rw(struct mmc_command *cmd) | ||
905 | { | ||
906 | return mmc_op_multi(cmd->opcode) || | ||
907 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || | ||
908 | (cmd->opcode == MMC_WRITE_BLOCK); | ||
909 | } | ||
910 | |||
688 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | 911 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) |
689 | { | 912 | { |
690 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | 913 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); |
@@ -693,6 +916,14 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
693 | struct mmc_data *data = mrq->data; | 916 | struct mmc_data *data = mrq->data; |
694 | unsigned int data_size = 0; | 917 | unsigned int data_size = 0; |
695 | int err; | 918 | int err; |
919 | unsigned long flags; | ||
920 | |||
921 | mutex_lock(&pcr->pcr_mutex); | ||
922 | spin_lock_irqsave(&host->lock, flags); | ||
923 | |||
924 | if (host->mrq) | ||
925 | dev_err(sdmmc_dev(host), "error: request already exist\n"); | ||
926 | host->mrq = mrq; | ||
696 | 927 | ||
697 | if (host->eject) { | 928 | if (host->eject) { |
698 | cmd->error = -ENOMEDIUM; | 929 | cmd->error = -ENOMEDIUM; |
@@ -705,8 +936,6 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
705 | goto finish; | 936 | goto finish; |
706 | } | 937 | } |
707 | 938 | ||
708 | mutex_lock(&pcr->pcr_mutex); | ||
709 | |||
710 | rtsx_pci_start_run(pcr); | 939 | rtsx_pci_start_run(pcr); |
711 | 940 | ||
712 | rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, | 941 | rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, |
@@ -715,46 +944,28 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
715 | rtsx_pci_write_register(pcr, CARD_SHARE_MODE, | 944 | rtsx_pci_write_register(pcr, CARD_SHARE_MODE, |
716 | CARD_SHARE_MASK, CARD_SHARE_48_SD); | 945 | CARD_SHARE_MASK, CARD_SHARE_48_SD); |
717 | 946 | ||
718 | mutex_lock(&host->host_mutex); | ||
719 | host->mrq = mrq; | ||
720 | mutex_unlock(&host->host_mutex); | ||
721 | |||
722 | if (mrq->data) | 947 | if (mrq->data) |
723 | data_size = data->blocks * data->blksz; | 948 | data_size = data->blocks * data->blksz; |
724 | 949 | ||
725 | if (!data_size || mmc_op_multi(cmd->opcode) || | 950 | if (sd_use_muti_rw(cmd)) |
726 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || | 951 | host->sg_count = sd_pre_dma_transfer(host, data, NULL); |
727 | (cmd->opcode == MMC_WRITE_BLOCK)) { | ||
728 | sd_send_cmd_get_rsp(host, cmd); | ||
729 | |||
730 | if (!cmd->error && data_size) { | ||
731 | sd_rw_multi(host, mrq); | ||
732 | 952 | ||
733 | if (mmc_op_multi(cmd->opcode) && mrq->stop) | 953 | if (!data_size || sd_use_muti_rw(cmd)) { |
734 | sd_send_cmd_get_rsp(host, mrq->stop); | 954 | if (mrq->sbc) |
735 | } | 955 | sd_send_cmd(host, mrq->sbc); |
956 | else | ||
957 | sd_send_cmd(host, cmd); | ||
958 | spin_unlock_irqrestore(&host->lock, flags); | ||
736 | } else { | 959 | } else { |
960 | spin_unlock_irqrestore(&host->lock, flags); | ||
737 | sd_normal_rw(host, mrq); | 961 | sd_normal_rw(host, mrq); |
962 | tasklet_schedule(&host->finish_tasklet); | ||
738 | } | 963 | } |
739 | 964 | return; | |
740 | if (mrq->data) { | ||
741 | if (cmd->error || data->error) | ||
742 | data->bytes_xfered = 0; | ||
743 | else | ||
744 | data->bytes_xfered = data->blocks * data->blksz; | ||
745 | } | ||
746 | |||
747 | mutex_unlock(&pcr->pcr_mutex); | ||
748 | 965 | ||
749 | finish: | 966 | finish: |
750 | if (cmd->error) | 967 | tasklet_schedule(&host->finish_tasklet); |
751 | dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); | 968 | spin_unlock_irqrestore(&host->lock, flags); |
752 | |||
753 | mutex_lock(&host->host_mutex); | ||
754 | host->mrq = NULL; | ||
755 | mutex_unlock(&host->host_mutex); | ||
756 | |||
757 | mmc_request_done(mmc, mrq); | ||
758 | } | 969 | } |
759 | 970 | ||
760 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, | 971 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, |
@@ -1189,6 +1400,8 @@ out: | |||
1189 | } | 1400 | } |
1190 | 1401 | ||
1191 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { | 1402 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { |
1403 | .pre_req = sdmmc_pre_req, | ||
1404 | .post_req = sdmmc_post_req, | ||
1192 | .request = sdmmc_request, | 1405 | .request = sdmmc_request, |
1193 | .set_ios = sdmmc_set_ios, | 1406 | .set_ios = sdmmc_set_ios, |
1194 | .get_ro = sdmmc_get_ro, | 1407 | .get_ro = sdmmc_get_ro, |
@@ -1252,6 +1465,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
1252 | struct realtek_pci_sdmmc *host; | 1465 | struct realtek_pci_sdmmc *host; |
1253 | struct rtsx_pcr *pcr; | 1466 | struct rtsx_pcr *pcr; |
1254 | struct pcr_handle *handle = pdev->dev.platform_data; | 1467 | struct pcr_handle *handle = pdev->dev.platform_data; |
1468 | unsigned long host_addr; | ||
1255 | 1469 | ||
1256 | if (!handle) | 1470 | if (!handle) |
1257 | return -ENXIO; | 1471 | return -ENXIO; |
@@ -1275,8 +1489,15 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
1275 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; | 1489 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; |
1276 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; | 1490 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; |
1277 | 1491 | ||
1278 | mutex_init(&host->host_mutex); | 1492 | host_addr = (unsigned long)host; |
1493 | host->next_data.cookie = 1; | ||
1494 | setup_timer(&host->timer, sd_request_timeout, host_addr); | ||
1495 | tasklet_init(&host->cmd_tasklet, sd_get_rsp, host_addr); | ||
1496 | tasklet_init(&host->data_tasklet, sd_finish_multi_rw, host_addr); | ||
1497 | tasklet_init(&host->finish_tasklet, sd_finish_request, host_addr); | ||
1498 | spin_lock_init(&host->lock); | ||
1279 | 1499 | ||
1500 | pcr->slots[RTSX_SD_CARD].done_transfer = sd_isr_done_transfer; | ||
1280 | realtek_init_host(host); | 1501 | realtek_init_host(host); |
1281 | 1502 | ||
1282 | mmc_add_host(mmc); | 1503 | mmc_add_host(mmc); |
@@ -1289,6 +1510,8 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
1289 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | 1510 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); |
1290 | struct rtsx_pcr *pcr; | 1511 | struct rtsx_pcr *pcr; |
1291 | struct mmc_host *mmc; | 1512 | struct mmc_host *mmc; |
1513 | struct mmc_request *mrq; | ||
1514 | unsigned long flags; | ||
1292 | 1515 | ||
1293 | if (!host) | 1516 | if (!host) |
1294 | return 0; | 1517 | return 0; |
@@ -1296,25 +1519,37 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
1296 | pcr = host->pcr; | 1519 | pcr = host->pcr; |
1297 | pcr->slots[RTSX_SD_CARD].p_dev = NULL; | 1520 | pcr->slots[RTSX_SD_CARD].p_dev = NULL; |
1298 | pcr->slots[RTSX_SD_CARD].card_event = NULL; | 1521 | pcr->slots[RTSX_SD_CARD].card_event = NULL; |
1522 | pcr->slots[RTSX_SD_CARD].done_transfer = NULL; | ||
1299 | mmc = host->mmc; | 1523 | mmc = host->mmc; |
1300 | host->eject = true; | 1524 | mrq = host->mrq; |
1301 | 1525 | ||
1302 | mutex_lock(&host->host_mutex); | 1526 | spin_lock_irqsave(&host->lock, flags); |
1303 | if (host->mrq) { | 1527 | if (host->mrq) { |
1304 | dev_dbg(&(pdev->dev), | 1528 | dev_dbg(&(pdev->dev), |
1305 | "%s: Controller removed during transfer\n", | 1529 | "%s: Controller removed during transfer\n", |
1306 | mmc_hostname(mmc)); | 1530 | mmc_hostname(mmc)); |
1307 | 1531 | ||
1308 | rtsx_pci_complete_unfinished_transfer(pcr); | 1532 | if (mrq->sbc) |
1533 | mrq->sbc->error = -ENOMEDIUM; | ||
1534 | if (mrq->cmd) | ||
1535 | mrq->cmd->error = -ENOMEDIUM; | ||
1536 | if (mrq->stop) | ||
1537 | mrq->stop->error = -ENOMEDIUM; | ||
1538 | if (mrq->data) | ||
1539 | mrq->data->error = -ENOMEDIUM; | ||
1309 | 1540 | ||
1310 | host->mrq->cmd->error = -ENOMEDIUM; | 1541 | tasklet_schedule(&host->finish_tasklet); |
1311 | if (host->mrq->stop) | ||
1312 | host->mrq->stop->error = -ENOMEDIUM; | ||
1313 | mmc_request_done(mmc, host->mrq); | ||
1314 | } | 1542 | } |
1315 | mutex_unlock(&host->host_mutex); | 1543 | spin_unlock_irqrestore(&host->lock, flags); |
1544 | |||
1545 | del_timer_sync(&host->timer); | ||
1546 | tasklet_kill(&host->cmd_tasklet); | ||
1547 | tasklet_kill(&host->data_tasklet); | ||
1548 | tasklet_kill(&host->finish_tasklet); | ||
1316 | 1549 | ||
1317 | mmc_remove_host(mmc); | 1550 | mmc_remove_host(mmc); |
1551 | host->eject = true; | ||
1552 | |||
1318 | mmc_free_host(mmc); | 1553 | mmc_free_host(mmc); |
1319 | 1554 | ||
1320 | dev_dbg(&(pdev->dev), | 1555 | dev_dbg(&(pdev->dev), |
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 9ce17f6e4014..ebb3f392b589 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/bitops.h> | 31 | #include <linux/bitops.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/err.h> | 33 | #include <linux/err.h> |
34 | #include <linux/gpio/consumer.h> | ||
35 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
36 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
37 | #include <linux/pm.h> | 36 | #include <linux/pm.h> |
@@ -40,13 +39,15 @@ | |||
40 | 39 | ||
41 | #include <linux/mmc/host.h> | 40 | #include <linux/mmc/host.h> |
42 | #include <linux/mmc/pm.h> | 41 | #include <linux/mmc/pm.h> |
42 | #include <linux/mmc/slot-gpio.h> | ||
43 | #include <linux/mmc/sdhci.h> | 43 | #include <linux/mmc/sdhci.h> |
44 | 44 | ||
45 | #include "sdhci.h" | 45 | #include "sdhci.h" |
46 | 46 | ||
47 | enum { | 47 | enum { |
48 | SDHCI_ACPI_SD_CD = BIT(0), | 48 | SDHCI_ACPI_SD_CD = BIT(0), |
49 | SDHCI_ACPI_RUNTIME_PM = BIT(1), | 49 | SDHCI_ACPI_RUNTIME_PM = BIT(1), |
50 | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL = BIT(2), | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | struct sdhci_acpi_chip { | 53 | struct sdhci_acpi_chip { |
@@ -121,6 +122,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = { | |||
121 | }; | 122 | }; |
122 | 123 | ||
123 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | 124 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { |
125 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION, | ||
124 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, | 126 | .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON, |
125 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, | 127 | .caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD, |
126 | .flags = SDHCI_ACPI_RUNTIME_PM, | 128 | .flags = SDHCI_ACPI_RUNTIME_PM, |
@@ -128,7 +130,8 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = { | |||
128 | }; | 130 | }; |
129 | 131 | ||
130 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { | 132 | static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = { |
131 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_RUNTIME_PM, | 133 | .flags = SDHCI_ACPI_SD_CD | SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL | |
134 | SDHCI_ACPI_RUNTIME_PM, | ||
132 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON, | 135 | .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON, |
133 | }; | 136 | }; |
134 | 137 | ||
@@ -141,6 +144,7 @@ struct sdhci_acpi_uid_slot { | |||
141 | static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { | 144 | static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { |
142 | { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc }, | 145 | { "80860F14" , "1" , &sdhci_acpi_slot_int_emmc }, |
143 | { "80860F14" , "3" , &sdhci_acpi_slot_int_sd }, | 146 | { "80860F14" , "3" , &sdhci_acpi_slot_int_sd }, |
147 | { "80860F16" , NULL, &sdhci_acpi_slot_int_sd }, | ||
144 | { "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio }, | 148 | { "INT33BB" , "2" , &sdhci_acpi_slot_int_sdio }, |
145 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, | 149 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, |
146 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, | 150 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, |
@@ -150,6 +154,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { | |||
150 | 154 | ||
151 | static const struct acpi_device_id sdhci_acpi_ids[] = { | 155 | static const struct acpi_device_id sdhci_acpi_ids[] = { |
152 | { "80860F14" }, | 156 | { "80860F14" }, |
157 | { "80860F16" }, | ||
153 | { "INT33BB" }, | 158 | { "INT33BB" }, |
154 | { "INT33C6" }, | 159 | { "INT33C6" }, |
155 | { "INT3436" }, | 160 | { "INT3436" }, |
@@ -192,59 +197,6 @@ static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(acpi_handle handle, | |||
192 | return slot; | 197 | return slot; |
193 | } | 198 | } |
194 | 199 | ||
195 | #ifdef CONFIG_PM_RUNTIME | ||
196 | |||
197 | static irqreturn_t sdhci_acpi_sd_cd(int irq, void *dev_id) | ||
198 | { | ||
199 | mmc_detect_change(dev_id, msecs_to_jiffies(200)); | ||
200 | return IRQ_HANDLED; | ||
201 | } | ||
202 | |||
203 | static int sdhci_acpi_add_own_cd(struct device *dev, struct mmc_host *mmc) | ||
204 | { | ||
205 | struct gpio_desc *desc; | ||
206 | unsigned long flags; | ||
207 | int err, irq; | ||
208 | |||
209 | desc = devm_gpiod_get_index(dev, "sd_cd", 0); | ||
210 | if (IS_ERR(desc)) { | ||
211 | err = PTR_ERR(desc); | ||
212 | goto out; | ||
213 | } | ||
214 | |||
215 | err = gpiod_direction_input(desc); | ||
216 | if (err) | ||
217 | goto out_free; | ||
218 | |||
219 | irq = gpiod_to_irq(desc); | ||
220 | if (irq < 0) { | ||
221 | err = irq; | ||
222 | goto out_free; | ||
223 | } | ||
224 | |||
225 | flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; | ||
226 | err = devm_request_irq(dev, irq, sdhci_acpi_sd_cd, flags, "sd_cd", mmc); | ||
227 | if (err) | ||
228 | goto out_free; | ||
229 | |||
230 | return 0; | ||
231 | |||
232 | out_free: | ||
233 | devm_gpiod_put(dev, desc); | ||
234 | out: | ||
235 | dev_warn(dev, "failed to setup card detect wake up\n"); | ||
236 | return err; | ||
237 | } | ||
238 | |||
239 | #else | ||
240 | |||
241 | static int sdhci_acpi_add_own_cd(struct device *dev, struct mmc_host *mmc) | ||
242 | { | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | #endif | ||
247 | |||
248 | static int sdhci_acpi_probe(struct platform_device *pdev) | 200 | static int sdhci_acpi_probe(struct platform_device *pdev) |
249 | { | 201 | { |
250 | struct device *dev = &pdev->dev; | 202 | struct device *dev = &pdev->dev; |
@@ -332,15 +284,19 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
332 | 284 | ||
333 | host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; | 285 | host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; |
334 | 286 | ||
335 | err = sdhci_add_host(host); | ||
336 | if (err) | ||
337 | goto err_free; | ||
338 | |||
339 | if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { | 287 | if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { |
340 | if (sdhci_acpi_add_own_cd(dev, host->mmc)) | 288 | bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL); |
289 | |||
290 | if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0)) { | ||
291 | dev_warn(dev, "failed to setup card detect gpio\n"); | ||
341 | c->use_runtime_pm = false; | 292 | c->use_runtime_pm = false; |
293 | } | ||
342 | } | 294 | } |
343 | 295 | ||
296 | err = sdhci_add_host(host); | ||
297 | if (err) | ||
298 | goto err_free; | ||
299 | |||
344 | if (c->use_runtime_pm) { | 300 | if (c->use_runtime_pm) { |
345 | pm_runtime_set_active(dev); | 301 | pm_runtime_set_active(dev); |
346 | pm_suspend_ignore_children(dev, 1); | 302 | pm_suspend_ignore_children(dev, 1); |
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c index 7a190fe4dff1..6f166e63b817 100644 --- a/drivers/mmc/host/sdhci-bcm-kona.c +++ b/drivers/mmc/host/sdhci-bcm-kona.c | |||
@@ -54,6 +54,7 @@ | |||
54 | 54 | ||
55 | struct sdhci_bcm_kona_dev { | 55 | struct sdhci_bcm_kona_dev { |
56 | struct mutex write_lock; /* protect back to back writes */ | 56 | struct mutex write_lock; /* protect back to back writes */ |
57 | struct clk *external_clk; | ||
57 | }; | 58 | }; |
58 | 59 | ||
59 | 60 | ||
@@ -257,6 +258,24 @@ static int sdhci_bcm_kona_probe(struct platform_device *pdev) | |||
257 | goto err_pltfm_free; | 258 | goto err_pltfm_free; |
258 | } | 259 | } |
259 | 260 | ||
261 | /* Get and enable the external clock */ | ||
262 | kona_dev->external_clk = devm_clk_get(dev, NULL); | ||
263 | if (IS_ERR(kona_dev->external_clk)) { | ||
264 | dev_err(dev, "Failed to get external clock\n"); | ||
265 | ret = PTR_ERR(kona_dev->external_clk); | ||
266 | goto err_pltfm_free; | ||
267 | } | ||
268 | |||
269 | if (clk_set_rate(kona_dev->external_clk, host->mmc->f_max) != 0) { | ||
270 | dev_err(dev, "Failed to set rate external clock\n"); | ||
271 | goto err_pltfm_free; | ||
272 | } | ||
273 | |||
274 | if (clk_prepare_enable(kona_dev->external_clk) != 0) { | ||
275 | dev_err(dev, "Failed to enable external clock\n"); | ||
276 | goto err_pltfm_free; | ||
277 | } | ||
278 | |||
260 | dev_dbg(dev, "non-removable=%c\n", | 279 | dev_dbg(dev, "non-removable=%c\n", |
261 | (host->mmc->caps & MMC_CAP_NONREMOVABLE) ? 'Y' : 'N'); | 280 | (host->mmc->caps & MMC_CAP_NONREMOVABLE) ? 'Y' : 'N'); |
262 | dev_dbg(dev, "cd_gpio %c, wp_gpio %c\n", | 281 | dev_dbg(dev, "cd_gpio %c, wp_gpio %c\n", |
@@ -271,7 +290,7 @@ static int sdhci_bcm_kona_probe(struct platform_device *pdev) | |||
271 | 290 | ||
272 | ret = sdhci_bcm_kona_sd_reset(host); | 291 | ret = sdhci_bcm_kona_sd_reset(host); |
273 | if (ret) | 292 | if (ret) |
274 | goto err_pltfm_free; | 293 | goto err_clk_disable; |
275 | 294 | ||
276 | sdhci_bcm_kona_sd_init(host); | 295 | sdhci_bcm_kona_sd_init(host); |
277 | 296 | ||
@@ -307,6 +326,9 @@ err_remove_host: | |||
307 | err_reset: | 326 | err_reset: |
308 | sdhci_bcm_kona_sd_reset(host); | 327 | sdhci_bcm_kona_sd_reset(host); |
309 | 328 | ||
329 | err_clk_disable: | ||
330 | clk_disable_unprepare(kona_dev->external_clk); | ||
331 | |||
310 | err_pltfm_free: | 332 | err_pltfm_free: |
311 | sdhci_pltfm_free(pdev); | 333 | sdhci_pltfm_free(pdev); |
312 | 334 | ||
@@ -314,9 +336,20 @@ err_pltfm_free: | |||
314 | return ret; | 336 | return ret; |
315 | } | 337 | } |
316 | 338 | ||
317 | static int __exit sdhci_bcm_kona_remove(struct platform_device *pdev) | 339 | static int sdhci_bcm_kona_remove(struct platform_device *pdev) |
318 | { | 340 | { |
319 | return sdhci_pltfm_unregister(pdev); | 341 | struct sdhci_host *host = platform_get_drvdata(pdev); |
342 | struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host); | ||
343 | struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv); | ||
344 | int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); | ||
345 | |||
346 | sdhci_remove_host(host, dead); | ||
347 | |||
348 | clk_disable_unprepare(kona_dev->external_clk); | ||
349 | |||
350 | sdhci_pltfm_free(pdev); | ||
351 | |||
352 | return 0; | ||
320 | } | 353 | } |
321 | 354 | ||
322 | static struct platform_driver sdhci_bcm_kona_driver = { | 355 | static struct platform_driver sdhci_bcm_kona_driver = { |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index 8424839660f8..736d7a2eb7ec 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
@@ -208,7 +208,7 @@ static struct platform_driver sdhci_dove_driver = { | |||
208 | .name = "sdhci-dove", | 208 | .name = "sdhci-dove", |
209 | .owner = THIS_MODULE, | 209 | .owner = THIS_MODULE, |
210 | .pm = SDHCI_PLTFM_PMOPS, | 210 | .pm = SDHCI_PLTFM_PMOPS, |
211 | .of_match_table = of_match_ptr(sdhci_dove_of_match_table), | 211 | .of_match_table = sdhci_dove_of_match_table, |
212 | }, | 212 | }, |
213 | .probe = sdhci_dove_probe, | 213 | .probe = sdhci_dove_probe, |
214 | .remove = sdhci_dove_remove, | 214 | .remove = sdhci_dove_remove, |
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c new file mode 100644 index 000000000000..acb0e9eb55f1 --- /dev/null +++ b/drivers/mmc/host/sdhci-msm.c | |||
@@ -0,0 +1,618 @@ | |||
1 | /* | ||
2 | * drivers/mmc/host/sdhci-msm.c - Qualcomm SDHCI Platform driver | ||
3 | * | ||
4 | * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 and | ||
8 | * only version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/of_device.h> | ||
19 | #include <linux/regulator/consumer.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/mmc/mmc.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #include "sdhci-pltfm.h" | ||
25 | |||
26 | #define CORE_HC_MODE 0x78 | ||
27 | #define HC_MODE_EN 0x1 | ||
28 | #define CORE_POWER 0x0 | ||
29 | #define CORE_SW_RST BIT(7) | ||
30 | |||
31 | #define MAX_PHASES 16 | ||
32 | #define CORE_DLL_LOCK BIT(7) | ||
33 | #define CORE_DLL_EN BIT(16) | ||
34 | #define CORE_CDR_EN BIT(17) | ||
35 | #define CORE_CK_OUT_EN BIT(18) | ||
36 | #define CORE_CDR_EXT_EN BIT(19) | ||
37 | #define CORE_DLL_PDN BIT(29) | ||
38 | #define CORE_DLL_RST BIT(30) | ||
39 | #define CORE_DLL_CONFIG 0x100 | ||
40 | #define CORE_DLL_STATUS 0x108 | ||
41 | |||
42 | #define CORE_VENDOR_SPEC 0x10c | ||
43 | #define CORE_CLK_PWRSAVE BIT(1) | ||
44 | |||
45 | #define CDR_SELEXT_SHIFT 20 | ||
46 | #define CDR_SELEXT_MASK (0xf << CDR_SELEXT_SHIFT) | ||
47 | #define CMUX_SHIFT_PHASE_SHIFT 24 | ||
48 | #define CMUX_SHIFT_PHASE_MASK (7 << CMUX_SHIFT_PHASE_SHIFT) | ||
49 | |||
50 | static const u32 tuning_block_64[] = { | ||
51 | 0x00ff0fff, 0xccc3ccff, 0xffcc3cc3, 0xeffefffe, | ||
52 | 0xddffdfff, 0xfbfffbff, 0xff7fffbf, 0xefbdf777, | ||
53 | 0xf0fff0ff, 0x3cccfc0f, 0xcfcc33cc, 0xeeffefff, | ||
54 | 0xfdfffdff, 0xffbfffdf, 0xfff7ffbb, 0xde7b7ff7 | ||
55 | }; | ||
56 | |||
57 | static const u32 tuning_block_128[] = { | ||
58 | 0xff00ffff, 0x0000ffff, 0xccccffff, 0xcccc33cc, | ||
59 | 0xcc3333cc, 0xffffcccc, 0xffffeeff, 0xffeeeeff, | ||
60 | 0xffddffff, 0xddddffff, 0xbbffffff, 0xbbffffff, | ||
61 | 0xffffffbb, 0xffffff77, 0x77ff7777, 0xffeeddbb, | ||
62 | 0x00ffffff, 0x00ffffff, 0xccffff00, 0xcc33cccc, | ||
63 | 0x3333cccc, 0xffcccccc, 0xffeeffff, 0xeeeeffff, | ||
64 | 0xddffffff, 0xddffffff, 0xffffffdd, 0xffffffbb, | ||
65 | 0xffffbbbb, 0xffff77ff, 0xff7777ff, 0xeeddbb77 | ||
66 | }; | ||
67 | |||
68 | struct sdhci_msm_host { | ||
69 | struct platform_device *pdev; | ||
70 | void __iomem *core_mem; /* MSM SDCC mapped address */ | ||
71 | struct clk *clk; /* main SD/MMC bus clock */ | ||
72 | struct clk *pclk; /* SDHC peripheral bus clock */ | ||
73 | struct clk *bus_clk; /* SDHC bus voter clock */ | ||
74 | struct mmc_host *mmc; | ||
75 | struct sdhci_pltfm_data sdhci_msm_pdata; | ||
76 | }; | ||
77 | |||
78 | /* Platform specific tuning */ | ||
79 | static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll) | ||
80 | { | ||
81 | u32 wait_cnt = 50; | ||
82 | u8 ck_out_en; | ||
83 | struct mmc_host *mmc = host->mmc; | ||
84 | |||
85 | /* Poll for CK_OUT_EN bit. max. poll time = 50us */ | ||
86 | ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) & | ||
87 | CORE_CK_OUT_EN); | ||
88 | |||
89 | while (ck_out_en != poll) { | ||
90 | if (--wait_cnt == 0) { | ||
91 | dev_err(mmc_dev(mmc), "%s: CK_OUT_EN bit is not %d\n", | ||
92 | mmc_hostname(mmc), poll); | ||
93 | return -ETIMEDOUT; | ||
94 | } | ||
95 | udelay(1); | ||
96 | |||
97 | ck_out_en = !!(readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) & | ||
98 | CORE_CK_OUT_EN); | ||
99 | } | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int msm_config_cm_dll_phase(struct sdhci_host *host, u8 phase) | ||
105 | { | ||
106 | int rc; | ||
107 | static const u8 grey_coded_phase_table[] = { | ||
108 | 0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, | ||
109 | 0xc, 0xd, 0xf, 0xe, 0xa, 0xb, 0x9, 0x8 | ||
110 | }; | ||
111 | unsigned long flags; | ||
112 | u32 config; | ||
113 | struct mmc_host *mmc = host->mmc; | ||
114 | |||
115 | spin_lock_irqsave(&host->lock, flags); | ||
116 | |||
117 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG); | ||
118 | config &= ~(CORE_CDR_EN | CORE_CK_OUT_EN); | ||
119 | config |= (CORE_CDR_EXT_EN | CORE_DLL_EN); | ||
120 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG); | ||
121 | |||
122 | /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '0' */ | ||
123 | rc = msm_dll_poll_ck_out_en(host, 0); | ||
124 | if (rc) | ||
125 | goto err_out; | ||
126 | |||
127 | /* | ||
128 | * Write the selected DLL clock output phase (0 ... 15) | ||
129 | * to CDR_SELEXT bit field of DLL_CONFIG register. | ||
130 | */ | ||
131 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG); | ||
132 | config &= ~CDR_SELEXT_MASK; | ||
133 | config |= grey_coded_phase_table[phase] << CDR_SELEXT_SHIFT; | ||
134 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG); | ||
135 | |||
136 | /* Set CK_OUT_EN bit of DLL_CONFIG register to 1. */ | ||
137 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) | ||
138 | | CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG); | ||
139 | |||
140 | /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '1' */ | ||
141 | rc = msm_dll_poll_ck_out_en(host, 1); | ||
142 | if (rc) | ||
143 | goto err_out; | ||
144 | |||
145 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG); | ||
146 | config |= CORE_CDR_EN; | ||
147 | config &= ~CORE_CDR_EXT_EN; | ||
148 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG); | ||
149 | goto out; | ||
150 | |||
151 | err_out: | ||
152 | dev_err(mmc_dev(mmc), "%s: Failed to set DLL phase: %d\n", | ||
153 | mmc_hostname(mmc), phase); | ||
154 | out: | ||
155 | spin_unlock_irqrestore(&host->lock, flags); | ||
156 | return rc; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Find out the greatest range of consecuitive selected | ||
161 | * DLL clock output phases that can be used as sampling | ||
162 | * setting for SD3.0 UHS-I card read operation (in SDR104 | ||
163 | * timing mode) or for eMMC4.5 card read operation (in HS200 | ||
164 | * timing mode). | ||
165 | * Select the 3/4 of the range and configure the DLL with the | ||
166 | * selected DLL clock output phase. | ||
167 | */ | ||
168 | |||
169 | static int msm_find_most_appropriate_phase(struct sdhci_host *host, | ||
170 | u8 *phase_table, u8 total_phases) | ||
171 | { | ||
172 | int ret; | ||
173 | u8 ranges[MAX_PHASES][MAX_PHASES] = { {0}, {0} }; | ||
174 | u8 phases_per_row[MAX_PHASES] = { 0 }; | ||
175 | int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0; | ||
176 | int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0; | ||
177 | bool phase_0_found = false, phase_15_found = false; | ||
178 | struct mmc_host *mmc = host->mmc; | ||
179 | |||
180 | if (!total_phases || (total_phases > MAX_PHASES)) { | ||
181 | dev_err(mmc_dev(mmc), "%s: Invalid argument: total_phases=%d\n", | ||
182 | mmc_hostname(mmc), total_phases); | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | for (cnt = 0; cnt < total_phases; cnt++) { | ||
187 | ranges[row_index][col_index] = phase_table[cnt]; | ||
188 | phases_per_row[row_index] += 1; | ||
189 | col_index++; | ||
190 | |||
191 | if ((cnt + 1) == total_phases) { | ||
192 | continue; | ||
193 | /* check if next phase in phase_table is consecutive or not */ | ||
194 | } else if ((phase_table[cnt] + 1) != phase_table[cnt + 1]) { | ||
195 | row_index++; | ||
196 | col_index = 0; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | if (row_index >= MAX_PHASES) | ||
201 | return -EINVAL; | ||
202 | |||
203 | /* Check if phase-0 is present in first valid window? */ | ||
204 | if (!ranges[0][0]) { | ||
205 | phase_0_found = true; | ||
206 | phase_0_raw_index = 0; | ||
207 | /* Check if cycle exist between 2 valid windows */ | ||
208 | for (cnt = 1; cnt <= row_index; cnt++) { | ||
209 | if (phases_per_row[cnt]) { | ||
210 | for (i = 0; i < phases_per_row[cnt]; i++) { | ||
211 | if (ranges[cnt][i] == 15) { | ||
212 | phase_15_found = true; | ||
213 | phase_15_raw_index = cnt; | ||
214 | break; | ||
215 | } | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /* If 2 valid windows form cycle then merge them as single window */ | ||
222 | if (phase_0_found && phase_15_found) { | ||
223 | /* number of phases in raw where phase 0 is present */ | ||
224 | u8 phases_0 = phases_per_row[phase_0_raw_index]; | ||
225 | /* number of phases in raw where phase 15 is present */ | ||
226 | u8 phases_15 = phases_per_row[phase_15_raw_index]; | ||
227 | |||
228 | if (phases_0 + phases_15 >= MAX_PHASES) | ||
229 | /* | ||
230 | * If there are more than 1 phase windows then total | ||
231 | * number of phases in both the windows should not be | ||
232 | * more than or equal to MAX_PHASES. | ||
233 | */ | ||
234 | return -EINVAL; | ||
235 | |||
236 | /* Merge 2 cyclic windows */ | ||
237 | i = phases_15; | ||
238 | for (cnt = 0; cnt < phases_0; cnt++) { | ||
239 | ranges[phase_15_raw_index][i] = | ||
240 | ranges[phase_0_raw_index][cnt]; | ||
241 | if (++i >= MAX_PHASES) | ||
242 | break; | ||
243 | } | ||
244 | |||
245 | phases_per_row[phase_0_raw_index] = 0; | ||
246 | phases_per_row[phase_15_raw_index] = phases_15 + phases_0; | ||
247 | } | ||
248 | |||
249 | for (cnt = 0; cnt <= row_index; cnt++) { | ||
250 | if (phases_per_row[cnt] > curr_max) { | ||
251 | curr_max = phases_per_row[cnt]; | ||
252 | selected_row_index = cnt; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | i = (curr_max * 3) / 4; | ||
257 | if (i) | ||
258 | i--; | ||
259 | |||
260 | ret = ranges[selected_row_index][i]; | ||
261 | |||
262 | if (ret >= MAX_PHASES) { | ||
263 | ret = -EINVAL; | ||
264 | dev_err(mmc_dev(mmc), "%s: Invalid phase selected=%d\n", | ||
265 | mmc_hostname(mmc), ret); | ||
266 | } | ||
267 | |||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | static inline void msm_cm_dll_set_freq(struct sdhci_host *host) | ||
272 | { | ||
273 | u32 mclk_freq = 0, config; | ||
274 | |||
275 | /* Program the MCLK value to MCLK_FREQ bit field */ | ||
276 | if (host->clock <= 112000000) | ||
277 | mclk_freq = 0; | ||
278 | else if (host->clock <= 125000000) | ||
279 | mclk_freq = 1; | ||
280 | else if (host->clock <= 137000000) | ||
281 | mclk_freq = 2; | ||
282 | else if (host->clock <= 150000000) | ||
283 | mclk_freq = 3; | ||
284 | else if (host->clock <= 162000000) | ||
285 | mclk_freq = 4; | ||
286 | else if (host->clock <= 175000000) | ||
287 | mclk_freq = 5; | ||
288 | else if (host->clock <= 187000000) | ||
289 | mclk_freq = 6; | ||
290 | else if (host->clock <= 200000000) | ||
291 | mclk_freq = 7; | ||
292 | |||
293 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG); | ||
294 | config &= ~CMUX_SHIFT_PHASE_MASK; | ||
295 | config |= mclk_freq << CMUX_SHIFT_PHASE_SHIFT; | ||
296 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG); | ||
297 | } | ||
298 | |||
299 | /* Initialize the DLL (Programmable Delay Line) */ | ||
300 | static int msm_init_cm_dll(struct sdhci_host *host) | ||
301 | { | ||
302 | struct mmc_host *mmc = host->mmc; | ||
303 | int wait_cnt = 50; | ||
304 | unsigned long flags; | ||
305 | |||
306 | spin_lock_irqsave(&host->lock, flags); | ||
307 | |||
308 | /* | ||
309 | * Make sure that clock is always enabled when DLL | ||
310 | * tuning is in progress. Keeping PWRSAVE ON may | ||
311 | * turn off the clock. | ||
312 | */ | ||
313 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC) | ||
314 | & ~CORE_CLK_PWRSAVE), host->ioaddr + CORE_VENDOR_SPEC); | ||
315 | |||
316 | /* Write 1 to DLL_RST bit of DLL_CONFIG register */ | ||
317 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) | ||
318 | | CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG); | ||
319 | |||
320 | /* Write 1 to DLL_PDN bit of DLL_CONFIG register */ | ||
321 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) | ||
322 | | CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG); | ||
323 | msm_cm_dll_set_freq(host); | ||
324 | |||
325 | /* Write 0 to DLL_RST bit of DLL_CONFIG register */ | ||
326 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) | ||
327 | & ~CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG); | ||
328 | |||
329 | /* Write 0 to DLL_PDN bit of DLL_CONFIG register */ | ||
330 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) | ||
331 | & ~CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG); | ||
332 | |||
333 | /* Set DLL_EN bit to 1. */ | ||
334 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) | ||
335 | | CORE_DLL_EN), host->ioaddr + CORE_DLL_CONFIG); | ||
336 | |||
337 | /* Set CK_OUT_EN bit to 1. */ | ||
338 | writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG) | ||
339 | | CORE_CK_OUT_EN), host->ioaddr + CORE_DLL_CONFIG); | ||
340 | |||
341 | /* Wait until DLL_LOCK bit of DLL_STATUS register becomes '1' */ | ||
342 | while (!(readl_relaxed(host->ioaddr + CORE_DLL_STATUS) & | ||
343 | CORE_DLL_LOCK)) { | ||
344 | /* max. wait for 50us sec for LOCK bit to be set */ | ||
345 | if (--wait_cnt == 0) { | ||
346 | dev_err(mmc_dev(mmc), "%s: DLL failed to LOCK\n", | ||
347 | mmc_hostname(mmc)); | ||
348 | spin_unlock_irqrestore(&host->lock, flags); | ||
349 | return -ETIMEDOUT; | ||
350 | } | ||
351 | udelay(1); | ||
352 | } | ||
353 | |||
354 | spin_unlock_irqrestore(&host->lock, flags); | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode) | ||
359 | { | ||
360 | int tuning_seq_cnt = 3; | ||
361 | u8 phase, *data_buf, tuned_phases[16], tuned_phase_cnt = 0; | ||
362 | const u32 *tuning_block_pattern = tuning_block_64; | ||
363 | int size = sizeof(tuning_block_64); /* Pattern size in bytes */ | ||
364 | int rc; | ||
365 | struct mmc_host *mmc = host->mmc; | ||
366 | struct mmc_ios ios = host->mmc->ios; | ||
367 | |||
368 | /* | ||
369 | * Tuning is required for SDR104, HS200 and HS400 cards and | ||
370 | * if clock frequency is greater than 100MHz in these modes. | ||
371 | */ | ||
372 | if (host->clock <= 100 * 1000 * 1000 || | ||
373 | !((ios.timing == MMC_TIMING_MMC_HS200) || | ||
374 | (ios.timing == MMC_TIMING_UHS_SDR104))) | ||
375 | return 0; | ||
376 | |||
377 | if ((opcode == MMC_SEND_TUNING_BLOCK_HS200) && | ||
378 | (mmc->ios.bus_width == MMC_BUS_WIDTH_8)) { | ||
379 | tuning_block_pattern = tuning_block_128; | ||
380 | size = sizeof(tuning_block_128); | ||
381 | } | ||
382 | |||
383 | data_buf = kmalloc(size, GFP_KERNEL); | ||
384 | if (!data_buf) | ||
385 | return -ENOMEM; | ||
386 | |||
387 | retry: | ||
388 | /* First of all reset the tuning block */ | ||
389 | rc = msm_init_cm_dll(host); | ||
390 | if (rc) | ||
391 | goto out; | ||
392 | |||
393 | phase = 0; | ||
394 | do { | ||
395 | struct mmc_command cmd = { 0 }; | ||
396 | struct mmc_data data = { 0 }; | ||
397 | struct mmc_request mrq = { | ||
398 | .cmd = &cmd, | ||
399 | .data = &data | ||
400 | }; | ||
401 | struct scatterlist sg; | ||
402 | |||
403 | /* Set the phase in delay line hw block */ | ||
404 | rc = msm_config_cm_dll_phase(host, phase); | ||
405 | if (rc) | ||
406 | goto out; | ||
407 | |||
408 | cmd.opcode = opcode; | ||
409 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
410 | |||
411 | data.blksz = size; | ||
412 | data.blocks = 1; | ||
413 | data.flags = MMC_DATA_READ; | ||
414 | data.timeout_ns = NSEC_PER_SEC; /* 1 second */ | ||
415 | |||
416 | data.sg = &sg; | ||
417 | data.sg_len = 1; | ||
418 | sg_init_one(&sg, data_buf, size); | ||
419 | memset(data_buf, 0, size); | ||
420 | mmc_wait_for_req(mmc, &mrq); | ||
421 | |||
422 | if (!cmd.error && !data.error && | ||
423 | !memcmp(data_buf, tuning_block_pattern, size)) { | ||
424 | /* Tuning is successful at this tuning point */ | ||
425 | tuned_phases[tuned_phase_cnt++] = phase; | ||
426 | dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n", | ||
427 | mmc_hostname(mmc), phase); | ||
428 | } | ||
429 | } while (++phase < ARRAY_SIZE(tuned_phases)); | ||
430 | |||
431 | if (tuned_phase_cnt) { | ||
432 | rc = msm_find_most_appropriate_phase(host, tuned_phases, | ||
433 | tuned_phase_cnt); | ||
434 | if (rc < 0) | ||
435 | goto out; | ||
436 | else | ||
437 | phase = rc; | ||
438 | |||
439 | /* | ||
440 | * Finally set the selected phase in delay | ||
441 | * line hw block. | ||
442 | */ | ||
443 | rc = msm_config_cm_dll_phase(host, phase); | ||
444 | if (rc) | ||
445 | goto out; | ||
446 | dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", | ||
447 | mmc_hostname(mmc), phase); | ||
448 | } else { | ||
449 | if (--tuning_seq_cnt) | ||
450 | goto retry; | ||
451 | /* Tuning failed */ | ||
452 | dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n", | ||
453 | mmc_hostname(mmc)); | ||
454 | rc = -EIO; | ||
455 | } | ||
456 | |||
457 | out: | ||
458 | kfree(data_buf); | ||
459 | return rc; | ||
460 | } | ||
461 | |||
462 | static const struct of_device_id sdhci_msm_dt_match[] = { | ||
463 | { .compatible = "qcom,sdhci-msm-v4" }, | ||
464 | {}, | ||
465 | }; | ||
466 | |||
467 | MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match); | ||
468 | |||
469 | static struct sdhci_ops sdhci_msm_ops = { | ||
470 | .platform_execute_tuning = sdhci_msm_execute_tuning, | ||
471 | }; | ||
472 | |||
473 | static int sdhci_msm_probe(struct platform_device *pdev) | ||
474 | { | ||
475 | struct sdhci_host *host; | ||
476 | struct sdhci_pltfm_host *pltfm_host; | ||
477 | struct sdhci_msm_host *msm_host; | ||
478 | struct resource *core_memres; | ||
479 | int ret; | ||
480 | u16 host_version; | ||
481 | |||
482 | msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL); | ||
483 | if (!msm_host) | ||
484 | return -ENOMEM; | ||
485 | |||
486 | msm_host->sdhci_msm_pdata.ops = &sdhci_msm_ops; | ||
487 | host = sdhci_pltfm_init(pdev, &msm_host->sdhci_msm_pdata, 0); | ||
488 | if (IS_ERR(host)) | ||
489 | return PTR_ERR(host); | ||
490 | |||
491 | pltfm_host = sdhci_priv(host); | ||
492 | pltfm_host->priv = msm_host; | ||
493 | msm_host->mmc = host->mmc; | ||
494 | msm_host->pdev = pdev; | ||
495 | |||
496 | ret = mmc_of_parse(host->mmc); | ||
497 | if (ret) | ||
498 | goto pltfm_free; | ||
499 | |||
500 | sdhci_get_of_property(pdev); | ||
501 | |||
502 | /* Setup SDCC bus voter clock. */ | ||
503 | msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus"); | ||
504 | if (!IS_ERR(msm_host->bus_clk)) { | ||
505 | /* Vote for max. clk rate for max. performance */ | ||
506 | ret = clk_set_rate(msm_host->bus_clk, INT_MAX); | ||
507 | if (ret) | ||
508 | goto pltfm_free; | ||
509 | ret = clk_prepare_enable(msm_host->bus_clk); | ||
510 | if (ret) | ||
511 | goto pltfm_free; | ||
512 | } | ||
513 | |||
514 | /* Setup main peripheral bus clock */ | ||
515 | msm_host->pclk = devm_clk_get(&pdev->dev, "iface"); | ||
516 | if (IS_ERR(msm_host->pclk)) { | ||
517 | ret = PTR_ERR(msm_host->pclk); | ||
518 | dev_err(&pdev->dev, "Perpheral clk setup failed (%d)\n", ret); | ||
519 | goto bus_clk_disable; | ||
520 | } | ||
521 | |||
522 | ret = clk_prepare_enable(msm_host->pclk); | ||
523 | if (ret) | ||
524 | goto bus_clk_disable; | ||
525 | |||
526 | /* Setup SDC MMC clock */ | ||
527 | msm_host->clk = devm_clk_get(&pdev->dev, "core"); | ||
528 | if (IS_ERR(msm_host->clk)) { | ||
529 | ret = PTR_ERR(msm_host->clk); | ||
530 | dev_err(&pdev->dev, "SDC MMC clk setup failed (%d)\n", ret); | ||
531 | goto pclk_disable; | ||
532 | } | ||
533 | |||
534 | ret = clk_prepare_enable(msm_host->clk); | ||
535 | if (ret) | ||
536 | goto pclk_disable; | ||
537 | |||
538 | core_memres = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
539 | msm_host->core_mem = devm_ioremap_resource(&pdev->dev, core_memres); | ||
540 | |||
541 | if (IS_ERR(msm_host->core_mem)) { | ||
542 | dev_err(&pdev->dev, "Failed to remap registers\n"); | ||
543 | ret = PTR_ERR(msm_host->core_mem); | ||
544 | goto clk_disable; | ||
545 | } | ||
546 | |||
547 | /* Reset the core and Enable SDHC mode */ | ||
548 | writel_relaxed(readl_relaxed(msm_host->core_mem + CORE_POWER) | | ||
549 | CORE_SW_RST, msm_host->core_mem + CORE_POWER); | ||
550 | |||
551 | /* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */ | ||
552 | usleep_range(1000, 5000); | ||
553 | if (readl(msm_host->core_mem + CORE_POWER) & CORE_SW_RST) { | ||
554 | dev_err(&pdev->dev, "Stuck in reset\n"); | ||
555 | ret = -ETIMEDOUT; | ||
556 | goto clk_disable; | ||
557 | } | ||
558 | |||
559 | /* Set HC_MODE_EN bit in HC_MODE register */ | ||
560 | writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE)); | ||
561 | |||
562 | host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; | ||
563 | host->quirks |= SDHCI_QUIRK_SINGLE_POWER_WRITE; | ||
564 | |||
565 | host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); | ||
566 | dev_dbg(&pdev->dev, "Host Version: 0x%x Vendor Version 0x%x\n", | ||
567 | host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >> | ||
568 | SDHCI_VENDOR_VER_SHIFT)); | ||
569 | |||
570 | ret = sdhci_add_host(host); | ||
571 | if (ret) | ||
572 | goto clk_disable; | ||
573 | |||
574 | return 0; | ||
575 | |||
576 | clk_disable: | ||
577 | clk_disable_unprepare(msm_host->clk); | ||
578 | pclk_disable: | ||
579 | clk_disable_unprepare(msm_host->pclk); | ||
580 | bus_clk_disable: | ||
581 | if (!IS_ERR(msm_host->bus_clk)) | ||
582 | clk_disable_unprepare(msm_host->bus_clk); | ||
583 | pltfm_free: | ||
584 | sdhci_pltfm_free(pdev); | ||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | static int sdhci_msm_remove(struct platform_device *pdev) | ||
589 | { | ||
590 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
591 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
592 | struct sdhci_msm_host *msm_host = pltfm_host->priv; | ||
593 | int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) == | ||
594 | 0xffffffff); | ||
595 | |||
596 | sdhci_remove_host(host, dead); | ||
597 | sdhci_pltfm_free(pdev); | ||
598 | clk_disable_unprepare(msm_host->clk); | ||
599 | clk_disable_unprepare(msm_host->pclk); | ||
600 | if (!IS_ERR(msm_host->bus_clk)) | ||
601 | clk_disable_unprepare(msm_host->bus_clk); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static struct platform_driver sdhci_msm_driver = { | ||
606 | .probe = sdhci_msm_probe, | ||
607 | .remove = sdhci_msm_remove, | ||
608 | .driver = { | ||
609 | .name = "sdhci_msm", | ||
610 | .owner = THIS_MODULE, | ||
611 | .of_match_table = sdhci_msm_dt_match, | ||
612 | }, | ||
613 | }; | ||
614 | |||
615 | module_platform_driver(sdhci_msm_driver); | ||
616 | |||
617 | MODULE_DESCRIPTION("Qualcomm Secure Digital Host Controller Interface driver"); | ||
618 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 0955777b6c7e..fdc612120362 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -610,6 +610,18 @@ static const struct sdhci_pci_fixes sdhci_via = { | |||
610 | .probe = via_probe, | 610 | .probe = via_probe, |
611 | }; | 611 | }; |
612 | 612 | ||
613 | static int rtsx_probe_slot(struct sdhci_pci_slot *slot) | ||
614 | { | ||
615 | slot->host->mmc->caps2 |= MMC_CAP2_HS200; | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static const struct sdhci_pci_fixes sdhci_rtsx = { | ||
620 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | ||
621 | SDHCI_QUIRK2_BROKEN_DDR50, | ||
622 | .probe_slot = rtsx_probe_slot, | ||
623 | }; | ||
624 | |||
613 | static const struct pci_device_id pci_ids[] = { | 625 | static const struct pci_device_id pci_ids[] = { |
614 | { | 626 | { |
615 | .vendor = PCI_VENDOR_ID_RICOH, | 627 | .vendor = PCI_VENDOR_ID_RICOH, |
@@ -732,6 +744,14 @@ static const struct pci_device_id pci_ids[] = { | |||
732 | }, | 744 | }, |
733 | 745 | ||
734 | { | 746 | { |
747 | .vendor = PCI_VENDOR_ID_REALTEK, | ||
748 | .device = 0x5250, | ||
749 | .subvendor = PCI_ANY_ID, | ||
750 | .subdevice = PCI_ANY_ID, | ||
751 | .driver_data = (kernel_ulong_t)&sdhci_rtsx, | ||
752 | }, | ||
753 | |||
754 | { | ||
735 | .vendor = PCI_VENDOR_ID_INTEL, | 755 | .vendor = PCI_VENDOR_ID_INTEL, |
736 | .device = PCI_DEVICE_ID_INTEL_MRST_SD0, | 756 | .device = PCI_DEVICE_ID_INTEL_MRST_SD0, |
737 | .subvendor = PCI_ANY_ID, | 757 | .subvendor = PCI_ANY_ID, |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 793dacd3b841..2fd73b38c303 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/of_gpio.h> | 34 | #include <linux/of_gpio.h> |
35 | #include <linux/pm.h> | 35 | #include <linux/pm.h> |
36 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
37 | #include <linux/mbus.h> | ||
37 | 38 | ||
38 | #include "sdhci.h" | 39 | #include "sdhci.h" |
39 | #include "sdhci-pltfm.h" | 40 | #include "sdhci-pltfm.h" |
@@ -57,6 +58,60 @@ | |||
57 | #define SDCE_MISC_INT (1<<2) | 58 | #define SDCE_MISC_INT (1<<2) |
58 | #define SDCE_MISC_INT_EN (1<<1) | 59 | #define SDCE_MISC_INT_EN (1<<1) |
59 | 60 | ||
61 | /* | ||
62 | * These registers are relative to the second register region, for the | ||
63 | * MBus bridge. | ||
64 | */ | ||
65 | #define SDHCI_WINDOW_CTRL(i) (0x80 + ((i) << 3)) | ||
66 | #define SDHCI_WINDOW_BASE(i) (0x84 + ((i) << 3)) | ||
67 | #define SDHCI_MAX_WIN_NUM 8 | ||
68 | |||
69 | static int mv_conf_mbus_windows(struct platform_device *pdev, | ||
70 | const struct mbus_dram_target_info *dram) | ||
71 | { | ||
72 | int i; | ||
73 | void __iomem *regs; | ||
74 | struct resource *res; | ||
75 | |||
76 | if (!dram) { | ||
77 | dev_err(&pdev->dev, "no mbus dram info\n"); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | |||
81 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
82 | if (!res) { | ||
83 | dev_err(&pdev->dev, "cannot get mbus registers\n"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | regs = ioremap(res->start, resource_size(res)); | ||
88 | if (!regs) { | ||
89 | dev_err(&pdev->dev, "cannot map mbus registers\n"); | ||
90 | return -ENOMEM; | ||
91 | } | ||
92 | |||
93 | for (i = 0; i < SDHCI_MAX_WIN_NUM; i++) { | ||
94 | writel(0, regs + SDHCI_WINDOW_CTRL(i)); | ||
95 | writel(0, regs + SDHCI_WINDOW_BASE(i)); | ||
96 | } | ||
97 | |||
98 | for (i = 0; i < dram->num_cs; i++) { | ||
99 | const struct mbus_dram_window *cs = dram->cs + i; | ||
100 | |||
101 | /* Write size, attributes and target id to control register */ | ||
102 | writel(((cs->size - 1) & 0xffff0000) | | ||
103 | (cs->mbus_attr << 8) | | ||
104 | (dram->mbus_dram_target_id << 4) | 1, | ||
105 | regs + SDHCI_WINDOW_CTRL(i)); | ||
106 | /* Write base address to base register */ | ||
107 | writel(cs->base, regs + SDHCI_WINDOW_BASE(i)); | ||
108 | } | ||
109 | |||
110 | iounmap(regs); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
60 | static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask) | 115 | static void pxav3_set_private_registers(struct sdhci_host *host, u8 mask) |
61 | { | 116 | { |
62 | struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc)); | 117 | struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc)); |
@@ -187,6 +242,9 @@ static const struct of_device_id sdhci_pxav3_of_match[] = { | |||
187 | { | 242 | { |
188 | .compatible = "mrvl,pxav3-mmc", | 243 | .compatible = "mrvl,pxav3-mmc", |
189 | }, | 244 | }, |
245 | { | ||
246 | .compatible = "marvell,armada-380-sdhci", | ||
247 | }, | ||
190 | {}, | 248 | {}, |
191 | }; | 249 | }; |
192 | MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match); | 250 | MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match); |
@@ -219,6 +277,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
219 | struct sdhci_pltfm_host *pltfm_host; | 277 | struct sdhci_pltfm_host *pltfm_host; |
220 | struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; | 278 | struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; |
221 | struct device *dev = &pdev->dev; | 279 | struct device *dev = &pdev->dev; |
280 | struct device_node *np = pdev->dev.of_node; | ||
222 | struct sdhci_host *host = NULL; | 281 | struct sdhci_host *host = NULL; |
223 | struct sdhci_pxa *pxa = NULL; | 282 | struct sdhci_pxa *pxa = NULL; |
224 | const struct of_device_id *match; | 283 | const struct of_device_id *match; |
@@ -235,6 +294,14 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
235 | kfree(pxa); | 294 | kfree(pxa); |
236 | return PTR_ERR(host); | 295 | return PTR_ERR(host); |
237 | } | 296 | } |
297 | |||
298 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | ||
299 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | ||
300 | if (ret < 0) | ||
301 | goto err_mbus_win; | ||
302 | } | ||
303 | |||
304 | |||
238 | pltfm_host = sdhci_priv(host); | 305 | pltfm_host = sdhci_priv(host); |
239 | pltfm_host->priv = pxa; | 306 | pltfm_host->priv = pxa; |
240 | 307 | ||
@@ -321,6 +388,7 @@ err_add_host: | |||
321 | clk_disable_unprepare(clk); | 388 | clk_disable_unprepare(clk); |
322 | clk_put(clk); | 389 | clk_put(clk); |
323 | err_clk_get: | 390 | err_clk_get: |
391 | err_mbus_win: | ||
324 | sdhci_pltfm_free(pdev); | 392 | sdhci_pltfm_free(pdev); |
325 | kfree(pxa); | 393 | kfree(pxa); |
326 | return ret; | 394 | return ret; |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 6debda952155..d61eb5a70833 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -51,12 +51,13 @@ struct sdhci_s3c { | |||
51 | struct platform_device *pdev; | 51 | struct platform_device *pdev; |
52 | struct resource *ioarea; | 52 | struct resource *ioarea; |
53 | struct s3c_sdhci_platdata *pdata; | 53 | struct s3c_sdhci_platdata *pdata; |
54 | unsigned int cur_clk; | 54 | int cur_clk; |
55 | int ext_cd_irq; | 55 | int ext_cd_irq; |
56 | int ext_cd_gpio; | 56 | int ext_cd_gpio; |
57 | 57 | ||
58 | struct clk *clk_io; | 58 | struct clk *clk_io; |
59 | struct clk *clk_bus[MAX_BUS_CLK]; | 59 | struct clk *clk_bus[MAX_BUS_CLK]; |
60 | unsigned long clk_rates[MAX_BUS_CLK]; | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | /** | 63 | /** |
@@ -77,32 +78,6 @@ static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) | |||
77 | } | 78 | } |
78 | 79 | ||
79 | /** | 80 | /** |
80 | * get_curclk - convert ctrl2 register to clock source number | ||
81 | * @ctrl2: Control2 register value. | ||
82 | */ | ||
83 | static u32 get_curclk(u32 ctrl2) | ||
84 | { | ||
85 | ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK; | ||
86 | ctrl2 >>= S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; | ||
87 | |||
88 | return ctrl2; | ||
89 | } | ||
90 | |||
91 | static void sdhci_s3c_check_sclk(struct sdhci_host *host) | ||
92 | { | ||
93 | struct sdhci_s3c *ourhost = to_s3c(host); | ||
94 | u32 tmp = readl(host->ioaddr + S3C_SDHCI_CONTROL2); | ||
95 | |||
96 | if (get_curclk(tmp) != ourhost->cur_clk) { | ||
97 | dev_dbg(&ourhost->pdev->dev, "restored ctrl2 clock setting\n"); | ||
98 | |||
99 | tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; | ||
100 | tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; | ||
101 | writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * sdhci_s3c_get_max_clk - callback to get maximum clock frequency. | 81 | * sdhci_s3c_get_max_clk - callback to get maximum clock frequency. |
107 | * @host: The SDHCI host instance. | 82 | * @host: The SDHCI host instance. |
108 | * | 83 | * |
@@ -111,20 +86,11 @@ static void sdhci_s3c_check_sclk(struct sdhci_host *host) | |||
111 | static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host) | 86 | static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host) |
112 | { | 87 | { |
113 | struct sdhci_s3c *ourhost = to_s3c(host); | 88 | struct sdhci_s3c *ourhost = to_s3c(host); |
114 | struct clk *busclk; | 89 | unsigned long rate, max = 0; |
115 | unsigned int rate, max; | 90 | int src; |
116 | int clk; | ||
117 | |||
118 | /* note, a reset will reset the clock source */ | ||
119 | |||
120 | sdhci_s3c_check_sclk(host); | ||
121 | |||
122 | for (max = 0, clk = 0; clk < MAX_BUS_CLK; clk++) { | ||
123 | busclk = ourhost->clk_bus[clk]; | ||
124 | if (!busclk) | ||
125 | continue; | ||
126 | 91 | ||
127 | rate = clk_get_rate(busclk); | 92 | for (src = 0; src < MAX_BUS_CLK; src++) { |
93 | rate = ourhost->clk_rates[src]; | ||
128 | if (rate > max) | 94 | if (rate > max) |
129 | max = rate; | 95 | max = rate; |
130 | } | 96 | } |
@@ -144,9 +110,9 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, | |||
144 | { | 110 | { |
145 | unsigned long rate; | 111 | unsigned long rate; |
146 | struct clk *clksrc = ourhost->clk_bus[src]; | 112 | struct clk *clksrc = ourhost->clk_bus[src]; |
147 | int div; | 113 | int shift; |
148 | 114 | ||
149 | if (!clksrc) | 115 | if (IS_ERR(clksrc)) |
150 | return UINT_MAX; | 116 | return UINT_MAX; |
151 | 117 | ||
152 | /* | 118 | /* |
@@ -158,17 +124,24 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, | |||
158 | return wanted - rate; | 124 | return wanted - rate; |
159 | } | 125 | } |
160 | 126 | ||
161 | rate = clk_get_rate(clksrc); | 127 | rate = ourhost->clk_rates[src]; |
162 | 128 | ||
163 | for (div = 1; div < 256; div *= 2) { | 129 | for (shift = 0; shift <= 8; ++shift) { |
164 | if ((rate / div) <= wanted) | 130 | if ((rate >> shift) <= wanted) |
165 | break; | 131 | break; |
166 | } | 132 | } |
167 | 133 | ||
134 | if (shift > 8) { | ||
135 | dev_dbg(&ourhost->pdev->dev, | ||
136 | "clk %d: rate %ld, min rate %lu > wanted %u\n", | ||
137 | src, rate, rate / 256, wanted); | ||
138 | return UINT_MAX; | ||
139 | } | ||
140 | |||
168 | dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n", | 141 | dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n", |
169 | src, rate, wanted, rate / div); | 142 | src, rate, wanted, rate >> shift); |
170 | 143 | ||
171 | return wanted - (rate / div); | 144 | return wanted - (rate >> shift); |
172 | } | 145 | } |
173 | 146 | ||
174 | /** | 147 | /** |
@@ -209,20 +182,22 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) | |||
209 | struct clk *clk = ourhost->clk_bus[best_src]; | 182 | struct clk *clk = ourhost->clk_bus[best_src]; |
210 | 183 | ||
211 | clk_prepare_enable(clk); | 184 | clk_prepare_enable(clk); |
212 | clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); | 185 | if (ourhost->cur_clk >= 0) |
213 | 186 | clk_disable_unprepare( | |
214 | /* turn clock off to card before changing clock source */ | 187 | ourhost->clk_bus[ourhost->cur_clk]); |
215 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); | ||
216 | 188 | ||
217 | ourhost->cur_clk = best_src; | 189 | ourhost->cur_clk = best_src; |
218 | host->max_clk = clk_get_rate(clk); | 190 | host->max_clk = ourhost->clk_rates[best_src]; |
219 | |||
220 | ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2); | ||
221 | ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; | ||
222 | ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; | ||
223 | writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2); | ||
224 | } | 191 | } |
225 | 192 | ||
193 | /* turn clock off to card before changing clock source */ | ||
194 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); | ||
195 | |||
196 | ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2); | ||
197 | ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; | ||
198 | ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; | ||
199 | writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2); | ||
200 | |||
226 | /* reprogram default hardware configuration */ | 201 | /* reprogram default hardware configuration */ |
227 | writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, | 202 | writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, |
228 | host->ioaddr + S3C64XX_SDHCI_CONTROL4); | 203 | host->ioaddr + S3C64XX_SDHCI_CONTROL4); |
@@ -254,17 +229,17 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) | |||
254 | static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) | 229 | static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) |
255 | { | 230 | { |
256 | struct sdhci_s3c *ourhost = to_s3c(host); | 231 | struct sdhci_s3c *ourhost = to_s3c(host); |
257 | unsigned int delta, min = UINT_MAX; | 232 | unsigned long rate, min = ULONG_MAX; |
258 | int src; | 233 | int src; |
259 | 234 | ||
260 | for (src = 0; src < MAX_BUS_CLK; src++) { | 235 | for (src = 0; src < MAX_BUS_CLK; src++) { |
261 | delta = sdhci_s3c_consider_clock(ourhost, src, 0); | 236 | rate = ourhost->clk_rates[src] / 256; |
262 | if (delta == UINT_MAX) | 237 | if (!rate) |
263 | continue; | 238 | continue; |
264 | /* delta is a negative value in this case */ | 239 | if (rate < min) |
265 | if (-delta < min) | 240 | min = rate; |
266 | min = -delta; | ||
267 | } | 241 | } |
242 | |||
268 | return min; | 243 | return min; |
269 | } | 244 | } |
270 | 245 | ||
@@ -272,20 +247,44 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) | |||
272 | static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host) | 247 | static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host) |
273 | { | 248 | { |
274 | struct sdhci_s3c *ourhost = to_s3c(host); | 249 | struct sdhci_s3c *ourhost = to_s3c(host); |
250 | unsigned long rate, max = 0; | ||
251 | int src; | ||
275 | 252 | ||
276 | return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], UINT_MAX); | 253 | for (src = 0; src < MAX_BUS_CLK; src++) { |
254 | struct clk *clk; | ||
255 | |||
256 | clk = ourhost->clk_bus[src]; | ||
257 | if (IS_ERR(clk)) | ||
258 | continue; | ||
259 | |||
260 | rate = clk_round_rate(clk, ULONG_MAX); | ||
261 | if (rate > max) | ||
262 | max = rate; | ||
263 | } | ||
264 | |||
265 | return max; | ||
277 | } | 266 | } |
278 | 267 | ||
279 | /* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */ | 268 | /* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */ |
280 | static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) | 269 | static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) |
281 | { | 270 | { |
282 | struct sdhci_s3c *ourhost = to_s3c(host); | 271 | struct sdhci_s3c *ourhost = to_s3c(host); |
272 | unsigned long rate, min = ULONG_MAX; | ||
273 | int src; | ||
283 | 274 | ||
284 | /* | 275 | for (src = 0; src < MAX_BUS_CLK; src++) { |
285 | * initial clock can be in the frequency range of | 276 | struct clk *clk; |
286 | * 100KHz-400KHz, so we set it as max value. | 277 | |
287 | */ | 278 | clk = ourhost->clk_bus[src]; |
288 | return clk_round_rate(ourhost->clk_bus[ourhost->cur_clk], 400000); | 279 | if (IS_ERR(clk)) |
280 | continue; | ||
281 | |||
282 | rate = clk_round_rate(clk, 0); | ||
283 | if (rate < min) | ||
284 | min = rate; | ||
285 | } | ||
286 | |||
287 | return min; | ||
289 | } | 288 | } |
290 | 289 | ||
291 | /* sdhci_cmu_set_clock - callback on clock change.*/ | 290 | /* sdhci_cmu_set_clock - callback on clock change.*/ |
@@ -552,6 +551,7 @@ static int sdhci_s3c_probe(struct platform_device *pdev) | |||
552 | sc->host = host; | 551 | sc->host = host; |
553 | sc->pdev = pdev; | 552 | sc->pdev = pdev; |
554 | sc->pdata = pdata; | 553 | sc->pdata = pdata; |
554 | sc->cur_clk = -1; | ||
555 | 555 | ||
556 | platform_set_drvdata(pdev, host); | 556 | platform_set_drvdata(pdev, host); |
557 | 557 | ||
@@ -566,25 +566,18 @@ static int sdhci_s3c_probe(struct platform_device *pdev) | |||
566 | clk_prepare_enable(sc->clk_io); | 566 | clk_prepare_enable(sc->clk_io); |
567 | 567 | ||
568 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 568 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
569 | struct clk *clk; | ||
570 | char name[14]; | 569 | char name[14]; |
571 | 570 | ||
572 | snprintf(name, 14, "mmc_busclk.%d", ptr); | 571 | snprintf(name, 14, "mmc_busclk.%d", ptr); |
573 | clk = devm_clk_get(dev, name); | 572 | sc->clk_bus[ptr] = devm_clk_get(dev, name); |
574 | if (IS_ERR(clk)) | 573 | if (IS_ERR(sc->clk_bus[ptr])) |
575 | continue; | 574 | continue; |
576 | 575 | ||
577 | clks++; | 576 | clks++; |
578 | sc->clk_bus[ptr] = clk; | 577 | sc->clk_rates[ptr] = clk_get_rate(sc->clk_bus[ptr]); |
579 | |||
580 | /* | ||
581 | * save current clock index to know which clock bus | ||
582 | * is used later in overriding functions. | ||
583 | */ | ||
584 | sc->cur_clk = ptr; | ||
585 | 578 | ||
586 | dev_info(dev, "clock source %d: %s (%ld Hz)\n", | 579 | dev_info(dev, "clock source %d: %s (%ld Hz)\n", |
587 | ptr, name, clk_get_rate(clk)); | 580 | ptr, name, sc->clk_rates[ptr]); |
588 | } | 581 | } |
589 | 582 | ||
590 | if (clks == 0) { | 583 | if (clks == 0) { |
@@ -593,10 +586,6 @@ static int sdhci_s3c_probe(struct platform_device *pdev) | |||
593 | goto err_no_busclks; | 586 | goto err_no_busclks; |
594 | } | 587 | } |
595 | 588 | ||
596 | #ifndef CONFIG_PM_RUNTIME | ||
597 | clk_prepare_enable(sc->clk_bus[sc->cur_clk]); | ||
598 | #endif | ||
599 | |||
600 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 589 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
601 | host->ioaddr = devm_ioremap_resource(&pdev->dev, res); | 590 | host->ioaddr = devm_ioremap_resource(&pdev->dev, res); |
602 | if (IS_ERR(host->ioaddr)) { | 591 | if (IS_ERR(host->ioaddr)) { |
@@ -709,10 +698,6 @@ static int sdhci_s3c_probe(struct platform_device *pdev) | |||
709 | return 0; | 698 | return 0; |
710 | 699 | ||
711 | err_req_regs: | 700 | err_req_regs: |
712 | #ifndef CONFIG_PM_RUNTIME | ||
713 | clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); | ||
714 | #endif | ||
715 | |||
716 | err_no_busclks: | 701 | err_no_busclks: |
717 | clk_disable_unprepare(sc->clk_io); | 702 | clk_disable_unprepare(sc->clk_io); |
718 | 703 | ||
@@ -743,9 +728,6 @@ static int sdhci_s3c_remove(struct platform_device *pdev) | |||
743 | pm_runtime_dont_use_autosuspend(&pdev->dev); | 728 | pm_runtime_dont_use_autosuspend(&pdev->dev); |
744 | pm_runtime_disable(&pdev->dev); | 729 | pm_runtime_disable(&pdev->dev); |
745 | 730 | ||
746 | #ifndef CONFIG_PM_RUNTIME | ||
747 | clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); | ||
748 | #endif | ||
749 | clk_disable_unprepare(sc->clk_io); | 731 | clk_disable_unprepare(sc->clk_io); |
750 | 732 | ||
751 | sdhci_free_host(host); | 733 | sdhci_free_host(host); |
@@ -779,7 +761,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) | |||
779 | 761 | ||
780 | ret = sdhci_runtime_suspend_host(host); | 762 | ret = sdhci_runtime_suspend_host(host); |
781 | 763 | ||
782 | clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); | 764 | if (ourhost->cur_clk >= 0) |
765 | clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); | ||
783 | clk_disable_unprepare(busclk); | 766 | clk_disable_unprepare(busclk); |
784 | return ret; | 767 | return ret; |
785 | } | 768 | } |
@@ -792,7 +775,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) | |||
792 | int ret; | 775 | int ret; |
793 | 776 | ||
794 | clk_prepare_enable(busclk); | 777 | clk_prepare_enable(busclk); |
795 | clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); | 778 | if (ourhost->cur_clk >= 0) |
779 | clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); | ||
796 | ret = sdhci_runtime_resume_host(host); | 780 | ret = sdhci_runtime_resume_host(host); |
797 | return ret; | 781 | return ret; |
798 | } | 782 | } |
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 2dba9f8d1760..0316dec3f006 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | #include <linux/mmc/sdhci-spear.h> | 29 | #include <linux/mmc/sdhci-spear.h> |
30 | #include <linux/mmc/slot-gpio.h> | ||
30 | #include <linux/io.h> | 31 | #include <linux/io.h> |
31 | #include "sdhci.h" | 32 | #include "sdhci.h" |
32 | 33 | ||
@@ -40,36 +41,6 @@ static const struct sdhci_ops sdhci_pltfm_ops = { | |||
40 | /* Nothing to do for now. */ | 41 | /* Nothing to do for now. */ |
41 | }; | 42 | }; |
42 | 43 | ||
43 | /* gpio card detection interrupt handler */ | ||
44 | static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id) | ||
45 | { | ||
46 | struct platform_device *pdev = dev_id; | ||
47 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
48 | struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev); | ||
49 | unsigned long gpio_irq_type; | ||
50 | int val; | ||
51 | |||
52 | val = gpio_get_value(sdhci->data->card_int_gpio); | ||
53 | |||
54 | /* val == 1 -> card removed, val == 0 -> card inserted */ | ||
55 | /* if card removed - set irq for low level, else vice versa */ | ||
56 | gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH; | ||
57 | irq_set_irq_type(irq, gpio_irq_type); | ||
58 | |||
59 | if (sdhci->data->card_power_gpio >= 0) { | ||
60 | if (!sdhci->data->power_always_enb) { | ||
61 | /* if card inserted, give power, otherwise remove it */ | ||
62 | val = sdhci->data->power_active_high ? !val : val ; | ||
63 | gpio_set_value(sdhci->data->card_power_gpio, val); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | /* inform sdhci driver about card insertion/removal */ | ||
68 | tasklet_schedule(&host->card_tasklet); | ||
69 | |||
70 | return IRQ_HANDLED; | ||
71 | } | ||
72 | |||
73 | #ifdef CONFIG_OF | 44 | #ifdef CONFIG_OF |
74 | static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev) | 45 | static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pdev) |
75 | { | 46 | { |
@@ -84,14 +55,12 @@ static struct sdhci_plat_data *sdhci_probe_config_dt(struct platform_device *pde | |||
84 | /* If pdata is required */ | 55 | /* If pdata is required */ |
85 | if (cd_gpio != -1) { | 56 | if (cd_gpio != -1) { |
86 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 57 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
87 | if (!pdata) { | 58 | if (!pdata) |
88 | dev_err(&pdev->dev, "DT: kzalloc failed\n"); | 59 | dev_err(&pdev->dev, "DT: kzalloc failed\n"); |
89 | return ERR_PTR(-ENOMEM); | 60 | else |
90 | } | 61 | pdata->card_int_gpio = cd_gpio; |
91 | } | 62 | } |
92 | 63 | ||
93 | pdata->card_int_gpio = cd_gpio; | ||
94 | |||
95 | return pdata; | 64 | return pdata; |
96 | } | 65 | } |
97 | #else | 66 | #else |
@@ -107,41 +76,44 @@ static int sdhci_probe(struct platform_device *pdev) | |||
107 | struct sdhci_host *host; | 76 | struct sdhci_host *host; |
108 | struct resource *iomem; | 77 | struct resource *iomem; |
109 | struct spear_sdhci *sdhci; | 78 | struct spear_sdhci *sdhci; |
79 | struct device *dev; | ||
110 | int ret; | 80 | int ret; |
111 | 81 | ||
112 | iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 82 | dev = pdev->dev.parent ? pdev->dev.parent : &pdev->dev; |
113 | if (!iomem) { | 83 | host = sdhci_alloc_host(dev, sizeof(*sdhci)); |
114 | ret = -ENOMEM; | 84 | if (IS_ERR(host)) { |
115 | dev_dbg(&pdev->dev, "memory resource not defined\n"); | 85 | ret = PTR_ERR(host); |
86 | dev_dbg(&pdev->dev, "cannot allocate memory for sdhci\n"); | ||
116 | goto err; | 87 | goto err; |
117 | } | 88 | } |
118 | 89 | ||
119 | if (!devm_request_mem_region(&pdev->dev, iomem->start, | 90 | iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
120 | resource_size(iomem), "spear-sdhci")) { | 91 | host->ioaddr = devm_ioremap_resource(&pdev->dev, iomem); |
121 | ret = -EBUSY; | 92 | if (IS_ERR(host->ioaddr)) { |
122 | dev_dbg(&pdev->dev, "cannot request region\n"); | 93 | ret = PTR_ERR(host->ioaddr); |
123 | goto err; | 94 | dev_dbg(&pdev->dev, "unable to map iomem: %d\n", ret); |
95 | goto err_host; | ||
124 | } | 96 | } |
125 | 97 | ||
126 | sdhci = devm_kzalloc(&pdev->dev, sizeof(*sdhci), GFP_KERNEL); | 98 | host->hw_name = "sdhci"; |
127 | if (!sdhci) { | 99 | host->ops = &sdhci_pltfm_ops; |
128 | ret = -ENOMEM; | 100 | host->irq = platform_get_irq(pdev, 0); |
129 | dev_dbg(&pdev->dev, "cannot allocate memory for sdhci\n"); | 101 | host->quirks = SDHCI_QUIRK_BROKEN_ADMA; |
130 | goto err; | 102 | |
131 | } | 103 | sdhci = sdhci_priv(host); |
132 | 104 | ||
133 | /* clk enable */ | 105 | /* clk enable */ |
134 | sdhci->clk = clk_get(&pdev->dev, NULL); | 106 | sdhci->clk = devm_clk_get(&pdev->dev, NULL); |
135 | if (IS_ERR(sdhci->clk)) { | 107 | if (IS_ERR(sdhci->clk)) { |
136 | ret = PTR_ERR(sdhci->clk); | 108 | ret = PTR_ERR(sdhci->clk); |
137 | dev_dbg(&pdev->dev, "Error getting clock\n"); | 109 | dev_dbg(&pdev->dev, "Error getting clock\n"); |
138 | goto err; | 110 | goto err_host; |
139 | } | 111 | } |
140 | 112 | ||
141 | ret = clk_prepare_enable(sdhci->clk); | 113 | ret = clk_prepare_enable(sdhci->clk); |
142 | if (ret) { | 114 | if (ret) { |
143 | dev_dbg(&pdev->dev, "Error enabling clock\n"); | 115 | dev_dbg(&pdev->dev, "Error enabling clock\n"); |
144 | goto put_clk; | 116 | goto err_host; |
145 | } | 117 | } |
146 | 118 | ||
147 | ret = clk_set_rate(sdhci->clk, 50000000); | 119 | ret = clk_set_rate(sdhci->clk, 50000000); |
@@ -153,118 +125,42 @@ static int sdhci_probe(struct platform_device *pdev) | |||
153 | sdhci->data = sdhci_probe_config_dt(pdev); | 125 | sdhci->data = sdhci_probe_config_dt(pdev); |
154 | if (IS_ERR(sdhci->data)) { | 126 | if (IS_ERR(sdhci->data)) { |
155 | dev_err(&pdev->dev, "DT: Failed to get pdata\n"); | 127 | dev_err(&pdev->dev, "DT: Failed to get pdata\n"); |
156 | return -ENODEV; | 128 | goto disable_clk; |
157 | } | 129 | } |
158 | } else { | 130 | } else { |
159 | sdhci->data = dev_get_platdata(&pdev->dev); | 131 | sdhci->data = dev_get_platdata(&pdev->dev); |
160 | } | 132 | } |
161 | 133 | ||
162 | pdev->dev.platform_data = sdhci; | 134 | /* |
163 | 135 | * It is optional to use GPIOs for sdhci card detection. If | |
164 | if (pdev->dev.parent) | 136 | * sdhci->data is NULL, then use original sdhci lines otherwise |
165 | host = sdhci_alloc_host(pdev->dev.parent, 0); | 137 | * GPIO lines. We use the built-in GPIO support for this. |
166 | else | 138 | */ |
167 | host = sdhci_alloc_host(&pdev->dev, 0); | 139 | if (sdhci->data && sdhci->data->card_int_gpio >= 0) { |
168 | 140 | ret = mmc_gpio_request_cd(host->mmc, | |
169 | if (IS_ERR(host)) { | 141 | sdhci->data->card_int_gpio, 0); |
170 | ret = PTR_ERR(host); | 142 | if (ret < 0) { |
171 | dev_dbg(&pdev->dev, "error allocating host\n"); | 143 | dev_dbg(&pdev->dev, |
172 | goto disable_clk; | 144 | "failed to request card-detect gpio%d\n", |
173 | } | 145 | sdhci->data->card_int_gpio); |
174 | 146 | goto disable_clk; | |
175 | host->hw_name = "sdhci"; | 147 | } |
176 | host->ops = &sdhci_pltfm_ops; | ||
177 | host->irq = platform_get_irq(pdev, 0); | ||
178 | host->quirks = SDHCI_QUIRK_BROKEN_ADMA; | ||
179 | |||
180 | host->ioaddr = devm_ioremap(&pdev->dev, iomem->start, | ||
181 | resource_size(iomem)); | ||
182 | if (!host->ioaddr) { | ||
183 | ret = -ENOMEM; | ||
184 | dev_dbg(&pdev->dev, "failed to remap registers\n"); | ||
185 | goto free_host; | ||
186 | } | 148 | } |
187 | 149 | ||
188 | ret = sdhci_add_host(host); | 150 | ret = sdhci_add_host(host); |
189 | if (ret) { | 151 | if (ret) { |
190 | dev_dbg(&pdev->dev, "error adding host\n"); | 152 | dev_dbg(&pdev->dev, "error adding host\n"); |
191 | goto free_host; | 153 | goto disable_clk; |
192 | } | 154 | } |
193 | 155 | ||
194 | platform_set_drvdata(pdev, host); | 156 | platform_set_drvdata(pdev, host); |
195 | 157 | ||
196 | /* | ||
197 | * It is optional to use GPIOs for sdhci Power control & sdhci card | ||
198 | * interrupt detection. If sdhci->data is NULL, then use original sdhci | ||
199 | * lines otherwise GPIO lines. | ||
200 | * If GPIO is selected for power control, then power should be disabled | ||
201 | * after card removal and should be enabled when card insertion | ||
202 | * interrupt occurs | ||
203 | */ | ||
204 | if (!sdhci->data) | ||
205 | return 0; | ||
206 | |||
207 | if (sdhci->data->card_power_gpio >= 0) { | ||
208 | int val = 0; | ||
209 | |||
210 | ret = devm_gpio_request(&pdev->dev, | ||
211 | sdhci->data->card_power_gpio, "sdhci"); | ||
212 | if (ret < 0) { | ||
213 | dev_dbg(&pdev->dev, "gpio request fail: %d\n", | ||
214 | sdhci->data->card_power_gpio); | ||
215 | goto set_drvdata; | ||
216 | } | ||
217 | |||
218 | if (sdhci->data->power_always_enb) | ||
219 | val = sdhci->data->power_active_high; | ||
220 | else | ||
221 | val = !sdhci->data->power_active_high; | ||
222 | |||
223 | ret = gpio_direction_output(sdhci->data->card_power_gpio, val); | ||
224 | if (ret) { | ||
225 | dev_dbg(&pdev->dev, "gpio set direction fail: %d\n", | ||
226 | sdhci->data->card_power_gpio); | ||
227 | goto set_drvdata; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | if (sdhci->data->card_int_gpio >= 0) { | ||
232 | ret = devm_gpio_request(&pdev->dev, sdhci->data->card_int_gpio, | ||
233 | "sdhci"); | ||
234 | if (ret < 0) { | ||
235 | dev_dbg(&pdev->dev, "gpio request fail: %d\n", | ||
236 | sdhci->data->card_int_gpio); | ||
237 | goto set_drvdata; | ||
238 | } | ||
239 | |||
240 | ret = gpio_direction_input(sdhci->data->card_int_gpio); | ||
241 | if (ret) { | ||
242 | dev_dbg(&pdev->dev, "gpio set direction fail: %d\n", | ||
243 | sdhci->data->card_int_gpio); | ||
244 | goto set_drvdata; | ||
245 | } | ||
246 | ret = devm_request_irq(&pdev->dev, | ||
247 | gpio_to_irq(sdhci->data->card_int_gpio), | ||
248 | sdhci_gpio_irq, IRQF_TRIGGER_LOW, | ||
249 | mmc_hostname(host->mmc), pdev); | ||
250 | if (ret) { | ||
251 | dev_dbg(&pdev->dev, "gpio request irq fail: %d\n", | ||
252 | sdhci->data->card_int_gpio); | ||
253 | goto set_drvdata; | ||
254 | } | ||
255 | |||
256 | } | ||
257 | |||
258 | return 0; | 158 | return 0; |
259 | 159 | ||
260 | set_drvdata: | ||
261 | sdhci_remove_host(host, 1); | ||
262 | free_host: | ||
263 | sdhci_free_host(host); | ||
264 | disable_clk: | 160 | disable_clk: |
265 | clk_disable_unprepare(sdhci->clk); | 161 | clk_disable_unprepare(sdhci->clk); |
266 | put_clk: | 162 | err_host: |
267 | clk_put(sdhci->clk); | 163 | sdhci_free_host(host); |
268 | err: | 164 | err: |
269 | dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret); | 165 | dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret); |
270 | return ret; | 166 | return ret; |
@@ -273,7 +169,7 @@ err: | |||
273 | static int sdhci_remove(struct platform_device *pdev) | 169 | static int sdhci_remove(struct platform_device *pdev) |
274 | { | 170 | { |
275 | struct sdhci_host *host = platform_get_drvdata(pdev); | 171 | struct sdhci_host *host = platform_get_drvdata(pdev); |
276 | struct spear_sdhci *sdhci = dev_get_platdata(&pdev->dev); | 172 | struct spear_sdhci *sdhci = sdhci_priv(host); |
277 | int dead = 0; | 173 | int dead = 0; |
278 | u32 scratch; | 174 | u32 scratch; |
279 | 175 | ||
@@ -282,9 +178,8 @@ static int sdhci_remove(struct platform_device *pdev) | |||
282 | dead = 1; | 178 | dead = 1; |
283 | 179 | ||
284 | sdhci_remove_host(host, dead); | 180 | sdhci_remove_host(host, dead); |
285 | sdhci_free_host(host); | ||
286 | clk_disable_unprepare(sdhci->clk); | 181 | clk_disable_unprepare(sdhci->clk); |
287 | clk_put(sdhci->clk); | 182 | sdhci_free_host(host); |
288 | 183 | ||
289 | return 0; | 184 | return 0; |
290 | } | 185 | } |
@@ -293,7 +188,7 @@ static int sdhci_remove(struct platform_device *pdev) | |||
293 | static int sdhci_suspend(struct device *dev) | 188 | static int sdhci_suspend(struct device *dev) |
294 | { | 189 | { |
295 | struct sdhci_host *host = dev_get_drvdata(dev); | 190 | struct sdhci_host *host = dev_get_drvdata(dev); |
296 | struct spear_sdhci *sdhci = dev_get_platdata(dev); | 191 | struct spear_sdhci *sdhci = sdhci_priv(host); |
297 | int ret; | 192 | int ret; |
298 | 193 | ||
299 | ret = sdhci_suspend_host(host); | 194 | ret = sdhci_suspend_host(host); |
@@ -306,7 +201,7 @@ static int sdhci_suspend(struct device *dev) | |||
306 | static int sdhci_resume(struct device *dev) | 201 | static int sdhci_resume(struct device *dev) |
307 | { | 202 | { |
308 | struct sdhci_host *host = dev_get_drvdata(dev); | 203 | struct sdhci_host *host = dev_get_drvdata(dev); |
309 | struct spear_sdhci *sdhci = dev_get_platdata(dev); | 204 | struct spear_sdhci *sdhci = sdhci_priv(host); |
310 | int ret; | 205 | int ret; |
311 | 206 | ||
312 | ret = clk_enable(sdhci->clk); | 207 | ret = clk_enable(sdhci->clk); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9ddef4763541..9a79fc4b60ca 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -675,12 +675,12 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | |||
675 | return 0xE; | 675 | return 0xE; |
676 | 676 | ||
677 | /* Unspecified timeout, assume max */ | 677 | /* Unspecified timeout, assume max */ |
678 | if (!data && !cmd->cmd_timeout_ms) | 678 | if (!data && !cmd->busy_timeout) |
679 | return 0xE; | 679 | return 0xE; |
680 | 680 | ||
681 | /* timeout in us */ | 681 | /* timeout in us */ |
682 | if (!data) | 682 | if (!data) |
683 | target_timeout = cmd->cmd_timeout_ms * 1000; | 683 | target_timeout = cmd->busy_timeout * 1000; |
684 | else { | 684 | else { |
685 | target_timeout = data->timeout_ns / 1000; | 685 | target_timeout = data->timeout_ns / 1000; |
686 | if (host->clock) | 686 | if (host->clock) |
@@ -1019,8 +1019,8 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | timeout = jiffies; | 1021 | timeout = jiffies; |
1022 | if (!cmd->data && cmd->cmd_timeout_ms > 9000) | 1022 | if (!cmd->data && cmd->busy_timeout > 9000) |
1023 | timeout += DIV_ROUND_UP(cmd->cmd_timeout_ms, 1000) * HZ + HZ; | 1023 | timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; |
1024 | else | 1024 | else |
1025 | timeout += 10 * HZ; | 1025 | timeout += 10 * HZ; |
1026 | mod_timer(&host->timer, timeout); | 1026 | mod_timer(&host->timer, timeout); |
@@ -2026,12 +2026,11 @@ out: | |||
2026 | host->tuning_count * HZ); | 2026 | host->tuning_count * HZ); |
2027 | /* Tuning mode 1 limits the maximum data length to 4MB */ | 2027 | /* Tuning mode 1 limits the maximum data length to 4MB */ |
2028 | mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; | 2028 | mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; |
2029 | } else { | 2029 | } else if (host->flags & SDHCI_USING_RETUNING_TIMER) { |
2030 | host->flags &= ~SDHCI_NEEDS_RETUNING; | 2030 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
2031 | /* Reload the new initial value for timer */ | 2031 | /* Reload the new initial value for timer */ |
2032 | if (host->tuning_mode == SDHCI_TUNING_MODE_1) | 2032 | mod_timer(&host->tuning_timer, jiffies + |
2033 | mod_timer(&host->tuning_timer, jiffies + | 2033 | host->tuning_count * HZ); |
2034 | host->tuning_count * HZ); | ||
2035 | } | 2034 | } |
2036 | 2035 | ||
2037 | /* | 2036 | /* |
@@ -2434,9 +2433,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) | |||
2434 | 2433 | ||
2435 | if (host->runtime_suspended) { | 2434 | if (host->runtime_suspended) { |
2436 | spin_unlock(&host->lock); | 2435 | spin_unlock(&host->lock); |
2437 | pr_warning("%s: got irq while runtime suspended\n", | 2436 | return IRQ_NONE; |
2438 | mmc_hostname(host->mmc)); | ||
2439 | return IRQ_HANDLED; | ||
2440 | } | 2437 | } |
2441 | 2438 | ||
2442 | intmask = sdhci_readl(host, SDHCI_INT_STATUS); | 2439 | intmask = sdhci_readl(host, SDHCI_INT_STATUS); |
@@ -2941,7 +2938,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2941 | if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) | 2938 | if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) |
2942 | host->timeout_clk = mmc->f_max / 1000; | 2939 | host->timeout_clk = mmc->f_max / 1000; |
2943 | 2940 | ||
2944 | mmc->max_discard_to = (1 << 27) / host->timeout_clk; | 2941 | mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; |
2945 | 2942 | ||
2946 | mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; | 2943 | mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; |
2947 | 2944 | ||
@@ -3020,7 +3017,8 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3020 | } else if (caps[1] & SDHCI_SUPPORT_SDR50) | 3017 | } else if (caps[1] & SDHCI_SUPPORT_SDR50) |
3021 | mmc->caps |= MMC_CAP_UHS_SDR50; | 3018 | mmc->caps |= MMC_CAP_UHS_SDR50; |
3022 | 3019 | ||
3023 | if (caps[1] & SDHCI_SUPPORT_DDR50) | 3020 | if ((caps[1] & SDHCI_SUPPORT_DDR50) && |
3021 | !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50)) | ||
3024 | mmc->caps |= MMC_CAP_UHS_DDR50; | 3022 | mmc->caps |= MMC_CAP_UHS_DDR50; |
3025 | 3023 | ||
3026 | /* Does the host need tuning for SDR50? */ | 3024 | /* Does the host need tuning for SDR50? */ |
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 2d6ce257a273..91058dabd11a 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | struct sh_mobile_sdhi_of_data { | 38 | struct sh_mobile_sdhi_of_data { |
39 | unsigned long tmio_flags; | 39 | unsigned long tmio_flags; |
40 | unsigned long capabilities; | ||
41 | unsigned long capabilities2; | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | static const struct sh_mobile_sdhi_of_data sh_mobile_sdhi_of_cfg[] = { | 44 | static const struct sh_mobile_sdhi_of_data sh_mobile_sdhi_of_cfg[] = { |
@@ -45,6 +47,31 @@ static const struct sh_mobile_sdhi_of_data sh_mobile_sdhi_of_cfg[] = { | |||
45 | }, | 47 | }, |
46 | }; | 48 | }; |
47 | 49 | ||
50 | static const struct sh_mobile_sdhi_of_data of_rcar_gen1_compatible = { | ||
51 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE, | ||
52 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, | ||
53 | }; | ||
54 | |||
55 | static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = { | ||
56 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE, | ||
57 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, | ||
58 | .capabilities2 = MMC_CAP2_NO_MULTI_READ, | ||
59 | }; | ||
60 | |||
61 | static const struct of_device_id sh_mobile_sdhi_of_match[] = { | ||
62 | { .compatible = "renesas,sdhi-shmobile" }, | ||
63 | { .compatible = "renesas,sdhi-sh7372" }, | ||
64 | { .compatible = "renesas,sdhi-sh73a0", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
65 | { .compatible = "renesas,sdhi-r8a73a4", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
66 | { .compatible = "renesas,sdhi-r8a7740", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
67 | { .compatible = "renesas,sdhi-r8a7778", .data = &of_rcar_gen1_compatible, }, | ||
68 | { .compatible = "renesas,sdhi-r8a7779", .data = &of_rcar_gen1_compatible, }, | ||
69 | { .compatible = "renesas,sdhi-r8a7790", .data = &of_rcar_gen2_compatible, }, | ||
70 | { .compatible = "renesas,sdhi-r8a7791", .data = &of_rcar_gen2_compatible, }, | ||
71 | {}, | ||
72 | }; | ||
73 | MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match); | ||
74 | |||
48 | struct sh_mobile_sdhi { | 75 | struct sh_mobile_sdhi { |
49 | struct clk *clk; | 76 | struct clk *clk; |
50 | struct tmio_mmc_data mmc_data; | 77 | struct tmio_mmc_data mmc_data; |
@@ -114,19 +141,6 @@ static const struct sh_mobile_sdhi_ops sdhi_ops = { | |||
114 | .cd_wakeup = sh_mobile_sdhi_cd_wakeup, | 141 | .cd_wakeup = sh_mobile_sdhi_cd_wakeup, |
115 | }; | 142 | }; |
116 | 143 | ||
117 | static const struct of_device_id sh_mobile_sdhi_of_match[] = { | ||
118 | { .compatible = "renesas,sdhi-shmobile" }, | ||
119 | { .compatible = "renesas,sdhi-sh7372" }, | ||
120 | { .compatible = "renesas,sdhi-sh73a0", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
121 | { .compatible = "renesas,sdhi-r8a73a4", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
122 | { .compatible = "renesas,sdhi-r8a7740", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
123 | { .compatible = "renesas,sdhi-r8a7778", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
124 | { .compatible = "renesas,sdhi-r8a7779", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
125 | { .compatible = "renesas,sdhi-r8a7790", .data = &sh_mobile_sdhi_of_cfg[0], }, | ||
126 | {}, | ||
127 | }; | ||
128 | MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match); | ||
129 | |||
130 | static int sh_mobile_sdhi_probe(struct platform_device *pdev) | 144 | static int sh_mobile_sdhi_probe(struct platform_device *pdev) |
131 | { | 145 | { |
132 | const struct of_device_id *of_id = | 146 | const struct of_device_id *of_id = |
@@ -212,6 +226,8 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
212 | if (of_id && of_id->data) { | 226 | if (of_id && of_id->data) { |
213 | const struct sh_mobile_sdhi_of_data *of_data = of_id->data; | 227 | const struct sh_mobile_sdhi_of_data *of_data = of_id->data; |
214 | mmc_data->flags |= of_data->tmio_flags; | 228 | mmc_data->flags |= of_data->tmio_flags; |
229 | mmc_data->capabilities |= of_data->capabilities; | ||
230 | mmc_data->capabilities2 |= of_data->capabilities2; | ||
215 | } | 231 | } |
216 | 232 | ||
217 | /* SD control register space size is 0x100, 0x200 for bus_shift=1 */ | 233 | /* SD control register space size is 0x100, 0x200 for bus_shift=1 */ |
@@ -316,10 +332,10 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev) | |||
316 | } | 332 | } |
317 | 333 | ||
318 | static const struct dev_pm_ops tmio_mmc_dev_pm_ops = { | 334 | static const struct dev_pm_ops tmio_mmc_dev_pm_ops = { |
319 | .suspend = tmio_mmc_host_suspend, | 335 | SET_SYSTEM_SLEEP_PM_OPS(tmio_mmc_host_suspend, tmio_mmc_host_resume) |
320 | .resume = tmio_mmc_host_resume, | 336 | SET_RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend, |
321 | .runtime_suspend = tmio_mmc_host_runtime_suspend, | 337 | tmio_mmc_host_runtime_resume, |
322 | .runtime_resume = tmio_mmc_host_runtime_resume, | 338 | NULL) |
323 | }; | 339 | }; |
324 | 340 | ||
325 | static struct platform_driver sh_mobile_sdhi_driver = { | 341 | static struct platform_driver sh_mobile_sdhi_driver = { |
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 1900abb04236..cfad844730d8 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -23,38 +23,37 @@ | |||
23 | 23 | ||
24 | #include "tmio_mmc.h" | 24 | #include "tmio_mmc.h" |
25 | 25 | ||
26 | #ifdef CONFIG_PM | 26 | #ifdef CONFIG_PM_SLEEP |
27 | static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) | 27 | static int tmio_mmc_suspend(struct device *dev) |
28 | { | 28 | { |
29 | const struct mfd_cell *cell = mfd_get_cell(dev); | 29 | struct platform_device *pdev = to_platform_device(dev); |
30 | const struct mfd_cell *cell = mfd_get_cell(pdev); | ||
30 | int ret; | 31 | int ret; |
31 | 32 | ||
32 | ret = tmio_mmc_host_suspend(&dev->dev); | 33 | ret = tmio_mmc_host_suspend(dev); |
33 | 34 | ||
34 | /* Tell MFD core it can disable us now.*/ | 35 | /* Tell MFD core it can disable us now.*/ |
35 | if (!ret && cell->disable) | 36 | if (!ret && cell->disable) |
36 | cell->disable(dev); | 37 | cell->disable(pdev); |
37 | 38 | ||
38 | return ret; | 39 | return ret; |
39 | } | 40 | } |
40 | 41 | ||
41 | static int tmio_mmc_resume(struct platform_device *dev) | 42 | static int tmio_mmc_resume(struct device *dev) |
42 | { | 43 | { |
43 | const struct mfd_cell *cell = mfd_get_cell(dev); | 44 | struct platform_device *pdev = to_platform_device(dev); |
45 | const struct mfd_cell *cell = mfd_get_cell(pdev); | ||
44 | int ret = 0; | 46 | int ret = 0; |
45 | 47 | ||
46 | /* Tell the MFD core we are ready to be enabled */ | 48 | /* Tell the MFD core we are ready to be enabled */ |
47 | if (cell->resume) | 49 | if (cell->resume) |
48 | ret = cell->resume(dev); | 50 | ret = cell->resume(pdev); |
49 | 51 | ||
50 | if (!ret) | 52 | if (!ret) |
51 | ret = tmio_mmc_host_resume(&dev->dev); | 53 | ret = tmio_mmc_host_resume(dev); |
52 | 54 | ||
53 | return ret; | 55 | return ret; |
54 | } | 56 | } |
55 | #else | ||
56 | #define tmio_mmc_suspend NULL | ||
57 | #define tmio_mmc_resume NULL | ||
58 | #endif | 57 | #endif |
59 | 58 | ||
60 | static int tmio_mmc_probe(struct platform_device *pdev) | 59 | static int tmio_mmc_probe(struct platform_device *pdev) |
@@ -134,15 +133,18 @@ static int tmio_mmc_remove(struct platform_device *pdev) | |||
134 | 133 | ||
135 | /* ------------------- device registration ----------------------- */ | 134 | /* ------------------- device registration ----------------------- */ |
136 | 135 | ||
136 | static const struct dev_pm_ops tmio_mmc_dev_pm_ops = { | ||
137 | SET_SYSTEM_SLEEP_PM_OPS(tmio_mmc_suspend, tmio_mmc_resume) | ||
138 | }; | ||
139 | |||
137 | static struct platform_driver tmio_mmc_driver = { | 140 | static struct platform_driver tmio_mmc_driver = { |
138 | .driver = { | 141 | .driver = { |
139 | .name = "tmio-mmc", | 142 | .name = "tmio-mmc", |
140 | .owner = THIS_MODULE, | 143 | .owner = THIS_MODULE, |
144 | .pm = &tmio_mmc_dev_pm_ops, | ||
141 | }, | 145 | }, |
142 | .probe = tmio_mmc_probe, | 146 | .probe = tmio_mmc_probe, |
143 | .remove = tmio_mmc_remove, | 147 | .remove = tmio_mmc_remove, |
144 | .suspend = tmio_mmc_suspend, | ||
145 | .resume = tmio_mmc_resume, | ||
146 | }; | 148 | }; |
147 | 149 | ||
148 | module_platform_driver(tmio_mmc_driver); | 150 | module_platform_driver(tmio_mmc_driver); |
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index aaa9c7e9e730..100ffe0b2faf 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -162,16 +162,15 @@ static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host) | |||
162 | } | 162 | } |
163 | #endif | 163 | #endif |
164 | 164 | ||
165 | #ifdef CONFIG_PM | 165 | #ifdef CONFIG_PM_SLEEP |
166 | int tmio_mmc_host_suspend(struct device *dev); | 166 | int tmio_mmc_host_suspend(struct device *dev); |
167 | int tmio_mmc_host_resume(struct device *dev); | 167 | int tmio_mmc_host_resume(struct device *dev); |
168 | #else | ||
169 | #define tmio_mmc_host_suspend NULL | ||
170 | #define tmio_mmc_host_resume NULL | ||
171 | #endif | 168 | #endif |
172 | 169 | ||
170 | #ifdef CONFIG_PM_RUNTIME | ||
173 | int tmio_mmc_host_runtime_suspend(struct device *dev); | 171 | int tmio_mmc_host_runtime_suspend(struct device *dev); |
174 | int tmio_mmc_host_runtime_resume(struct device *dev); | 172 | int tmio_mmc_host_runtime_resume(struct device *dev); |
173 | #endif | ||
175 | 174 | ||
176 | static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr) | 175 | static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr) |
177 | { | 176 | { |
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 8d8abf23a611..faf0924e71cb 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -1142,7 +1142,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) | |||
1142 | } | 1142 | } |
1143 | EXPORT_SYMBOL(tmio_mmc_host_remove); | 1143 | EXPORT_SYMBOL(tmio_mmc_host_remove); |
1144 | 1144 | ||
1145 | #ifdef CONFIG_PM | 1145 | #ifdef CONFIG_PM_SLEEP |
1146 | int tmio_mmc_host_suspend(struct device *dev) | 1146 | int tmio_mmc_host_suspend(struct device *dev) |
1147 | { | 1147 | { |
1148 | struct mmc_host *mmc = dev_get_drvdata(dev); | 1148 | struct mmc_host *mmc = dev_get_drvdata(dev); |
@@ -1165,9 +1165,9 @@ int tmio_mmc_host_resume(struct device *dev) | |||
1165 | return 0; | 1165 | return 0; |
1166 | } | 1166 | } |
1167 | EXPORT_SYMBOL(tmio_mmc_host_resume); | 1167 | EXPORT_SYMBOL(tmio_mmc_host_resume); |
1168 | #endif | ||
1168 | 1169 | ||
1169 | #endif /* CONFIG_PM */ | 1170 | #ifdef CONFIG_PM_RUNTIME |
1170 | |||
1171 | int tmio_mmc_host_runtime_suspend(struct device *dev) | 1171 | int tmio_mmc_host_runtime_suspend(struct device *dev) |
1172 | { | 1172 | { |
1173 | return 0; | 1173 | return 0; |
@@ -1184,5 +1184,6 @@ int tmio_mmc_host_runtime_resume(struct device *dev) | |||
1184 | return 0; | 1184 | return 0; |
1185 | } | 1185 | } |
1186 | EXPORT_SYMBOL(tmio_mmc_host_runtime_resume); | 1186 | EXPORT_SYMBOL(tmio_mmc_host_runtime_resume); |
1187 | #endif | ||
1187 | 1188 | ||
1188 | MODULE_LICENSE("GPL v2"); | 1189 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index c0105a2e269a..d2c386f09d69 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c | |||
@@ -504,7 +504,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
504 | ret = -ENOMEM; | 504 | ret = -ENOMEM; |
505 | goto err; | 505 | goto err; |
506 | } | 506 | } |
507 | ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); | 507 | ushc->csw = kzalloc(sizeof(struct ushc_csw), GFP_KERNEL); |
508 | if (ushc->csw == NULL) { | 508 | if (ushc->csw == NULL) { |
509 | ret = -ENOMEM; | 509 | ret = -ENOMEM; |
510 | goto err; | 510 | goto err; |
diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index e902ed7846b0..498d1f799085 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c | |||
@@ -757,7 +757,7 @@ static int wmt_mci_probe(struct platform_device *pdev) | |||
757 | struct device_node *np = pdev->dev.of_node; | 757 | struct device_node *np = pdev->dev.of_node; |
758 | const struct of_device_id *of_id = | 758 | const struct of_device_id *of_id = |
759 | of_match_device(wmt_mci_dt_ids, &pdev->dev); | 759 | of_match_device(wmt_mci_dt_ids, &pdev->dev); |
760 | const struct wmt_mci_caps *wmt_caps = of_id->data; | 760 | const struct wmt_mci_caps *wmt_caps; |
761 | int ret; | 761 | int ret; |
762 | int regular_irq, dma_irq; | 762 | int regular_irq, dma_irq; |
763 | 763 | ||
@@ -766,6 +766,8 @@ static int wmt_mci_probe(struct platform_device *pdev) | |||
766 | return -EFAULT; | 766 | return -EFAULT; |
767 | } | 767 | } |
768 | 768 | ||
769 | wmt_caps = of_id->data; | ||
770 | |||
769 | if (!np) { | 771 | if (!np) { |
770 | dev_err(&pdev->dev, "Missing SDMMC description in devicetree\n"); | 772 | dev_err(&pdev->dev, "Missing SDMMC description in devicetree\n"); |
771 | return -EFAULT; | 773 | return -EFAULT; |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 1cd8584a7b88..903eb37f047a 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -392,6 +392,15 @@ config REGULATOR_PALMAS | |||
392 | on the muxing. This is handled automatically in the driver by | 392 | on the muxing. This is handled automatically in the driver by |
393 | reading the mux info from OTP. | 393 | reading the mux info from OTP. |
394 | 394 | ||
395 | config REGULATOR_PBIAS | ||
396 | tristate "PBIAS OMAP regulator driver" | ||
397 | depends on (ARCH_OMAP || COMPILE_TEST) && MFD_SYSCON | ||
398 | help | ||
399 | Say y here to support pbias regulator for mmc1:SD card i/o | ||
400 | on OMAP SoCs. | ||
401 | This driver provides support for OMAP pbias modelled | ||
402 | regulators. | ||
403 | |||
395 | config REGULATOR_PCAP | 404 | config REGULATOR_PCAP |
396 | tristate "Motorola PCAP2 regulator driver" | 405 | tristate "Motorola PCAP2 regulator driver" |
397 | depends on EZX_PCAP | 406 | depends on EZX_PCAP |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index f0fe0c50b59c..12ef277a48b4 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o | |||
55 | obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o | 55 | obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o |
56 | obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o | 56 | obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o |
57 | obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o | 57 | obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o |
58 | obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o | ||
58 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 59 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
59 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 60 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
60 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o | 61 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o |
diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c new file mode 100644 index 000000000000..ded3b3574209 --- /dev/null +++ b/drivers/regulator/pbias-regulator.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * pbias-regulator.c | ||
3 | * | ||
4 | * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ | ||
5 | * Author: Balaji T K <balajitk@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation version 2. | ||
10 | * | ||
11 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
12 | * kind, whether express or implied; without even the implied warranty | ||
13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/err.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/mfd/syscon.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/regulator/driver.h> | ||
23 | #include <linux/regulator/machine.h> | ||
24 | #include <linux/regulator/of_regulator.h> | ||
25 | #include <linux/regmap.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/of.h> | ||
28 | #include <linux/of_device.h> | ||
29 | |||
30 | struct pbias_reg_info { | ||
31 | u32 enable; | ||
32 | u32 enable_mask; | ||
33 | u32 vmode; | ||
34 | unsigned int enable_time; | ||
35 | char *name; | ||
36 | }; | ||
37 | |||
38 | struct pbias_regulator_data { | ||
39 | struct regulator_desc desc; | ||
40 | void __iomem *pbias_addr; | ||
41 | unsigned int pbias_reg; | ||
42 | struct regulator_dev *dev; | ||
43 | struct regmap *syscon; | ||
44 | const struct pbias_reg_info *info; | ||
45 | int voltage; | ||
46 | }; | ||
47 | |||
48 | static int pbias_regulator_set_voltage(struct regulator_dev *dev, | ||
49 | int min_uV, int max_uV, unsigned *selector) | ||
50 | { | ||
51 | struct pbias_regulator_data *data = rdev_get_drvdata(dev); | ||
52 | const struct pbias_reg_info *info = data->info; | ||
53 | int ret, vmode; | ||
54 | |||
55 | if (min_uV <= 1800000) | ||
56 | vmode = 0; | ||
57 | else if (min_uV > 1800000) | ||
58 | vmode = info->vmode; | ||
59 | |||
60 | ret = regmap_update_bits(data->syscon, data->pbias_reg, | ||
61 | info->vmode, vmode); | ||
62 | |||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | static int pbias_regulator_get_voltage(struct regulator_dev *rdev) | ||
67 | { | ||
68 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
69 | const struct pbias_reg_info *info = data->info; | ||
70 | int value, voltage; | ||
71 | |||
72 | regmap_read(data->syscon, data->pbias_reg, &value); | ||
73 | value &= info->vmode; | ||
74 | |||
75 | voltage = value ? 3000000 : 1800000; | ||
76 | |||
77 | return voltage; | ||
78 | } | ||
79 | |||
80 | static int pbias_regulator_enable(struct regulator_dev *rdev) | ||
81 | { | ||
82 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
83 | const struct pbias_reg_info *info = data->info; | ||
84 | int ret; | ||
85 | |||
86 | ret = regmap_update_bits(data->syscon, data->pbias_reg, | ||
87 | info->enable_mask, info->enable); | ||
88 | |||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static int pbias_regulator_disable(struct regulator_dev *rdev) | ||
93 | { | ||
94 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
95 | const struct pbias_reg_info *info = data->info; | ||
96 | int ret; | ||
97 | |||
98 | ret = regmap_update_bits(data->syscon, data->pbias_reg, | ||
99 | info->enable_mask, 0); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | static int pbias_regulator_is_enable(struct regulator_dev *rdev) | ||
104 | { | ||
105 | struct pbias_regulator_data *data = rdev_get_drvdata(rdev); | ||
106 | const struct pbias_reg_info *info = data->info; | ||
107 | int value; | ||
108 | |||
109 | regmap_read(data->syscon, data->pbias_reg, &value); | ||
110 | |||
111 | return (value & info->enable_mask) == info->enable_mask; | ||
112 | } | ||
113 | |||
114 | static struct regulator_ops pbias_regulator_voltage_ops = { | ||
115 | .set_voltage = pbias_regulator_set_voltage, | ||
116 | .get_voltage = pbias_regulator_get_voltage, | ||
117 | .enable = pbias_regulator_enable, | ||
118 | .disable = pbias_regulator_disable, | ||
119 | .is_enabled = pbias_regulator_is_enable, | ||
120 | }; | ||
121 | |||
122 | static const struct pbias_reg_info pbias_mmc_omap2430 = { | ||
123 | .enable = BIT(1), | ||
124 | .enable_mask = BIT(1), | ||
125 | .vmode = BIT(0), | ||
126 | .enable_time = 100, | ||
127 | .name = "pbias_mmc_omap2430" | ||
128 | }; | ||
129 | |||
130 | static const struct pbias_reg_info pbias_sim_omap3 = { | ||
131 | .enable = BIT(9), | ||
132 | .enable_mask = BIT(9), | ||
133 | .vmode = BIT(8), | ||
134 | .enable_time = 100, | ||
135 | .name = "pbias_sim_omap3" | ||
136 | }; | ||
137 | |||
138 | static const struct pbias_reg_info pbias_mmc_omap4 = { | ||
139 | .enable = BIT(26) | BIT(22), | ||
140 | .enable_mask = BIT(26) | BIT(25) | BIT(22), | ||
141 | .vmode = BIT(21), | ||
142 | .enable_time = 100, | ||
143 | .name = "pbias_mmc_omap4" | ||
144 | }; | ||
145 | |||
146 | static const struct pbias_reg_info pbias_mmc_omap5 = { | ||
147 | .enable = BIT(27) | BIT(26), | ||
148 | .enable_mask = BIT(27) | BIT(25) | BIT(26), | ||
149 | .vmode = BIT(21), | ||
150 | .enable_time = 100, | ||
151 | .name = "pbias_mmc_omap5" | ||
152 | }; | ||
153 | |||
154 | static struct of_regulator_match pbias_matches[] = { | ||
155 | { .name = "pbias_mmc_omap2430", .driver_data = (void *)&pbias_mmc_omap2430}, | ||
156 | { .name = "pbias_sim_omap3", .driver_data = (void *)&pbias_sim_omap3}, | ||
157 | { .name = "pbias_mmc_omap4", .driver_data = (void *)&pbias_mmc_omap4}, | ||
158 | { .name = "pbias_mmc_omap5", .driver_data = (void *)&pbias_mmc_omap5}, | ||
159 | }; | ||
160 | #define PBIAS_NUM_REGS ARRAY_SIZE(pbias_matches) | ||
161 | |||
162 | static const struct of_device_id pbias_of_match[] = { | ||
163 | { .compatible = "ti,pbias-omap", }, | ||
164 | {}, | ||
165 | }; | ||
166 | MODULE_DEVICE_TABLE(of, pbias_of_match); | ||
167 | |||
168 | static int pbias_regulator_probe(struct platform_device *pdev) | ||
169 | { | ||
170 | struct device_node *np = pdev->dev.of_node; | ||
171 | struct pbias_regulator_data *drvdata; | ||
172 | struct resource *res; | ||
173 | struct regulator_config cfg = { }; | ||
174 | struct regmap *syscon; | ||
175 | const struct pbias_reg_info *info; | ||
176 | int ret = 0; | ||
177 | int count, idx, data_idx = 0; | ||
178 | |||
179 | count = of_regulator_match(&pdev->dev, np, pbias_matches, | ||
180 | PBIAS_NUM_REGS); | ||
181 | if (count < 0) | ||
182 | return count; | ||
183 | |||
184 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct pbias_regulator_data) | ||
185 | * count, GFP_KERNEL); | ||
186 | if (drvdata == NULL) { | ||
187 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | ||
188 | return -ENOMEM; | ||
189 | } | ||
190 | |||
191 | syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); | ||
192 | if (IS_ERR(syscon)) | ||
193 | return PTR_ERR(syscon); | ||
194 | |||
195 | cfg.dev = &pdev->dev; | ||
196 | |||
197 | for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) { | ||
198 | if (!pbias_matches[idx].init_data || | ||
199 | !pbias_matches[idx].of_node) | ||
200 | continue; | ||
201 | |||
202 | info = pbias_matches[idx].driver_data; | ||
203 | if (!info) | ||
204 | return -ENODEV; | ||
205 | |||
206 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
207 | if (!res) | ||
208 | return -EINVAL; | ||
209 | |||
210 | drvdata[data_idx].pbias_reg = res->start; | ||
211 | drvdata[data_idx].syscon = syscon; | ||
212 | drvdata[data_idx].info = info; | ||
213 | drvdata[data_idx].desc.name = info->name; | ||
214 | drvdata[data_idx].desc.owner = THIS_MODULE; | ||
215 | drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; | ||
216 | drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; | ||
217 | drvdata[data_idx].desc.n_voltages = 2; | ||
218 | drvdata[data_idx].desc.enable_time = info->enable_time; | ||
219 | |||
220 | cfg.init_data = pbias_matches[idx].init_data; | ||
221 | cfg.driver_data = &drvdata[data_idx]; | ||
222 | cfg.of_node = pbias_matches[idx].of_node; | ||
223 | |||
224 | drvdata[data_idx].dev = devm_regulator_register(&pdev->dev, | ||
225 | &drvdata[data_idx].desc, &cfg); | ||
226 | if (IS_ERR(drvdata[data_idx].dev)) { | ||
227 | ret = PTR_ERR(drvdata[data_idx].dev); | ||
228 | dev_err(&pdev->dev, | ||
229 | "Failed to register regulator: %d\n", ret); | ||
230 | goto err_regulator; | ||
231 | } | ||
232 | data_idx++; | ||
233 | } | ||
234 | |||
235 | platform_set_drvdata(pdev, drvdata); | ||
236 | |||
237 | err_regulator: | ||
238 | return ret; | ||
239 | } | ||
240 | |||
241 | static struct platform_driver pbias_regulator_driver = { | ||
242 | .probe = pbias_regulator_probe, | ||
243 | .driver = { | ||
244 | .name = "pbias-regulator", | ||
245 | .owner = THIS_MODULE, | ||
246 | .of_match_table = of_match_ptr(pbias_of_match), | ||
247 | }, | ||
248 | }; | ||
249 | |||
250 | module_platform_driver(pbias_regulator_driver); | ||
251 | |||
252 | MODULE_AUTHOR("Balaji T K <balajitk@ti.com>"); | ||
253 | MODULE_DESCRIPTION("pbias voltage regulator"); | ||
254 | MODULE_LICENSE("GPL"); | ||
255 | MODULE_ALIAS("platform:pbias-regulator"); | ||
diff --git a/include/linux/mfd/rtsx_common.h b/include/linux/mfd/rtsx_common.h index 443176ee1ab0..7c36cc55d2c7 100644 --- a/include/linux/mfd/rtsx_common.h +++ b/include/linux/mfd/rtsx_common.h | |||
@@ -45,6 +45,7 @@ struct platform_device; | |||
45 | struct rtsx_slot { | 45 | struct rtsx_slot { |
46 | struct platform_device *p_dev; | 46 | struct platform_device *p_dev; |
47 | void (*card_event)(struct platform_device *p_dev); | 47 | void (*card_event)(struct platform_device *p_dev); |
48 | void (*done_transfer)(struct platform_device *p_dev); | ||
48 | }; | 49 | }; |
49 | 50 | ||
50 | #endif | 51 | #endif |
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 0ce772105508..8d6bbd609ad9 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h | |||
@@ -144,7 +144,7 @@ | |||
144 | #define HOST_TO_DEVICE 0 | 144 | #define HOST_TO_DEVICE 0 |
145 | #define DEVICE_TO_HOST 1 | 145 | #define DEVICE_TO_HOST 1 |
146 | 146 | ||
147 | #define MAX_PHASE 31 | 147 | #define RTSX_PHASE_MAX 32 |
148 | #define RX_TUNING_CNT 3 | 148 | #define RX_TUNING_CNT 3 |
149 | 149 | ||
150 | /* SG descriptor */ | 150 | /* SG descriptor */ |
@@ -943,6 +943,12 @@ void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr); | |||
943 | int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); | 943 | int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); |
944 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | 944 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, |
945 | int num_sg, bool read, int timeout); | 945 | int num_sg, bool read, int timeout); |
946 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
947 | int num_sg, bool read); | ||
948 | int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
949 | int num_sg, bool read); | ||
950 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
951 | int sg_count, bool read); | ||
946 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); | 952 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); |
947 | int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); | 953 | int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); |
948 | int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); | 954 | int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 87079fc38011..f206e29f94d7 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -95,7 +95,7 @@ struct mmc_command { | |||
95 | * actively failing requests | 95 | * actively failing requests |
96 | */ | 96 | */ |
97 | 97 | ||
98 | unsigned int cmd_timeout_ms; /* in milliseconds */ | 98 | unsigned int busy_timeout; /* busy detect timeout in ms */ |
99 | /* Set this flag only for blocking sanitize request */ | 99 | /* Set this flag only for blocking sanitize request */ |
100 | bool sanitize_busy; | 100 | bool sanitize_busy; |
101 | 101 | ||
@@ -152,7 +152,7 @@ extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, | |||
152 | struct mmc_command *, int); | 152 | struct mmc_command *, int); |
153 | extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); | 153 | extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); |
154 | extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool, | 154 | extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool, |
155 | bool); | 155 | bool, bool); |
156 | extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); | 156 | extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); |
157 | extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); | 157 | extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); |
158 | 158 | ||
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 99f5709ac343..cb61ea4d6945 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -264,15 +264,12 @@ struct mmc_host { | |||
264 | u32 caps2; /* More host capabilities */ | 264 | u32 caps2; /* More host capabilities */ |
265 | 265 | ||
266 | #define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */ | 266 | #define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */ |
267 | #define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */ | ||
268 | #define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */ | 267 | #define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */ |
269 | #define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */ | 268 | #define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */ |
270 | #define MMC_CAP2_NO_SLEEP_CMD (1 << 4) /* Don't allow sleep command */ | ||
271 | #define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */ | 269 | #define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */ |
272 | #define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */ | 270 | #define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */ |
273 | #define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ | 271 | #define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ |
274 | MMC_CAP2_HS200_1_2V_SDR) | 272 | MMC_CAP2_HS200_1_2V_SDR) |
275 | #define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */ | ||
276 | #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */ | 273 | #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */ |
277 | #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ | 274 | #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ |
278 | #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ | 275 | #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ |
@@ -281,7 +278,6 @@ struct mmc_host { | |||
281 | #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ | 278 | #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ |
282 | MMC_CAP2_PACKED_WR) | 279 | MMC_CAP2_PACKED_WR) |
283 | #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ | 280 | #define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */ |
284 | #define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */ | ||
285 | 281 | ||
286 | mmc_pm_flag_t pm_caps; /* supported pm features */ | 282 | mmc_pm_flag_t pm_caps; /* supported pm features */ |
287 | 283 | ||
@@ -304,7 +300,7 @@ struct mmc_host { | |||
304 | unsigned int max_req_size; /* maximum number of bytes in one req */ | 300 | unsigned int max_req_size; /* maximum number of bytes in one req */ |
305 | unsigned int max_blk_size; /* maximum size of one mmc block */ | 301 | unsigned int max_blk_size; /* maximum size of one mmc block */ |
306 | unsigned int max_blk_count; /* maximum number of blocks in one req */ | 302 | unsigned int max_blk_count; /* maximum number of blocks in one req */ |
307 | unsigned int max_discard_to; /* max. discard timeout in ms */ | 303 | unsigned int max_busy_timeout; /* max busy timeout in ms */ |
308 | 304 | ||
309 | /* private data */ | 305 | /* private data */ |
310 | spinlock_t lock; /* lock for claim and bus ops */ | 306 | spinlock_t lock; /* lock for claim and bus ops */ |
@@ -388,8 +384,6 @@ int mmc_power_restore_host(struct mmc_host *host); | |||
388 | void mmc_detect_change(struct mmc_host *, unsigned long delay); | 384 | void mmc_detect_change(struct mmc_host *, unsigned long delay); |
389 | void mmc_request_done(struct mmc_host *, struct mmc_request *); | 385 | void mmc_request_done(struct mmc_host *, struct mmc_request *); |
390 | 386 | ||
391 | int mmc_cache_ctrl(struct mmc_host *, u8); | ||
392 | |||
393 | static inline void mmc_signal_sdio_irq(struct mmc_host *host) | 387 | static inline void mmc_signal_sdio_irq(struct mmc_host *host) |
394 | { | 388 | { |
395 | host->ops->enable_sdio_irq(host, 0); | 389 | host->ops->enable_sdio_irq(host, 0); |
@@ -424,12 +418,9 @@ static inline int mmc_regulator_get_supply(struct mmc_host *mmc) | |||
424 | 418 | ||
425 | int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *); | 419 | int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *); |
426 | 420 | ||
427 | /* Module parameter */ | ||
428 | extern bool mmc_assume_removable; | ||
429 | |||
430 | static inline int mmc_card_is_removable(struct mmc_host *host) | 421 | static inline int mmc_card_is_removable(struct mmc_host *host) |
431 | { | 422 | { |
432 | return !(host->caps & MMC_CAP_NONREMOVABLE) && mmc_assume_removable; | 423 | return !(host->caps & MMC_CAP_NONREMOVABLE); |
433 | } | 424 | } |
434 | 425 | ||
435 | static inline int mmc_card_keep_power(struct mmc_host *host) | 426 | static inline int mmc_card_keep_power(struct mmc_host *host) |
diff --git a/include/linux/mmc/sdhci-spear.h b/include/linux/mmc/sdhci-spear.h index e78c0e236e9d..8cc095a76cf8 100644 --- a/include/linux/mmc/sdhci-spear.h +++ b/include/linux/mmc/sdhci-spear.h | |||
@@ -18,17 +18,9 @@ | |||
18 | /* | 18 | /* |
19 | * struct sdhci_plat_data: spear sdhci platform data structure | 19 | * struct sdhci_plat_data: spear sdhci platform data structure |
20 | * | 20 | * |
21 | * @card_power_gpio: gpio pin for enabling/disabling power to sdhci socket | ||
22 | * @power_active_high: if set, enable power to sdhci socket by setting | ||
23 | * card_power_gpio | ||
24 | * @power_always_enb: If set, then enable power on probe, otherwise enable only | ||
25 | * on card insertion and disable on card removal. | ||
26 | * card_int_gpio: gpio pin used for card detection | 21 | * card_int_gpio: gpio pin used for card detection |
27 | */ | 22 | */ |
28 | struct sdhci_plat_data { | 23 | struct sdhci_plat_data { |
29 | int card_power_gpio; | ||
30 | int power_active_high; | ||
31 | int power_always_enb; | ||
32 | int card_int_gpio; | 24 | int card_int_gpio; |
33 | }; | 25 | }; |
34 | 26 | ||
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 362927c48f97..7be12b883485 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h | |||
@@ -100,6 +100,8 @@ struct sdhci_host { | |||
100 | #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5) | 100 | #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5) |
101 | /* Controller does not support HS200 */ | 101 | /* Controller does not support HS200 */ |
102 | #define SDHCI_QUIRK2_BROKEN_HS200 (1<<6) | 102 | #define SDHCI_QUIRK2_BROKEN_HS200 (1<<6) |
103 | /* Controller does not support DDR50 */ | ||
104 | #define SDHCI_QUIRK2_BROKEN_DDR50 (1<<7) | ||
103 | 105 | ||
104 | int irq; /* Device IRQ */ | 106 | int irq; /* Device IRQ */ |
105 | void __iomem *ioaddr; /* Mapped address */ | 107 | void __iomem *ioaddr; /* Mapped address */ |
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h index b0c73e4cacea..d2433381e828 100644 --- a/include/linux/mmc/slot-gpio.h +++ b/include/linux/mmc/slot-gpio.h | |||
@@ -22,4 +22,10 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | |||
22 | unsigned int debounce); | 22 | unsigned int debounce); |
23 | void mmc_gpio_free_cd(struct mmc_host *host); | 23 | void mmc_gpio_free_cd(struct mmc_host *host); |
24 | 24 | ||
25 | int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | ||
26 | unsigned int idx, bool override_active_level, | ||
27 | unsigned int debounce); | ||
28 | void mmc_gpiod_free_cd(struct mmc_host *host); | ||
29 | void mmc_gpiod_request_cd_irq(struct mmc_host *host); | ||
30 | |||
25 | #endif | 31 | #endif |
diff --git a/include/linux/platform_data/mmc-msm_sdcc.h b/include/linux/platform_data/mmc-msm_sdcc.h index ffcd9e3a6a7e..55aa873c9396 100644 --- a/include/linux/platform_data/mmc-msm_sdcc.h +++ b/include/linux/platform_data/mmc-msm_sdcc.h | |||
@@ -1,8 +1,5 @@ | |||
1 | /* | 1 | #ifndef __MMC_MSM_SDCC_H |
2 | * arch/arm/include/asm/mach/mmc.h | 2 | #define __MMC_MSM_SDCC_H |
3 | */ | ||
4 | #ifndef ASMARM_MACH_MMC_H | ||
5 | #define ASMARM_MACH_MMC_H | ||
6 | 3 | ||
7 | #include <linux/mmc/host.h> | 4 | #include <linux/mmc/host.h> |
8 | #include <linux/mmc/card.h> | 5 | #include <linux/mmc/card.h> |
diff --git a/include/linux/platform_data/mmc-mvsdio.h b/include/linux/platform_data/mmc-mvsdio.h index 1190efedcb94..d02704cd3695 100644 --- a/include/linux/platform_data/mmc-mvsdio.h +++ b/include/linux/platform_data/mmc-mvsdio.h | |||
@@ -1,13 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/plat-orion/include/plat/mvsdio.h | ||
3 | * | ||
4 | * This file is licensed under the terms of the GNU General Public | 2 | * This file is licensed under the terms of the GNU General Public |
5 | * License version 2. This program is licensed "as is" without any | 3 | * License version 2. This program is licensed "as is" without any |
6 | * warranty of any kind, whether express or implied. | 4 | * warranty of any kind, whether express or implied. |
7 | */ | 5 | */ |
8 | 6 | ||
9 | #ifndef __MACH_MVSDIO_H | 7 | #ifndef __MMC_MVSDIO_H |
10 | #define __MACH_MVSDIO_H | 8 | #define __MMC_MVSDIO_H |
11 | 9 | ||
12 | #include <linux/mbus.h> | 10 | #include <linux/mbus.h> |
13 | 11 | ||