diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-21 15:04:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-21 15:04:54 -0500 |
commit | e67bd12d6036ae3de9eeb0ba52e43691264ec850 (patch) | |
tree | 0232867e68e2b56fd601f7c31b0d5f87d7ec3792 | |
parent | cdc194705d26fdd7fc5446b5d830f2bbe2b22c30 (diff) | |
parent | 8c7cdbf9272c300dc093da3c62fa3b4bc6dc960e (diff) |
Merge tag 'mmc-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Add support for Marvell SD8787 Wifi/BT chip
- Improve UHS support for SDIO
- Invent MMC_CAP_3_3V_DDR and a DT binding for eMMC DDR 3.3V mode
- Detect Auto BKOPS enable bit
- Export eMMC device lifetime information through sysfs
- First take to slim down the public mmc headers to avoid abuse
- Re-factoring of the mmc block device driver to prepare for blkmq
- Cleanup code for the mmc block device driver
- Clarify and cleanup code dealing with data requests
- Cleanup some code by converting to ida_simple_ functions
- Cleanup code dealing with card quirks
- Cleanup private and public mmc header files
MMC host:
- Don't rely on public mmc headers to include non-mmc related headers
- meson: Add support for eMMC HS400 mode
- meson: Various cleanups and improvements
- omap_hsmmc: Use the proper provided busy timeout from the core
- sunxi: Enable new timings for the A64 MMC controllers
- sunxi: Improvements for clock management
- tmio: Improvements for SDIO interrupts
- mxs-mmc: Add CMD23 support
- sdhci-msm: Enable HS400 enhanced strobe mode support
- sdhci-msm: Correct HS400 tuning sequence
- sdhci-acpi: Support deferred probe
- sdhci-pci: Add support for eMMC HS200 tuning mode on AMD
- mediatek: Correct the implementation of card busy detection
- dw_mmc: Initial support for ZX mmc controller
- sh_mobile_sdhi: Enable support for eMMC HS200 mode
- sh_mmcif: Various cleanups and improvements"
* tag 'mmc-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (145 commits)
mmc: core: add mmc prefix for blk_fixups
mmc: core: move all quirks together into quirks.h
mmc: core: improve the quirks for sdio devices
mmc: core: move some sdio IDs out of quirks file
mmc: core: change quirks.c to be a header file
mmc: sdhci-cadence: fix bit shift of read data from PHY port
mmc: Adding AUTO_BKOPS_EN bit set for Auto BKOPS support
mmc: MAN_BKOPS_EN inverse debug message logic
mmc: meson-gx: add support for HS400 mode
mmc: meson-gx: remove unneeded checks in remove
mmc: meson-gx: reduce bounce buffer size
mmc: meson-gx: set max block count and request size
mmc: meson-gx: improve interrupt handling
mmc: meson-gx: improve meson_mmc_irq_thread
mmc: meson-gx: improve meson_mmc_clk_set
mmc: meson-gx: minor improvements in meson_mmc_set_ios
mmc: meson: Assign the minimum clk rate as close to 400KHz as possible
mmc: core: start to break apart mmc_start_areq()
mmc: block: respect bool returned from blk_end_request()
mmc: block: return errorcode from mmc_sd_num_wr_blocks()
...
114 files changed, 2591 insertions, 1818 deletions
diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt index 7f95ec400863..50bf611a4d2c 100644 --- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx.txt | |||
@@ -17,7 +17,7 @@ Required properties: | |||
17 | "core" - Main peripheral bus clock | 17 | "core" - Main peripheral bus clock |
18 | "clkin0" - Parent clock of internal mux | 18 | "clkin0" - Parent clock of internal mux |
19 | "clkin1" - Other parent clock of internal mux | 19 | "clkin1" - Other parent clock of internal mux |
20 | The driver has an interal mux clock which switches between clkin0 and clkin1 depending on the | 20 | The driver has an internal mux clock which switches between clkin0 and clkin1 depending on the |
21 | clock rate requested by the MMC core. | 21 | clock rate requested by the MMC core. |
22 | 22 | ||
23 | Example: | 23 | Example: |
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt new file mode 100644 index 000000000000..22e9340e4ba2 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-sd8787.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | * Marvell SD8787 power sequence provider | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: must be "mmc-pwrseq-sd8787". | ||
5 | - powerdown-gpios: contains a power down GPIO specifier with the | ||
6 | default active state | ||
7 | - reset-gpios: contains a reset GPIO specifier with the default | ||
8 | active state | ||
9 | |||
10 | Example: | ||
11 | |||
12 | wifi_pwrseq: wifi_pwrseq { | ||
13 | compatible = "mmc-pwrseq-sd8787"; | ||
14 | powerdown-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>; | ||
15 | reset-gpios = <&twl_gpio 1 GPIO_ACTIVE_LOW>; | ||
16 | } | ||
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index 8a377827695b..c7f4a0ec48ed 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt | |||
@@ -40,6 +40,7 @@ Optional properties: | |||
40 | - cap-mmc-hw-reset: eMMC hardware reset is supported | 40 | - cap-mmc-hw-reset: eMMC hardware reset is supported |
41 | - cap-sdio-irq: enable SDIO IRQ signalling on this interface | 41 | - cap-sdio-irq: enable SDIO IRQ signalling on this interface |
42 | - full-pwr-cycle: full power cycle of the card is supported | 42 | - full-pwr-cycle: full power cycle of the card is supported |
43 | - mmc-ddr-3_3v: eMMC high-speed DDR mode(3.3V I/O) is supported | ||
43 | - mmc-ddr-1_8v: eMMC high-speed DDR mode(1.8V I/O) is supported | 44 | - mmc-ddr-1_8v: eMMC high-speed DDR mode(1.8V I/O) is supported |
44 | - mmc-ddr-1_2v: eMMC high-speed DDR mode(1.2V I/O) is supported | 45 | - mmc-ddr-1_2v: eMMC high-speed DDR mode(1.2V I/O) is supported |
45 | - mmc-hs200-1_8v: eMMC HS200 mode(1.8V I/O) is supported | 46 | - mmc-hs200-1_8v: eMMC HS200 mode(1.8V I/O) is supported |
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-st.txt b/Documentation/devicetree/bindings/mmc/sdhci-st.txt index 3cd4c43a3260..230fd696eb92 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-st.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-st.txt | |||
@@ -38,7 +38,7 @@ Optional properties: | |||
38 | - bus-width: Number of data lines. | 38 | - bus-width: Number of data lines. |
39 | See: Documentation/devicetree/bindings/mmc/mmc.txt. | 39 | See: Documentation/devicetree/bindings/mmc/mmc.txt. |
40 | 40 | ||
41 | - max-frequency: Can be 200MHz, 100Mz or 50MHz (default) and used for | 41 | - max-frequency: Can be 200MHz, 100MHz or 50MHz (default) and used for |
42 | configuring the CCONFIG3 in the mmcss. | 42 | configuring the CCONFIG3 in the mmcss. |
43 | See: Documentation/devicetree/bindings/mmc/mmc.txt. | 43 | See: Documentation/devicetree/bindings/mmc/mmc.txt. |
44 | 44 | ||
diff --git a/Documentation/devicetree/bindings/mmc/sdhci.txt b/Documentation/devicetree/bindings/mmc/sdhci.txt index 1c95a1a555c3..0e9923a64024 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci.txt | |||
@@ -5,7 +5,7 @@ host controllers refer to the mmc[1] bindings. | |||
5 | 5 | ||
6 | Optional properties: | 6 | Optional properties: |
7 | - sdhci-caps-mask: The sdhci capabilities register is incorrect. This 64bit | 7 | - sdhci-caps-mask: The sdhci capabilities register is incorrect. This 64bit |
8 | property corresponds to the bits in the sdhci capabilty register. If the bit | 8 | property corresponds to the bits in the sdhci capability register. If the bit |
9 | is on in the mask then the bit is incorrect in the register and should be | 9 | is on in the mask then the bit is incorrect in the register and should be |
10 | turned off, before applying sdhci-caps. | 10 | turned off, before applying sdhci-caps. |
11 | - sdhci-caps: The sdhci capabilities register is incorrect. This 64bit | 11 | - sdhci-caps: The sdhci capabilities register is incorrect. This 64bit |
diff --git a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt index 55cdd804cdba..7d53a799f140 100644 --- a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt +++ b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt | |||
@@ -13,6 +13,7 @@ Required properties: | |||
13 | * "allwinner,sun5i-a13-mmc" | 13 | * "allwinner,sun5i-a13-mmc" |
14 | * "allwinner,sun7i-a20-mmc" | 14 | * "allwinner,sun7i-a20-mmc" |
15 | * "allwinner,sun9i-a80-mmc" | 15 | * "allwinner,sun9i-a80-mmc" |
16 | * "allwinner,sun50i-a64-emmc" | ||
16 | * "allwinner,sun50i-a64-mmc" | 17 | * "allwinner,sun50i-a64-mmc" |
17 | - reg : mmc controller base registers | 18 | - reg : mmc controller base registers |
18 | - clocks : a list with 4 phandle + clock specifier pairs | 19 | - clocks : a list with 4 phandle + clock specifier pairs |
diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt index 7fd17c3da116..9cb55ca57461 100644 --- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt | |||
@@ -16,7 +16,7 @@ Required Properties: | |||
16 | each child-node representing a supported slot. There should be atleast one | 16 | each child-node representing a supported slot. There should be atleast one |
17 | child node representing a card slot. The name of the child node representing | 17 | child node representing a card slot. The name of the child node representing |
18 | the slot is recommended to be slot@n where n is the unique number of the slot | 18 | the slot is recommended to be slot@n where n is the unique number of the slot |
19 | connnected to the controller. The following are optional properties which | 19 | connected to the controller. The following are optional properties which |
20 | can be included in the slot child node. | 20 | can be included in the slot child node. |
21 | 21 | ||
22 | * reg: specifies the physical slot number. The valid values of this | 22 | * reg: specifies the physical slot number. The valid values of this |
@@ -75,6 +75,17 @@ Optional properties: | |||
75 | * card-detect-delay: Delay in milli-seconds before detecting card after card | 75 | * card-detect-delay: Delay in milli-seconds before detecting card after card |
76 | insert event. The default value is 0. | 76 | insert event. The default value is 0. |
77 | 77 | ||
78 | * data-addr: Override fifo address with value provided by DT. The default FIFO reg | ||
79 | offset is assumed as 0x100 (version < 0x240A) and 0x200(version >= 0x240A) by | ||
80 | driver. If the controller does not follow this rule, please use this property | ||
81 | to set fifo address in device tree. | ||
82 | |||
83 | * fifo-watermark-aligned: Data done irq is expected if data length is less than | ||
84 | watermark in PIO mode. But fifo watermark is requested to be aligned with data | ||
85 | length in some SoC so that TX/RX irq can be generated with data done irq. Add this | ||
86 | watermark quirk to mark this requirement and force fifo watermark setting | ||
87 | accordingly. | ||
88 | |||
78 | * vmmc-supply: The phandle to the regulator to use for vmmc. If this is | 89 | * vmmc-supply: The phandle to the regulator to use for vmmc. If this is |
79 | specified we'll defer probe until we can find this regulator. | 90 | specified we'll defer probe until we can find this regulator. |
80 | 91 | ||
@@ -102,6 +113,8 @@ board specific portions as listed below. | |||
102 | interrupts = <0 75 0>; | 113 | interrupts = <0 75 0>; |
103 | #address-cells = <1>; | 114 | #address-cells = <1>; |
104 | #size-cells = <0>; | 115 | #size-cells = <0>; |
116 | data-addr = <0x200>; | ||
117 | fifo-watermark-aligned; | ||
105 | resets = <&rst 20>; | 118 | resets = <&rst 20>; |
106 | reset-names = "reset"; | 119 | reset-names = "reset"; |
107 | }; | 120 | }; |
diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index a1650edfd2b7..4fd8b7acc510 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt | |||
@@ -25,6 +25,19 @@ Required properties: | |||
25 | "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC | 25 | "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC |
26 | "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC | 26 | "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC |
27 | 27 | ||
28 | - clocks: Most controllers only have 1 clock source per channel. However, on | ||
29 | some variations of this controller, the internal card detection | ||
30 | logic that exists in this controller is sectioned off to be run by a | ||
31 | separate second clock source to allow the main core clock to be turned | ||
32 | off to save power. | ||
33 | If 2 clocks are specified by the hardware, you must name them as | ||
34 | "core" and "cd". If the controller only has 1 clock, naming is not | ||
35 | required. | ||
36 | Below is the number clocks for each supported SoC: | ||
37 | 1: SH73A0, R8A73A4, R8A7740, R8A7778, R8A7779, R8A7790 | ||
38 | R8A7791, R8A7792, R8A7793, R8A7794, R8A7795, R8A7796 | ||
39 | 2: R7S72100 | ||
40 | |||
28 | Optional properties: | 41 | Optional properties: |
29 | - toshiba,mmc-wrprotect-disable: write-protect detection is unavailable | 42 | - toshiba,mmc-wrprotect-disable: write-protect detection is unavailable |
30 | - pinctrl-names: should be "default", "state_uhs" | 43 | - pinctrl-names: should be "default", "state_uhs" |
diff --git a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt new file mode 100644 index 000000000000..eaade0e5adeb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt | |||
@@ -0,0 +1,33 @@ | |||
1 | * ZTE specific extensions to the Synopsys Designware Mobile Storage | ||
2 | Host Controller | ||
3 | |||
4 | The Synopsys designware mobile storage host controller is used to interface | ||
5 | a SoC with storage medium such as eMMC or SD/MMC cards. This file documents | ||
6 | differences between the core Synopsys dw mshc controller properties described | ||
7 | by synopsys-dw-mshc.txt and the properties used by the ZTE specific | ||
8 | extensions to the Synopsys Designware Mobile Storage Host Controller. | ||
9 | |||
10 | Required Properties: | ||
11 | |||
12 | * compatible: should be | ||
13 | - "zte,zx296718-dw-mshc": for ZX SoCs | ||
14 | |||
15 | Example: | ||
16 | |||
17 | mmc1: mmc@1110000 { | ||
18 | compatible = "zte,zx296718-dw-mshc"; | ||
19 | reg = <0x01110000 0x1000>; | ||
20 | interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; | ||
21 | fifo-depth = <32>; | ||
22 | data-addr = <0x200>; | ||
23 | fifo-watermark-aligned; | ||
24 | bus-width = <4>; | ||
25 | clock-frequency = <50000000>; | ||
26 | clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>; | ||
27 | clock-names = "biu", "ciu"; | ||
28 | num-slots = <1>; | ||
29 | max-frequency = <50000000>; | ||
30 | cap-sdio-irq; | ||
31 | cap-sd-highspeed; | ||
32 | status = "disabled"; | ||
33 | }; | ||
diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt index 980b16df74c3..0854451ff91d 100644 --- a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt +++ b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt | |||
@@ -1,4 +1,4 @@ | |||
1 | Marvell 8897/8997 (sd8897/sd8997/pcie8997) SDIO/PCIE devices | 1 | Marvell 8787/8897/8997 (sd8787/sd8897/sd8997/pcie8997) SDIO/PCIE devices |
2 | ------ | 2 | ------ |
3 | 3 | ||
4 | This node provides properties for controlling the Marvell SDIO/PCIE wireless device. | 4 | This node provides properties for controlling the Marvell SDIO/PCIE wireless device. |
@@ -8,6 +8,7 @@ connects the device to the system. | |||
8 | Required properties: | 8 | Required properties: |
9 | 9 | ||
10 | - compatible : should be one of the following: | 10 | - compatible : should be one of the following: |
11 | * "marvell,sd8787" | ||
11 | * "marvell,sd8897" | 12 | * "marvell,sd8897" |
12 | * "marvell,sd8997" | 13 | * "marvell,sd8997" |
13 | * "pci11ab,2b42" | 14 | * "pci11ab,2b42" |
@@ -34,6 +35,9 @@ Optional properties: | |||
34 | so that the wifi chip can wakeup host platform under certain condition. | 35 | so that the wifi chip can wakeup host platform under certain condition. |
35 | during system resume, the irq will be disabled to make sure | 36 | during system resume, the irq will be disabled to make sure |
36 | unnecessary interrupt is not received. | 37 | unnecessary interrupt is not received. |
38 | - vmmc-supply: a phandle of a regulator, supplying VCC to the card | ||
39 | - mmc-pwrseq: phandle to the MMC power sequence node. See "mmc-pwrseq-*" | ||
40 | for documentation of MMC power sequence bindings. | ||
37 | 41 | ||
38 | Example: | 42 | Example: |
39 | 43 | ||
@@ -46,6 +50,7 @@ so that firmware can wakeup host using this device side pin. | |||
46 | &mmc3 { | 50 | &mmc3 { |
47 | status = "okay"; | 51 | status = "okay"; |
48 | vmmc-supply = <&wlan_en_reg>; | 52 | vmmc-supply = <&wlan_en_reg>; |
53 | mmc-pwrseq = <&wifi_pwrseq>; | ||
49 | bus-width = <4>; | 54 | bus-width = <4>; |
50 | cap-power-off-card; | 55 | cap-power-off-card; |
51 | keep-power-in-suspend; | 56 | keep-power-in-suspend; |
diff --git a/MAINTAINERS b/MAINTAINERS index a0fb98c6399a..d5dee50d7c69 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -10894,7 +10894,6 @@ SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER | |||
10894 | M: Jaehoon Chung <jh80.chung@samsung.com> | 10894 | M: Jaehoon Chung <jh80.chung@samsung.com> |
10895 | L: linux-mmc@vger.kernel.org | 10895 | L: linux-mmc@vger.kernel.org |
10896 | S: Maintained | 10896 | S: Maintained |
10897 | F: include/linux/mmc/dw_mmc.h | ||
10898 | F: drivers/mmc/host/dw_mmc* | 10897 | F: drivers/mmc/host/dw_mmc* |
10899 | 10898 | ||
10900 | SYSTEM TRACE MODULE CLASS | 10899 | SYSTEM TRACE MODULE CLASS |
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index aac3ab1a044f..df3ca38778af 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/gpio/machine.h> | 18 | #include <linux/gpio/machine.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/leds.h> | ||
21 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
22 | #include <linux/platform_data/at24.h> | 23 | #include <linux/platform_data/at24.h> |
23 | #include <linux/platform_data/pca953x.h> | 24 | #include <linux/platform_data/pca953x.h> |
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 521e40977265..023480b75244 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/videodev2.h> | 25 | #include <linux/videodev2.h> |
26 | #include <linux/v4l2-dv-timings.h> | 26 | #include <linux/v4l2-dv-timings.h> |
27 | #include <linux/export.h> | 27 | #include <linux/export.h> |
28 | #include <linux/leds.h> | ||
28 | 29 | ||
29 | #include <media/i2c/tvp514x.h> | 30 | #include <media/i2c/tvp514x.h> |
30 | 31 | ||
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index ad10017203c1..0a7838852649 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/leds.h> | ||
28 | #include <linux/mtd/partitions.h> | 29 | #include <linux/mtd/partitions.h> |
29 | #include <linux/platform_data/gpio-davinci.h> | 30 | #include <linux/platform_data/gpio-davinci.h> |
30 | #include <linux/platform_data/i2c-davinci.h> | 31 | #include <linux/platform_data/i2c-davinci.h> |
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 41d5500996b2..a3e78074be70 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/console.h> | 14 | #include <linux/console.h> |
15 | #include <linux/interrupt.h> | ||
15 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
16 | #include <linux/gpio/machine.h> | 17 | #include <linux/gpio/machine.h> |
17 | #include <linux/platform_data/gpio-davinci.h> | 18 | #include <linux/platform_data/gpio-davinci.h> |
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 8a3c409294bf..d452a49c0396 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/leds.h> | ||
20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
21 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
22 | #include <linux/fb.h> | 23 | #include <linux/fb.h> |
diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c index 8cff770e6a00..d7cf47d03618 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-income.c +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/leds.h> | ||
20 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 183cd3446f25..7270f0db3432 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/major.h> | 19 | #include <linux/major.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/leds.h> | ||
22 | #include <linux/mmc/host.h> | 23 | #include <linux/mmc/host.h> |
23 | #include <linux/mtd/physmap.h> | 24 | #include <linux/mtd/physmap.h> |
24 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index ea78bc5c4198..3dd13b44c311 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/leds.h> | ||
19 | #include <linux/export.h> | 20 | #include <linux/export.h> |
20 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
21 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index c006ee902a8f..70ab3ad28237 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/gpio_keys.h> | 16 | #include <linux/gpio_keys.h> |
17 | #include <linux/input.h> | 17 | #include <linux/input.h> |
18 | #include <linux/leds.h> | ||
18 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
19 | #include <linux/usb/gpio_vbus.h> | 20 | #include <linux/usb/gpio_vbus.h> |
20 | #include <linux/mtd/mtd.h> | 21 | #include <linux/mtd/mtd.h> |
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 3b94ecfb9426..ecbcaee5a2d5 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/leds.h> | ||
16 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
17 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
18 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 3642389b301a..4268552d600d 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/leds.h> | ||
19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index d3c087f59f1a..a5504f57cb00 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/leds.h> | 15 | #include <linux/leds.h> |
16 | #include <linux/interrupt.h> | ||
16 | #include <linux/ata_platform.h> | 17 | #include <linux/ata_platform.h> |
17 | #include <linux/mmc/host.h> | 18 | #include <linux/mmc/host.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
diff --git a/arch/sh/boot/romimage/mmcif-sh7724.c b/arch/sh/boot/romimage/mmcif-sh7724.c index 16b122510c84..6595b6b45bf1 100644 --- a/arch/sh/boot/romimage/mmcif-sh7724.c +++ b/arch/sh/boot/romimage/mmcif-sh7724.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/mmc/sh_mmcif.h> | 11 | #include <linux/mmc/sh_mmcif.h> |
12 | #include <linux/mmc/boot.h> | ||
13 | #include <mach/romimage.h> | 12 | #include <mach/romimage.h> |
14 | 13 | ||
15 | #define MMCIF_BASE (void __iomem *)0xa4ca0000 | 14 | #define MMCIF_BASE (void __iomem *)0xa4ca0000 |
@@ -22,6 +21,13 @@ | |||
22 | #define HIZCRC 0xa405015c | 21 | #define HIZCRC 0xa405015c |
23 | #define DRVCRA 0xa405018a | 22 | #define DRVCRA 0xa405018a |
24 | 23 | ||
24 | enum { | ||
25 | MMCIF_PROGRESS_ENTER, | ||
26 | MMCIF_PROGRESS_INIT, | ||
27 | MMCIF_PROGRESS_LOAD, | ||
28 | MMCIF_PROGRESS_DONE | ||
29 | }; | ||
30 | |||
25 | /* SH7724 specific MMCIF loader | 31 | /* SH7724 specific MMCIF loader |
26 | * | 32 | * |
27 | * loads the romImage from an MMC card starting from block 512 | 33 | * loads the romImage from an MMC card starting from block 512 |
@@ -30,7 +36,7 @@ | |||
30 | */ | 36 | */ |
31 | asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) | 37 | asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) |
32 | { | 38 | { |
33 | mmcif_update_progress(MMC_PROGRESS_ENTER); | 39 | mmcif_update_progress(MMCIF_PROGRESS_ENTER); |
34 | 40 | ||
35 | /* enable clock to the MMCIF hardware block */ | 41 | /* enable clock to the MMCIF hardware block */ |
36 | __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2); | 42 | __raw_writel(__raw_readl(MSTPCR2) & ~0x20000000, MSTPCR2); |
@@ -53,12 +59,12 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) | |||
53 | /* high drive capability for MMC pins */ | 59 | /* high drive capability for MMC pins */ |
54 | __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA); | 60 | __raw_writew(__raw_readw(DRVCRA) | 0x3000, DRVCRA); |
55 | 61 | ||
56 | mmcif_update_progress(MMC_PROGRESS_INIT); | 62 | mmcif_update_progress(MMCIF_PROGRESS_INIT); |
57 | 63 | ||
58 | /* setup MMCIF hardware */ | 64 | /* setup MMCIF hardware */ |
59 | sh_mmcif_boot_init(MMCIF_BASE); | 65 | sh_mmcif_boot_init(MMCIF_BASE); |
60 | 66 | ||
61 | mmcif_update_progress(MMC_PROGRESS_LOAD); | 67 | mmcif_update_progress(MMCIF_PROGRESS_LOAD); |
62 | 68 | ||
63 | /* load kernel via MMCIF interface */ | 69 | /* load kernel via MMCIF interface */ |
64 | sh_mmcif_boot_do_read(MMCIF_BASE, 512, | 70 | sh_mmcif_boot_do_read(MMCIF_BASE, 512, |
@@ -68,5 +74,5 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) | |||
68 | /* disable clock to the MMCIF hardware block */ | 74 | /* disable clock to the MMCIF hardware block */ |
69 | __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); | 75 | __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); |
70 | 76 | ||
71 | mmcif_update_progress(MMC_PROGRESS_DONE); | 77 | mmcif_update_progress(MMCIF_PROGRESS_DONE); |
72 | } | 78 | } |
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index cdfa8520a4b1..fc1ecdaaa9ca 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig | |||
@@ -12,6 +12,16 @@ config PWRSEQ_EMMC | |||
12 | This driver can also be built as a module. If so, the module | 12 | This driver can also be built as a module. If so, the module |
13 | will be called pwrseq_emmc. | 13 | will be called pwrseq_emmc. |
14 | 14 | ||
15 | config PWRSEQ_SD8787 | ||
16 | tristate "HW reset support for SD8787 BT + Wifi module" | ||
17 | depends on OF && (MWIFIEX || BT_MRVL_SDIO) | ||
18 | help | ||
19 | This selects hardware reset support for the SD8787 BT + Wifi | ||
20 | module. By default this option is set to n. | ||
21 | |||
22 | This driver can also be built as a module. If so, the module | ||
23 | will be called pwrseq_sd8787. | ||
24 | |||
15 | config PWRSEQ_SIMPLE | 25 | config PWRSEQ_SIMPLE |
16 | tristate "Simple HW reset support for MMC" | 26 | tristate "Simple HW reset support for MMC" |
17 | default y | 27 | default y |
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index b2a257dc644f..7e3ed1aeada2 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile | |||
@@ -7,9 +7,10 @@ mmc_core-y := core.o bus.o host.o \ | |||
7 | mmc.o mmc_ops.o sd.o sd_ops.o \ | 7 | mmc.o mmc_ops.o sd.o sd_ops.o \ |
8 | sdio.o sdio_ops.o sdio_bus.o \ | 8 | sdio.o sdio_ops.o sdio_bus.o \ |
9 | sdio_cis.o sdio_io.o sdio_irq.o \ | 9 | sdio_cis.o sdio_io.o sdio_irq.o \ |
10 | quirks.o slot-gpio.o | 10 | slot-gpio.o |
11 | mmc_core-$(CONFIG_OF) += pwrseq.o | 11 | mmc_core-$(CONFIG_OF) += pwrseq.o |
12 | obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o | 12 | obj-$(CONFIG_PWRSEQ_SIMPLE) += pwrseq_simple.o |
13 | obj-$(CONFIG_PWRSEQ_SD8787) += pwrseq_sd8787.o | ||
13 | obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o | 14 | obj-$(CONFIG_PWRSEQ_EMMC) += pwrseq_emmc.o |
14 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o | 15 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o |
15 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o | 16 | obj-$(CONFIG_MMC_BLOCK) += mmc_block.o |
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index cb1698f268f1..1621fa08e206 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c | |||
@@ -47,6 +47,13 @@ | |||
47 | 47 | ||
48 | #include "queue.h" | 48 | #include "queue.h" |
49 | #include "block.h" | 49 | #include "block.h" |
50 | #include "core.h" | ||
51 | #include "card.h" | ||
52 | #include "host.h" | ||
53 | #include "bus.h" | ||
54 | #include "mmc_ops.h" | ||
55 | #include "quirks.h" | ||
56 | #include "sd_ops.h" | ||
50 | 57 | ||
51 | MODULE_ALIAS("mmc:block"); | 58 | MODULE_ALIAS("mmc:block"); |
52 | #ifdef MODULE_PARAM_PREFIX | 59 | #ifdef MODULE_PARAM_PREFIX |
@@ -54,12 +61,6 @@ MODULE_ALIAS("mmc:block"); | |||
54 | #endif | 61 | #endif |
55 | #define MODULE_PARAM_PREFIX "mmcblk." | 62 | #define MODULE_PARAM_PREFIX "mmcblk." |
56 | 63 | ||
57 | #define INAND_CMD38_ARG_EXT_CSD 113 | ||
58 | #define INAND_CMD38_ARG_ERASE 0x00 | ||
59 | #define INAND_CMD38_ARG_TRIM 0x01 | ||
60 | #define INAND_CMD38_ARG_SECERASE 0x80 | ||
61 | #define INAND_CMD38_ARG_SECTRIM1 0x81 | ||
62 | #define INAND_CMD38_ARG_SECTRIM2 0x88 | ||
63 | #define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ | 64 | #define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ |
64 | #define MMC_SANITIZE_REQ_TIMEOUT 240000 | 65 | #define MMC_SANITIZE_REQ_TIMEOUT 240000 |
65 | #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) | 66 | #define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) |
@@ -84,7 +85,6 @@ static int max_devices; | |||
84 | #define MAX_DEVICES 256 | 85 | #define MAX_DEVICES 256 |
85 | 86 | ||
86 | static DEFINE_IDA(mmc_blk_ida); | 87 | static DEFINE_IDA(mmc_blk_ida); |
87 | static DEFINE_SPINLOCK(mmc_blk_lock); | ||
88 | 88 | ||
89 | /* | 89 | /* |
90 | * There is one mmc_blk_data per slot. | 90 | * There is one mmc_blk_data per slot. |
@@ -157,11 +157,7 @@ static void mmc_blk_put(struct mmc_blk_data *md) | |||
157 | if (md->usage == 0) { | 157 | if (md->usage == 0) { |
158 | int devidx = mmc_get_devidx(md->disk); | 158 | int devidx = mmc_get_devidx(md->disk); |
159 | blk_cleanup_queue(md->queue.queue); | 159 | blk_cleanup_queue(md->queue.queue); |
160 | 160 | ida_simple_remove(&mmc_blk_ida, devidx); | |
161 | spin_lock(&mmc_blk_lock); | ||
162 | ida_remove(&mmc_blk_ida, devidx); | ||
163 | spin_unlock(&mmc_blk_lock); | ||
164 | |||
165 | put_disk(md->disk); | 161 | put_disk(md->disk); |
166 | kfree(md); | 162 | kfree(md); |
167 | } | 163 | } |
@@ -442,9 +438,9 @@ out: | |||
442 | static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, | 438 | static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, |
443 | struct mmc_blk_ioc_data *idata) | 439 | struct mmc_blk_ioc_data *idata) |
444 | { | 440 | { |
445 | struct mmc_command cmd = {0}; | 441 | struct mmc_command cmd = {}; |
446 | struct mmc_data data = {0}; | 442 | struct mmc_data data = {}; |
447 | struct mmc_request mrq = {NULL}; | 443 | struct mmc_request mrq = {}; |
448 | struct scatterlist sg; | 444 | struct scatterlist sg; |
449 | int err; | 445 | int err; |
450 | int is_rpmb = false; | 446 | int is_rpmb = false; |
@@ -762,15 +758,15 @@ static inline int mmc_blk_part_switch(struct mmc_card *card, | |||
762 | return 0; | 758 | return 0; |
763 | } | 759 | } |
764 | 760 | ||
765 | static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | 761 | static int mmc_sd_num_wr_blocks(struct mmc_card *card, u32 *written_blocks) |
766 | { | 762 | { |
767 | int err; | 763 | int err; |
768 | u32 result; | 764 | u32 result; |
769 | __be32 *blocks; | 765 | __be32 *blocks; |
770 | 766 | ||
771 | struct mmc_request mrq = {NULL}; | 767 | struct mmc_request mrq = {}; |
772 | struct mmc_command cmd = {0}; | 768 | struct mmc_command cmd = {}; |
773 | struct mmc_data data = {0}; | 769 | struct mmc_data data = {}; |
774 | 770 | ||
775 | struct scatterlist sg; | 771 | struct scatterlist sg; |
776 | 772 | ||
@@ -780,9 +776,9 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | |||
780 | 776 | ||
781 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | 777 | err = mmc_wait_for_cmd(card->host, &cmd, 0); |
782 | if (err) | 778 | if (err) |
783 | return (u32)-1; | 779 | return err; |
784 | if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) | 780 | if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) |
785 | return (u32)-1; | 781 | return -EIO; |
786 | 782 | ||
787 | memset(&cmd, 0, sizeof(struct mmc_command)); | 783 | memset(&cmd, 0, sizeof(struct mmc_command)); |
788 | 784 | ||
@@ -802,7 +798,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | |||
802 | 798 | ||
803 | blocks = kmalloc(4, GFP_KERNEL); | 799 | blocks = kmalloc(4, GFP_KERNEL); |
804 | if (!blocks) | 800 | if (!blocks) |
805 | return (u32)-1; | 801 | return -ENOMEM; |
806 | 802 | ||
807 | sg_init_one(&sg, blocks, 4); | 803 | sg_init_one(&sg, blocks, 4); |
808 | 804 | ||
@@ -812,14 +808,16 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) | |||
812 | kfree(blocks); | 808 | kfree(blocks); |
813 | 809 | ||
814 | if (cmd.error || data.error) | 810 | if (cmd.error || data.error) |
815 | result = (u32)-1; | 811 | return -EIO; |
812 | |||
813 | *written_blocks = result; | ||
816 | 814 | ||
817 | return result; | 815 | return 0; |
818 | } | 816 | } |
819 | 817 | ||
820 | static int get_card_status(struct mmc_card *card, u32 *status, int retries) | 818 | static int get_card_status(struct mmc_card *card, u32 *status, int retries) |
821 | { | 819 | { |
822 | struct mmc_command cmd = {0}; | 820 | struct mmc_command cmd = {}; |
823 | int err; | 821 | int err; |
824 | 822 | ||
825 | cmd.opcode = MMC_SEND_STATUS; | 823 | cmd.opcode = MMC_SEND_STATUS; |
@@ -884,7 +882,7 @@ static int send_stop(struct mmc_card *card, unsigned int timeout_ms, | |||
884 | struct request *req, bool *gen_err, u32 *stop_status) | 882 | struct request *req, bool *gen_err, u32 *stop_status) |
885 | { | 883 | { |
886 | struct mmc_host *host = card->host; | 884 | struct mmc_host *host = card->host; |
887 | struct mmc_command cmd = {0}; | 885 | struct mmc_command cmd = {}; |
888 | int err; | 886 | int err; |
889 | bool use_r1b_resp = rq_data_dir(req) == WRITE; | 887 | bool use_r1b_resp = rq_data_dir(req) == WRITE; |
890 | 888 | ||
@@ -1143,7 +1141,7 @@ int mmc_access_rpmb(struct mmc_queue *mq) | |||
1143 | return false; | 1141 | return false; |
1144 | } | 1142 | } |
1145 | 1143 | ||
1146 | static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) | 1144 | static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) |
1147 | { | 1145 | { |
1148 | struct mmc_blk_data *md = mq->blkdata; | 1146 | struct mmc_blk_data *md = mq->blkdata; |
1149 | struct mmc_card *card = md->queue.card; | 1147 | struct mmc_card *card = md->queue.card; |
@@ -1152,7 +1150,7 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) | |||
1152 | 1150 | ||
1153 | if (!mmc_can_erase(card)) { | 1151 | if (!mmc_can_erase(card)) { |
1154 | err = -EOPNOTSUPP; | 1152 | err = -EOPNOTSUPP; |
1155 | goto out; | 1153 | goto fail; |
1156 | } | 1154 | } |
1157 | 1155 | ||
1158 | from = blk_rq_pos(req); | 1156 | from = blk_rq_pos(req); |
@@ -1164,29 +1162,26 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) | |||
1164 | arg = MMC_TRIM_ARG; | 1162 | arg = MMC_TRIM_ARG; |
1165 | else | 1163 | else |
1166 | arg = MMC_ERASE_ARG; | 1164 | arg = MMC_ERASE_ARG; |
1167 | retry: | 1165 | do { |
1168 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { | 1166 | err = 0; |
1169 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1167 | if (card->quirks & MMC_QUIRK_INAND_CMD38) { |
1170 | INAND_CMD38_ARG_EXT_CSD, | 1168 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1171 | arg == MMC_TRIM_ARG ? | 1169 | INAND_CMD38_ARG_EXT_CSD, |
1172 | INAND_CMD38_ARG_TRIM : | 1170 | arg == MMC_TRIM_ARG ? |
1173 | INAND_CMD38_ARG_ERASE, | 1171 | INAND_CMD38_ARG_TRIM : |
1174 | 0); | 1172 | INAND_CMD38_ARG_ERASE, |
1175 | if (err) | 1173 | 0); |
1176 | goto out; | 1174 | } |
1177 | } | 1175 | if (!err) |
1178 | err = mmc_erase(card, from, nr, arg); | 1176 | err = mmc_erase(card, from, nr, arg); |
1179 | out: | 1177 | } while (err == -EIO && !mmc_blk_reset(md, card->host, type)); |
1180 | if (err == -EIO && !mmc_blk_reset(md, card->host, type)) | ||
1181 | goto retry; | ||
1182 | if (!err) | 1178 | if (!err) |
1183 | mmc_blk_reset_success(md, type); | 1179 | mmc_blk_reset_success(md, type); |
1180 | fail: | ||
1184 | blk_end_request(req, err, blk_rq_bytes(req)); | 1181 | blk_end_request(req, err, blk_rq_bytes(req)); |
1185 | |||
1186 | return err ? 0 : 1; | ||
1187 | } | 1182 | } |
1188 | 1183 | ||
1189 | static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, | 1184 | static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, |
1190 | struct request *req) | 1185 | struct request *req) |
1191 | { | 1186 | { |
1192 | struct mmc_blk_data *md = mq->blkdata; | 1187 | struct mmc_blk_data *md = mq->blkdata; |
@@ -1249,11 +1244,9 @@ out_retry: | |||
1249 | mmc_blk_reset_success(md, type); | 1244 | mmc_blk_reset_success(md, type); |
1250 | out: | 1245 | out: |
1251 | blk_end_request(req, err, blk_rq_bytes(req)); | 1246 | blk_end_request(req, err, blk_rq_bytes(req)); |
1252 | |||
1253 | return err ? 0 : 1; | ||
1254 | } | 1247 | } |
1255 | 1248 | ||
1256 | static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) | 1249 | static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) |
1257 | { | 1250 | { |
1258 | struct mmc_blk_data *md = mq->blkdata; | 1251 | struct mmc_blk_data *md = mq->blkdata; |
1259 | struct mmc_card *card = md->queue.card; | 1252 | struct mmc_card *card = md->queue.card; |
@@ -1264,8 +1257,6 @@ static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) | |||
1264 | ret = -EIO; | 1257 | ret = -EIO; |
1265 | 1258 | ||
1266 | blk_end_request_all(req, ret); | 1259 | blk_end_request_all(req, ret); |
1267 | |||
1268 | return ret ? 0 : 1; | ||
1269 | } | 1260 | } |
1270 | 1261 | ||
1271 | /* | 1262 | /* |
@@ -1303,7 +1294,7 @@ static enum mmc_blk_status mmc_blk_err_check(struct mmc_card *card, | |||
1303 | struct mmc_async_req *areq) | 1294 | struct mmc_async_req *areq) |
1304 | { | 1295 | { |
1305 | struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req, | 1296 | struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req, |
1306 | mmc_active); | 1297 | areq); |
1307 | struct mmc_blk_request *brq = &mq_mrq->brq; | 1298 | struct mmc_blk_request *brq = &mq_mrq->brq; |
1308 | struct request *req = mq_mrq->req; | 1299 | struct request *req = mq_mrq->req; |
1309 | int need_retune = card->host->need_retune; | 1300 | int need_retune = card->host->need_retune; |
@@ -1559,17 +1550,19 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, | |||
1559 | brq->data.sg_len = i; | 1550 | brq->data.sg_len = i; |
1560 | } | 1551 | } |
1561 | 1552 | ||
1562 | mqrq->mmc_active.mrq = &brq->mrq; | 1553 | mqrq->areq.mrq = &brq->mrq; |
1563 | mqrq->mmc_active.err_check = mmc_blk_err_check; | 1554 | mqrq->areq.err_check = mmc_blk_err_check; |
1564 | 1555 | ||
1565 | mmc_queue_bounce_pre(mqrq); | 1556 | mmc_queue_bounce_pre(mqrq); |
1566 | } | 1557 | } |
1567 | 1558 | ||
1568 | static int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card, | 1559 | static bool mmc_blk_rw_cmd_err(struct mmc_blk_data *md, struct mmc_card *card, |
1569 | struct mmc_blk_request *brq, struct request *req, | 1560 | struct mmc_blk_request *brq, struct request *req, |
1570 | int ret) | 1561 | bool old_req_pending) |
1571 | { | 1562 | { |
1572 | struct mmc_queue_req *mq_rq; | 1563 | struct mmc_queue_req *mq_rq; |
1564 | bool req_pending; | ||
1565 | |||
1573 | mq_rq = container_of(brq, struct mmc_queue_req, brq); | 1566 | mq_rq = container_of(brq, struct mmc_queue_req, brq); |
1574 | 1567 | ||
1575 | /* | 1568 | /* |
@@ -1582,62 +1575,104 @@ static int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card, | |||
1582 | */ | 1575 | */ |
1583 | if (mmc_card_sd(card)) { | 1576 | if (mmc_card_sd(card)) { |
1584 | u32 blocks; | 1577 | u32 blocks; |
1578 | int err; | ||
1585 | 1579 | ||
1586 | blocks = mmc_sd_num_wr_blocks(card); | 1580 | err = mmc_sd_num_wr_blocks(card, &blocks); |
1587 | if (blocks != (u32)-1) { | 1581 | if (err) |
1588 | ret = blk_end_request(req, 0, blocks << 9); | 1582 | req_pending = old_req_pending; |
1589 | } | 1583 | else |
1584 | req_pending = blk_end_request(req, 0, blocks << 9); | ||
1590 | } else { | 1585 | } else { |
1591 | ret = blk_end_request(req, 0, brq->data.bytes_xfered); | 1586 | req_pending = blk_end_request(req, 0, brq->data.bytes_xfered); |
1592 | } | 1587 | } |
1593 | return ret; | 1588 | return req_pending; |
1589 | } | ||
1590 | |||
1591 | static void mmc_blk_rw_cmd_abort(struct mmc_card *card, struct request *req) | ||
1592 | { | ||
1593 | if (mmc_card_removed(card)) | ||
1594 | req->rq_flags |= RQF_QUIET; | ||
1595 | while (blk_end_request(req, -EIO, blk_rq_cur_bytes(req))); | ||
1596 | } | ||
1597 | |||
1598 | /** | ||
1599 | * mmc_blk_rw_try_restart() - tries to restart the current async request | ||
1600 | * @mq: the queue with the card and host to restart | ||
1601 | * @req: a new request that want to be started after the current one | ||
1602 | */ | ||
1603 | static void mmc_blk_rw_try_restart(struct mmc_queue *mq, struct request *req) | ||
1604 | { | ||
1605 | if (!req) | ||
1606 | return; | ||
1607 | |||
1608 | /* | ||
1609 | * If the card was removed, just cancel everything and return. | ||
1610 | */ | ||
1611 | if (mmc_card_removed(mq->card)) { | ||
1612 | req->rq_flags |= RQF_QUIET; | ||
1613 | blk_end_request_all(req, -EIO); | ||
1614 | return; | ||
1615 | } | ||
1616 | /* Else proceed and try to restart the current async request */ | ||
1617 | mmc_blk_rw_rq_prep(mq->mqrq_cur, mq->card, 0, mq); | ||
1618 | mmc_start_areq(mq->card->host, &mq->mqrq_cur->areq, NULL); | ||
1594 | } | 1619 | } |
1595 | 1620 | ||
1596 | static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | 1621 | static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) |
1597 | { | 1622 | { |
1598 | struct mmc_blk_data *md = mq->blkdata; | 1623 | struct mmc_blk_data *md = mq->blkdata; |
1599 | struct mmc_card *card = md->queue.card; | 1624 | struct mmc_card *card = md->queue.card; |
1600 | struct mmc_blk_request *brq; | 1625 | struct mmc_blk_request *brq; |
1601 | int ret = 1, disable_multi = 0, retry = 0, type, retune_retry_done = 0; | 1626 | int disable_multi = 0, retry = 0, type, retune_retry_done = 0; |
1602 | enum mmc_blk_status status; | 1627 | enum mmc_blk_status status; |
1603 | struct mmc_queue_req *mq_rq; | 1628 | struct mmc_queue_req *mq_rq; |
1604 | struct request *req; | 1629 | struct request *old_req; |
1605 | struct mmc_async_req *areq; | 1630 | struct mmc_async_req *new_areq; |
1631 | struct mmc_async_req *old_areq; | ||
1632 | bool req_pending = true; | ||
1606 | 1633 | ||
1607 | if (!rqc && !mq->mqrq_prev->req) | 1634 | if (!new_req && !mq->mqrq_prev->req) |
1608 | return 0; | 1635 | return; |
1609 | 1636 | ||
1610 | do { | 1637 | do { |
1611 | if (rqc) { | 1638 | if (new_req) { |
1612 | /* | 1639 | /* |
1613 | * When 4KB native sector is enabled, only 8 blocks | 1640 | * When 4KB native sector is enabled, only 8 blocks |
1614 | * multiple read or write is allowed | 1641 | * multiple read or write is allowed |
1615 | */ | 1642 | */ |
1616 | if (mmc_large_sector(card) && | 1643 | if (mmc_large_sector(card) && |
1617 | !IS_ALIGNED(blk_rq_sectors(rqc), 8)) { | 1644 | !IS_ALIGNED(blk_rq_sectors(new_req), 8)) { |
1618 | pr_err("%s: Transfer size is not 4KB sector size aligned\n", | 1645 | pr_err("%s: Transfer size is not 4KB sector size aligned\n", |
1619 | rqc->rq_disk->disk_name); | 1646 | new_req->rq_disk->disk_name); |
1620 | mq_rq = mq->mqrq_cur; | 1647 | mmc_blk_rw_cmd_abort(card, new_req); |
1621 | req = rqc; | 1648 | return; |
1622 | rqc = NULL; | ||
1623 | goto cmd_abort; | ||
1624 | } | 1649 | } |
1625 | 1650 | ||
1626 | mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); | 1651 | mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); |
1627 | areq = &mq->mqrq_cur->mmc_active; | 1652 | new_areq = &mq->mqrq_cur->areq; |
1628 | } else | 1653 | } else |
1629 | areq = NULL; | 1654 | new_areq = NULL; |
1630 | areq = mmc_start_req(card->host, areq, &status); | 1655 | |
1631 | if (!areq) { | 1656 | old_areq = mmc_start_areq(card->host, new_areq, &status); |
1657 | if (!old_areq) { | ||
1658 | /* | ||
1659 | * We have just put the first request into the pipeline | ||
1660 | * and there is nothing more to do until it is | ||
1661 | * complete. | ||
1662 | */ | ||
1632 | if (status == MMC_BLK_NEW_REQUEST) | 1663 | if (status == MMC_BLK_NEW_REQUEST) |
1633 | mq->flags |= MMC_QUEUE_NEW_REQUEST; | 1664 | mq->new_request = true; |
1634 | return 0; | 1665 | return; |
1635 | } | 1666 | } |
1636 | 1667 | ||
1637 | mq_rq = container_of(areq, struct mmc_queue_req, mmc_active); | 1668 | /* |
1669 | * An asynchronous request has been completed and we proceed | ||
1670 | * to handle the result of it. | ||
1671 | */ | ||
1672 | mq_rq = container_of(old_areq, struct mmc_queue_req, areq); | ||
1638 | brq = &mq_rq->brq; | 1673 | brq = &mq_rq->brq; |
1639 | req = mq_rq->req; | 1674 | old_req = mq_rq->req; |
1640 | type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; | 1675 | type = rq_data_dir(old_req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; |
1641 | mmc_queue_bounce_post(mq_rq); | 1676 | mmc_queue_bounce_post(mq_rq); |
1642 | 1677 | ||
1643 | switch (status) { | 1678 | switch (status) { |
@@ -1648,28 +1683,32 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1648 | */ | 1683 | */ |
1649 | mmc_blk_reset_success(md, type); | 1684 | mmc_blk_reset_success(md, type); |
1650 | 1685 | ||
1651 | ret = blk_end_request(req, 0, | 1686 | req_pending = blk_end_request(old_req, 0, |
1652 | brq->data.bytes_xfered); | 1687 | brq->data.bytes_xfered); |
1653 | |||
1654 | /* | 1688 | /* |
1655 | * If the blk_end_request function returns non-zero even | 1689 | * If the blk_end_request function returns non-zero even |
1656 | * though all data has been transferred and no errors | 1690 | * though all data has been transferred and no errors |
1657 | * were returned by the host controller, it's a bug. | 1691 | * were returned by the host controller, it's a bug. |
1658 | */ | 1692 | */ |
1659 | if (status == MMC_BLK_SUCCESS && ret) { | 1693 | if (status == MMC_BLK_SUCCESS && req_pending) { |
1660 | pr_err("%s BUG rq_tot %d d_xfer %d\n", | 1694 | pr_err("%s BUG rq_tot %d d_xfer %d\n", |
1661 | __func__, blk_rq_bytes(req), | 1695 | __func__, blk_rq_bytes(old_req), |
1662 | brq->data.bytes_xfered); | 1696 | brq->data.bytes_xfered); |
1663 | rqc = NULL; | 1697 | mmc_blk_rw_cmd_abort(card, old_req); |
1664 | goto cmd_abort; | 1698 | return; |
1665 | } | 1699 | } |
1666 | break; | 1700 | break; |
1667 | case MMC_BLK_CMD_ERR: | 1701 | case MMC_BLK_CMD_ERR: |
1668 | ret = mmc_blk_cmd_err(md, card, brq, req, ret); | 1702 | req_pending = mmc_blk_rw_cmd_err(md, card, brq, old_req, req_pending); |
1669 | if (mmc_blk_reset(md, card->host, type)) | 1703 | if (mmc_blk_reset(md, card->host, type)) { |
1670 | goto cmd_abort; | 1704 | mmc_blk_rw_cmd_abort(card, old_req); |
1671 | if (!ret) | 1705 | mmc_blk_rw_try_restart(mq, new_req); |
1672 | goto start_new_req; | 1706 | return; |
1707 | } | ||
1708 | if (!req_pending) { | ||
1709 | mmc_blk_rw_try_restart(mq, new_req); | ||
1710 | return; | ||
1711 | } | ||
1673 | break; | 1712 | break; |
1674 | case MMC_BLK_RETRY: | 1713 | case MMC_BLK_RETRY: |
1675 | retune_retry_done = brq->retune_retry_done; | 1714 | retune_retry_done = brq->retune_retry_done; |
@@ -1679,22 +1718,27 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1679 | case MMC_BLK_ABORT: | 1718 | case MMC_BLK_ABORT: |
1680 | if (!mmc_blk_reset(md, card->host, type)) | 1719 | if (!mmc_blk_reset(md, card->host, type)) |
1681 | break; | 1720 | break; |
1682 | goto cmd_abort; | 1721 | mmc_blk_rw_cmd_abort(card, old_req); |
1722 | mmc_blk_rw_try_restart(mq, new_req); | ||
1723 | return; | ||
1683 | case MMC_BLK_DATA_ERR: { | 1724 | case MMC_BLK_DATA_ERR: { |
1684 | int err; | 1725 | int err; |
1685 | 1726 | ||
1686 | err = mmc_blk_reset(md, card->host, type); | 1727 | err = mmc_blk_reset(md, card->host, type); |
1687 | if (!err) | 1728 | if (!err) |
1688 | break; | 1729 | break; |
1689 | if (err == -ENODEV) | 1730 | if (err == -ENODEV) { |
1690 | goto cmd_abort; | 1731 | mmc_blk_rw_cmd_abort(card, old_req); |
1732 | mmc_blk_rw_try_restart(mq, new_req); | ||
1733 | return; | ||
1734 | } | ||
1691 | /* Fall through */ | 1735 | /* Fall through */ |
1692 | } | 1736 | } |
1693 | case MMC_BLK_ECC_ERR: | 1737 | case MMC_BLK_ECC_ERR: |
1694 | if (brq->data.blocks > 1) { | 1738 | if (brq->data.blocks > 1) { |
1695 | /* Redo read one sector at a time */ | 1739 | /* Redo read one sector at a time */ |
1696 | pr_warn("%s: retrying using single block read\n", | 1740 | pr_warn("%s: retrying using single block read\n", |
1697 | req->rq_disk->disk_name); | 1741 | old_req->rq_disk->disk_name); |
1698 | disable_multi = 1; | 1742 | disable_multi = 1; |
1699 | break; | 1743 | break; |
1700 | } | 1744 | } |
@@ -1703,57 +1747,40 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1703 | * time, so we only reach here after trying to | 1747 | * time, so we only reach here after trying to |
1704 | * read a single sector. | 1748 | * read a single sector. |
1705 | */ | 1749 | */ |
1706 | ret = blk_end_request(req, -EIO, | 1750 | req_pending = blk_end_request(old_req, -EIO, |
1707 | brq->data.blksz); | 1751 | brq->data.blksz); |
1708 | if (!ret) | 1752 | if (!req_pending) { |
1709 | goto start_new_req; | 1753 | mmc_blk_rw_try_restart(mq, new_req); |
1754 | return; | ||
1755 | } | ||
1710 | break; | 1756 | break; |
1711 | case MMC_BLK_NOMEDIUM: | 1757 | case MMC_BLK_NOMEDIUM: |
1712 | goto cmd_abort; | 1758 | mmc_blk_rw_cmd_abort(card, old_req); |
1759 | mmc_blk_rw_try_restart(mq, new_req); | ||
1760 | return; | ||
1713 | default: | 1761 | default: |
1714 | pr_err("%s: Unhandled return value (%d)", | 1762 | pr_err("%s: Unhandled return value (%d)", |
1715 | req->rq_disk->disk_name, status); | 1763 | old_req->rq_disk->disk_name, status); |
1716 | goto cmd_abort; | 1764 | mmc_blk_rw_cmd_abort(card, old_req); |
1765 | mmc_blk_rw_try_restart(mq, new_req); | ||
1766 | return; | ||
1717 | } | 1767 | } |
1718 | 1768 | ||
1719 | if (ret) { | 1769 | if (req_pending) { |
1720 | /* | 1770 | /* |
1721 | * In case of a incomplete request | 1771 | * In case of a incomplete request |
1722 | * prepare it again and resend. | 1772 | * prepare it again and resend. |
1723 | */ | 1773 | */ |
1724 | mmc_blk_rw_rq_prep(mq_rq, card, | 1774 | mmc_blk_rw_rq_prep(mq_rq, card, |
1725 | disable_multi, mq); | 1775 | disable_multi, mq); |
1726 | mmc_start_req(card->host, | 1776 | mmc_start_areq(card->host, |
1727 | &mq_rq->mmc_active, NULL); | 1777 | &mq_rq->areq, NULL); |
1728 | mq_rq->brq.retune_retry_done = retune_retry_done; | 1778 | mq_rq->brq.retune_retry_done = retune_retry_done; |
1729 | } | 1779 | } |
1730 | } while (ret); | 1780 | } while (req_pending); |
1731 | |||
1732 | return 1; | ||
1733 | |||
1734 | cmd_abort: | ||
1735 | if (mmc_card_removed(card)) | ||
1736 | req->rq_flags |= RQF_QUIET; | ||
1737 | while (ret) | ||
1738 | ret = blk_end_request(req, -EIO, | ||
1739 | blk_rq_cur_bytes(req)); | ||
1740 | |||
1741 | start_new_req: | ||
1742 | if (rqc) { | ||
1743 | if (mmc_card_removed(card)) { | ||
1744 | rqc->rq_flags |= RQF_QUIET; | ||
1745 | blk_end_request_all(rqc, -EIO); | ||
1746 | } else { | ||
1747 | mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); | ||
1748 | mmc_start_req(card->host, | ||
1749 | &mq->mqrq_cur->mmc_active, NULL); | ||
1750 | } | ||
1751 | } | ||
1752 | |||
1753 | return 0; | ||
1754 | } | 1781 | } |
1755 | 1782 | ||
1756 | int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | 1783 | void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) |
1757 | { | 1784 | { |
1758 | int ret; | 1785 | int ret; |
1759 | struct mmc_blk_data *md = mq->blkdata; | 1786 | struct mmc_blk_data *md = mq->blkdata; |
@@ -1769,32 +1796,31 @@ int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1769 | if (req) { | 1796 | if (req) { |
1770 | blk_end_request_all(req, -EIO); | 1797 | blk_end_request_all(req, -EIO); |
1771 | } | 1798 | } |
1772 | ret = 0; | ||
1773 | goto out; | 1799 | goto out; |
1774 | } | 1800 | } |
1775 | 1801 | ||
1776 | mq->flags &= ~MMC_QUEUE_NEW_REQUEST; | 1802 | mq->new_request = false; |
1777 | if (req && req_op(req) == REQ_OP_DISCARD) { | 1803 | if (req && req_op(req) == REQ_OP_DISCARD) { |
1778 | /* complete ongoing async transfer before issuing discard */ | 1804 | /* complete ongoing async transfer before issuing discard */ |
1779 | if (card->host->areq) | 1805 | if (card->host->areq) |
1780 | mmc_blk_issue_rw_rq(mq, NULL); | 1806 | mmc_blk_issue_rw_rq(mq, NULL); |
1781 | ret = mmc_blk_issue_discard_rq(mq, req); | 1807 | mmc_blk_issue_discard_rq(mq, req); |
1782 | } else if (req && req_op(req) == REQ_OP_SECURE_ERASE) { | 1808 | } else if (req && req_op(req) == REQ_OP_SECURE_ERASE) { |
1783 | /* complete ongoing async transfer before issuing secure erase*/ | 1809 | /* complete ongoing async transfer before issuing secure erase*/ |
1784 | if (card->host->areq) | 1810 | if (card->host->areq) |
1785 | mmc_blk_issue_rw_rq(mq, NULL); | 1811 | mmc_blk_issue_rw_rq(mq, NULL); |
1786 | ret = mmc_blk_issue_secdiscard_rq(mq, req); | 1812 | mmc_blk_issue_secdiscard_rq(mq, req); |
1787 | } else if (req && req_op(req) == REQ_OP_FLUSH) { | 1813 | } else if (req && req_op(req) == REQ_OP_FLUSH) { |
1788 | /* complete ongoing async transfer before issuing flush */ | 1814 | /* complete ongoing async transfer before issuing flush */ |
1789 | if (card->host->areq) | 1815 | if (card->host->areq) |
1790 | mmc_blk_issue_rw_rq(mq, NULL); | 1816 | mmc_blk_issue_rw_rq(mq, NULL); |
1791 | ret = mmc_blk_issue_flush(mq, req); | 1817 | mmc_blk_issue_flush(mq, req); |
1792 | } else { | 1818 | } else { |
1793 | ret = mmc_blk_issue_rw_rq(mq, req); | 1819 | mmc_blk_issue_rw_rq(mq, req); |
1794 | } | 1820 | } |
1795 | 1821 | ||
1796 | out: | 1822 | out: |
1797 | if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) || req_is_special) | 1823 | if ((!req && !mq->new_request) || req_is_special) |
1798 | /* | 1824 | /* |
1799 | * Release host when there are no more requests | 1825 | * Release host when there are no more requests |
1800 | * and after special request(discard, flush) is done. | 1826 | * and after special request(discard, flush) is done. |
@@ -1802,7 +1828,6 @@ out: | |||
1802 | * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'. | 1828 | * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'. |
1803 | */ | 1829 | */ |
1804 | mmc_put_card(card); | 1830 | mmc_put_card(card); |
1805 | return ret; | ||
1806 | } | 1831 | } |
1807 | 1832 | ||
1808 | static inline int mmc_blk_readonly(struct mmc_card *card) | 1833 | static inline int mmc_blk_readonly(struct mmc_card *card) |
@@ -1821,23 +1846,9 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
1821 | struct mmc_blk_data *md; | 1846 | struct mmc_blk_data *md; |
1822 | int devidx, ret; | 1847 | int devidx, ret; |
1823 | 1848 | ||
1824 | again: | 1849 | devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL); |
1825 | if (!ida_pre_get(&mmc_blk_ida, GFP_KERNEL)) | 1850 | if (devidx < 0) |
1826 | return ERR_PTR(-ENOMEM); | 1851 | return ERR_PTR(devidx); |
1827 | |||
1828 | spin_lock(&mmc_blk_lock); | ||
1829 | ret = ida_get_new(&mmc_blk_ida, &devidx); | ||
1830 | spin_unlock(&mmc_blk_lock); | ||
1831 | |||
1832 | if (ret == -EAGAIN) | ||
1833 | goto again; | ||
1834 | else if (ret) | ||
1835 | return ERR_PTR(ret); | ||
1836 | |||
1837 | if (devidx >= max_devices) { | ||
1838 | ret = -ENOSPC; | ||
1839 | goto out; | ||
1840 | } | ||
1841 | 1852 | ||
1842 | md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); | 1853 | md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); |
1843 | if (!md) { | 1854 | if (!md) { |
@@ -1926,9 +1937,7 @@ again: | |||
1926 | err_kfree: | 1937 | err_kfree: |
1927 | kfree(md); | 1938 | kfree(md); |
1928 | out: | 1939 | out: |
1929 | spin_lock(&mmc_blk_lock); | 1940 | ida_simple_remove(&mmc_blk_ida, devidx); |
1930 | ida_remove(&mmc_blk_ida, devidx); | ||
1931 | spin_unlock(&mmc_blk_lock); | ||
1932 | return ERR_PTR(ret); | 1941 | return ERR_PTR(ret); |
1933 | } | 1942 | } |
1934 | 1943 | ||
@@ -2093,80 +2102,6 @@ force_ro_fail: | |||
2093 | return ret; | 2102 | return ret; |
2094 | } | 2103 | } |
2095 | 2104 | ||
2096 | static const struct mmc_fixup blk_fixups[] = | ||
2097 | { | ||
2098 | MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
2099 | MMC_QUIRK_INAND_CMD38), | ||
2100 | MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
2101 | MMC_QUIRK_INAND_CMD38), | ||
2102 | MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
2103 | MMC_QUIRK_INAND_CMD38), | ||
2104 | MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
2105 | MMC_QUIRK_INAND_CMD38), | ||
2106 | MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
2107 | MMC_QUIRK_INAND_CMD38), | ||
2108 | |||
2109 | /* | ||
2110 | * Some MMC cards experience performance degradation with CMD23 | ||
2111 | * instead of CMD12-bounded multiblock transfers. For now we'll | ||
2112 | * black list what's bad... | ||
2113 | * - Certain Toshiba cards. | ||
2114 | * | ||
2115 | * N.B. This doesn't affect SD cards. | ||
2116 | */ | ||
2117 | MMC_FIXUP("SDMB-32", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, | ||
2118 | MMC_QUIRK_BLK_NO_CMD23), | ||
2119 | MMC_FIXUP("SDM032", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, | ||
2120 | MMC_QUIRK_BLK_NO_CMD23), | ||
2121 | MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
2122 | MMC_QUIRK_BLK_NO_CMD23), | ||
2123 | MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
2124 | MMC_QUIRK_BLK_NO_CMD23), | ||
2125 | MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
2126 | MMC_QUIRK_BLK_NO_CMD23), | ||
2127 | |||
2128 | /* | ||
2129 | * Some MMC cards need longer data read timeout than indicated in CSD. | ||
2130 | */ | ||
2131 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, | ||
2132 | MMC_QUIRK_LONG_READ_TIME), | ||
2133 | MMC_FIXUP("008GE0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
2134 | MMC_QUIRK_LONG_READ_TIME), | ||
2135 | |||
2136 | /* | ||
2137 | * On these Samsung MoviNAND parts, performing secure erase or | ||
2138 | * secure trim can result in unrecoverable corruption due to a | ||
2139 | * firmware bug. | ||
2140 | */ | ||
2141 | MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2142 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2143 | MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2144 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2145 | MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2146 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2147 | MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2148 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2149 | MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2150 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2151 | MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2152 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2153 | MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2154 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2155 | MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
2156 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
2157 | |||
2158 | /* | ||
2159 | * On Some Kingston eMMCs, performing trim can result in | ||
2160 | * unrecoverable data conrruption occasionally due to a firmware bug. | ||
2161 | */ | ||
2162 | MMC_FIXUP("V10008", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, | ||
2163 | MMC_QUIRK_TRIM_BROKEN), | ||
2164 | MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, | ||
2165 | MMC_QUIRK_TRIM_BROKEN), | ||
2166 | |||
2167 | END_FIXUP | ||
2168 | }; | ||
2169 | |||
2170 | static int mmc_blk_probe(struct mmc_card *card) | 2105 | static int mmc_blk_probe(struct mmc_card *card) |
2171 | { | 2106 | { |
2172 | struct mmc_blk_data *md, *part_md; | 2107 | struct mmc_blk_data *md, *part_md; |
@@ -2178,7 +2113,7 @@ static int mmc_blk_probe(struct mmc_card *card) | |||
2178 | if (!(card->csd.cmdclass & CCC_BLOCK_READ)) | 2113 | if (!(card->csd.cmdclass & CCC_BLOCK_READ)) |
2179 | return -ENODEV; | 2114 | return -ENODEV; |
2180 | 2115 | ||
2181 | mmc_fixup_device(card, blk_fixups); | 2116 | mmc_fixup_device(card, mmc_blk_fixups); |
2182 | 2117 | ||
2183 | md = mmc_blk_alloc(card); | 2118 | md = mmc_blk_alloc(card); |
2184 | if (IS_ERR(md)) | 2119 | if (IS_ERR(md)) |
diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h index cdabb2ee74be..860ca7c8df86 100644 --- a/drivers/mmc/core/block.h +++ b/drivers/mmc/core/block.h | |||
@@ -1 +1,9 @@ | |||
1 | int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req); | 1 | #ifndef _MMC_CORE_BLOCK_H |
2 | #define _MMC_CORE_BLOCK_H | ||
3 | |||
4 | struct mmc_queue; | ||
5 | struct request; | ||
6 | |||
7 | void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req); | ||
8 | |||
9 | #endif | ||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index c64266f5a399..301246513a37 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/mmc/host.h> | 23 | #include <linux/mmc/host.h> |
24 | 24 | ||
25 | #include "core.h" | 25 | #include "core.h" |
26 | #include "card.h" | ||
27 | #include "host.h" | ||
26 | #include "sdio_cis.h" | 28 | #include "sdio_cis.h" |
27 | #include "bus.h" | 29 | #include "bus.h" |
28 | 30 | ||
diff --git a/drivers/mmc/core/bus.h b/drivers/mmc/core/bus.h index 00a19710b6b4..72b0ef03f10a 100644 --- a/drivers/mmc/core/bus.h +++ b/drivers/mmc/core/bus.h | |||
@@ -11,6 +11,11 @@ | |||
11 | #ifndef _MMC_CORE_BUS_H | 11 | #ifndef _MMC_CORE_BUS_H |
12 | #define _MMC_CORE_BUS_H | 12 | #define _MMC_CORE_BUS_H |
13 | 13 | ||
14 | #include <linux/device.h> | ||
15 | |||
16 | struct mmc_host; | ||
17 | struct mmc_card; | ||
18 | |||
14 | #define MMC_DEV_ATTR(name, fmt, args...) \ | 19 | #define MMC_DEV_ATTR(name, fmt, args...) \ |
15 | static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ | 20 | static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ |
16 | { \ | 21 | { \ |
@@ -27,5 +32,14 @@ void mmc_remove_card(struct mmc_card *card); | |||
27 | int mmc_register_bus(void); | 32 | int mmc_register_bus(void); |
28 | void mmc_unregister_bus(void); | 33 | void mmc_unregister_bus(void); |
29 | 34 | ||
30 | #endif | 35 | struct mmc_driver { |
36 | struct device_driver drv; | ||
37 | int (*probe)(struct mmc_card *card); | ||
38 | void (*remove)(struct mmc_card *card); | ||
39 | void (*shutdown)(struct mmc_card *card); | ||
40 | }; | ||
31 | 41 | ||
42 | int mmc_register_driver(struct mmc_driver *drv); | ||
43 | void mmc_unregister_driver(struct mmc_driver *drv); | ||
44 | |||
45 | #endif | ||
diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h new file mode 100644 index 000000000000..f06cd91964ce --- /dev/null +++ b/drivers/mmc/core/card.h | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * Private header for the mmc subsystem | ||
3 | * | ||
4 | * Copyright (C) 2016 Linaro Ltd | ||
5 | * | ||
6 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
7 | * | ||
8 | * License terms: GNU General Public License (GPL) version 2 | ||
9 | */ | ||
10 | |||
11 | #ifndef _MMC_CORE_CARD_H | ||
12 | #define _MMC_CORE_CARD_H | ||
13 | |||
14 | #include <linux/mmc/card.h> | ||
15 | |||
16 | #define mmc_card_name(c) ((c)->cid.prod_name) | ||
17 | #define mmc_card_id(c) (dev_name(&(c)->dev)) | ||
18 | #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev) | ||
19 | |||
20 | /* Card states */ | ||
21 | #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ | ||
22 | #define MMC_STATE_READONLY (1<<1) /* card is read-only */ | ||
23 | #define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */ | ||
24 | #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ | ||
25 | #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ | ||
26 | #define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ | ||
27 | #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ | ||
28 | |||
29 | #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) | ||
30 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) | ||
31 | #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) | ||
32 | #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) | ||
33 | #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) | ||
34 | #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) | ||
35 | #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) | ||
36 | |||
37 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) | ||
38 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) | ||
39 | #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) | ||
40 | #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) | ||
41 | #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) | ||
42 | #define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS) | ||
43 | #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) | ||
44 | #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) | ||
45 | #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) | ||
46 | |||
47 | /* | ||
48 | * The world is not perfect and supplies us with broken mmc/sdio devices. | ||
49 | * For at least some of these bugs we need a work-around. | ||
50 | */ | ||
51 | struct mmc_fixup { | ||
52 | /* CID-specific fields. */ | ||
53 | const char *name; | ||
54 | |||
55 | /* Valid revision range */ | ||
56 | u64 rev_start, rev_end; | ||
57 | |||
58 | unsigned int manfid; | ||
59 | unsigned short oemid; | ||
60 | |||
61 | /* SDIO-specific fields. You can use SDIO_ANY_ID here of course */ | ||
62 | u16 cis_vendor, cis_device; | ||
63 | |||
64 | /* for MMC cards */ | ||
65 | unsigned int ext_csd_rev; | ||
66 | |||
67 | void (*vendor_fixup)(struct mmc_card *card, int data); | ||
68 | int data; | ||
69 | }; | ||
70 | |||
71 | #define CID_MANFID_ANY (-1u) | ||
72 | #define CID_OEMID_ANY ((unsigned short) -1) | ||
73 | #define CID_NAME_ANY (NULL) | ||
74 | |||
75 | #define EXT_CSD_REV_ANY (-1u) | ||
76 | |||
77 | #define CID_MANFID_SANDISK 0x2 | ||
78 | #define CID_MANFID_TOSHIBA 0x11 | ||
79 | #define CID_MANFID_MICRON 0x13 | ||
80 | #define CID_MANFID_SAMSUNG 0x15 | ||
81 | #define CID_MANFID_KINGSTON 0x70 | ||
82 | #define CID_MANFID_HYNIX 0x90 | ||
83 | |||
84 | #define END_FIXUP { NULL } | ||
85 | |||
86 | #define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ | ||
87 | _cis_vendor, _cis_device, \ | ||
88 | _fixup, _data, _ext_csd_rev) \ | ||
89 | { \ | ||
90 | .name = (_name), \ | ||
91 | .manfid = (_manfid), \ | ||
92 | .oemid = (_oemid), \ | ||
93 | .rev_start = (_rev_start), \ | ||
94 | .rev_end = (_rev_end), \ | ||
95 | .cis_vendor = (_cis_vendor), \ | ||
96 | .cis_device = (_cis_device), \ | ||
97 | .vendor_fixup = (_fixup), \ | ||
98 | .data = (_data), \ | ||
99 | .ext_csd_rev = (_ext_csd_rev), \ | ||
100 | } | ||
101 | |||
102 | #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ | ||
103 | _fixup, _data, _ext_csd_rev) \ | ||
104 | _FIXUP_EXT(_name, _manfid, \ | ||
105 | _oemid, _rev_start, _rev_end, \ | ||
106 | SDIO_ANY_ID, SDIO_ANY_ID, \ | ||
107 | _fixup, _data, _ext_csd_rev) \ | ||
108 | |||
109 | #define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \ | ||
110 | MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ | ||
111 | EXT_CSD_REV_ANY) | ||
112 | |||
113 | #define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \ | ||
114 | _ext_csd_rev) \ | ||
115 | MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ | ||
116 | _ext_csd_rev) | ||
117 | |||
118 | #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ | ||
119 | _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ | ||
120 | CID_OEMID_ANY, 0, -1ull, \ | ||
121 | _vendor, _device, \ | ||
122 | _fixup, _data, EXT_CSD_REV_ANY) \ | ||
123 | |||
124 | #define cid_rev(hwrev, fwrev, year, month) \ | ||
125 | (((u64) hwrev) << 40 | \ | ||
126 | ((u64) fwrev) << 32 | \ | ||
127 | ((u64) year) << 16 | \ | ||
128 | ((u64) month)) | ||
129 | |||
130 | #define cid_rev_card(card) \ | ||
131 | cid_rev(card->cid.hwrev, \ | ||
132 | card->cid.fwrev, \ | ||
133 | card->cid.year, \ | ||
134 | card->cid.month) | ||
135 | |||
136 | /* | ||
137 | * Unconditionally quirk add/remove. | ||
138 | */ | ||
139 | static inline void __maybe_unused add_quirk(struct mmc_card *card, int data) | ||
140 | { | ||
141 | card->quirks |= data; | ||
142 | } | ||
143 | |||
144 | static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) | ||
145 | { | ||
146 | card->quirks &= ~data; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Quirk add/remove for MMC products. | ||
151 | */ | ||
152 | static inline void __maybe_unused add_quirk_mmc(struct mmc_card *card, int data) | ||
153 | { | ||
154 | if (mmc_card_mmc(card)) | ||
155 | card->quirks |= data; | ||
156 | } | ||
157 | |||
158 | static inline void __maybe_unused remove_quirk_mmc(struct mmc_card *card, | ||
159 | int data) | ||
160 | { | ||
161 | if (mmc_card_mmc(card)) | ||
162 | card->quirks &= ~data; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Quirk add/remove for SD products. | ||
167 | */ | ||
168 | static inline void __maybe_unused add_quirk_sd(struct mmc_card *card, int data) | ||
169 | { | ||
170 | if (mmc_card_sd(card)) | ||
171 | card->quirks |= data; | ||
172 | } | ||
173 | |||
174 | static inline void __maybe_unused remove_quirk_sd(struct mmc_card *card, | ||
175 | int data) | ||
176 | { | ||
177 | if (mmc_card_sd(card)) | ||
178 | card->quirks &= ~data; | ||
179 | } | ||
180 | |||
181 | static inline int mmc_card_lenient_fn0(const struct mmc_card *c) | ||
182 | { | ||
183 | return c->quirks & MMC_QUIRK_LENIENT_FN0; | ||
184 | } | ||
185 | |||
186 | static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c) | ||
187 | { | ||
188 | return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; | ||
189 | } | ||
190 | |||
191 | static inline int mmc_card_disable_cd(const struct mmc_card *c) | ||
192 | { | ||
193 | return c->quirks & MMC_QUIRK_DISABLE_CD; | ||
194 | } | ||
195 | |||
196 | static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c) | ||
197 | { | ||
198 | return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF; | ||
199 | } | ||
200 | |||
201 | static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c) | ||
202 | { | ||
203 | return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512; | ||
204 | } | ||
205 | |||
206 | static inline int mmc_card_long_read_time(const struct mmc_card *c) | ||
207 | { | ||
208 | return c->quirks & MMC_QUIRK_LONG_READ_TIME; | ||
209 | } | ||
210 | |||
211 | static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) | ||
212 | { | ||
213 | return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING; | ||
214 | } | ||
215 | |||
216 | static inline int mmc_card_broken_hpi(const struct mmc_card *c) | ||
217 | { | ||
218 | return c->quirks & MMC_QUIRK_BROKEN_HPI; | ||
219 | } | ||
220 | |||
221 | #endif | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 1076b9d89df3..926e0fde07d7 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <trace/events/mmc.h> | 40 | #include <trace/events/mmc.h> |
41 | 41 | ||
42 | #include "core.h" | 42 | #include "core.h" |
43 | #include "card.h" | ||
43 | #include "bus.h" | 44 | #include "bus.h" |
44 | #include "host.h" | 45 | #include "host.h" |
45 | #include "sdio_bus.h" | 46 | #include "sdio_bus.h" |
@@ -630,10 +631,41 @@ static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, | |||
630 | } | 631 | } |
631 | 632 | ||
632 | /** | 633 | /** |
633 | * mmc_start_req - start a non-blocking request | 634 | * mmc_finalize_areq() - finalize an asynchronous request |
635 | * @host: MMC host to finalize any ongoing request on | ||
636 | * | ||
637 | * Returns the status of the ongoing asynchronous request, but | ||
638 | * MMC_BLK_SUCCESS if no request was going on. | ||
639 | */ | ||
640 | static enum mmc_blk_status mmc_finalize_areq(struct mmc_host *host) | ||
641 | { | ||
642 | enum mmc_blk_status status; | ||
643 | |||
644 | if (!host->areq) | ||
645 | return MMC_BLK_SUCCESS; | ||
646 | |||
647 | status = mmc_wait_for_data_req_done(host, host->areq->mrq); | ||
648 | if (status == MMC_BLK_NEW_REQUEST) | ||
649 | return status; | ||
650 | |||
651 | /* | ||
652 | * Check BKOPS urgency for each R1 response | ||
653 | */ | ||
654 | if (host->card && mmc_card_mmc(host->card) && | ||
655 | ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) || | ||
656 | (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) && | ||
657 | (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT)) { | ||
658 | mmc_start_bkops(host->card, true); | ||
659 | } | ||
660 | |||
661 | return status; | ||
662 | } | ||
663 | |||
664 | /** | ||
665 | * mmc_start_areq - start an asynchronous request | ||
634 | * @host: MMC host to start command | 666 | * @host: MMC host to start command |
635 | * @areq: async request to start | 667 | * @areq: asynchronous request to start |
636 | * @error: out parameter returns 0 for success, otherwise non zero | 668 | * @ret_stat: out parameter for status |
637 | * | 669 | * |
638 | * Start a new MMC custom command request for a host. | 670 | * Start a new MMC custom command request for a host. |
639 | * If there is on ongoing async request wait for completion | 671 | * If there is on ongoing async request wait for completion |
@@ -645,11 +677,11 @@ static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, | |||
645 | * return the completed request. If there is no ongoing request, NULL | 677 | * return the completed request. If there is no ongoing request, NULL |
646 | * is returned without waiting. NULL is not an error condition. | 678 | * is returned without waiting. NULL is not an error condition. |
647 | */ | 679 | */ |
648 | struct mmc_async_req *mmc_start_req(struct mmc_host *host, | 680 | struct mmc_async_req *mmc_start_areq(struct mmc_host *host, |
649 | struct mmc_async_req *areq, | 681 | struct mmc_async_req *areq, |
650 | enum mmc_blk_status *ret_stat) | 682 | enum mmc_blk_status *ret_stat) |
651 | { | 683 | { |
652 | enum mmc_blk_status status = MMC_BLK_SUCCESS; | 684 | enum mmc_blk_status status; |
653 | int start_err = 0; | 685 | int start_err = 0; |
654 | struct mmc_async_req *data = host->areq; | 686 | struct mmc_async_req *data = host->areq; |
655 | 687 | ||
@@ -657,44 +689,25 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, | |||
657 | if (areq) | 689 | if (areq) |
658 | mmc_pre_req(host, areq->mrq); | 690 | mmc_pre_req(host, areq->mrq); |
659 | 691 | ||
660 | if (host->areq) { | 692 | /* Finalize previous request */ |
661 | status = mmc_wait_for_data_req_done(host, host->areq->mrq); | 693 | status = mmc_finalize_areq(host); |
662 | if (status == MMC_BLK_NEW_REQUEST) { | ||
663 | if (ret_stat) | ||
664 | *ret_stat = status; | ||
665 | /* | ||
666 | * The previous request was not completed, | ||
667 | * nothing to return | ||
668 | */ | ||
669 | return NULL; | ||
670 | } | ||
671 | /* | ||
672 | * Check BKOPS urgency for each R1 response | ||
673 | */ | ||
674 | if (host->card && mmc_card_mmc(host->card) && | ||
675 | ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) || | ||
676 | (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) && | ||
677 | (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT)) { | ||
678 | |||
679 | /* Cancel the prepared request */ | ||
680 | if (areq) | ||
681 | mmc_post_req(host, areq->mrq, -EINVAL); | ||
682 | |||
683 | mmc_start_bkops(host->card, true); | ||
684 | 694 | ||
685 | /* prepare the request again */ | 695 | /* The previous request is still going on... */ |
686 | if (areq) | 696 | if (status == MMC_BLK_NEW_REQUEST) { |
687 | mmc_pre_req(host, areq->mrq); | 697 | if (ret_stat) |
688 | } | 698 | *ret_stat = status; |
699 | return NULL; | ||
689 | } | 700 | } |
690 | 701 | ||
702 | /* Fine so far, start the new request! */ | ||
691 | if (status == MMC_BLK_SUCCESS && areq) | 703 | if (status == MMC_BLK_SUCCESS && areq) |
692 | start_err = __mmc_start_data_req(host, areq->mrq); | 704 | start_err = __mmc_start_data_req(host, areq->mrq); |
693 | 705 | ||
706 | /* Postprocess the old request at this point */ | ||
694 | if (host->areq) | 707 | if (host->areq) |
695 | mmc_post_req(host, host->areq->mrq, 0); | 708 | mmc_post_req(host, host->areq->mrq, 0); |
696 | 709 | ||
697 | /* Cancel a prepared request if it was not started. */ | 710 | /* Cancel a prepared request if it was not started. */ |
698 | if ((status != MMC_BLK_SUCCESS || start_err) && areq) | 711 | if ((status != MMC_BLK_SUCCESS || start_err) && areq) |
699 | mmc_post_req(host, areq->mrq, -EINVAL); | 712 | mmc_post_req(host, areq->mrq, -EINVAL); |
700 | 713 | ||
@@ -707,7 +720,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, | |||
707 | *ret_stat = status; | 720 | *ret_stat = status; |
708 | return data; | 721 | return data; |
709 | } | 722 | } |
710 | EXPORT_SYMBOL(mmc_start_req); | 723 | EXPORT_SYMBOL(mmc_start_areq); |
711 | 724 | ||
712 | /** | 725 | /** |
713 | * mmc_wait_for_req - start a request and wait for completion | 726 | * mmc_wait_for_req - start a request and wait for completion |
@@ -807,7 +820,7 @@ EXPORT_SYMBOL(mmc_interrupt_hpi); | |||
807 | */ | 820 | */ |
808 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) | 821 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) |
809 | { | 822 | { |
810 | struct mmc_request mrq = {NULL}; | 823 | struct mmc_request mrq = {}; |
811 | 824 | ||
812 | WARN_ON(!host->claimed); | 825 | WARN_ON(!host->claimed); |
813 | 826 | ||
@@ -1630,7 +1643,7 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | |||
1630 | return ocr; | 1643 | return ocr; |
1631 | } | 1644 | } |
1632 | 1645 | ||
1633 | int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) | 1646 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) |
1634 | { | 1647 | { |
1635 | int err = 0; | 1648 | int err = 0; |
1636 | int old_signal_voltage = host->ios.signal_voltage; | 1649 | int old_signal_voltage = host->ios.signal_voltage; |
@@ -1646,20 +1659,13 @@ int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage) | |||
1646 | 1659 | ||
1647 | } | 1660 | } |
1648 | 1661 | ||
1649 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr) | 1662 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr) |
1650 | { | 1663 | { |
1651 | struct mmc_command cmd = {0}; | 1664 | struct mmc_command cmd = {}; |
1652 | int err = 0; | 1665 | int err = 0; |
1653 | u32 clock; | 1666 | u32 clock; |
1654 | 1667 | ||
1655 | /* | 1668 | /* |
1656 | * Send CMD11 only if the request is to switch the card to | ||
1657 | * 1.8V signalling. | ||
1658 | */ | ||
1659 | if (signal_voltage == MMC_SIGNAL_VOLTAGE_330) | ||
1660 | return __mmc_set_signal_voltage(host, signal_voltage); | ||
1661 | |||
1662 | /* | ||
1663 | * If we cannot switch voltages, return failure so the caller | 1669 | * If we cannot switch voltages, return failure so the caller |
1664 | * can continue without UHS mode | 1670 | * can continue without UHS mode |
1665 | */ | 1671 | */ |
@@ -1697,7 +1703,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr) | |||
1697 | host->ios.clock = 0; | 1703 | host->ios.clock = 0; |
1698 | mmc_set_ios(host); | 1704 | mmc_set_ios(host); |
1699 | 1705 | ||
1700 | if (__mmc_set_signal_voltage(host, signal_voltage)) { | 1706 | if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) { |
1701 | /* | 1707 | /* |
1702 | * Voltages may not have been switched, but we've already | 1708 | * Voltages may not have been switched, but we've already |
1703 | * sent CMD11, so a power cycle is required anyway | 1709 | * sent CMD11, so a power cycle is required anyway |
@@ -1806,11 +1812,11 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
1806 | mmc_set_initial_state(host); | 1812 | mmc_set_initial_state(host); |
1807 | 1813 | ||
1808 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ | 1814 | /* Try to set signal voltage to 3.3V but fall back to 1.8v or 1.2v */ |
1809 | if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330) == 0) | 1815 | if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330)) |
1810 | dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); | 1816 | dev_dbg(mmc_dev(host), "Initial signal voltage of 3.3v\n"); |
1811 | else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180) == 0) | 1817 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180)) |
1812 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); | 1818 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.8v\n"); |
1813 | else if (__mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120) == 0) | 1819 | else if (!mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120)) |
1814 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); | 1820 | dev_dbg(mmc_dev(host), "Initial signal voltage of 1.2v\n"); |
1815 | 1821 | ||
1816 | /* | 1822 | /* |
@@ -2129,7 +2135,7 @@ static unsigned int mmc_erase_timeout(struct mmc_card *card, | |||
2129 | static int mmc_do_erase(struct mmc_card *card, unsigned int from, | 2135 | static int mmc_do_erase(struct mmc_card *card, unsigned int from, |
2130 | unsigned int to, unsigned int arg) | 2136 | unsigned int to, unsigned int arg) |
2131 | { | 2137 | { |
2132 | struct mmc_command cmd = {0}; | 2138 | struct mmc_command cmd = {}; |
2133 | unsigned int qty = 0, busy_timeout = 0; | 2139 | unsigned int qty = 0, busy_timeout = 0; |
2134 | bool use_r1b_resp = false; | 2140 | bool use_r1b_resp = false; |
2135 | unsigned long timeout; | 2141 | unsigned long timeout; |
@@ -2551,7 +2557,7 @@ EXPORT_SYMBOL(mmc_calc_max_discard); | |||
2551 | 2557 | ||
2552 | int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen) | 2558 | int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen) |
2553 | { | 2559 | { |
2554 | struct mmc_command cmd = {0}; | 2560 | struct mmc_command cmd = {}; |
2555 | 2561 | ||
2556 | if (mmc_card_blockaddr(card) || mmc_card_ddr52(card) || | 2562 | if (mmc_card_blockaddr(card) || mmc_card_ddr52(card) || |
2557 | mmc_card_hs400(card) || mmc_card_hs400es(card)) | 2563 | mmc_card_hs400(card) || mmc_card_hs400es(card)) |
@@ -2567,7 +2573,7 @@ EXPORT_SYMBOL(mmc_set_blocklen); | |||
2567 | int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, | 2573 | int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, |
2568 | bool is_rel_write) | 2574 | bool is_rel_write) |
2569 | { | 2575 | { |
2570 | struct mmc_command cmd = {0}; | 2576 | struct mmc_command cmd = {}; |
2571 | 2577 | ||
2572 | cmd.opcode = MMC_SET_BLOCK_COUNT; | 2578 | cmd.opcode = MMC_SET_BLOCK_COUNT; |
2573 | cmd.arg = blockcount & 0x0000FFFF; | 2579 | cmd.arg = blockcount & 0x0000FFFF; |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 0fa86a2afc26..55f543fd37c4 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -12,6 +12,11 @@ | |||
12 | #define _MMC_CORE_CORE_H | 12 | #define _MMC_CORE_CORE_H |
13 | 13 | ||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/sched.h> | ||
16 | |||
17 | struct mmc_host; | ||
18 | struct mmc_card; | ||
19 | struct mmc_request; | ||
15 | 20 | ||
16 | #define MMC_CMD_RETRIES 3 | 21 | #define MMC_CMD_RETRIES 3 |
17 | 22 | ||
@@ -43,8 +48,8 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz); | |||
43 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); | 48 | void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); |
44 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width); | 49 | void mmc_set_bus_width(struct mmc_host *host, unsigned int width); |
45 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); | 50 | u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); |
46 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr); | 51 | int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr); |
47 | int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); | 52 | int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); |
48 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | 53 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); |
49 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); | 54 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); |
50 | int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr, | 55 | int mmc_select_drive_strength(struct mmc_card *card, unsigned int max_dtr, |
@@ -69,6 +74,7 @@ void mmc_start_host(struct mmc_host *host); | |||
69 | void mmc_stop_host(struct mmc_host *host); | 74 | void mmc_stop_host(struct mmc_host *host); |
70 | 75 | ||
71 | int _mmc_detect_card_removed(struct mmc_host *host); | 76 | int _mmc_detect_card_removed(struct mmc_host *host); |
77 | int mmc_detect_card_removed(struct mmc_host *host); | ||
72 | 78 | ||
73 | int mmc_attach_mmc(struct mmc_host *host); | 79 | int mmc_attach_mmc(struct mmc_host *host); |
74 | int mmc_attach_sd(struct mmc_host *host); | 80 | int mmc_attach_sd(struct mmc_host *host); |
@@ -98,5 +104,38 @@ static inline void mmc_register_pm_notifier(struct mmc_host *host) { } | |||
98 | static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { } | 104 | static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { } |
99 | #endif | 105 | #endif |
100 | 106 | ||
101 | #endif | 107 | void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq); |
108 | bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq); | ||
109 | |||
110 | int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, | ||
111 | unsigned int arg); | ||
112 | int mmc_can_erase(struct mmc_card *card); | ||
113 | int mmc_can_trim(struct mmc_card *card); | ||
114 | int mmc_can_discard(struct mmc_card *card); | ||
115 | int mmc_can_sanitize(struct mmc_card *card); | ||
116 | int mmc_can_secure_erase_trim(struct mmc_card *card); | ||
117 | int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, | ||
118 | unsigned int nr); | ||
119 | unsigned int mmc_calc_max_discard(struct mmc_card *card); | ||
120 | |||
121 | int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); | ||
122 | int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, | ||
123 | bool is_rel_write); | ||
124 | |||
125 | int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); | ||
126 | void mmc_release_host(struct mmc_host *host); | ||
127 | void mmc_get_card(struct mmc_card *card); | ||
128 | void mmc_put_card(struct mmc_card *card); | ||
129 | |||
130 | /** | ||
131 | * mmc_claim_host - exclusively claim a host | ||
132 | * @host: mmc host to claim | ||
133 | * | ||
134 | * Claim a host for a set of operations. | ||
135 | */ | ||
136 | static inline void mmc_claim_host(struct mmc_host *host) | ||
137 | { | ||
138 | __mmc_claim_host(host, NULL); | ||
139 | } | ||
102 | 140 | ||
141 | #endif | ||
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 30623b8b86a4..a1fba5732d66 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/mmc/host.h> | 20 | #include <linux/mmc/host.h> |
21 | 21 | ||
22 | #include "core.h" | 22 | #include "core.h" |
23 | #include "card.h" | ||
24 | #include "host.h" | ||
23 | #include "mmc_ops.h" | 25 | #include "mmc_ops.h" |
24 | 26 | ||
25 | #ifdef CONFIG_FAIL_MMC_REQUEST | 27 | #ifdef CONFIG_FAIL_MMC_REQUEST |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 98f25ffb4258..3f8c85d5aa09 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -34,14 +34,11 @@ | |||
34 | #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) | 34 | #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) |
35 | 35 | ||
36 | static DEFINE_IDA(mmc_host_ida); | 36 | static DEFINE_IDA(mmc_host_ida); |
37 | static DEFINE_SPINLOCK(mmc_host_lock); | ||
38 | 37 | ||
39 | static void mmc_host_classdev_release(struct device *dev) | 38 | static void mmc_host_classdev_release(struct device *dev) |
40 | { | 39 | { |
41 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | 40 | struct mmc_host *host = cls_dev_to_mmc_host(dev); |
42 | spin_lock(&mmc_host_lock); | 41 | ida_simple_remove(&mmc_host_ida, host->index); |
43 | ida_remove(&mmc_host_ida, host->index); | ||
44 | spin_unlock(&mmc_host_lock); | ||
45 | kfree(host); | 42 | kfree(host); |
46 | } | 43 | } |
47 | 44 | ||
@@ -301,6 +298,8 @@ int mmc_of_parse(struct mmc_host *host) | |||
301 | if (of_property_read_bool(np, "wakeup-source") || | 298 | if (of_property_read_bool(np, "wakeup-source") || |
302 | of_property_read_bool(np, "enable-sdio-wakeup")) /* legacy */ | 299 | of_property_read_bool(np, "enable-sdio-wakeup")) /* legacy */ |
303 | host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; | 300 | host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; |
301 | if (of_property_read_bool(np, "mmc-ddr-3_3v")) | ||
302 | host->caps |= MMC_CAP_3_3V_DDR; | ||
304 | if (of_property_read_bool(np, "mmc-ddr-1_8v")) | 303 | if (of_property_read_bool(np, "mmc-ddr-1_8v")) |
305 | host->caps |= MMC_CAP_1_8V_DDR; | 304 | host->caps |= MMC_CAP_1_8V_DDR; |
306 | if (of_property_read_bool(np, "mmc-ddr-1_2v")) | 305 | if (of_property_read_bool(np, "mmc-ddr-1_2v")) |
@@ -354,22 +353,13 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
354 | /* scanning will be enabled when we're ready */ | 353 | /* scanning will be enabled when we're ready */ |
355 | host->rescan_disable = 1; | 354 | host->rescan_disable = 1; |
356 | 355 | ||
357 | again: | 356 | err = ida_simple_get(&mmc_host_ida, 0, 0, GFP_KERNEL); |
358 | if (!ida_pre_get(&mmc_host_ida, GFP_KERNEL)) { | 357 | if (err < 0) { |
359 | kfree(host); | 358 | kfree(host); |
360 | return NULL; | 359 | return NULL; |
361 | } | 360 | } |
362 | 361 | ||
363 | spin_lock(&mmc_host_lock); | 362 | host->index = err; |
364 | err = ida_get_new(&mmc_host_ida, &host->index); | ||
365 | spin_unlock(&mmc_host_lock); | ||
366 | |||
367 | if (err == -EAGAIN) { | ||
368 | goto again; | ||
369 | } else if (err) { | ||
370 | kfree(host); | ||
371 | return NULL; | ||
372 | } | ||
373 | 363 | ||
374 | dev_set_name(&host->class_dev, "mmc%d", host->index); | 364 | dev_set_name(&host->class_dev, "mmc%d", host->index); |
375 | 365 | ||
@@ -381,6 +371,8 @@ again: | |||
381 | 371 | ||
382 | if (mmc_gpio_alloc(host)) { | 372 | if (mmc_gpio_alloc(host)) { |
383 | put_device(&host->class_dev); | 373 | put_device(&host->class_dev); |
374 | ida_simple_remove(&mmc_host_ida, host->index); | ||
375 | kfree(host); | ||
384 | return NULL; | 376 | return NULL; |
385 | } | 377 | } |
386 | 378 | ||
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 992bf5397633..fb6a76a03833 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | #ifndef _MMC_CORE_HOST_H | 11 | #ifndef _MMC_CORE_HOST_H |
12 | #define _MMC_CORE_HOST_H | 12 | #define _MMC_CORE_HOST_H |
13 | |||
13 | #include <linux/mmc/host.h> | 14 | #include <linux/mmc/host.h> |
14 | 15 | ||
15 | int mmc_register_host_class(void); | 16 | int mmc_register_host_class(void); |
@@ -20,6 +21,53 @@ void mmc_retune_disable(struct mmc_host *host); | |||
20 | void mmc_retune_hold(struct mmc_host *host); | 21 | void mmc_retune_hold(struct mmc_host *host); |
21 | void mmc_retune_release(struct mmc_host *host); | 22 | void mmc_retune_release(struct mmc_host *host); |
22 | int mmc_retune(struct mmc_host *host); | 23 | int mmc_retune(struct mmc_host *host); |
24 | void mmc_retune_pause(struct mmc_host *host); | ||
25 | void mmc_retune_unpause(struct mmc_host *host); | ||
26 | |||
27 | static inline void mmc_retune_recheck(struct mmc_host *host) | ||
28 | { | ||
29 | if (host->hold_retune <= 1) | ||
30 | host->retune_now = 1; | ||
31 | } | ||
32 | |||
33 | static inline int mmc_host_cmd23(struct mmc_host *host) | ||
34 | { | ||
35 | return host->caps & MMC_CAP_CMD23; | ||
36 | } | ||
37 | |||
38 | static inline int mmc_boot_partition_access(struct mmc_host *host) | ||
39 | { | ||
40 | return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); | ||
41 | } | ||
42 | |||
43 | static inline int mmc_host_uhs(struct mmc_host *host) | ||
44 | { | ||
45 | return host->caps & | ||
46 | (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
47 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | | ||
48 | MMC_CAP_UHS_DDR50); | ||
49 | } | ||
50 | |||
51 | static inline bool mmc_card_hs200(struct mmc_card *card) | ||
52 | { | ||
53 | return card->host->ios.timing == MMC_TIMING_MMC_HS200; | ||
54 | } | ||
55 | |||
56 | static inline bool mmc_card_ddr52(struct mmc_card *card) | ||
57 | { | ||
58 | return card->host->ios.timing == MMC_TIMING_MMC_DDR52; | ||
59 | } | ||
60 | |||
61 | static inline bool mmc_card_hs400(struct mmc_card *card) | ||
62 | { | ||
63 | return card->host->ios.timing == MMC_TIMING_MMC_HS400; | ||
64 | } | ||
65 | |||
66 | static inline bool mmc_card_hs400es(struct mmc_card *card) | ||
67 | { | ||
68 | return card->host->ios.enhanced_strobe; | ||
69 | } | ||
70 | |||
23 | 71 | ||
24 | #endif | 72 | #endif |
25 | 73 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 0fccca075e29..7fd722868875 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -21,9 +21,11 @@ | |||
21 | #include <linux/mmc/mmc.h> | 21 | #include <linux/mmc/mmc.h> |
22 | 22 | ||
23 | #include "core.h" | 23 | #include "core.h" |
24 | #include "card.h" | ||
24 | #include "host.h" | 25 | #include "host.h" |
25 | #include "bus.h" | 26 | #include "bus.h" |
26 | #include "mmc_ops.h" | 27 | #include "mmc_ops.h" |
28 | #include "quirks.h" | ||
27 | #include "sd_ops.h" | 29 | #include "sd_ops.h" |
28 | 30 | ||
29 | #define DEFAULT_CMD6_TIMEOUT_MS 500 | 31 | #define DEFAULT_CMD6_TIMEOUT_MS 500 |
@@ -47,17 +49,6 @@ static const unsigned int tacc_mant[] = { | |||
47 | 35, 40, 45, 50, 55, 60, 70, 80, | 49 | 35, 40, 45, 50, 55, 60, 70, 80, |
48 | }; | 50 | }; |
49 | 51 | ||
50 | static const struct mmc_fixup mmc_ext_csd_fixups[] = { | ||
51 | /* | ||
52 | * Certain Hynix eMMC 4.41 cards might get broken when HPI feature | ||
53 | * is used so disable the HPI feature for such buggy cards. | ||
54 | */ | ||
55 | MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX, | ||
56 | 0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5), | ||
57 | |||
58 | END_FIXUP | ||
59 | }; | ||
60 | |||
61 | #define UNSTUFF_BITS(resp,start,size) \ | 52 | #define UNSTUFF_BITS(resp,start,size) \ |
62 | ({ \ | 53 | ({ \ |
63 | const int __size = size; \ | 54 | const int __size = size; \ |
@@ -212,7 +203,7 @@ static void mmc_select_card_type(struct mmc_card *card) | |||
212 | avail_type |= EXT_CSD_CARD_TYPE_HS_52; | 203 | avail_type |= EXT_CSD_CARD_TYPE_HS_52; |
213 | } | 204 | } |
214 | 205 | ||
215 | if (caps & MMC_CAP_1_8V_DDR && | 206 | if (caps & (MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR) && |
216 | card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) { | 207 | card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) { |
217 | hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; | 208 | hs_max_dtr = MMC_HIGH_DDR_MAX_DTR; |
218 | avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V; | 209 | avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V; |
@@ -307,6 +298,18 @@ static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) | |||
307 | } | 298 | } |
308 | } | 299 | } |
309 | 300 | ||
301 | static void mmc_part_add(struct mmc_card *card, unsigned int size, | ||
302 | unsigned int part_cfg, char *name, int idx, bool ro, | ||
303 | int area_type) | ||
304 | { | ||
305 | card->part[card->nr_parts].size = size; | ||
306 | card->part[card->nr_parts].part_cfg = part_cfg; | ||
307 | sprintf(card->part[card->nr_parts].name, name, idx); | ||
308 | card->part[card->nr_parts].force_ro = ro; | ||
309 | card->part[card->nr_parts].area_type = area_type; | ||
310 | card->nr_parts++; | ||
311 | } | ||
312 | |||
310 | static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) | 313 | static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) |
311 | { | 314 | { |
312 | int idx; | 315 | int idx; |
@@ -530,8 +533,14 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
530 | EXT_CSD_MANUAL_BKOPS_MASK); | 533 | EXT_CSD_MANUAL_BKOPS_MASK); |
531 | card->ext_csd.raw_bkops_status = | 534 | card->ext_csd.raw_bkops_status = |
532 | ext_csd[EXT_CSD_BKOPS_STATUS]; | 535 | ext_csd[EXT_CSD_BKOPS_STATUS]; |
533 | if (!card->ext_csd.man_bkops_en) | 536 | if (card->ext_csd.man_bkops_en) |
534 | pr_debug("%s: MAN_BKOPS_EN bit is not set\n", | 537 | pr_debug("%s: MAN_BKOPS_EN bit is set\n", |
538 | mmc_hostname(card->host)); | ||
539 | card->ext_csd.auto_bkops_en = | ||
540 | (ext_csd[EXT_CSD_BKOPS_EN] & | ||
541 | EXT_CSD_AUTO_BKOPS_MASK); | ||
542 | if (card->ext_csd.auto_bkops_en) | ||
543 | pr_debug("%s: AUTO_BKOPS_EN bit is set\n", | ||
535 | mmc_hostname(card->host)); | 544 | mmc_hostname(card->host)); |
536 | } | 545 | } |
537 | 546 | ||
@@ -617,6 +626,12 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
617 | card->ext_csd.ffu_capable = | 626 | card->ext_csd.ffu_capable = |
618 | (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) && | 627 | (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) && |
619 | !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1); | 628 | !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1); |
629 | |||
630 | card->ext_csd.pre_eol_info = ext_csd[EXT_CSD_PRE_EOL_INFO]; | ||
631 | card->ext_csd.device_life_time_est_typ_a = | ||
632 | ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]; | ||
633 | card->ext_csd.device_life_time_est_typ_b = | ||
634 | ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]; | ||
620 | } | 635 | } |
621 | 636 | ||
622 | /* eMMC v5.1 or later */ | 637 | /* eMMC v5.1 or later */ |
@@ -764,6 +779,10 @@ MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); | |||
764 | MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); | 779 | MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); |
765 | MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); | 780 | MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); |
766 | MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); | 781 | MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv); |
782 | MMC_DEV_ATTR(pre_eol_info, "%02x\n", card->ext_csd.pre_eol_info); | ||
783 | MMC_DEV_ATTR(life_time, "0x%02x 0x%02x\n", | ||
784 | card->ext_csd.device_life_time_est_typ_a, | ||
785 | card->ext_csd.device_life_time_est_typ_b); | ||
767 | MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); | 786 | MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); |
768 | MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", | 787 | MMC_DEV_ATTR(enhanced_area_offset, "%llu\n", |
769 | card->ext_csd.enhanced_area_offset); | 788 | card->ext_csd.enhanced_area_offset); |
@@ -817,6 +836,8 @@ static struct attribute *mmc_std_attrs[] = { | |||
817 | &dev_attr_name.attr, | 836 | &dev_attr_name.attr, |
818 | &dev_attr_oemid.attr, | 837 | &dev_attr_oemid.attr, |
819 | &dev_attr_prv.attr, | 838 | &dev_attr_prv.attr, |
839 | &dev_attr_pre_eol_info.attr, | ||
840 | &dev_attr_life_time.attr, | ||
820 | &dev_attr_serial.attr, | 841 | &dev_attr_serial.attr, |
821 | &dev_attr_enhanced_area_offset.attr, | 842 | &dev_attr_enhanced_area_offset.attr, |
822 | &dev_attr_enhanced_area_size.attr, | 843 | &dev_attr_enhanced_area_size.attr, |
@@ -1095,16 +1116,19 @@ static int mmc_select_hs_ddr(struct mmc_card *card) | |||
1095 | * | 1116 | * |
1096 | * WARNING: eMMC rules are NOT the same as SD DDR | 1117 | * WARNING: eMMC rules are NOT the same as SD DDR |
1097 | */ | 1118 | */ |
1098 | err = -EINVAL; | 1119 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) { |
1099 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_2V) | 1120 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); |
1100 | err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); | 1121 | if (!err) |
1122 | return 0; | ||
1123 | } | ||
1101 | 1124 | ||
1102 | if (err && (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V)) | 1125 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_DDR_1_8V && |
1103 | err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); | 1126 | host->caps & MMC_CAP_1_8V_DDR) |
1127 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); | ||
1104 | 1128 | ||
1105 | /* make sure vccq is 3.3v after switching disaster */ | 1129 | /* make sure vccq is 3.3v after switching disaster */ |
1106 | if (err) | 1130 | if (err) |
1107 | err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); | 1131 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330); |
1108 | 1132 | ||
1109 | return err; | 1133 | return err; |
1110 | } | 1134 | } |
@@ -1271,10 +1295,10 @@ static int mmc_select_hs400es(struct mmc_card *card) | |||
1271 | } | 1295 | } |
1272 | 1296 | ||
1273 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V) | 1297 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V) |
1274 | err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); | 1298 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); |
1275 | 1299 | ||
1276 | if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V) | 1300 | if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V) |
1277 | err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); | 1301 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); |
1278 | 1302 | ||
1279 | /* If fails try again during next card power cycle */ | 1303 | /* If fails try again during next card power cycle */ |
1280 | if (err) | 1304 | if (err) |
@@ -1380,10 +1404,10 @@ static int mmc_select_hs200(struct mmc_card *card) | |||
1380 | 1404 | ||
1381 | old_signal_voltage = host->ios.signal_voltage; | 1405 | old_signal_voltage = host->ios.signal_voltage; |
1382 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) | 1406 | if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V) |
1383 | err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); | 1407 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); |
1384 | 1408 | ||
1385 | if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) | 1409 | if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V) |
1386 | err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); | 1410 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180); |
1387 | 1411 | ||
1388 | /* If fails try again during next card power cycle */ | 1412 | /* If fails try again during next card power cycle */ |
1389 | if (err) | 1413 | if (err) |
@@ -1425,7 +1449,7 @@ static int mmc_select_hs200(struct mmc_card *card) | |||
1425 | err: | 1449 | err: |
1426 | if (err) { | 1450 | if (err) { |
1427 | /* fall back to the old signal voltage, if fails report error */ | 1451 | /* fall back to the old signal voltage, if fails report error */ |
1428 | if (__mmc_set_signal_voltage(host, old_signal_voltage)) | 1452 | if (mmc_set_signal_voltage(host, old_signal_voltage)) |
1429 | err = -EIO; | 1453 | err = -EIO; |
1430 | 1454 | ||
1431 | pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host), | 1455 | pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host), |
@@ -1805,7 +1829,7 @@ static int mmc_can_sleep(struct mmc_card *card) | |||
1805 | 1829 | ||
1806 | static int mmc_sleep(struct mmc_host *host) | 1830 | static int mmc_sleep(struct mmc_host *host) |
1807 | { | 1831 | { |
1808 | struct mmc_command cmd = {0}; | 1832 | struct mmc_command cmd = {}; |
1809 | struct mmc_card *card = host->card; | 1833 | struct mmc_card *card = host->card; |
1810 | unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); | 1834 | unsigned int timeout_ms = DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000); |
1811 | int err; | 1835 | int err; |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index e6ea8503f40c..fe80f26d6971 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -57,7 +57,7 @@ static const u8 tuning_blk_pattern_8bit[] = { | |||
57 | int mmc_send_status(struct mmc_card *card, u32 *status) | 57 | int mmc_send_status(struct mmc_card *card, u32 *status) |
58 | { | 58 | { |
59 | int err; | 59 | int err; |
60 | struct mmc_command cmd = {0}; | 60 | struct mmc_command cmd = {}; |
61 | 61 | ||
62 | cmd.opcode = MMC_SEND_STATUS; | 62 | cmd.opcode = MMC_SEND_STATUS; |
63 | if (!mmc_host_is_spi(card->host)) | 63 | if (!mmc_host_is_spi(card->host)) |
@@ -79,7 +79,7 @@ int mmc_send_status(struct mmc_card *card, u32 *status) | |||
79 | 79 | ||
80 | static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) | 80 | static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) |
81 | { | 81 | { |
82 | struct mmc_command cmd = {0}; | 82 | struct mmc_command cmd = {}; |
83 | 83 | ||
84 | cmd.opcode = MMC_SELECT_CARD; | 84 | cmd.opcode = MMC_SELECT_CARD; |
85 | 85 | ||
@@ -115,7 +115,7 @@ int mmc_deselect_cards(struct mmc_host *host) | |||
115 | */ | 115 | */ |
116 | int mmc_set_dsr(struct mmc_host *host) | 116 | int mmc_set_dsr(struct mmc_host *host) |
117 | { | 117 | { |
118 | struct mmc_command cmd = {0}; | 118 | struct mmc_command cmd = {}; |
119 | 119 | ||
120 | cmd.opcode = MMC_SET_DSR; | 120 | cmd.opcode = MMC_SET_DSR; |
121 | 121 | ||
@@ -128,7 +128,7 @@ int mmc_set_dsr(struct mmc_host *host) | |||
128 | int mmc_go_idle(struct mmc_host *host) | 128 | int mmc_go_idle(struct mmc_host *host) |
129 | { | 129 | { |
130 | int err; | 130 | int err; |
131 | struct mmc_command cmd = {0}; | 131 | struct mmc_command cmd = {}; |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * Non-SPI hosts need to prevent chipselect going active during | 134 | * Non-SPI hosts need to prevent chipselect going active during |
@@ -164,7 +164,7 @@ int mmc_go_idle(struct mmc_host *host) | |||
164 | 164 | ||
165 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | 165 | int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) |
166 | { | 166 | { |
167 | struct mmc_command cmd = {0}; | 167 | struct mmc_command cmd = {}; |
168 | int i, err = 0; | 168 | int i, err = 0; |
169 | 169 | ||
170 | cmd.opcode = MMC_SEND_OP_COND; | 170 | cmd.opcode = MMC_SEND_OP_COND; |
@@ -203,7 +203,7 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
203 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | 203 | int mmc_all_send_cid(struct mmc_host *host, u32 *cid) |
204 | { | 204 | { |
205 | int err; | 205 | int err; |
206 | struct mmc_command cmd = {0}; | 206 | struct mmc_command cmd = {}; |
207 | 207 | ||
208 | cmd.opcode = MMC_ALL_SEND_CID; | 208 | cmd.opcode = MMC_ALL_SEND_CID; |
209 | cmd.arg = 0; | 209 | cmd.arg = 0; |
@@ -220,7 +220,7 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid) | |||
220 | 220 | ||
221 | int mmc_set_relative_addr(struct mmc_card *card) | 221 | int mmc_set_relative_addr(struct mmc_card *card) |
222 | { | 222 | { |
223 | struct mmc_command cmd = {0}; | 223 | struct mmc_command cmd = {}; |
224 | 224 | ||
225 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | 225 | cmd.opcode = MMC_SET_RELATIVE_ADDR; |
226 | cmd.arg = card->rca << 16; | 226 | cmd.arg = card->rca << 16; |
@@ -233,7 +233,7 @@ static int | |||
233 | mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) | 233 | mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode) |
234 | { | 234 | { |
235 | int err; | 235 | int err; |
236 | struct mmc_command cmd = {0}; | 236 | struct mmc_command cmd = {}; |
237 | 237 | ||
238 | cmd.opcode = opcode; | 238 | cmd.opcode = opcode; |
239 | cmd.arg = arg; | 239 | cmd.arg = arg; |
@@ -256,9 +256,9 @@ static int | |||
256 | mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, | 256 | mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, |
257 | u32 opcode, void *buf, unsigned len) | 257 | u32 opcode, void *buf, unsigned len) |
258 | { | 258 | { |
259 | struct mmc_request mrq = {NULL}; | 259 | struct mmc_request mrq = {}; |
260 | struct mmc_command cmd = {0}; | 260 | struct mmc_command cmd = {}; |
261 | struct mmc_data data = {0}; | 261 | struct mmc_data data = {}; |
262 | struct scatterlist sg; | 262 | struct scatterlist sg; |
263 | 263 | ||
264 | mrq.cmd = &cmd; | 264 | mrq.cmd = &cmd; |
@@ -387,7 +387,7 @@ EXPORT_SYMBOL_GPL(mmc_get_ext_csd); | |||
387 | 387 | ||
388 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) | 388 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) |
389 | { | 389 | { |
390 | struct mmc_command cmd = {0}; | 390 | struct mmc_command cmd = {}; |
391 | int err; | 391 | int err; |
392 | 392 | ||
393 | cmd.opcode = MMC_SPI_READ_OCR; | 393 | cmd.opcode = MMC_SPI_READ_OCR; |
@@ -402,7 +402,7 @@ int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp) | |||
402 | 402 | ||
403 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc) | 403 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc) |
404 | { | 404 | { |
405 | struct mmc_command cmd = {0}; | 405 | struct mmc_command cmd = {}; |
406 | int err; | 406 | int err; |
407 | 407 | ||
408 | cmd.opcode = MMC_SPI_CRC_ON_OFF; | 408 | cmd.opcode = MMC_SPI_CRC_ON_OFF; |
@@ -530,7 +530,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | |||
530 | { | 530 | { |
531 | struct mmc_host *host = card->host; | 531 | struct mmc_host *host = card->host; |
532 | int err; | 532 | int err; |
533 | struct mmc_command cmd = {0}; | 533 | struct mmc_command cmd = {}; |
534 | bool use_r1b_resp = use_busy_signal; | 534 | bool use_r1b_resp = use_busy_signal; |
535 | unsigned char old_timing = host->ios.timing; | 535 | unsigned char old_timing = host->ios.timing; |
536 | 536 | ||
@@ -610,9 +610,9 @@ EXPORT_SYMBOL_GPL(mmc_switch); | |||
610 | 610 | ||
611 | int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error) | 611 | int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error) |
612 | { | 612 | { |
613 | struct mmc_request mrq = {NULL}; | 613 | struct mmc_request mrq = {}; |
614 | struct mmc_command cmd = {0}; | 614 | struct mmc_command cmd = {}; |
615 | struct mmc_data data = {0}; | 615 | struct mmc_data data = {}; |
616 | struct scatterlist sg; | 616 | struct scatterlist sg; |
617 | struct mmc_ios *ios = &host->ios; | 617 | struct mmc_ios *ios = &host->ios; |
618 | const u8 *tuning_block_pattern; | 618 | const u8 *tuning_block_pattern; |
@@ -679,7 +679,7 @@ EXPORT_SYMBOL_GPL(mmc_send_tuning); | |||
679 | 679 | ||
680 | int mmc_abort_tuning(struct mmc_host *host, u32 opcode) | 680 | int mmc_abort_tuning(struct mmc_host *host, u32 opcode) |
681 | { | 681 | { |
682 | struct mmc_command cmd = {0}; | 682 | struct mmc_command cmd = {}; |
683 | 683 | ||
684 | /* | 684 | /* |
685 | * eMMC specification specifies that CMD12 can be used to stop a tuning | 685 | * eMMC specification specifies that CMD12 can be used to stop a tuning |
@@ -706,9 +706,9 @@ static int | |||
706 | mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, | 706 | mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode, |
707 | u8 len) | 707 | u8 len) |
708 | { | 708 | { |
709 | struct mmc_request mrq = {NULL}; | 709 | struct mmc_request mrq = {}; |
710 | struct mmc_command cmd = {0}; | 710 | struct mmc_command cmd = {}; |
711 | struct mmc_data data = {0}; | 711 | struct mmc_data data = {}; |
712 | struct scatterlist sg; | 712 | struct scatterlist sg; |
713 | u8 *data_buf; | 713 | u8 *data_buf; |
714 | u8 *test_buf; | 714 | u8 *test_buf; |
@@ -802,7 +802,7 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width) | |||
802 | 802 | ||
803 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) | 803 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) |
804 | { | 804 | { |
805 | struct mmc_command cmd = {0}; | 805 | struct mmc_command cmd = {}; |
806 | unsigned int opcode; | 806 | unsigned int opcode; |
807 | int err; | 807 | int err; |
808 | 808 | ||
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index abd525ed74be..74beea8a9c7e 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -12,6 +12,11 @@ | |||
12 | #ifndef _MMC_MMC_OPS_H | 12 | #ifndef _MMC_MMC_OPS_H |
13 | #define _MMC_MMC_OPS_H | 13 | #define _MMC_MMC_OPS_H |
14 | 14 | ||
15 | #include <linux/types.h> | ||
16 | |||
17 | struct mmc_host; | ||
18 | struct mmc_card; | ||
19 | |||
15 | int mmc_select_card(struct mmc_card *card); | 20 | int mmc_select_card(struct mmc_card *card); |
16 | int mmc_deselect_cards(struct mmc_host *host); | 21 | int mmc_deselect_cards(struct mmc_host *host); |
17 | int mmc_set_dsr(struct mmc_host *host); | 22 | int mmc_set_dsr(struct mmc_host *host); |
@@ -26,12 +31,21 @@ int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); | |||
26 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc); | 31 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc); |
27 | int mmc_bus_test(struct mmc_card *card, u8 bus_width); | 32 | int mmc_bus_test(struct mmc_card *card, u8 bus_width); |
28 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); | 33 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); |
34 | int mmc_interrupt_hpi(struct mmc_card *card); | ||
29 | int mmc_can_ext_csd(struct mmc_card *card); | 35 | int mmc_can_ext_csd(struct mmc_card *card); |
36 | int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); | ||
30 | int mmc_switch_status(struct mmc_card *card); | 37 | int mmc_switch_status(struct mmc_card *card); |
31 | int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal); | 38 | int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal); |
32 | int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | 39 | int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, |
33 | unsigned int timeout_ms, unsigned char timing, | 40 | unsigned int timeout_ms, unsigned char timing, |
34 | bool use_busy_signal, bool send_status, bool retry_crc_err); | 41 | bool use_busy_signal, bool send_status, bool retry_crc_err); |
42 | int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | ||
43 | unsigned int timeout_ms); | ||
44 | int mmc_stop_bkops(struct mmc_card *card); | ||
45 | int mmc_read_bkops_status(struct mmc_card *card); | ||
46 | void mmc_start_bkops(struct mmc_card *card, bool from_exception); | ||
47 | int mmc_can_reset(struct mmc_card *card); | ||
48 | int mmc_flush_cache(struct mmc_card *card); | ||
35 | 49 | ||
36 | #endif | 50 | #endif |
37 | 51 | ||
diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c index 3ab6e52d106c..f99ac3123fd2 100644 --- a/drivers/mmc/core/mmc_test.c +++ b/drivers/mmc/core/mmc_test.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | 24 | ||
25 | #include "core.h" | ||
26 | #include "card.h" | ||
27 | #include "host.h" | ||
28 | #include "bus.h" | ||
29 | |||
25 | #define RESULT_OK 0 | 30 | #define RESULT_OK 0 |
26 | #define RESULT_FAIL 1 | 31 | #define RESULT_FAIL 1 |
27 | #define RESULT_UNSUP_HOST 2 | 32 | #define RESULT_UNSUP_HOST 2 |
@@ -260,7 +265,7 @@ static int mmc_test_busy(struct mmc_command *cmd) | |||
260 | static int mmc_test_wait_busy(struct mmc_test_card *test) | 265 | static int mmc_test_wait_busy(struct mmc_test_card *test) |
261 | { | 266 | { |
262 | int ret, busy; | 267 | int ret, busy; |
263 | struct mmc_command cmd = {0}; | 268 | struct mmc_command cmd = {}; |
264 | 269 | ||
265 | busy = 0; | 270 | busy = 0; |
266 | do { | 271 | do { |
@@ -277,8 +282,7 @@ static int mmc_test_wait_busy(struct mmc_test_card *test) | |||
277 | if (!busy && mmc_test_busy(&cmd)) { | 282 | if (!busy && mmc_test_busy(&cmd)) { |
278 | busy = 1; | 283 | busy = 1; |
279 | if (test->card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) | 284 | if (test->card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) |
280 | pr_info("%s: Warning: Host did not " | 285 | pr_info("%s: Warning: Host did not wait for busy state to end.\n", |
281 | "wait for busy state to end.\n", | ||
282 | mmc_hostname(test->card->host)); | 286 | mmc_hostname(test->card->host)); |
283 | } | 287 | } |
284 | } while (mmc_test_busy(&cmd)); | 288 | } while (mmc_test_busy(&cmd)); |
@@ -292,10 +296,10 @@ static int mmc_test_wait_busy(struct mmc_test_card *test) | |||
292 | static int mmc_test_buffer_transfer(struct mmc_test_card *test, | 296 | static int mmc_test_buffer_transfer(struct mmc_test_card *test, |
293 | u8 *buffer, unsigned addr, unsigned blksz, int write) | 297 | u8 *buffer, unsigned addr, unsigned blksz, int write) |
294 | { | 298 | { |
295 | struct mmc_request mrq = {0}; | 299 | struct mmc_request mrq = {}; |
296 | struct mmc_command cmd = {0}; | 300 | struct mmc_command cmd = {}; |
297 | struct mmc_command stop = {0}; | 301 | struct mmc_command stop = {}; |
298 | struct mmc_data data = {0}; | 302 | struct mmc_data data = {}; |
299 | 303 | ||
300 | struct scatterlist sg; | 304 | struct scatterlist sg; |
301 | 305 | ||
@@ -357,12 +361,11 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz, | |||
357 | if (max_segs > max_page_cnt) | 361 | if (max_segs > max_page_cnt) |
358 | max_segs = max_page_cnt; | 362 | max_segs = max_page_cnt; |
359 | 363 | ||
360 | mem = kzalloc(sizeof(struct mmc_test_mem), GFP_KERNEL); | 364 | mem = kzalloc(sizeof(*mem), GFP_KERNEL); |
361 | if (!mem) | 365 | if (!mem) |
362 | return NULL; | 366 | return NULL; |
363 | 367 | ||
364 | mem->arr = kzalloc(sizeof(struct mmc_test_pages) * max_segs, | 368 | mem->arr = kcalloc(max_segs, sizeof(*mem->arr), GFP_KERNEL); |
365 | GFP_KERNEL); | ||
366 | if (!mem->arr) | 369 | if (!mem->arr) |
367 | goto out_free; | 370 | goto out_free; |
368 | 371 | ||
@@ -546,7 +549,7 @@ static void mmc_test_save_transfer_result(struct mmc_test_card *test, | |||
546 | if (!test->gr) | 549 | if (!test->gr) |
547 | return; | 550 | return; |
548 | 551 | ||
549 | tr = kmalloc(sizeof(struct mmc_test_transfer_result), GFP_KERNEL); | 552 | tr = kmalloc(sizeof(*tr), GFP_KERNEL); |
550 | if (!tr) | 553 | if (!tr) |
551 | return; | 554 | return; |
552 | 555 | ||
@@ -641,11 +644,11 @@ static int __mmc_test_prepare(struct mmc_test_card *test, int write) | |||
641 | if (write) | 644 | if (write) |
642 | memset(test->buffer, 0xDF, 512); | 645 | memset(test->buffer, 0xDF, 512); |
643 | else { | 646 | else { |
644 | for (i = 0;i < 512;i++) | 647 | for (i = 0; i < 512; i++) |
645 | test->buffer[i] = i; | 648 | test->buffer[i] = i; |
646 | } | 649 | } |
647 | 650 | ||
648 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | 651 | for (i = 0; i < BUFFER_SIZE / 512; i++) { |
649 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); | 652 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); |
650 | if (ret) | 653 | if (ret) |
651 | return ret; | 654 | return ret; |
@@ -674,7 +677,7 @@ static int mmc_test_cleanup(struct mmc_test_card *test) | |||
674 | 677 | ||
675 | memset(test->buffer, 0, 512); | 678 | memset(test->buffer, 0, 512); |
676 | 679 | ||
677 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | 680 | for (i = 0; i < BUFFER_SIZE / 512; i++) { |
678 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); | 681 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); |
679 | if (ret) | 682 | if (ret) |
680 | return ret; | 683 | return ret; |
@@ -850,7 +853,7 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test, | |||
850 | for (i = 0; i < count; i++) { | 853 | for (i = 0; i < count; i++) { |
851 | mmc_test_prepare_mrq(test, cur_areq->mrq, sg, sg_len, dev_addr, | 854 | mmc_test_prepare_mrq(test, cur_areq->mrq, sg, sg_len, dev_addr, |
852 | blocks, blksz, write); | 855 | blocks, blksz, write); |
853 | done_areq = mmc_start_req(test->card->host, cur_areq, &status); | 856 | done_areq = mmc_start_areq(test->card->host, cur_areq, &status); |
854 | 857 | ||
855 | if (status != MMC_BLK_SUCCESS || (!done_areq && i > 0)) { | 858 | if (status != MMC_BLK_SUCCESS || (!done_areq && i > 0)) { |
856 | ret = RESULT_FAIL; | 859 | ret = RESULT_FAIL; |
@@ -869,7 +872,7 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test, | |||
869 | dev_addr += blocks; | 872 | dev_addr += blocks; |
870 | } | 873 | } |
871 | 874 | ||
872 | done_areq = mmc_start_req(test->card->host, NULL, &status); | 875 | done_areq = mmc_start_areq(test->card->host, NULL, &status); |
873 | if (status != MMC_BLK_SUCCESS) | 876 | if (status != MMC_BLK_SUCCESS) |
874 | ret = RESULT_FAIL; | 877 | ret = RESULT_FAIL; |
875 | 878 | ||
@@ -885,10 +888,10 @@ static int mmc_test_simple_transfer(struct mmc_test_card *test, | |||
885 | struct scatterlist *sg, unsigned sg_len, unsigned dev_addr, | 888 | struct scatterlist *sg, unsigned sg_len, unsigned dev_addr, |
886 | unsigned blocks, unsigned blksz, int write) | 889 | unsigned blocks, unsigned blksz, int write) |
887 | { | 890 | { |
888 | struct mmc_request mrq = {0}; | 891 | struct mmc_request mrq = {}; |
889 | struct mmc_command cmd = {0}; | 892 | struct mmc_command cmd = {}; |
890 | struct mmc_command stop = {0}; | 893 | struct mmc_command stop = {}; |
891 | struct mmc_data data = {0}; | 894 | struct mmc_data data = {}; |
892 | 895 | ||
893 | mrq.cmd = &cmd; | 896 | mrq.cmd = &cmd; |
894 | mrq.data = &data; | 897 | mrq.data = &data; |
@@ -910,10 +913,10 @@ static int mmc_test_simple_transfer(struct mmc_test_card *test, | |||
910 | static int mmc_test_broken_transfer(struct mmc_test_card *test, | 913 | static int mmc_test_broken_transfer(struct mmc_test_card *test, |
911 | unsigned blocks, unsigned blksz, int write) | 914 | unsigned blocks, unsigned blksz, int write) |
912 | { | 915 | { |
913 | struct mmc_request mrq = {0}; | 916 | struct mmc_request mrq = {}; |
914 | struct mmc_command cmd = {0}; | 917 | struct mmc_command cmd = {}; |
915 | struct mmc_command stop = {0}; | 918 | struct mmc_command stop = {}; |
916 | struct mmc_data data = {0}; | 919 | struct mmc_data data = {}; |
917 | 920 | ||
918 | struct scatterlist sg; | 921 | struct scatterlist sg; |
919 | 922 | ||
@@ -946,7 +949,7 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
946 | unsigned long flags; | 949 | unsigned long flags; |
947 | 950 | ||
948 | if (write) { | 951 | if (write) { |
949 | for (i = 0;i < blocks * blksz;i++) | 952 | for (i = 0; i < blocks * blksz; i++) |
950 | test->scratch[i] = i; | 953 | test->scratch[i] = i; |
951 | } else { | 954 | } else { |
952 | memset(test->scratch, 0, BUFFER_SIZE); | 955 | memset(test->scratch, 0, BUFFER_SIZE); |
@@ -980,7 +983,7 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
980 | 983 | ||
981 | memset(test->buffer, 0, sectors * 512); | 984 | memset(test->buffer, 0, sectors * 512); |
982 | 985 | ||
983 | for (i = 0;i < sectors;i++) { | 986 | for (i = 0; i < sectors; i++) { |
984 | ret = mmc_test_buffer_transfer(test, | 987 | ret = mmc_test_buffer_transfer(test, |
985 | test->buffer + i * 512, | 988 | test->buffer + i * 512, |
986 | dev_addr + i, 512, 0); | 989 | dev_addr + i, 512, 0); |
@@ -988,12 +991,12 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
988 | return ret; | 991 | return ret; |
989 | } | 992 | } |
990 | 993 | ||
991 | for (i = 0;i < blocks * blksz;i++) { | 994 | for (i = 0; i < blocks * blksz; i++) { |
992 | if (test->buffer[i] != (u8)i) | 995 | if (test->buffer[i] != (u8)i) |
993 | return RESULT_FAIL; | 996 | return RESULT_FAIL; |
994 | } | 997 | } |
995 | 998 | ||
996 | for (;i < sectors * 512;i++) { | 999 | for (; i < sectors * 512; i++) { |
997 | if (test->buffer[i] != 0xDF) | 1000 | if (test->buffer[i] != 0xDF) |
998 | return RESULT_FAIL; | 1001 | return RESULT_FAIL; |
999 | } | 1002 | } |
@@ -1001,7 +1004,7 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
1001 | local_irq_save(flags); | 1004 | local_irq_save(flags); |
1002 | sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); | 1005 | sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE); |
1003 | local_irq_restore(flags); | 1006 | local_irq_restore(flags); |
1004 | for (i = 0;i < blocks * blksz;i++) { | 1007 | for (i = 0; i < blocks * blksz; i++) { |
1005 | if (test->scratch[i] != (u8)i) | 1008 | if (test->scratch[i] != (u8)i) |
1006 | return RESULT_FAIL; | 1009 | return RESULT_FAIL; |
1007 | } | 1010 | } |
@@ -1086,7 +1089,7 @@ static int mmc_test_multi_write(struct mmc_test_card *test) | |||
1086 | 1089 | ||
1087 | sg_init_one(&sg, test->buffer, size); | 1090 | sg_init_one(&sg, test->buffer, size); |
1088 | 1091 | ||
1089 | return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); | 1092 | return mmc_test_transfer(test, &sg, 1, 0, size / 512, 512, 1); |
1090 | } | 1093 | } |
1091 | 1094 | ||
1092 | static int mmc_test_multi_read(struct mmc_test_card *test) | 1095 | static int mmc_test_multi_read(struct mmc_test_card *test) |
@@ -1107,7 +1110,7 @@ static int mmc_test_multi_read(struct mmc_test_card *test) | |||
1107 | 1110 | ||
1108 | sg_init_one(&sg, test->buffer, size); | 1111 | sg_init_one(&sg, test->buffer, size); |
1109 | 1112 | ||
1110 | return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); | 1113 | return mmc_test_transfer(test, &sg, 1, 0, size / 512, 512, 0); |
1111 | } | 1114 | } |
1112 | 1115 | ||
1113 | static int mmc_test_pow2_write(struct mmc_test_card *test) | 1116 | static int mmc_test_pow2_write(struct mmc_test_card *test) |
@@ -1118,7 +1121,7 @@ static int mmc_test_pow2_write(struct mmc_test_card *test) | |||
1118 | if (!test->card->csd.write_partial) | 1121 | if (!test->card->csd.write_partial) |
1119 | return RESULT_UNSUP_CARD; | 1122 | return RESULT_UNSUP_CARD; |
1120 | 1123 | ||
1121 | for (i = 1; i < 512;i <<= 1) { | 1124 | for (i = 1; i < 512; i <<= 1) { |
1122 | sg_init_one(&sg, test->buffer, i); | 1125 | sg_init_one(&sg, test->buffer, i); |
1123 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1); | 1126 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1); |
1124 | if (ret) | 1127 | if (ret) |
@@ -1136,7 +1139,7 @@ static int mmc_test_pow2_read(struct mmc_test_card *test) | |||
1136 | if (!test->card->csd.read_partial) | 1139 | if (!test->card->csd.read_partial) |
1137 | return RESULT_UNSUP_CARD; | 1140 | return RESULT_UNSUP_CARD; |
1138 | 1141 | ||
1139 | for (i = 1; i < 512;i <<= 1) { | 1142 | for (i = 1; i < 512; i <<= 1) { |
1140 | sg_init_one(&sg, test->buffer, i); | 1143 | sg_init_one(&sg, test->buffer, i); |
1141 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0); | 1144 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0); |
1142 | if (ret) | 1145 | if (ret) |
@@ -1154,7 +1157,7 @@ static int mmc_test_weird_write(struct mmc_test_card *test) | |||
1154 | if (!test->card->csd.write_partial) | 1157 | if (!test->card->csd.write_partial) |
1155 | return RESULT_UNSUP_CARD; | 1158 | return RESULT_UNSUP_CARD; |
1156 | 1159 | ||
1157 | for (i = 3; i < 512;i += 7) { | 1160 | for (i = 3; i < 512; i += 7) { |
1158 | sg_init_one(&sg, test->buffer, i); | 1161 | sg_init_one(&sg, test->buffer, i); |
1159 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1); | 1162 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1); |
1160 | if (ret) | 1163 | if (ret) |
@@ -1172,7 +1175,7 @@ static int mmc_test_weird_read(struct mmc_test_card *test) | |||
1172 | if (!test->card->csd.read_partial) | 1175 | if (!test->card->csd.read_partial) |
1173 | return RESULT_UNSUP_CARD; | 1176 | return RESULT_UNSUP_CARD; |
1174 | 1177 | ||
1175 | for (i = 3; i < 512;i += 7) { | 1178 | for (i = 3; i < 512; i += 7) { |
1176 | sg_init_one(&sg, test->buffer, i); | 1179 | sg_init_one(&sg, test->buffer, i); |
1177 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0); | 1180 | ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0); |
1178 | if (ret) | 1181 | if (ret) |
@@ -1231,7 +1234,7 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test) | |||
1231 | 1234 | ||
1232 | for (i = 1; i < TEST_ALIGN_END; i++) { | 1235 | for (i = 1; i < TEST_ALIGN_END; i++) { |
1233 | sg_init_one(&sg, test->buffer + i, size); | 1236 | sg_init_one(&sg, test->buffer + i, size); |
1234 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); | 1237 | ret = mmc_test_transfer(test, &sg, 1, 0, size / 512, 512, 1); |
1235 | if (ret) | 1238 | if (ret) |
1236 | return ret; | 1239 | return ret; |
1237 | } | 1240 | } |
@@ -1258,7 +1261,7 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test) | |||
1258 | 1261 | ||
1259 | for (i = 1; i < TEST_ALIGN_END; i++) { | 1262 | for (i = 1; i < TEST_ALIGN_END; i++) { |
1260 | sg_init_one(&sg, test->buffer + i, size); | 1263 | sg_init_one(&sg, test->buffer + i, size); |
1261 | ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); | 1264 | ret = mmc_test_transfer(test, &sg, 1, 0, size / 512, 512, 0); |
1262 | if (ret) | 1265 | if (ret) |
1263 | return ret; | 1266 | return ret; |
1264 | } | 1267 | } |
@@ -1357,7 +1360,7 @@ static int mmc_test_multi_write_high(struct mmc_test_card *test) | |||
1357 | sg_init_table(&sg, 1); | 1360 | sg_init_table(&sg, 1); |
1358 | sg_set_page(&sg, test->highmem, size, 0); | 1361 | sg_set_page(&sg, test->highmem, size, 0); |
1359 | 1362 | ||
1360 | return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1); | 1363 | return mmc_test_transfer(test, &sg, 1, 0, size / 512, 512, 1); |
1361 | } | 1364 | } |
1362 | 1365 | ||
1363 | static int mmc_test_multi_read_high(struct mmc_test_card *test) | 1366 | static int mmc_test_multi_read_high(struct mmc_test_card *test) |
@@ -1379,7 +1382,7 @@ static int mmc_test_multi_read_high(struct mmc_test_card *test) | |||
1379 | sg_init_table(&sg, 1); | 1382 | sg_init_table(&sg, 1); |
1380 | sg_set_page(&sg, test->highmem, size, 0); | 1383 | sg_set_page(&sg, test->highmem, size, 0); |
1381 | 1384 | ||
1382 | return mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0); | 1385 | return mmc_test_transfer(test, &sg, 1, 0, size / 512, 512, 0); |
1383 | } | 1386 | } |
1384 | 1387 | ||
1385 | #else | 1388 | #else |
@@ -1533,7 +1536,7 @@ static int mmc_test_area_cleanup(struct mmc_test_card *test) | |||
1533 | 1536 | ||
1534 | /* | 1537 | /* |
1535 | * Initialize an area for testing large transfers. The test area is set to the | 1538 | * Initialize an area for testing large transfers. The test area is set to the |
1536 | * middle of the card because cards may have different charateristics at the | 1539 | * middle of the card because cards may have different characteristics at the |
1537 | * front (for FAT file system optimization). Optionally, the area is erased | 1540 | * front (for FAT file system optimization). Optionally, the area is erased |
1538 | * (if the card supports it) which may improve write performance. Optionally, | 1541 | * (if the card supports it) which may improve write performance. Optionally, |
1539 | * the area is filled with data for subsequent read tests. | 1542 | * the area is filled with data for subsequent read tests. |
@@ -1579,7 +1582,7 @@ static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill) | |||
1579 | if (!t->mem) | 1582 | if (!t->mem) |
1580 | return -ENOMEM; | 1583 | return -ENOMEM; |
1581 | 1584 | ||
1582 | t->sg = kmalloc(sizeof(struct scatterlist) * t->max_segs, GFP_KERNEL); | 1585 | t->sg = kmalloc_array(t->max_segs, sizeof(*t->sg), GFP_KERNEL); |
1583 | if (!t->sg) { | 1586 | if (!t->sg) { |
1584 | ret = -ENOMEM; | 1587 | ret = -ENOMEM; |
1585 | goto out_free; | 1588 | goto out_free; |
@@ -2147,7 +2150,7 @@ static int mmc_test_rw_multiple_sg_len(struct mmc_test_card *test, | |||
2147 | int i; | 2150 | int i; |
2148 | 2151 | ||
2149 | for (i = 0 ; i < rw->len && ret == 0; i++) { | 2152 | for (i = 0 ; i < rw->len && ret == 0; i++) { |
2150 | ret = mmc_test_rw_multiple(test, rw, 512*1024, rw->size, | 2153 | ret = mmc_test_rw_multiple(test, rw, 512 * 1024, rw->size, |
2151 | rw->sg_len[i]); | 2154 | rw->sg_len[i]); |
2152 | if (ret) | 2155 | if (ret) |
2153 | break; | 2156 | break; |
@@ -2399,7 +2402,7 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, | |||
2399 | 2402 | ||
2400 | /* Start ongoing data request */ | 2403 | /* Start ongoing data request */ |
2401 | if (use_areq) { | 2404 | if (use_areq) { |
2402 | mmc_start_req(host, &test_areq.areq, &blkstat); | 2405 | mmc_start_areq(host, &test_areq.areq, &blkstat); |
2403 | if (blkstat != MMC_BLK_SUCCESS) { | 2406 | if (blkstat != MMC_BLK_SUCCESS) { |
2404 | ret = RESULT_FAIL; | 2407 | ret = RESULT_FAIL; |
2405 | goto out_free; | 2408 | goto out_free; |
@@ -2437,7 +2440,7 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, | |||
2437 | 2440 | ||
2438 | /* Wait for data request to complete */ | 2441 | /* Wait for data request to complete */ |
2439 | if (use_areq) { | 2442 | if (use_areq) { |
2440 | mmc_start_req(host, NULL, &blkstat); | 2443 | mmc_start_areq(host, NULL, &blkstat); |
2441 | if (blkstat != MMC_BLK_SUCCESS) | 2444 | if (blkstat != MMC_BLK_SUCCESS) |
2442 | ret = RESULT_FAIL; | 2445 | ret = RESULT_FAIL; |
2443 | } else { | 2446 | } else { |
@@ -2954,7 +2957,7 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase) | |||
2954 | 2957 | ||
2955 | mmc_claim_host(test->card->host); | 2958 | mmc_claim_host(test->card->host); |
2956 | 2959 | ||
2957 | for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) { | 2960 | for (i = 0; i < ARRAY_SIZE(mmc_test_cases); i++) { |
2958 | struct mmc_test_general_result *gr; | 2961 | struct mmc_test_general_result *gr; |
2959 | 2962 | ||
2960 | if (testcase && ((i + 1) != testcase)) | 2963 | if (testcase && ((i + 1) != testcase)) |
@@ -2967,16 +2970,14 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase) | |||
2967 | if (mmc_test_cases[i].prepare) { | 2970 | if (mmc_test_cases[i].prepare) { |
2968 | ret = mmc_test_cases[i].prepare(test); | 2971 | ret = mmc_test_cases[i].prepare(test); |
2969 | if (ret) { | 2972 | if (ret) { |
2970 | pr_info("%s: Result: Prepare " | 2973 | pr_info("%s: Result: Prepare stage failed! (%d)\n", |
2971 | "stage failed! (%d)\n", | ||
2972 | mmc_hostname(test->card->host), | 2974 | mmc_hostname(test->card->host), |
2973 | ret); | 2975 | ret); |
2974 | continue; | 2976 | continue; |
2975 | } | 2977 | } |
2976 | } | 2978 | } |
2977 | 2979 | ||
2978 | gr = kzalloc(sizeof(struct mmc_test_general_result), | 2980 | gr = kzalloc(sizeof(*gr), GFP_KERNEL); |
2979 | GFP_KERNEL); | ||
2980 | if (gr) { | 2981 | if (gr) { |
2981 | INIT_LIST_HEAD(&gr->tr_lst); | 2982 | INIT_LIST_HEAD(&gr->tr_lst); |
2982 | 2983 | ||
@@ -3005,13 +3006,11 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase) | |||
3005 | mmc_hostname(test->card->host)); | 3006 | mmc_hostname(test->card->host)); |
3006 | break; | 3007 | break; |
3007 | case RESULT_UNSUP_HOST: | 3008 | case RESULT_UNSUP_HOST: |
3008 | pr_info("%s: Result: UNSUPPORTED " | 3009 | pr_info("%s: Result: UNSUPPORTED (by host)\n", |
3009 | "(by host)\n", | ||
3010 | mmc_hostname(test->card->host)); | 3010 | mmc_hostname(test->card->host)); |
3011 | break; | 3011 | break; |
3012 | case RESULT_UNSUP_CARD: | 3012 | case RESULT_UNSUP_CARD: |
3013 | pr_info("%s: Result: UNSUPPORTED " | 3013 | pr_info("%s: Result: UNSUPPORTED (by card)\n", |
3014 | "(by card)\n", | ||
3015 | mmc_hostname(test->card->host)); | 3014 | mmc_hostname(test->card->host)); |
3016 | break; | 3015 | break; |
3017 | default: | 3016 | default: |
@@ -3026,8 +3025,7 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase) | |||
3026 | if (mmc_test_cases[i].cleanup) { | 3025 | if (mmc_test_cases[i].cleanup) { |
3027 | ret = mmc_test_cases[i].cleanup(test); | 3026 | ret = mmc_test_cases[i].cleanup(test); |
3028 | if (ret) { | 3027 | if (ret) { |
3029 | pr_info("%s: Warning: Cleanup " | 3028 | pr_info("%s: Warning: Cleanup stage failed! (%d)\n", |
3030 | "stage failed! (%d)\n", | ||
3031 | mmc_hostname(test->card->host), | 3029 | mmc_hostname(test->card->host), |
3032 | ret); | 3030 | ret); |
3033 | } | 3031 | } |
@@ -3113,7 +3111,7 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf, | |||
3113 | if (ret) | 3111 | if (ret) |
3114 | return ret; | 3112 | return ret; |
3115 | 3113 | ||
3116 | test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL); | 3114 | test = kzalloc(sizeof(*test), GFP_KERNEL); |
3117 | if (!test) | 3115 | if (!test) |
3118 | return -ENOMEM; | 3116 | return -ENOMEM; |
3119 | 3117 | ||
@@ -3163,9 +3161,9 @@ static int mtf_testlist_show(struct seq_file *sf, void *data) | |||
3163 | 3161 | ||
3164 | mutex_lock(&mmc_test_lock); | 3162 | mutex_lock(&mmc_test_lock); |
3165 | 3163 | ||
3166 | seq_printf(sf, "0:\tRun all tests\n"); | 3164 | seq_puts(sf, "0:\tRun all tests\n"); |
3167 | for (i = 0; i < ARRAY_SIZE(mmc_test_cases); i++) | 3165 | for (i = 0; i < ARRAY_SIZE(mmc_test_cases); i++) |
3168 | seq_printf(sf, "%d:\t%s\n", i+1, mmc_test_cases[i].name); | 3166 | seq_printf(sf, "%d:\t%s\n", i + 1, mmc_test_cases[i].name); |
3169 | 3167 | ||
3170 | mutex_unlock(&mmc_test_lock); | 3168 | mutex_unlock(&mmc_test_lock); |
3171 | 3169 | ||
@@ -3218,7 +3216,7 @@ static int __mmc_test_register_dbgfs_file(struct mmc_card *card, | |||
3218 | return -ENODEV; | 3216 | return -ENODEV; |
3219 | } | 3217 | } |
3220 | 3218 | ||
3221 | df = kmalloc(sizeof(struct mmc_test_dbgfs_file), GFP_KERNEL); | 3219 | df = kmalloc(sizeof(*df), GFP_KERNEL); |
3222 | if (!df) { | 3220 | if (!df) { |
3223 | debugfs_remove(file); | 3221 | debugfs_remove(file); |
3224 | dev_err(&card->dev, | 3222 | dev_err(&card->dev, |
diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h index d69e751f148b..39c911aa6ebb 100644 --- a/drivers/mmc/core/pwrseq.h +++ b/drivers/mmc/core/pwrseq.h | |||
@@ -8,7 +8,11 @@ | |||
8 | #ifndef _MMC_CORE_PWRSEQ_H | 8 | #ifndef _MMC_CORE_PWRSEQ_H |
9 | #define _MMC_CORE_PWRSEQ_H | 9 | #define _MMC_CORE_PWRSEQ_H |
10 | 10 | ||
11 | #include <linux/mmc/host.h> | 11 | #include <linux/types.h> |
12 | |||
13 | struct mmc_host; | ||
14 | struct device; | ||
15 | struct module; | ||
12 | 16 | ||
13 | struct mmc_pwrseq_ops { | 17 | struct mmc_pwrseq_ops { |
14 | void (*pre_power_on)(struct mmc_host *host); | 18 | void (*pre_power_on)(struct mmc_host *host); |
diff --git a/drivers/mmc/core/pwrseq_sd8787.c b/drivers/mmc/core/pwrseq_sd8787.c new file mode 100644 index 000000000000..1a21e14458d3 --- /dev/null +++ b/drivers/mmc/core/pwrseq_sd8787.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi chip | ||
3 | * | ||
4 | * Copyright (C) 2016 Matt Ranostay <matt@ranostay.consulting> | ||
5 | * | ||
6 | * Based on the original work pwrseq_simple.c | ||
7 | * Copyright (C) 2014 Linaro Ltd | ||
8 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/delay.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/err.h> | ||
30 | #include <linux/gpio/consumer.h> | ||
31 | |||
32 | #include <linux/mmc/host.h> | ||
33 | |||
34 | #include "pwrseq.h" | ||
35 | |||
36 | struct mmc_pwrseq_sd8787 { | ||
37 | struct mmc_pwrseq pwrseq; | ||
38 | struct gpio_desc *reset_gpio; | ||
39 | struct gpio_desc *pwrdn_gpio; | ||
40 | }; | ||
41 | |||
42 | #define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787, pwrseq) | ||
43 | |||
44 | static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host) | ||
45 | { | ||
46 | struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq); | ||
47 | |||
48 | gpiod_set_value_cansleep(pwrseq->reset_gpio, 1); | ||
49 | |||
50 | msleep(300); | ||
51 | gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1); | ||
52 | } | ||
53 | |||
54 | static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host) | ||
55 | { | ||
56 | struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq); | ||
57 | |||
58 | gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0); | ||
59 | gpiod_set_value_cansleep(pwrseq->reset_gpio, 0); | ||
60 | } | ||
61 | |||
62 | static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = { | ||
63 | .pre_power_on = mmc_pwrseq_sd8787_pre_power_on, | ||
64 | .power_off = mmc_pwrseq_sd8787_power_off, | ||
65 | }; | ||
66 | |||
67 | static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = { | ||
68 | { .compatible = "mmc-pwrseq-sd8787",}, | ||
69 | {/* sentinel */}, | ||
70 | }; | ||
71 | MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match); | ||
72 | |||
73 | static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev) | ||
74 | { | ||
75 | struct mmc_pwrseq_sd8787 *pwrseq; | ||
76 | struct device *dev = &pdev->dev; | ||
77 | |||
78 | pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL); | ||
79 | if (!pwrseq) | ||
80 | return -ENOMEM; | ||
81 | |||
82 | pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); | ||
83 | if (IS_ERR(pwrseq->pwrdn_gpio)) | ||
84 | return PTR_ERR(pwrseq->pwrdn_gpio); | ||
85 | |||
86 | pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); | ||
87 | if (IS_ERR(pwrseq->reset_gpio)) | ||
88 | return PTR_ERR(pwrseq->reset_gpio); | ||
89 | |||
90 | pwrseq->pwrseq.dev = dev; | ||
91 | pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops; | ||
92 | pwrseq->pwrseq.owner = THIS_MODULE; | ||
93 | platform_set_drvdata(pdev, pwrseq); | ||
94 | |||
95 | return mmc_pwrseq_register(&pwrseq->pwrseq); | ||
96 | } | ||
97 | |||
98 | static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev) | ||
99 | { | ||
100 | struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev); | ||
101 | |||
102 | mmc_pwrseq_unregister(&pwrseq->pwrseq); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static struct platform_driver mmc_pwrseq_sd8787_driver = { | ||
108 | .probe = mmc_pwrseq_sd8787_probe, | ||
109 | .remove = mmc_pwrseq_sd8787_remove, | ||
110 | .driver = { | ||
111 | .name = "pwrseq_sd8787", | ||
112 | .of_match_table = mmc_pwrseq_sd8787_of_match, | ||
113 | }, | ||
114 | }; | ||
115 | |||
116 | module_platform_driver(mmc_pwrseq_sd8787_driver); | ||
117 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 033f641eb8b7..493eb10ce580 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c | |||
@@ -20,6 +20,8 @@ | |||
20 | 20 | ||
21 | #include "queue.h" | 21 | #include "queue.h" |
22 | #include "block.h" | 22 | #include "block.h" |
23 | #include "core.h" | ||
24 | #include "card.h" | ||
23 | 25 | ||
24 | #define MMC_QUEUE_BOUNCESZ 65536 | 26 | #define MMC_QUEUE_BOUNCESZ 65536 |
25 | 27 | ||
@@ -75,8 +77,8 @@ static int mmc_queue_thread(void *d) | |||
75 | set_current_state(TASK_RUNNING); | 77 | set_current_state(TASK_RUNNING); |
76 | mmc_blk_issue_rq(mq, req); | 78 | mmc_blk_issue_rq(mq, req); |
77 | cond_resched(); | 79 | cond_resched(); |
78 | if (mq->flags & MMC_QUEUE_NEW_REQUEST) { | 80 | if (mq->new_request) { |
79 | mq->flags &= ~MMC_QUEUE_NEW_REQUEST; | 81 | mq->new_request = false; |
80 | continue; /* fetch again */ | 82 | continue; /* fetch again */ |
81 | } | 83 | } |
82 | 84 | ||
@@ -143,7 +145,7 @@ static struct scatterlist *mmc_alloc_sg(int sg_len, int *err) | |||
143 | { | 145 | { |
144 | struct scatterlist *sg; | 146 | struct scatterlist *sg; |
145 | 147 | ||
146 | sg = kmalloc(sizeof(struct scatterlist)*sg_len, GFP_KERNEL); | 148 | sg = kmalloc_array(sg_len, sizeof(*sg), GFP_KERNEL); |
147 | if (!sg) | 149 | if (!sg) |
148 | *err = -ENOMEM; | 150 | *err = -ENOMEM; |
149 | else { | 151 | else { |
@@ -390,8 +392,8 @@ void mmc_queue_suspend(struct mmc_queue *mq) | |||
390 | struct request_queue *q = mq->queue; | 392 | struct request_queue *q = mq->queue; |
391 | unsigned long flags; | 393 | unsigned long flags; |
392 | 394 | ||
393 | if (!(mq->flags & MMC_QUEUE_SUSPENDED)) { | 395 | if (!mq->suspended) { |
394 | mq->flags |= MMC_QUEUE_SUSPENDED; | 396 | mq->suspended |= true; |
395 | 397 | ||
396 | spin_lock_irqsave(q->queue_lock, flags); | 398 | spin_lock_irqsave(q->queue_lock, flags); |
397 | blk_stop_queue(q); | 399 | blk_stop_queue(q); |
@@ -410,8 +412,8 @@ void mmc_queue_resume(struct mmc_queue *mq) | |||
410 | struct request_queue *q = mq->queue; | 412 | struct request_queue *q = mq->queue; |
411 | unsigned long flags; | 413 | unsigned long flags; |
412 | 414 | ||
413 | if (mq->flags & MMC_QUEUE_SUSPENDED) { | 415 | if (mq->suspended) { |
414 | mq->flags &= ~MMC_QUEUE_SUSPENDED; | 416 | mq->suspended = false; |
415 | 417 | ||
416 | up(&mq->thread_sem); | 418 | up(&mq->thread_sem); |
417 | 419 | ||
diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index dac8c3d010dd..e298f100101b 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h | |||
@@ -1,6 +1,11 @@ | |||
1 | #ifndef MMC_QUEUE_H | 1 | #ifndef MMC_QUEUE_H |
2 | #define MMC_QUEUE_H | 2 | #define MMC_QUEUE_H |
3 | 3 | ||
4 | #include <linux/types.h> | ||
5 | #include <linux/blkdev.h> | ||
6 | #include <linux/mmc/core.h> | ||
7 | #include <linux/mmc/host.h> | ||
8 | |||
4 | static inline bool mmc_req_is_special(struct request *req) | 9 | static inline bool mmc_req_is_special(struct request *req) |
5 | { | 10 | { |
6 | return req && | 11 | return req && |
@@ -9,7 +14,6 @@ static inline bool mmc_req_is_special(struct request *req) | |||
9 | req_op(req) == REQ_OP_SECURE_ERASE); | 14 | req_op(req) == REQ_OP_SECURE_ERASE); |
10 | } | 15 | } |
11 | 16 | ||
12 | struct request; | ||
13 | struct task_struct; | 17 | struct task_struct; |
14 | struct mmc_blk_data; | 18 | struct mmc_blk_data; |
15 | 19 | ||
@@ -29,16 +33,15 @@ struct mmc_queue_req { | |||
29 | char *bounce_buf; | 33 | char *bounce_buf; |
30 | struct scatterlist *bounce_sg; | 34 | struct scatterlist *bounce_sg; |
31 | unsigned int bounce_sg_len; | 35 | unsigned int bounce_sg_len; |
32 | struct mmc_async_req mmc_active; | 36 | struct mmc_async_req areq; |
33 | }; | 37 | }; |
34 | 38 | ||
35 | struct mmc_queue { | 39 | struct mmc_queue { |
36 | struct mmc_card *card; | 40 | struct mmc_card *card; |
37 | struct task_struct *thread; | 41 | struct task_struct *thread; |
38 | struct semaphore thread_sem; | 42 | struct semaphore thread_sem; |
39 | unsigned int flags; | 43 | bool new_request; |
40 | #define MMC_QUEUE_SUSPENDED (1 << 0) | 44 | bool suspended; |
41 | #define MMC_QUEUE_NEW_REQUEST (1 << 1) | ||
42 | bool asleep; | 45 | bool asleep; |
43 | struct mmc_blk_data *blkdata; | 46 | struct mmc_blk_data *blkdata; |
44 | struct request_queue *queue; | 47 | struct request_queue *queue; |
diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c deleted file mode 100644 index ca9cade317c7..000000000000 --- a/drivers/mmc/core/quirks.c +++ /dev/null | |||
@@ -1,83 +0,0 @@ | |||
1 | /* | ||
2 | * This file contains work-arounds for many known SD/MMC | ||
3 | * and SDIO hardware bugs. | ||
4 | * | ||
5 | * Copyright (c) 2011 Andrei Warkentin <andreiw@motorola.com> | ||
6 | * Copyright (c) 2011 Pierre Tardy <tardyp@gmail.com> | ||
7 | * Inspired from pci fixup code: | ||
8 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/mmc/card.h> | ||
16 | #include <linux/mmc/sdio_ids.h> | ||
17 | |||
18 | #ifndef SDIO_VENDOR_ID_TI | ||
19 | #define SDIO_VENDOR_ID_TI 0x0097 | ||
20 | #endif | ||
21 | |||
22 | #ifndef SDIO_DEVICE_ID_TI_WL1271 | ||
23 | #define SDIO_DEVICE_ID_TI_WL1271 0x4076 | ||
24 | #endif | ||
25 | |||
26 | #ifndef SDIO_VENDOR_ID_STE | ||
27 | #define SDIO_VENDOR_ID_STE 0x0020 | ||
28 | #endif | ||
29 | |||
30 | #ifndef SDIO_DEVICE_ID_STE_CW1200 | ||
31 | #define SDIO_DEVICE_ID_STE_CW1200 0x2280 | ||
32 | #endif | ||
33 | |||
34 | #ifndef SDIO_DEVICE_ID_MARVELL_8797_F0 | ||
35 | #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 | ||
36 | #endif | ||
37 | |||
38 | static const struct mmc_fixup mmc_fixup_methods[] = { | ||
39 | SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, | ||
40 | add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), | ||
41 | |||
42 | SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, | ||
43 | add_quirk, MMC_QUIRK_DISABLE_CD), | ||
44 | |||
45 | SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200, | ||
46 | add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512), | ||
47 | |||
48 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, | ||
49 | add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), | ||
50 | |||
51 | END_FIXUP | ||
52 | }; | ||
53 | |||
54 | void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) | ||
55 | { | ||
56 | const struct mmc_fixup *f; | ||
57 | u64 rev = cid_rev_card(card); | ||
58 | |||
59 | /* Non-core specific workarounds. */ | ||
60 | if (!table) | ||
61 | table = mmc_fixup_methods; | ||
62 | |||
63 | for (f = table; f->vendor_fixup; f++) { | ||
64 | if ((f->manfid == CID_MANFID_ANY || | ||
65 | f->manfid == card->cid.manfid) && | ||
66 | (f->oemid == CID_OEMID_ANY || | ||
67 | f->oemid == card->cid.oemid) && | ||
68 | (f->name == CID_NAME_ANY || | ||
69 | !strncmp(f->name, card->cid.prod_name, | ||
70 | sizeof(card->cid.prod_name))) && | ||
71 | (f->cis_vendor == card->cis.vendor || | ||
72 | f->cis_vendor == (u16) SDIO_ANY_ID) && | ||
73 | (f->cis_device == card->cis.device || | ||
74 | f->cis_device == (u16) SDIO_ANY_ID) && | ||
75 | (f->ext_csd_rev == EXT_CSD_REV_ANY || | ||
76 | f->ext_csd_rev == card->ext_csd.rev) && | ||
77 | rev >= f->rev_start && rev <= f->rev_end) { | ||
78 | dev_dbg(&card->dev, "calling %pf\n", f->vendor_fixup); | ||
79 | f->vendor_fixup(card, f->data); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | EXPORT_SYMBOL(mmc_fixup_device); | ||
diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h new file mode 100644 index 000000000000..fb725934fa21 --- /dev/null +++ b/drivers/mmc/core/quirks.h | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * This file contains work-arounds for many known SD/MMC | ||
3 | * and SDIO hardware bugs. | ||
4 | * | ||
5 | * Copyright (c) 2011 Andrei Warkentin <andreiw@motorola.com> | ||
6 | * Copyright (c) 2011 Pierre Tardy <tardyp@gmail.com> | ||
7 | * Inspired from pci fixup code: | ||
8 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/mmc/sdio_ids.h> | ||
13 | |||
14 | #include "card.h" | ||
15 | |||
16 | static const struct mmc_fixup mmc_blk_fixups[] = { | ||
17 | #define INAND_CMD38_ARG_EXT_CSD 113 | ||
18 | #define INAND_CMD38_ARG_ERASE 0x00 | ||
19 | #define INAND_CMD38_ARG_TRIM 0x01 | ||
20 | #define INAND_CMD38_ARG_SECERASE 0x80 | ||
21 | #define INAND_CMD38_ARG_SECTRIM1 0x81 | ||
22 | #define INAND_CMD38_ARG_SECTRIM2 0x88 | ||
23 | /* CMD38 argument is passed through EXT_CSD[113] */ | ||
24 | MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
25 | MMC_QUIRK_INAND_CMD38), | ||
26 | MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
27 | MMC_QUIRK_INAND_CMD38), | ||
28 | MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
29 | MMC_QUIRK_INAND_CMD38), | ||
30 | MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
31 | MMC_QUIRK_INAND_CMD38), | ||
32 | MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
33 | MMC_QUIRK_INAND_CMD38), | ||
34 | |||
35 | /* | ||
36 | * Some MMC cards experience performance degradation with CMD23 | ||
37 | * instead of CMD12-bounded multiblock transfers. For now we'll | ||
38 | * black list what's bad... | ||
39 | * - Certain Toshiba cards. | ||
40 | * | ||
41 | * N.B. This doesn't affect SD cards. | ||
42 | */ | ||
43 | MMC_FIXUP("SDMB-32", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, | ||
44 | MMC_QUIRK_BLK_NO_CMD23), | ||
45 | MMC_FIXUP("SDM032", CID_MANFID_SANDISK, CID_OEMID_ANY, add_quirk_mmc, | ||
46 | MMC_QUIRK_BLK_NO_CMD23), | ||
47 | MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
48 | MMC_QUIRK_BLK_NO_CMD23), | ||
49 | MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
50 | MMC_QUIRK_BLK_NO_CMD23), | ||
51 | MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
52 | MMC_QUIRK_BLK_NO_CMD23), | ||
53 | |||
54 | /* | ||
55 | * Some MMC cards need longer data read timeout than indicated in CSD. | ||
56 | */ | ||
57 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, | ||
58 | MMC_QUIRK_LONG_READ_TIME), | ||
59 | MMC_FIXUP("008GE0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, | ||
60 | MMC_QUIRK_LONG_READ_TIME), | ||
61 | |||
62 | /* | ||
63 | * On these Samsung MoviNAND parts, performing secure erase or | ||
64 | * secure trim can result in unrecoverable corruption due to a | ||
65 | * firmware bug. | ||
66 | */ | ||
67 | MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
68 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
69 | MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
70 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
71 | MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
72 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
73 | MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
74 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
75 | MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
76 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
77 | MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
78 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
79 | MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
80 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
81 | MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
82 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
83 | |||
84 | /* | ||
85 | * On Some Kingston eMMCs, performing trim can result in | ||
86 | * unrecoverable data conrruption occasionally due to a firmware bug. | ||
87 | */ | ||
88 | MMC_FIXUP("V10008", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, | ||
89 | MMC_QUIRK_TRIM_BROKEN), | ||
90 | MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc, | ||
91 | MMC_QUIRK_TRIM_BROKEN), | ||
92 | |||
93 | END_FIXUP | ||
94 | }; | ||
95 | |||
96 | static const struct mmc_fixup mmc_ext_csd_fixups[] = { | ||
97 | /* | ||
98 | * Certain Hynix eMMC 4.41 cards might get broken when HPI feature | ||
99 | * is used so disable the HPI feature for such buggy cards. | ||
100 | */ | ||
101 | MMC_FIXUP_EXT_CSD_REV(CID_NAME_ANY, CID_MANFID_HYNIX, | ||
102 | 0x014a, add_quirk, MMC_QUIRK_BROKEN_HPI, 5), | ||
103 | |||
104 | END_FIXUP | ||
105 | }; | ||
106 | |||
107 | static const struct mmc_fixup sdio_fixup_methods[] = { | ||
108 | SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, | ||
109 | add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), | ||
110 | |||
111 | SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, | ||
112 | add_quirk, MMC_QUIRK_DISABLE_CD), | ||
113 | |||
114 | SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200, | ||
115 | add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512), | ||
116 | |||
117 | SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, | ||
118 | add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), | ||
119 | |||
120 | END_FIXUP | ||
121 | }; | ||
122 | |||
123 | static inline void mmc_fixup_device(struct mmc_card *card, | ||
124 | const struct mmc_fixup *table) | ||
125 | { | ||
126 | const struct mmc_fixup *f; | ||
127 | u64 rev = cid_rev_card(card); | ||
128 | |||
129 | for (f = table; f->vendor_fixup; f++) { | ||
130 | if ((f->manfid == CID_MANFID_ANY || | ||
131 | f->manfid == card->cid.manfid) && | ||
132 | (f->oemid == CID_OEMID_ANY || | ||
133 | f->oemid == card->cid.oemid) && | ||
134 | (f->name == CID_NAME_ANY || | ||
135 | !strncmp(f->name, card->cid.prod_name, | ||
136 | sizeof(card->cid.prod_name))) && | ||
137 | (f->cis_vendor == card->cis.vendor || | ||
138 | f->cis_vendor == (u16) SDIO_ANY_ID) && | ||
139 | (f->cis_device == card->cis.device || | ||
140 | f->cis_device == (u16) SDIO_ANY_ID) && | ||
141 | (f->ext_csd_rev == EXT_CSD_REV_ANY || | ||
142 | f->ext_csd_rev == card->ext_csd.rev) && | ||
143 | rev >= f->rev_start && rev <= f->rev_end) { | ||
144 | dev_dbg(&card->dev, "calling %pf\n", f->vendor_fixup); | ||
145 | f->vendor_fixup(card, f->data); | ||
146 | } | ||
147 | } | ||
148 | } | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index a614f37faf27..89531b48ae84 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/mmc/sd.h> | 22 | #include <linux/mmc/sd.h> |
23 | 23 | ||
24 | #include "core.h" | 24 | #include "core.h" |
25 | #include "card.h" | ||
26 | #include "host.h" | ||
25 | #include "bus.h" | 27 | #include "bus.h" |
26 | #include "mmc_ops.h" | 28 | #include "mmc_ops.h" |
27 | #include "sd.h" | 29 | #include "sd.h" |
@@ -786,8 +788,7 @@ try_again: | |||
786 | */ | 788 | */ |
787 | if (!mmc_host_is_spi(host) && rocr && | 789 | if (!mmc_host_is_spi(host) && rocr && |
788 | ((*rocr & 0x41000000) == 0x41000000)) { | 790 | ((*rocr & 0x41000000) == 0x41000000)) { |
789 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, | 791 | err = mmc_set_uhs_voltage(host, pocr); |
790 | pocr); | ||
791 | if (err == -EAGAIN) { | 792 | if (err == -EAGAIN) { |
792 | retries--; | 793 | retries--; |
793 | goto try_again; | 794 | goto try_again; |
diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h index aab824a9a7f3..1ada9808c329 100644 --- a/drivers/mmc/core/sd.h +++ b/drivers/mmc/core/sd.h | |||
@@ -1,10 +1,13 @@ | |||
1 | #ifndef _MMC_CORE_SD_H | 1 | #ifndef _MMC_CORE_SD_H |
2 | #define _MMC_CORE_SD_H | 2 | #define _MMC_CORE_SD_H |
3 | 3 | ||
4 | #include <linux/mmc/card.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | extern struct device_type sd_type; | 6 | extern struct device_type sd_type; |
7 | 7 | ||
8 | struct mmc_host; | ||
9 | struct mmc_card; | ||
10 | |||
8 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); | 11 | int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); |
9 | int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); | 12 | int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); |
10 | void mmc_decode_cid(struct mmc_card *card); | 13 | void mmc_decode_cid(struct mmc_card *card); |
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c index de125a41aa7a..9d5824a37586 100644 --- a/drivers/mmc/core/sd_ops.c +++ b/drivers/mmc/core/sd_ops.c | |||
@@ -25,7 +25,7 @@ | |||
25 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) | 25 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) |
26 | { | 26 | { |
27 | int err; | 27 | int err; |
28 | struct mmc_command cmd = {0}; | 28 | struct mmc_command cmd = {}; |
29 | 29 | ||
30 | if (WARN_ON(card && card->host != host)) | 30 | if (WARN_ON(card && card->host != host)) |
31 | return -EINVAL; | 31 | return -EINVAL; |
@@ -68,7 +68,7 @@ EXPORT_SYMBOL_GPL(mmc_app_cmd); | |||
68 | int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | 68 | int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, |
69 | struct mmc_command *cmd, int retries) | 69 | struct mmc_command *cmd, int retries) |
70 | { | 70 | { |
71 | struct mmc_request mrq = {NULL}; | 71 | struct mmc_request mrq = {}; |
72 | 72 | ||
73 | int i, err; | 73 | int i, err; |
74 | 74 | ||
@@ -120,7 +120,7 @@ EXPORT_SYMBOL(mmc_wait_for_app_cmd); | |||
120 | 120 | ||
121 | int mmc_app_set_bus_width(struct mmc_card *card, int width) | 121 | int mmc_app_set_bus_width(struct mmc_card *card, int width) |
122 | { | 122 | { |
123 | struct mmc_command cmd = {0}; | 123 | struct mmc_command cmd = {}; |
124 | 124 | ||
125 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | 125 | cmd.opcode = SD_APP_SET_BUS_WIDTH; |
126 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; | 126 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
@@ -141,7 +141,7 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width) | |||
141 | 141 | ||
142 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | 142 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) |
143 | { | 143 | { |
144 | struct mmc_command cmd = {0}; | 144 | struct mmc_command cmd = {}; |
145 | int i, err = 0; | 145 | int i, err = 0; |
146 | 146 | ||
147 | cmd.opcode = SD_APP_OP_COND; | 147 | cmd.opcode = SD_APP_OP_COND; |
@@ -185,7 +185,7 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
185 | 185 | ||
186 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | 186 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr) |
187 | { | 187 | { |
188 | struct mmc_command cmd = {0}; | 188 | struct mmc_command cmd = {}; |
189 | int err; | 189 | int err; |
190 | static const u8 test_pattern = 0xAA; | 190 | static const u8 test_pattern = 0xAA; |
191 | u8 result_pattern; | 191 | u8 result_pattern; |
@@ -217,7 +217,7 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr) | |||
217 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | 217 | int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) |
218 | { | 218 | { |
219 | int err; | 219 | int err; |
220 | struct mmc_command cmd = {0}; | 220 | struct mmc_command cmd = {}; |
221 | 221 | ||
222 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | 222 | cmd.opcode = SD_SEND_RELATIVE_ADDR; |
223 | cmd.arg = 0; | 223 | cmd.arg = 0; |
@@ -235,9 +235,9 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) | |||
235 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | 235 | int mmc_app_send_scr(struct mmc_card *card, u32 *scr) |
236 | { | 236 | { |
237 | int err; | 237 | int err; |
238 | struct mmc_request mrq = {NULL}; | 238 | struct mmc_request mrq = {}; |
239 | struct mmc_command cmd = {0}; | 239 | struct mmc_command cmd = {}; |
240 | struct mmc_data data = {0}; | 240 | struct mmc_data data = {}; |
241 | struct scatterlist sg; | 241 | struct scatterlist sg; |
242 | void *data_buf; | 242 | void *data_buf; |
243 | 243 | ||
@@ -290,9 +290,9 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr) | |||
290 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | 290 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, |
291 | u8 value, u8 *resp) | 291 | u8 value, u8 *resp) |
292 | { | 292 | { |
293 | struct mmc_request mrq = {NULL}; | 293 | struct mmc_request mrq = {}; |
294 | struct mmc_command cmd = {0}; | 294 | struct mmc_command cmd = {}; |
295 | struct mmc_data data = {0}; | 295 | struct mmc_data data = {}; |
296 | struct scatterlist sg; | 296 | struct scatterlist sg; |
297 | 297 | ||
298 | /* NOTE: caller guarantees resp is heap-allocated */ | 298 | /* NOTE: caller guarantees resp is heap-allocated */ |
@@ -332,9 +332,9 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group, | |||
332 | int mmc_app_sd_status(struct mmc_card *card, void *ssr) | 332 | int mmc_app_sd_status(struct mmc_card *card, void *ssr) |
333 | { | 333 | { |
334 | int err; | 334 | int err; |
335 | struct mmc_request mrq = {NULL}; | 335 | struct mmc_request mrq = {}; |
336 | struct mmc_command cmd = {0}; | 336 | struct mmc_command cmd = {}; |
337 | struct mmc_data data = {0}; | 337 | struct mmc_data data = {}; |
338 | struct scatterlist sg; | 338 | struct scatterlist sg; |
339 | 339 | ||
340 | /* NOTE: caller guarantees ssr is heap-allocated */ | 340 | /* NOTE: caller guarantees ssr is heap-allocated */ |
diff --git a/drivers/mmc/core/sd_ops.h b/drivers/mmc/core/sd_ops.h index ffc2305d905f..784f8e6b6baa 100644 --- a/drivers/mmc/core/sd_ops.h +++ b/drivers/mmc/core/sd_ops.h | |||
@@ -12,6 +12,12 @@ | |||
12 | #ifndef _MMC_SD_OPS_H | 12 | #ifndef _MMC_SD_OPS_H |
13 | #define _MMC_SD_OPS_H | 13 | #define _MMC_SD_OPS_H |
14 | 14 | ||
15 | #include <linux/types.h> | ||
16 | |||
17 | struct mmc_card; | ||
18 | struct mmc_host; | ||
19 | struct mmc_command; | ||
20 | |||
15 | int mmc_app_set_bus_width(struct mmc_card *card, int width); | 21 | int mmc_app_set_bus_width(struct mmc_card *card, int width); |
16 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | 22 | int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); |
17 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr); | 23 | int mmc_send_if_cond(struct mmc_host *host, u32 ocr); |
@@ -20,6 +26,9 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr); | |||
20 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, | 26 | int mmc_sd_switch(struct mmc_card *card, int mode, int group, |
21 | u8 value, u8 *resp); | 27 | u8 value, u8 *resp); |
22 | int mmc_app_sd_status(struct mmc_card *card, void *ssr); | 28 | int mmc_app_sd_status(struct mmc_card *card, void *ssr); |
29 | int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); | ||
30 | int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, | ||
31 | struct mmc_command *cmd, int retries); | ||
23 | 32 | ||
24 | #endif | 33 | #endif |
25 | 34 | ||
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index ecbc52981ba5..fae732c870a9 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -20,7 +20,10 @@ | |||
20 | #include <linux/mmc/sdio_ids.h> | 20 | #include <linux/mmc/sdio_ids.h> |
21 | 21 | ||
22 | #include "core.h" | 22 | #include "core.h" |
23 | #include "card.h" | ||
24 | #include "host.h" | ||
23 | #include "bus.h" | 25 | #include "bus.h" |
26 | #include "quirks.h" | ||
24 | #include "sd.h" | 27 | #include "sd.h" |
25 | #include "sdio_bus.h" | 28 | #include "sdio_bus.h" |
26 | #include "mmc_ops.h" | 29 | #include "mmc_ops.h" |
@@ -541,6 +544,15 @@ out: | |||
541 | return err; | 544 | return err; |
542 | } | 545 | } |
543 | 546 | ||
547 | static void mmc_sdio_resend_if_cond(struct mmc_host *host, | ||
548 | struct mmc_card *card) | ||
549 | { | ||
550 | sdio_reset(host); | ||
551 | mmc_go_idle(host); | ||
552 | mmc_send_if_cond(host, host->ocr_avail); | ||
553 | mmc_remove_card(card); | ||
554 | } | ||
555 | |||
544 | /* | 556 | /* |
545 | * Handle the detection and initialisation of a card. | 557 | * Handle the detection and initialisation of a card. |
546 | * | 558 | * |
@@ -624,24 +636,21 @@ try_again: | |||
624 | * to switch to 1.8V signaling level. No 1.8v signalling if | 636 | * to switch to 1.8V signaling level. No 1.8v signalling if |
625 | * UHS mode is not enabled to maintain compatibility and some | 637 | * UHS mode is not enabled to maintain compatibility and some |
626 | * systems that claim 1.8v signalling in fact do not support | 638 | * systems that claim 1.8v signalling in fact do not support |
627 | * it. | 639 | * it. Per SDIO spec v3, section 3.1.2, if the voltage is already |
640 | * 1.8v, the card sets S18A to 0 in the R4 response. So it will | ||
641 | * fails to check rocr & R4_18V_PRESENT, but we still need to | ||
642 | * try to init uhs card. sdio_read_cccr will take over this task | ||
643 | * to make sure which speed mode should work. | ||
628 | */ | 644 | */ |
629 | if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) { | 645 | if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) { |
630 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, | 646 | err = mmc_set_uhs_voltage(host, ocr_card); |
631 | ocr_card); | ||
632 | if (err == -EAGAIN) { | 647 | if (err == -EAGAIN) { |
633 | sdio_reset(host); | 648 | mmc_sdio_resend_if_cond(host, card); |
634 | mmc_go_idle(host); | ||
635 | mmc_send_if_cond(host, host->ocr_avail); | ||
636 | mmc_remove_card(card); | ||
637 | retries--; | 649 | retries--; |
638 | goto try_again; | 650 | goto try_again; |
639 | } else if (err) { | 651 | } else if (err) { |
640 | ocr &= ~R4_18V_PRESENT; | 652 | ocr &= ~R4_18V_PRESENT; |
641 | } | 653 | } |
642 | err = 0; | ||
643 | } else { | ||
644 | ocr &= ~R4_18V_PRESENT; | ||
645 | } | 654 | } |
646 | 655 | ||
647 | /* | 656 | /* |
@@ -698,11 +707,20 @@ try_again: | |||
698 | } | 707 | } |
699 | 708 | ||
700 | /* | 709 | /* |
701 | * Read the common registers. | 710 | * Read the common registers. Note that we should try to |
711 | * validate whether UHS would work or not. | ||
702 | */ | 712 | */ |
703 | err = sdio_read_cccr(card, ocr); | 713 | err = sdio_read_cccr(card, ocr); |
704 | if (err) | 714 | if (err) { |
705 | goto remove; | 715 | mmc_sdio_resend_if_cond(host, card); |
716 | if (ocr & R4_18V_PRESENT) { | ||
717 | /* Retry init sequence, but without R4_18V_PRESENT. */ | ||
718 | retries = 0; | ||
719 | goto try_again; | ||
720 | } else { | ||
721 | goto remove; | ||
722 | } | ||
723 | } | ||
706 | 724 | ||
707 | /* | 725 | /* |
708 | * Read the common CIS tuples. | 726 | * Read the common CIS tuples. |
@@ -721,7 +739,7 @@ try_again: | |||
721 | card = oldcard; | 739 | card = oldcard; |
722 | } | 740 | } |
723 | card->ocr = ocr_card; | 741 | card->ocr = ocr_card; |
724 | mmc_fixup_device(card, NULL); | 742 | mmc_fixup_device(card, sdio_fixup_methods); |
725 | 743 | ||
726 | if (card->type == MMC_TYPE_SD_COMBO) { | 744 | if (card->type == MMC_TYPE_SD_COMBO) { |
727 | err = mmc_sd_setup_card(host, card, oldcard != NULL); | 745 | err = mmc_sd_setup_card(host, card, oldcard != NULL); |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 86f5b3223aae..e992a7f8a16f 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | 26 | ||
27 | #include "core.h" | 27 | #include "core.h" |
28 | #include "card.h" | ||
28 | #include "sdio_cis.h" | 29 | #include "sdio_cis.h" |
29 | #include "sdio_bus.h" | 30 | #include "sdio_bus.h" |
30 | 31 | ||
diff --git a/drivers/mmc/core/sdio_bus.h b/drivers/mmc/core/sdio_bus.h index 567a76821ba7..b69a2540a076 100644 --- a/drivers/mmc/core/sdio_bus.h +++ b/drivers/mmc/core/sdio_bus.h | |||
@@ -11,6 +11,9 @@ | |||
11 | #ifndef _MMC_CORE_SDIO_BUS_H | 11 | #ifndef _MMC_CORE_SDIO_BUS_H |
12 | #define _MMC_CORE_SDIO_BUS_H | 12 | #define _MMC_CORE_SDIO_BUS_H |
13 | 13 | ||
14 | struct mmc_card; | ||
15 | struct sdio_func; | ||
16 | |||
14 | struct sdio_func *sdio_alloc_func(struct mmc_card *card); | 17 | struct sdio_func *sdio_alloc_func(struct mmc_card *card); |
15 | int sdio_add_func(struct sdio_func *func); | 18 | int sdio_add_func(struct sdio_func *func); |
16 | void sdio_remove_func(struct sdio_func *func); | 19 | void sdio_remove_func(struct sdio_func *func); |
diff --git a/drivers/mmc/core/sdio_cis.h b/drivers/mmc/core/sdio_cis.h index 4d903c2e425e..16aa563faa00 100644 --- a/drivers/mmc/core/sdio_cis.h +++ b/drivers/mmc/core/sdio_cis.h | |||
@@ -14,6 +14,9 @@ | |||
14 | #ifndef _MMC_SDIO_CIS_H | 14 | #ifndef _MMC_SDIO_CIS_H |
15 | #define _MMC_SDIO_CIS_H | 15 | #define _MMC_SDIO_CIS_H |
16 | 16 | ||
17 | struct mmc_card; | ||
18 | struct sdio_func; | ||
19 | |||
17 | int sdio_read_common_cis(struct mmc_card *card); | 20 | int sdio_read_common_cis(struct mmc_card *card); |
18 | void sdio_free_common_cis(struct mmc_card *card); | 21 | void sdio_free_common_cis(struct mmc_card *card); |
19 | 22 | ||
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 406e5f037e32..74195d772f5a 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/mmc/sdio_func.h> | 16 | #include <linux/mmc/sdio_func.h> |
17 | 17 | ||
18 | #include "sdio_ops.h" | 18 | #include "sdio_ops.h" |
19 | #include "core.h" | ||
20 | #include "card.h" | ||
19 | 21 | ||
20 | /** | 22 | /** |
21 | * sdio_claim_host - exclusively claim a bus for a certain SDIO function | 23 | * sdio_claim_host - exclusively claim a bus for a certain SDIO function |
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index f1faf9acc007..d29faf2addfe 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mmc/sdio_func.h> | 27 | #include <linux/mmc/sdio_func.h> |
28 | 28 | ||
29 | #include "sdio_ops.h" | 29 | #include "sdio_ops.h" |
30 | #include "core.h" | ||
31 | #include "card.h" | ||
30 | 32 | ||
31 | static int process_sdio_pending_irqs(struct mmc_host *host) | 33 | static int process_sdio_pending_irqs(struct mmc_host *host) |
32 | { | 34 | { |
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index 90fe5545c677..3c0d3ab4324c 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | 22 | int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) |
23 | { | 23 | { |
24 | struct mmc_command cmd = {0}; | 24 | struct mmc_command cmd = {}; |
25 | int i, err = 0; | 25 | int i, err = 0; |
26 | 26 | ||
27 | cmd.opcode = SD_IO_SEND_OP_COND; | 27 | cmd.opcode = SD_IO_SEND_OP_COND; |
@@ -66,7 +66,7 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
66 | static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn, | 66 | static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn, |
67 | unsigned addr, u8 in, u8 *out) | 67 | unsigned addr, u8 in, u8 *out) |
68 | { | 68 | { |
69 | struct mmc_command cmd = {0}; | 69 | struct mmc_command cmd = {}; |
70 | int err; | 70 | int err; |
71 | 71 | ||
72 | if (fn > 7) | 72 | if (fn > 7) |
@@ -118,9 +118,9 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
118 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 118 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
119 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) | 119 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) |
120 | { | 120 | { |
121 | struct mmc_request mrq = {NULL}; | 121 | struct mmc_request mrq = {}; |
122 | struct mmc_command cmd = {0}; | 122 | struct mmc_command cmd = {}; |
123 | struct mmc_data data = {0}; | 123 | struct mmc_data data = {}; |
124 | struct scatterlist sg, *sg_ptr; | 124 | struct scatterlist sg, *sg_ptr; |
125 | struct sg_table sgtable; | 125 | struct sg_table sgtable; |
126 | unsigned int nents, left_size, i; | 126 | unsigned int nents, left_size, i; |
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index 5660c7f459e9..bed8a8377fec 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h | |||
@@ -12,14 +12,19 @@ | |||
12 | #ifndef _MMC_SDIO_OPS_H | 12 | #ifndef _MMC_SDIO_OPS_H |
13 | #define _MMC_SDIO_OPS_H | 13 | #define _MMC_SDIO_OPS_H |
14 | 14 | ||
15 | #include <linux/types.h> | ||
15 | #include <linux/mmc/sdio.h> | 16 | #include <linux/mmc/sdio.h> |
16 | 17 | ||
18 | struct mmc_host; | ||
19 | struct mmc_card; | ||
20 | |||
17 | int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); | 21 | int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); |
18 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | 22 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, |
19 | unsigned addr, u8 in, u8* out); | 23 | unsigned addr, u8 in, u8* out); |
20 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 24 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
21 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); | 25 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); |
22 | int sdio_reset(struct mmc_host *host); | 26 | int sdio_reset(struct mmc_host *host); |
27 | unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz); | ||
23 | 28 | ||
24 | static inline bool mmc_is_io_op(u32 opcode) | 29 | static inline bool mmc_is_io_op(u32 opcode) |
25 | { | 30 | { |
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index babe591aea96..a8450a8701e4 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c | |||
@@ -235,9 +235,6 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | |||
235 | struct gpio_desc *desc; | 235 | struct gpio_desc *desc; |
236 | int ret; | 236 | int ret; |
237 | 237 | ||
238 | if (!con_id) | ||
239 | con_id = ctx->cd_label; | ||
240 | |||
241 | desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN); | 238 | desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN); |
242 | if (IS_ERR(desc)) | 239 | if (IS_ERR(desc)) |
243 | return PTR_ERR(desc); | 240 | return PTR_ERR(desc); |
@@ -289,9 +286,6 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, | |||
289 | struct gpio_desc *desc; | 286 | struct gpio_desc *desc; |
290 | int ret; | 287 | int ret; |
291 | 288 | ||
292 | if (!con_id) | ||
293 | con_id = ctx->ro_label; | ||
294 | |||
295 | desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN); | 289 | desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN); |
296 | if (IS_ERR(desc)) | 290 | if (IS_ERR(desc)) |
297 | return PTR_ERR(desc); | 291 | return PTR_ERR(desc); |
diff --git a/drivers/mmc/core/slot-gpio.h b/drivers/mmc/core/slot-gpio.h index 8c1854dc5d58..a06fd843f025 100644 --- a/drivers/mmc/core/slot-gpio.h +++ b/drivers/mmc/core/slot-gpio.h | |||
@@ -8,6 +8,8 @@ | |||
8 | #ifndef _MMC_CORE_SLOTGPIO_H | 8 | #ifndef _MMC_CORE_SLOTGPIO_H |
9 | #define _MMC_CORE_SLOTGPIO_H | 9 | #define _MMC_CORE_SLOTGPIO_H |
10 | 10 | ||
11 | struct mmc_host; | ||
12 | |||
11 | int mmc_gpio_alloc(struct mmc_host *host); | 13 | int mmc_gpio_alloc(struct mmc_host *host); |
12 | 14 | ||
13 | #endif | 15 | #endif |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 2eb97014dc3f..f08691a58d7e 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -683,6 +683,15 @@ config MMC_DW_ROCKCHIP | |||
683 | Synopsys DesignWare Memory Card Interface driver. Select this option | 683 | Synopsys DesignWare Memory Card Interface driver. Select this option |
684 | for platforms based on RK3066, RK3188 and RK3288 SoC's. | 684 | for platforms based on RK3066, RK3188 and RK3288 SoC's. |
685 | 685 | ||
686 | config MMC_DW_ZX | ||
687 | tristate "ZTE specific extensions for Synopsys DW Memory Card Interface" | ||
688 | depends on MMC_DW && ARCH_ZX | ||
689 | select MMC_DW_PLTFM | ||
690 | help | ||
691 | This selects support for ZTE SoC specific extensions to the | ||
692 | Synopsys DesignWare Memory Card Interface driver. Select this option | ||
693 | for platforms based on ZX296718 SoC's. | ||
694 | |||
686 | config MMC_SH_MMCIF | 695 | config MMC_SH_MMCIF |
687 | tristate "SuperH Internal MMCIF support" | 696 | tristate "SuperH Internal MMCIF support" |
688 | depends on HAS_DMA | 697 | depends on HAS_DMA |
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index ccc9c4cba154..6d548c4ee2fa 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o | |||
48 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o | 48 | obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o |
49 | obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o | 49 | obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o |
50 | obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o | 50 | obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o |
51 | obj-$(CONFIG_MMC_DW_ZX) += dw_mmc-zx.o | ||
51 | obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o | 52 | obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o |
52 | obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o | 53 | obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o |
53 | obj-$(CONFIG_MMC_VUB300) += vub300.o | 54 | obj-$(CONFIG_MMC_VUB300) += vub300.o |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 36b5af8eadb8..1e2600da105f 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/of.h> | 36 | #include <linux/of.h> |
37 | #include <linux/of_device.h> | 37 | #include <linux/of_device.h> |
38 | #include <linux/mmc/slot-gpio.h> | 38 | #include <linux/mmc/slot-gpio.h> |
39 | #include <linux/interrupt.h> | ||
39 | 40 | ||
40 | #include <linux/platform_data/mmc-davinci.h> | 41 | #include <linux/platform_data/mmc-davinci.h> |
41 | 42 | ||
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index e1335289316c..25691cca1881 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/mmc/host.h> | 15 | #include <linux/mmc/host.h> |
16 | #include <linux/mmc/dw_mmc.h> | ||
17 | #include <linux/mmc/mmc.h> | 16 | #include <linux/mmc/mmc.h> |
18 | #include <linux/of.h> | 17 | #include <linux/of.h> |
19 | #include <linux/of_gpio.h> | 18 | #include <linux/of_gpio.h> |
diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 9821e6bd5d5e..e38fb0020bb1 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
12 | #include <linux/mfd/syscon.h> | 12 | #include <linux/mfd/syscon.h> |
13 | #include <linux/mmc/host.h> | 13 | #include <linux/mmc/host.h> |
14 | #include <linux/mmc/dw_mmc.h> | ||
15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
16 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
diff --git a/drivers/mmc/host/dw_mmc-pci.c b/drivers/mmc/host/dw_mmc-pci.c index ab82796b01e2..ab8713297edb 100644 --- a/drivers/mmc/host/dw_mmc-pci.c +++ b/drivers/mmc/host/dw_mmc-pci.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
20 | #include <linux/mmc/mmc.h> | 20 | #include <linux/mmc/mmc.h> |
21 | #include <linux/mmc/dw_mmc.h> | ||
22 | #include "dw_mmc.h" | 21 | #include "dw_mmc.h" |
23 | 22 | ||
24 | #define PCI_BAR_NO 2 | 23 | #define PCI_BAR_NO 2 |
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 1236d49ba36e..58c13e21bd5a 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
22 | #include <linux/mmc/mmc.h> | 22 | #include <linux/mmc/mmc.h> |
23 | #include <linux/mmc/dw_mmc.h> | ||
24 | #include <linux/of.h> | 23 | #include <linux/of.h> |
25 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
26 | 25 | ||
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 9a46e4694227..372fb6e948c1 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
13 | #include <linux/mmc/host.h> | 13 | #include <linux/mmc/host.h> |
14 | #include <linux/mmc/dw_mmc.h> | ||
15 | #include <linux/of_address.h> | 14 | #include <linux/of_address.h> |
16 | #include <linux/mmc/slot-gpio.h> | 15 | #include <linux/mmc/slot-gpio.h> |
17 | #include <linux/pm_runtime.h> | 16 | #include <linux/pm_runtime.h> |
diff --git a/drivers/mmc/host/dw_mmc-zx.c b/drivers/mmc/host/dw_mmc-zx.c new file mode 100644 index 000000000000..d38e94ae2b85 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-zx.c | |||
@@ -0,0 +1,241 @@ | |||
1 | /* | ||
2 | * ZX Specific Extensions for Synopsys DW Multimedia Card Interface driver | ||
3 | * | ||
4 | * Copyright (C) 2016, Linaro Ltd. | ||
5 | * Copyright (C) 2016, ZTE Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk.h> | ||
14 | #include <linux/mfd/syscon.h> | ||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/mmc/mmc.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/pm_runtime.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #include "dw_mmc.h" | ||
25 | #include "dw_mmc-pltfm.h" | ||
26 | #include "dw_mmc-zx.h" | ||
27 | |||
28 | struct dw_mci_zx_priv_data { | ||
29 | struct regmap *sysc_base; | ||
30 | }; | ||
31 | |||
32 | enum delay_type { | ||
33 | DELAY_TYPE_READ, /* read dqs delay */ | ||
34 | DELAY_TYPE_CLK, /* clk sample delay */ | ||
35 | }; | ||
36 | |||
37 | static int dw_mci_zx_emmc_set_delay(struct dw_mci *host, unsigned int delay, | ||
38 | enum delay_type dflag) | ||
39 | { | ||
40 | struct dw_mci_zx_priv_data *priv = host->priv; | ||
41 | struct regmap *sysc_base = priv->sysc_base; | ||
42 | unsigned int clksel; | ||
43 | unsigned int loop = 1000; | ||
44 | int ret; | ||
45 | |||
46 | if (!sysc_base) | ||
47 | return -EINVAL; | ||
48 | |||
49 | ret = regmap_update_bits(sysc_base, LB_AON_EMMC_CFG_REG0, | ||
50 | PARA_HALF_CLK_MODE | PARA_DLL_BYPASS_MODE | | ||
51 | PARA_PHASE_DET_SEL_MASK | | ||
52 | PARA_DLL_LOCK_NUM_MASK | | ||
53 | DLL_REG_SET | PARA_DLL_START_MASK, | ||
54 | PARA_DLL_START(4) | PARA_DLL_LOCK_NUM(4)); | ||
55 | if (ret) | ||
56 | return ret; | ||
57 | |||
58 | ret = regmap_read(sysc_base, LB_AON_EMMC_CFG_REG1, &clksel); | ||
59 | if (ret) | ||
60 | return ret; | ||
61 | |||
62 | if (dflag == DELAY_TYPE_CLK) { | ||
63 | clksel &= ~CLK_SAMP_DELAY_MASK; | ||
64 | clksel |= CLK_SAMP_DELAY(delay); | ||
65 | } else { | ||
66 | clksel &= ~READ_DQS_DELAY_MASK; | ||
67 | clksel |= READ_DQS_DELAY(delay); | ||
68 | } | ||
69 | |||
70 | regmap_write(sysc_base, LB_AON_EMMC_CFG_REG1, clksel); | ||
71 | regmap_update_bits(sysc_base, LB_AON_EMMC_CFG_REG0, | ||
72 | PARA_DLL_START_MASK | PARA_DLL_LOCK_NUM_MASK | | ||
73 | DLL_REG_SET, | ||
74 | PARA_DLL_START(4) | PARA_DLL_LOCK_NUM(4) | | ||
75 | DLL_REG_SET); | ||
76 | |||
77 | do { | ||
78 | ret = regmap_read(sysc_base, LB_AON_EMMC_CFG_REG2, &clksel); | ||
79 | if (ret) | ||
80 | return ret; | ||
81 | |||
82 | } while (--loop && !(clksel & ZX_DLL_LOCKED)); | ||
83 | |||
84 | if (!loop) { | ||
85 | dev_err(host->dev, "Error: %s dll lock fail\n", __func__); | ||
86 | return -EIO; | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int dw_mci_zx_emmc_execute_tuning(struct dw_mci_slot *slot, u32 opcode) | ||
93 | { | ||
94 | struct dw_mci *host = slot->host; | ||
95 | struct mmc_host *mmc = slot->mmc; | ||
96 | int ret, len = 0, start = 0, end = 0, delay, best = 0; | ||
97 | |||
98 | for (delay = 1; delay < 128; delay++) { | ||
99 | ret = dw_mci_zx_emmc_set_delay(host, delay, DELAY_TYPE_CLK); | ||
100 | if (!ret && mmc_send_tuning(mmc, opcode, NULL)) { | ||
101 | if (start >= 0) { | ||
102 | end = delay - 1; | ||
103 | /* check and update longest good range */ | ||
104 | if ((end - start) > len) { | ||
105 | best = (start + end) >> 1; | ||
106 | len = end - start; | ||
107 | } | ||
108 | } | ||
109 | start = -1; | ||
110 | end = 0; | ||
111 | continue; | ||
112 | } | ||
113 | if (start < 0) | ||
114 | start = delay; | ||
115 | } | ||
116 | |||
117 | if (start >= 0) { | ||
118 | end = delay - 1; | ||
119 | if ((end - start) > len) { | ||
120 | best = (start + end) >> 1; | ||
121 | len = end - start; | ||
122 | } | ||
123 | } | ||
124 | if (best < 0) | ||
125 | return -EIO; | ||
126 | |||
127 | dev_info(host->dev, "%s best range: start %d end %d\n", __func__, | ||
128 | start, end); | ||
129 | return dw_mci_zx_emmc_set_delay(host, best, DELAY_TYPE_CLK); | ||
130 | } | ||
131 | |||
132 | static int dw_mci_zx_prepare_hs400_tuning(struct dw_mci *host, | ||
133 | struct mmc_ios *ios) | ||
134 | { | ||
135 | int ret; | ||
136 | |||
137 | /* config phase shift as 90 degree */ | ||
138 | ret = dw_mci_zx_emmc_set_delay(host, 32, DELAY_TYPE_READ); | ||
139 | if (ret < 0) | ||
140 | return -EIO; | ||
141 | |||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int dw_mci_zx_execute_tuning(struct dw_mci_slot *slot, u32 opcode) | ||
146 | { | ||
147 | struct dw_mci *host = slot->host; | ||
148 | |||
149 | if (host->verid == 0x290a) /* only for emmc */ | ||
150 | return dw_mci_zx_emmc_execute_tuning(slot, opcode); | ||
151 | /* TODO: Add 0x210a dedicated tuning for sd/sdio */ | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static int dw_mci_zx_parse_dt(struct dw_mci *host) | ||
157 | { | ||
158 | struct device_node *np = host->dev->of_node; | ||
159 | struct device_node *node; | ||
160 | struct dw_mci_zx_priv_data *priv; | ||
161 | struct regmap *sysc_base; | ||
162 | int ret; | ||
163 | |||
164 | /* syscon is needed only by emmc */ | ||
165 | node = of_parse_phandle(np, "zte,aon-syscon", 0); | ||
166 | if (node) { | ||
167 | sysc_base = syscon_node_to_regmap(node); | ||
168 | of_node_put(node); | ||
169 | |||
170 | if (IS_ERR(sysc_base)) { | ||
171 | ret = PTR_ERR(sysc_base); | ||
172 | if (ret != -EPROBE_DEFER) | ||
173 | dev_err(host->dev, "Can't get syscon: %d\n", | ||
174 | ret); | ||
175 | return ret; | ||
176 | } | ||
177 | } else { | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); | ||
182 | if (!priv) | ||
183 | return -ENOMEM; | ||
184 | priv->sysc_base = sysc_base; | ||
185 | host->priv = priv; | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static unsigned long zx_dwmmc_caps[3] = { | ||
191 | MMC_CAP_CMD23, | ||
192 | MMC_CAP_CMD23, | ||
193 | MMC_CAP_CMD23, | ||
194 | }; | ||
195 | |||
196 | static const struct dw_mci_drv_data zx_drv_data = { | ||
197 | .caps = zx_dwmmc_caps, | ||
198 | .execute_tuning = dw_mci_zx_execute_tuning, | ||
199 | .prepare_hs400_tuning = dw_mci_zx_prepare_hs400_tuning, | ||
200 | .parse_dt = dw_mci_zx_parse_dt, | ||
201 | }; | ||
202 | |||
203 | static const struct of_device_id dw_mci_zx_match[] = { | ||
204 | { .compatible = "zte,zx296718-dw-mshc", .data = &zx_drv_data}, | ||
205 | {}, | ||
206 | }; | ||
207 | MODULE_DEVICE_TABLE(of, dw_mci_zx_match); | ||
208 | |||
209 | static int dw_mci_zx_probe(struct platform_device *pdev) | ||
210 | { | ||
211 | const struct dw_mci_drv_data *drv_data; | ||
212 | const struct of_device_id *match; | ||
213 | |||
214 | match = of_match_node(dw_mci_zx_match, pdev->dev.of_node); | ||
215 | drv_data = match->data; | ||
216 | |||
217 | return dw_mci_pltfm_register(pdev, drv_data); | ||
218 | } | ||
219 | |||
220 | static const struct dev_pm_ops dw_mci_zx_dev_pm_ops = { | ||
221 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | ||
222 | pm_runtime_force_resume) | ||
223 | SET_RUNTIME_PM_OPS(dw_mci_runtime_suspend, | ||
224 | dw_mci_runtime_resume, | ||
225 | NULL) | ||
226 | }; | ||
227 | |||
228 | static struct platform_driver dw_mci_zx_pltfm_driver = { | ||
229 | .probe = dw_mci_zx_probe, | ||
230 | .remove = dw_mci_pltfm_remove, | ||
231 | .driver = { | ||
232 | .name = "dwmmc_zx", | ||
233 | .of_match_table = dw_mci_zx_match, | ||
234 | .pm = &dw_mci_zx_dev_pm_ops, | ||
235 | }, | ||
236 | }; | ||
237 | |||
238 | module_platform_driver(dw_mci_zx_pltfm_driver); | ||
239 | |||
240 | MODULE_DESCRIPTION("ZTE emmc/sd driver"); | ||
241 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mmc/host/dw_mmc-zx.h b/drivers/mmc/host/dw_mmc-zx.h new file mode 100644 index 000000000000..f369997a39ec --- /dev/null +++ b/drivers/mmc/host/dw_mmc-zx.h | |||
@@ -0,0 +1,31 @@ | |||
1 | #ifndef _DW_MMC_ZX_H_ | ||
2 | #define _DW_MMC_ZX_H_ | ||
3 | |||
4 | /* ZX296718 SoC specific DLL register offset. */ | ||
5 | #define LB_AON_EMMC_CFG_REG0 0x1B0 | ||
6 | #define LB_AON_EMMC_CFG_REG1 0x1B4 | ||
7 | #define LB_AON_EMMC_CFG_REG2 0x1B8 | ||
8 | |||
9 | /* LB_AON_EMMC_CFG_REG0 register defines */ | ||
10 | #define PARA_DLL_START(x) ((x) & 0xFF) | ||
11 | #define PARA_DLL_START_MASK 0xFF | ||
12 | #define DLL_REG_SET BIT(8) | ||
13 | #define PARA_DLL_LOCK_NUM(x) (((x) & 7) << 16) | ||
14 | #define PARA_DLL_LOCK_NUM_MASK (7 << 16) | ||
15 | #define PARA_PHASE_DET_SEL(x) (((x) & 7) << 20) | ||
16 | #define PARA_PHASE_DET_SEL_MASK (7 << 20) | ||
17 | #define PARA_DLL_BYPASS_MODE BIT(23) | ||
18 | #define PARA_HALF_CLK_MODE BIT(24) | ||
19 | |||
20 | /* LB_AON_EMMC_CFG_REG1 register defines */ | ||
21 | #define READ_DQS_DELAY(x) ((x) & 0x7F) | ||
22 | #define READ_DQS_DELAY_MASK (0x7F) | ||
23 | #define READ_DQS_BYPASS_MODE BIT(7) | ||
24 | #define CLK_SAMP_DELAY(x) (((x) & 0x7F) << 8) | ||
25 | #define CLK_SAMP_DELAY_MASK (0x7F << 8) | ||
26 | #define CLK_SAMP_BYPASS_MODE BIT(15) | ||
27 | |||
28 | /* LB_AON_EMMC_CFG_REG2 register defines */ | ||
29 | #define ZX_DLL_LOCKED BIT(2) | ||
30 | |||
31 | #endif /* _DW_MMC_ZX_H_ */ | ||
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 73db08558e4d..a9ac0b457313 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/mmc/mmc.h> | 32 | #include <linux/mmc/mmc.h> |
33 | #include <linux/mmc/sd.h> | 33 | #include <linux/mmc/sd.h> |
34 | #include <linux/mmc/sdio.h> | 34 | #include <linux/mmc/sdio.h> |
35 | #include <linux/mmc/dw_mmc.h> | ||
36 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
37 | #include <linux/regulator/consumer.h> | 36 | #include <linux/regulator/consumer.h> |
38 | #include <linux/of.h> | 37 | #include <linux/of.h> |
@@ -1113,11 +1112,15 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) | |||
1113 | mci_writel(host, CTRL, temp); | 1112 | mci_writel(host, CTRL, temp); |
1114 | 1113 | ||
1115 | /* | 1114 | /* |
1116 | * Use the initial fifoth_val for PIO mode. | 1115 | * Use the initial fifoth_val for PIO mode. If wm_algined |
1116 | * is set, we set watermark same as data size. | ||
1117 | * If next issued data may be transfered by DMA mode, | 1117 | * If next issued data may be transfered by DMA mode, |
1118 | * prev_blksz should be invalidated. | 1118 | * prev_blksz should be invalidated. |
1119 | */ | 1119 | */ |
1120 | mci_writel(host, FIFOTH, host->fifoth_val); | 1120 | if (host->wm_aligned) |
1121 | dw_mci_adjust_fifoth(host, data); | ||
1122 | else | ||
1123 | mci_writel(host, FIFOTH, host->fifoth_val); | ||
1121 | host->prev_blksz = 0; | 1124 | host->prev_blksz = 0; |
1122 | } else { | 1125 | } else { |
1123 | /* | 1126 | /* |
@@ -1179,11 +1182,13 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
1179 | if ((clock != slot->__clk_old && | 1182 | if ((clock != slot->__clk_old && |
1180 | !test_bit(DW_MMC_CARD_NEEDS_POLL, &slot->flags)) || | 1183 | !test_bit(DW_MMC_CARD_NEEDS_POLL, &slot->flags)) || |
1181 | force_clkinit) { | 1184 | force_clkinit) { |
1182 | dev_info(&slot->mmc->class_dev, | 1185 | /* Silent the verbose log if calling from PM context */ |
1183 | "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n", | 1186 | if (!force_clkinit) |
1184 | slot->id, host->bus_hz, clock, | 1187 | dev_info(&slot->mmc->class_dev, |
1185 | div ? ((host->bus_hz / div) >> 1) : | 1188 | "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ div = %d)\n", |
1186 | host->bus_hz, div); | 1189 | slot->id, host->bus_hz, clock, |
1190 | div ? ((host->bus_hz / div) >> 1) : | ||
1191 | host->bus_hz, div); | ||
1187 | 1192 | ||
1188 | /* | 1193 | /* |
1189 | * If card is polling, display the message only | 1194 | * If card is polling, display the message only |
@@ -2977,6 +2982,11 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
2977 | 2982 | ||
2978 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); | 2983 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); |
2979 | 2984 | ||
2985 | of_property_read_u32(np, "data-addr", &host->data_addr_override); | ||
2986 | |||
2987 | if (of_get_property(np, "fifo-watermark-aligned", NULL)) | ||
2988 | host->wm_aligned = true; | ||
2989 | |||
2980 | if (!of_property_read_u32(np, "clock-frequency", &clock_frequency)) | 2990 | if (!of_property_read_u32(np, "clock-frequency", &clock_frequency)) |
2981 | pdata->bus_hz = clock_frequency; | 2991 | pdata->bus_hz = clock_frequency; |
2982 | 2992 | ||
@@ -3180,7 +3190,9 @@ int dw_mci_probe(struct dw_mci *host) | |||
3180 | host->verid = SDMMC_GET_VERID(mci_readl(host, VERID)); | 3190 | host->verid = SDMMC_GET_VERID(mci_readl(host, VERID)); |
3181 | dev_info(host->dev, "Version ID is %04x\n", host->verid); | 3191 | dev_info(host->dev, "Version ID is %04x\n", host->verid); |
3182 | 3192 | ||
3183 | if (host->verid < DW_MMC_240A) | 3193 | if (host->data_addr_override) |
3194 | host->fifo_reg = host->regs + host->data_addr_override; | ||
3195 | else if (host->verid < DW_MMC_240A) | ||
3184 | host->fifo_reg = host->regs + DATA_OFFSET; | 3196 | host->fifo_reg = host->regs + DATA_OFFSET; |
3185 | else | 3197 | else |
3186 | host->fifo_reg = host->regs + DATA_240A_OFFSET; | 3198 | host->fifo_reg = host->regs + DATA_240A_OFFSET; |
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index c59465829387..ce347361f3dc 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
@@ -14,6 +14,269 @@ | |||
14 | #ifndef _DW_MMC_H_ | 14 | #ifndef _DW_MMC_H_ |
15 | #define _DW_MMC_H_ | 15 | #define _DW_MMC_H_ |
16 | 16 | ||
17 | #include <linux/scatterlist.h> | ||
18 | #include <linux/mmc/core.h> | ||
19 | #include <linux/dmaengine.h> | ||
20 | #include <linux/reset.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | |||
23 | #define MAX_MCI_SLOTS 2 | ||
24 | |||
25 | enum dw_mci_state { | ||
26 | STATE_IDLE = 0, | ||
27 | STATE_SENDING_CMD, | ||
28 | STATE_SENDING_DATA, | ||
29 | STATE_DATA_BUSY, | ||
30 | STATE_SENDING_STOP, | ||
31 | STATE_DATA_ERROR, | ||
32 | STATE_SENDING_CMD11, | ||
33 | STATE_WAITING_CMD11_DONE, | ||
34 | }; | ||
35 | |||
36 | enum { | ||
37 | EVENT_CMD_COMPLETE = 0, | ||
38 | EVENT_XFER_COMPLETE, | ||
39 | EVENT_DATA_COMPLETE, | ||
40 | EVENT_DATA_ERROR, | ||
41 | }; | ||
42 | |||
43 | enum dw_mci_cookie { | ||
44 | COOKIE_UNMAPPED, | ||
45 | COOKIE_PRE_MAPPED, /* mapped by pre_req() of dwmmc */ | ||
46 | COOKIE_MAPPED, /* mapped by prepare_data() of dwmmc */ | ||
47 | }; | ||
48 | |||
49 | struct mmc_data; | ||
50 | |||
51 | enum { | ||
52 | TRANS_MODE_PIO = 0, | ||
53 | TRANS_MODE_IDMAC, | ||
54 | TRANS_MODE_EDMAC | ||
55 | }; | ||
56 | |||
57 | struct dw_mci_dma_slave { | ||
58 | struct dma_chan *ch; | ||
59 | enum dma_transfer_direction direction; | ||
60 | }; | ||
61 | |||
62 | /** | ||
63 | * struct dw_mci - MMC controller state shared between all slots | ||
64 | * @lock: Spinlock protecting the queue and associated data. | ||
65 | * @irq_lock: Spinlock protecting the INTMASK setting. | ||
66 | * @regs: Pointer to MMIO registers. | ||
67 | * @fifo_reg: Pointer to MMIO registers for data FIFO | ||
68 | * @sg: Scatterlist entry currently being processed by PIO code, if any. | ||
69 | * @sg_miter: PIO mapping scatterlist iterator. | ||
70 | * @cur_slot: The slot which is currently using the controller. | ||
71 | * @mrq: The request currently being processed on @cur_slot, | ||
72 | * or NULL if the controller is idle. | ||
73 | * @cmd: The command currently being sent to the card, or NULL. | ||
74 | * @data: The data currently being transferred, or NULL if no data | ||
75 | * transfer is in progress. | ||
76 | * @stop_abort: The command currently prepared for stoping transfer. | ||
77 | * @prev_blksz: The former transfer blksz record. | ||
78 | * @timing: Record of current ios timing. | ||
79 | * @use_dma: Whether DMA channel is initialized or not. | ||
80 | * @using_dma: Whether DMA is in use for the current transfer. | ||
81 | * @dma_64bit_address: Whether DMA supports 64-bit address mode or not. | ||
82 | * @sg_dma: Bus address of DMA buffer. | ||
83 | * @sg_cpu: Virtual address of DMA buffer. | ||
84 | * @dma_ops: Pointer to platform-specific DMA callbacks. | ||
85 | * @cmd_status: Snapshot of SR taken upon completion of the current | ||
86 | * @ring_size: Buffer size for idma descriptors. | ||
87 | * command. Only valid when EVENT_CMD_COMPLETE is pending. | ||
88 | * @dms: structure of slave-dma private data. | ||
89 | * @phy_regs: physical address of controller's register map | ||
90 | * @data_status: Snapshot of SR taken upon completion of the current | ||
91 | * data transfer. Only valid when EVENT_DATA_COMPLETE or | ||
92 | * EVENT_DATA_ERROR is pending. | ||
93 | * @stop_cmdr: Value to be loaded into CMDR when the stop command is | ||
94 | * to be sent. | ||
95 | * @dir_status: Direction of current transfer. | ||
96 | * @tasklet: Tasklet running the request state machine. | ||
97 | * @pending_events: Bitmask of events flagged by the interrupt handler | ||
98 | * to be processed by the tasklet. | ||
99 | * @completed_events: Bitmask of events which the state machine has | ||
100 | * processed. | ||
101 | * @state: Tasklet state. | ||
102 | * @queue: List of slots waiting for access to the controller. | ||
103 | * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus | ||
104 | * rate and timeout calculations. | ||
105 | * @current_speed: Configured rate of the controller. | ||
106 | * @num_slots: Number of slots available. | ||
107 | * @fifoth_val: The value of FIFOTH register. | ||
108 | * @verid: Denote Version ID. | ||
109 | * @dev: Device associated with the MMC controller. | ||
110 | * @pdata: Platform data associated with the MMC controller. | ||
111 | * @drv_data: Driver specific data for identified variant of the controller | ||
112 | * @priv: Implementation defined private data. | ||
113 | * @biu_clk: Pointer to bus interface unit clock instance. | ||
114 | * @ciu_clk: Pointer to card interface unit clock instance. | ||
115 | * @slot: Slots sharing this MMC controller. | ||
116 | * @fifo_depth: depth of FIFO. | ||
117 | * @data_addr_override: override fifo reg offset with this value. | ||
118 | * @wm_aligned: force fifo watermark equal with data length in PIO mode. | ||
119 | * Set as true if alignment is needed. | ||
120 | * @data_shift: log2 of FIFO item size. | ||
121 | * @part_buf_start: Start index in part_buf. | ||
122 | * @part_buf_count: Bytes of partial data in part_buf. | ||
123 | * @part_buf: Simple buffer for partial fifo reads/writes. | ||
124 | * @push_data: Pointer to FIFO push function. | ||
125 | * @pull_data: Pointer to FIFO pull function. | ||
126 | * @vqmmc_enabled: Status of vqmmc, should be true or false. | ||
127 | * @irq_flags: The flags to be passed to request_irq. | ||
128 | * @irq: The irq value to be passed to request_irq. | ||
129 | * @sdio_id0: Number of slot0 in the SDIO interrupt registers. | ||
130 | * @cmd11_timer: Timer for SD3.0 voltage switch over scheme. | ||
131 | * @dto_timer: Timer for broken data transfer over scheme. | ||
132 | * | ||
133 | * Locking | ||
134 | * ======= | ||
135 | * | ||
136 | * @lock is a softirq-safe spinlock protecting @queue as well as | ||
137 | * @cur_slot, @mrq and @state. These must always be updated | ||
138 | * at the same time while holding @lock. | ||
139 | * | ||
140 | * @irq_lock is an irq-safe spinlock protecting the INTMASK register | ||
141 | * to allow the interrupt handler to modify it directly. Held for only long | ||
142 | * enough to read-modify-write INTMASK and no other locks are grabbed when | ||
143 | * holding this one. | ||
144 | * | ||
145 | * The @mrq field of struct dw_mci_slot is also protected by @lock, | ||
146 | * and must always be written at the same time as the slot is added to | ||
147 | * @queue. | ||
148 | * | ||
149 | * @pending_events and @completed_events are accessed using atomic bit | ||
150 | * operations, so they don't need any locking. | ||
151 | * | ||
152 | * None of the fields touched by the interrupt handler need any | ||
153 | * locking. However, ordering is important: Before EVENT_DATA_ERROR or | ||
154 | * EVENT_DATA_COMPLETE is set in @pending_events, all data-related | ||
155 | * interrupts must be disabled and @data_status updated with a | ||
156 | * snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the | ||
157 | * CMDRDY interrupt must be disabled and @cmd_status updated with a | ||
158 | * snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the | ||
159 | * bytes_xfered field of @data must be written. This is ensured by | ||
160 | * using barriers. | ||
161 | */ | ||
162 | struct dw_mci { | ||
163 | spinlock_t lock; | ||
164 | spinlock_t irq_lock; | ||
165 | void __iomem *regs; | ||
166 | void __iomem *fifo_reg; | ||
167 | u32 data_addr_override; | ||
168 | bool wm_aligned; | ||
169 | |||
170 | struct scatterlist *sg; | ||
171 | struct sg_mapping_iter sg_miter; | ||
172 | |||
173 | struct dw_mci_slot *cur_slot; | ||
174 | struct mmc_request *mrq; | ||
175 | struct mmc_command *cmd; | ||
176 | struct mmc_data *data; | ||
177 | struct mmc_command stop_abort; | ||
178 | unsigned int prev_blksz; | ||
179 | unsigned char timing; | ||
180 | |||
181 | /* DMA interface members*/ | ||
182 | int use_dma; | ||
183 | int using_dma; | ||
184 | int dma_64bit_address; | ||
185 | |||
186 | dma_addr_t sg_dma; | ||
187 | void *sg_cpu; | ||
188 | const struct dw_mci_dma_ops *dma_ops; | ||
189 | /* For idmac */ | ||
190 | unsigned int ring_size; | ||
191 | |||
192 | /* For edmac */ | ||
193 | struct dw_mci_dma_slave *dms; | ||
194 | /* Registers's physical base address */ | ||
195 | resource_size_t phy_regs; | ||
196 | |||
197 | u32 cmd_status; | ||
198 | u32 data_status; | ||
199 | u32 stop_cmdr; | ||
200 | u32 dir_status; | ||
201 | struct tasklet_struct tasklet; | ||
202 | unsigned long pending_events; | ||
203 | unsigned long completed_events; | ||
204 | enum dw_mci_state state; | ||
205 | struct list_head queue; | ||
206 | |||
207 | u32 bus_hz; | ||
208 | u32 current_speed; | ||
209 | u32 num_slots; | ||
210 | u32 fifoth_val; | ||
211 | u16 verid; | ||
212 | struct device *dev; | ||
213 | struct dw_mci_board *pdata; | ||
214 | const struct dw_mci_drv_data *drv_data; | ||
215 | void *priv; | ||
216 | struct clk *biu_clk; | ||
217 | struct clk *ciu_clk; | ||
218 | struct dw_mci_slot *slot[MAX_MCI_SLOTS]; | ||
219 | |||
220 | /* FIFO push and pull */ | ||
221 | int fifo_depth; | ||
222 | int data_shift; | ||
223 | u8 part_buf_start; | ||
224 | u8 part_buf_count; | ||
225 | union { | ||
226 | u16 part_buf16; | ||
227 | u32 part_buf32; | ||
228 | u64 part_buf; | ||
229 | }; | ||
230 | void (*push_data)(struct dw_mci *host, void *buf, int cnt); | ||
231 | void (*pull_data)(struct dw_mci *host, void *buf, int cnt); | ||
232 | |||
233 | bool vqmmc_enabled; | ||
234 | unsigned long irq_flags; /* IRQ flags */ | ||
235 | int irq; | ||
236 | |||
237 | int sdio_id0; | ||
238 | |||
239 | struct timer_list cmd11_timer; | ||
240 | struct timer_list dto_timer; | ||
241 | }; | ||
242 | |||
243 | /* DMA ops for Internal/External DMAC interface */ | ||
244 | struct dw_mci_dma_ops { | ||
245 | /* DMA Ops */ | ||
246 | int (*init)(struct dw_mci *host); | ||
247 | int (*start)(struct dw_mci *host, unsigned int sg_len); | ||
248 | void (*complete)(void *host); | ||
249 | void (*stop)(struct dw_mci *host); | ||
250 | void (*cleanup)(struct dw_mci *host); | ||
251 | void (*exit)(struct dw_mci *host); | ||
252 | }; | ||
253 | |||
254 | struct dma_pdata; | ||
255 | |||
256 | /* Board platform data */ | ||
257 | struct dw_mci_board { | ||
258 | u32 num_slots; | ||
259 | |||
260 | unsigned int bus_hz; /* Clock speed at the cclk_in pad */ | ||
261 | |||
262 | u32 caps; /* Capabilities */ | ||
263 | u32 caps2; /* More capabilities */ | ||
264 | u32 pm_caps; /* PM capabilities */ | ||
265 | /* | ||
266 | * Override fifo depth. If 0, autodetect it from the FIFOTH register, | ||
267 | * but note that this may not be reliable after a bootloader has used | ||
268 | * it. | ||
269 | */ | ||
270 | unsigned int fifo_depth; | ||
271 | |||
272 | /* delay in mS before detecting cards after interrupt */ | ||
273 | u32 detect_delay_ms; | ||
274 | |||
275 | struct reset_control *rstc; | ||
276 | struct dw_mci_dma_ops *dma_ops; | ||
277 | struct dma_pdata *data; | ||
278 | }; | ||
279 | |||
17 | #define DW_MMC_240A 0x240a | 280 | #define DW_MMC_240A 0x240a |
18 | #define DW_MMC_280A 0x280a | 281 | #define DW_MMC_280A 0x280a |
19 | 282 | ||
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 09739352834c..5a959783304b 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/clk-provider.h> | 36 | #include <linux/clk-provider.h> |
37 | #include <linux/regulator/consumer.h> | 37 | #include <linux/regulator/consumer.h> |
38 | #include <linux/interrupt.h> | ||
38 | 39 | ||
39 | #define DRIVER_NAME "meson-gx-mmc" | 40 | #define DRIVER_NAME "meson-gx-mmc" |
40 | 41 | ||
@@ -82,6 +83,7 @@ | |||
82 | #define CFG_RC_CC_MASK 0xf | 83 | #define CFG_RC_CC_MASK 0xf |
83 | #define CFG_STOP_CLOCK BIT(22) | 84 | #define CFG_STOP_CLOCK BIT(22) |
84 | #define CFG_CLK_ALWAYS_ON BIT(18) | 85 | #define CFG_CLK_ALWAYS_ON BIT(18) |
86 | #define CFG_CHK_DS BIT(20) | ||
85 | #define CFG_AUTO_CLK BIT(23) | 87 | #define CFG_AUTO_CLK BIT(23) |
86 | 88 | ||
87 | #define SD_EMMC_STATUS 0x48 | 89 | #define SD_EMMC_STATUS 0x48 |
@@ -131,7 +133,7 @@ struct meson_host { | |||
131 | struct clk_mux mux; | 133 | struct clk_mux mux; |
132 | struct clk *mux_clk; | 134 | struct clk *mux_clk; |
133 | struct clk *mux_parent[MUX_CLK_NUM_PARENTS]; | 135 | struct clk *mux_parent[MUX_CLK_NUM_PARENTS]; |
134 | unsigned long mux_parent_rate[MUX_CLK_NUM_PARENTS]; | 136 | unsigned long current_clock; |
135 | 137 | ||
136 | struct clk_divider cfg_div; | 138 | struct clk_divider cfg_div; |
137 | struct clk *cfg_div_clk; | 139 | struct clk *cfg_div_clk; |
@@ -178,7 +180,7 @@ struct sd_emmc_desc { | |||
178 | static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) | 180 | static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) |
179 | { | 181 | { |
180 | struct mmc_host *mmc = host->mmc; | 182 | struct mmc_host *mmc = host->mmc; |
181 | int ret = 0; | 183 | int ret; |
182 | u32 cfg; | 184 | u32 cfg; |
183 | 185 | ||
184 | if (clk_rate) { | 186 | if (clk_rate) { |
@@ -188,7 +190,7 @@ static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) | |||
188 | clk_rate = mmc->f_min; | 190 | clk_rate = mmc->f_min; |
189 | } | 191 | } |
190 | 192 | ||
191 | if (clk_rate == mmc->actual_clock) | 193 | if (clk_rate == host->current_clock) |
192 | return 0; | 194 | return 0; |
193 | 195 | ||
194 | /* stop clock */ | 196 | /* stop clock */ |
@@ -201,29 +203,34 @@ static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) | |||
201 | dev_dbg(host->dev, "change clock rate %u -> %lu\n", | 203 | dev_dbg(host->dev, "change clock rate %u -> %lu\n", |
202 | mmc->actual_clock, clk_rate); | 204 | mmc->actual_clock, clk_rate); |
203 | 205 | ||
204 | if (clk_rate == 0) { | 206 | if (!clk_rate) { |
205 | mmc->actual_clock = 0; | 207 | mmc->actual_clock = 0; |
208 | host->current_clock = 0; | ||
209 | /* return with clock being stopped */ | ||
206 | return 0; | 210 | return 0; |
207 | } | 211 | } |
208 | 212 | ||
209 | ret = clk_set_rate(host->cfg_div_clk, clk_rate); | 213 | ret = clk_set_rate(host->cfg_div_clk, clk_rate); |
210 | if (ret) | 214 | if (ret) { |
211 | dev_warn(host->dev, "Unable to set cfg_div_clk to %lu. ret=%d\n", | 215 | dev_err(host->dev, "Unable to set cfg_div_clk to %lu. ret=%d\n", |
212 | clk_rate, ret); | 216 | clk_rate, ret); |
213 | else if (clk_rate && clk_rate != clk_get_rate(host->cfg_div_clk)) | 217 | return ret; |
214 | dev_warn(host->dev, "divider requested rate %lu != actual rate %lu: ret=%d\n", | ||
215 | clk_rate, clk_get_rate(host->cfg_div_clk), ret); | ||
216 | else | ||
217 | mmc->actual_clock = clk_rate; | ||
218 | |||
219 | /* (re)start clock, if non-zero */ | ||
220 | if (!ret && clk_rate) { | ||
221 | cfg = readl(host->regs + SD_EMMC_CFG); | ||
222 | cfg &= ~CFG_STOP_CLOCK; | ||
223 | writel(cfg, host->regs + SD_EMMC_CFG); | ||
224 | } | 218 | } |
225 | 219 | ||
226 | return ret; | 220 | mmc->actual_clock = clk_get_rate(host->cfg_div_clk); |
221 | host->current_clock = clk_rate; | ||
222 | |||
223 | if (clk_rate != mmc->actual_clock) | ||
224 | dev_dbg(host->dev, | ||
225 | "divider requested rate %lu != actual rate %u\n", | ||
226 | clk_rate, mmc->actual_clock); | ||
227 | |||
228 | /* (re)start clock */ | ||
229 | cfg = readl(host->regs + SD_EMMC_CFG); | ||
230 | cfg &= ~CFG_STOP_CLOCK; | ||
231 | writel(cfg, host->regs + SD_EMMC_CFG); | ||
232 | |||
233 | return 0; | ||
227 | } | 234 | } |
228 | 235 | ||
229 | /* | 236 | /* |
@@ -239,7 +246,6 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
239 | const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; | 246 | const char *mux_parent_names[MUX_CLK_NUM_PARENTS]; |
240 | unsigned int mux_parent_count = 0; | 247 | unsigned int mux_parent_count = 0; |
241 | const char *clk_div_parents[1]; | 248 | const char *clk_div_parents[1]; |
242 | unsigned int f_min = UINT_MAX; | ||
243 | u32 clk_reg, cfg; | 249 | u32 clk_reg, cfg; |
244 | 250 | ||
245 | /* get the mux parents */ | 251 | /* get the mux parents */ |
@@ -256,20 +262,10 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
256 | return ret; | 262 | return ret; |
257 | } | 263 | } |
258 | 264 | ||
259 | host->mux_parent_rate[i] = clk_get_rate(host->mux_parent[i]); | ||
260 | mux_parent_names[i] = __clk_get_name(host->mux_parent[i]); | 265 | mux_parent_names[i] = __clk_get_name(host->mux_parent[i]); |
261 | mux_parent_count++; | 266 | mux_parent_count++; |
262 | if (host->mux_parent_rate[i] < f_min) | ||
263 | f_min = host->mux_parent_rate[i]; | ||
264 | } | 267 | } |
265 | 268 | ||
266 | /* cacluate f_min based on input clocks, and max divider value */ | ||
267 | if (f_min != UINT_MAX) | ||
268 | f_min = DIV_ROUND_UP(CLK_SRC_XTAL_RATE, CLK_DIV_MAX); | ||
269 | else | ||
270 | f_min = 4000000; /* default min: 400 MHz */ | ||
271 | host->mmc->f_min = f_min; | ||
272 | |||
273 | /* create the mux */ | 269 | /* create the mux */ |
274 | snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev)); | 270 | snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev)); |
275 | init.name = clk_name; | 271 | init.name = clk_name; |
@@ -324,9 +320,13 @@ static int meson_mmc_clk_init(struct meson_host *host) | |||
324 | writel(cfg, host->regs + SD_EMMC_CFG); | 320 | writel(cfg, host->regs + SD_EMMC_CFG); |
325 | 321 | ||
326 | ret = clk_prepare_enable(host->cfg_div_clk); | 322 | ret = clk_prepare_enable(host->cfg_div_clk); |
327 | if (!ret) | 323 | if (ret) |
328 | ret = meson_mmc_clk_set(host, f_min); | 324 | return ret; |
329 | 325 | ||
326 | /* Get the nearest minimum clock to 400KHz */ | ||
327 | host->mmc->f_min = clk_round_rate(host->cfg_div_clk, 400000); | ||
328 | |||
329 | ret = meson_mmc_clk_set(host, host->mmc->f_min); | ||
330 | if (!ret) | 330 | if (!ret) |
331 | clk_disable_unprepare(host->cfg_div_clk); | 331 | clk_disable_unprepare(host->cfg_div_clk); |
332 | 332 | ||
@@ -378,7 +378,6 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
378 | meson_mmc_clk_set(host, ios->clock); | 378 | meson_mmc_clk_set(host, ios->clock); |
379 | 379 | ||
380 | /* Bus width */ | 380 | /* Bus width */ |
381 | val = readl(host->regs + SD_EMMC_CFG); | ||
382 | switch (ios->bus_width) { | 381 | switch (ios->bus_width) { |
383 | case MMC_BUS_WIDTH_1: | 382 | case MMC_BUS_WIDTH_1: |
384 | bus_width = CFG_BUS_WIDTH_1; | 383 | bus_width = CFG_BUS_WIDTH_1; |
@@ -393,7 +392,6 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
393 | dev_err(host->dev, "Invalid ios->bus_width: %u. Setting to 4.\n", | 392 | dev_err(host->dev, "Invalid ios->bus_width: %u. Setting to 4.\n", |
394 | ios->bus_width); | 393 | ios->bus_width); |
395 | bus_width = CFG_BUS_WIDTH_4; | 394 | bus_width = CFG_BUS_WIDTH_4; |
396 | return; | ||
397 | } | 395 | } |
398 | 396 | ||
399 | val = readl(host->regs + SD_EMMC_CFG); | 397 | val = readl(host->regs + SD_EMMC_CFG); |
@@ -411,6 +409,16 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
411 | val &= ~(CFG_RC_CC_MASK << CFG_RC_CC_SHIFT); | 409 | val &= ~(CFG_RC_CC_MASK << CFG_RC_CC_SHIFT); |
412 | val |= ilog2(SD_EMMC_CFG_CMD_GAP) << CFG_RC_CC_SHIFT; | 410 | val |= ilog2(SD_EMMC_CFG_CMD_GAP) << CFG_RC_CC_SHIFT; |
413 | 411 | ||
412 | val &= ~CFG_DDR; | ||
413 | if (ios->timing == MMC_TIMING_UHS_DDR50 || | ||
414 | ios->timing == MMC_TIMING_MMC_DDR52 || | ||
415 | ios->timing == MMC_TIMING_MMC_HS400) | ||
416 | val |= CFG_DDR; | ||
417 | |||
418 | val &= ~CFG_CHK_DS; | ||
419 | if (ios->timing == MMC_TIMING_MMC_HS400) | ||
420 | val |= CFG_CHK_DS; | ||
421 | |||
414 | writel(val, host->regs + SD_EMMC_CFG); | 422 | writel(val, host->regs + SD_EMMC_CFG); |
415 | 423 | ||
416 | if (val != orig) | 424 | if (val != orig) |
@@ -480,9 +488,9 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) | |||
480 | blk_len = cfg & (CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT); | 488 | blk_len = cfg & (CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT); |
481 | blk_len >>= CFG_BLK_LEN_SHIFT; | 489 | blk_len >>= CFG_BLK_LEN_SHIFT; |
482 | if (blk_len != ilog2(cmd->data->blksz)) { | 490 | if (blk_len != ilog2(cmd->data->blksz)) { |
483 | dev_warn(host->dev, "%s: update blk_len %d -> %d\n", | 491 | dev_dbg(host->dev, "%s: update blk_len %d -> %d\n", |
484 | __func__, blk_len, | 492 | __func__, blk_len, |
485 | ilog2(cmd->data->blksz)); | 493 | ilog2(cmd->data->blksz)); |
486 | blk_len = ilog2(cmd->data->blksz); | 494 | blk_len = ilog2(cmd->data->blksz); |
487 | cfg &= ~(CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT); | 495 | cfg &= ~(CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT); |
488 | cfg |= blk_len << CFG_BLK_LEN_SHIFT; | 496 | cfg |= blk_len << CFG_BLK_LEN_SHIFT; |
@@ -545,11 +553,6 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
545 | /* Stop execution */ | 553 | /* Stop execution */ |
546 | writel(0, host->regs + SD_EMMC_START); | 554 | writel(0, host->regs + SD_EMMC_START); |
547 | 555 | ||
548 | /* clear, ack, enable all interrupts */ | ||
549 | writel(0, host->regs + SD_EMMC_IRQ_EN); | ||
550 | writel(IRQ_EN_MASK, host->regs + SD_EMMC_STATUS); | ||
551 | writel(IRQ_EN_MASK, host->regs + SD_EMMC_IRQ_EN); | ||
552 | |||
553 | host->mrq = mrq; | 556 | host->mrq = mrq; |
554 | 557 | ||
555 | if (mrq->sbc) | 558 | if (mrq->sbc) |
@@ -669,7 +672,6 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) | |||
669 | struct mmc_command *cmd = host->cmd; | 672 | struct mmc_command *cmd = host->cmd; |
670 | struct mmc_data *data; | 673 | struct mmc_data *data; |
671 | unsigned int xfer_bytes; | 674 | unsigned int xfer_bytes; |
672 | int ret = IRQ_HANDLED; | ||
673 | 675 | ||
674 | if (WARN_ON(!mrq)) | 676 | if (WARN_ON(!mrq)) |
675 | return IRQ_NONE; | 677 | return IRQ_NONE; |
@@ -678,14 +680,12 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) | |||
678 | return IRQ_NONE; | 680 | return IRQ_NONE; |
679 | 681 | ||
680 | data = cmd->data; | 682 | data = cmd->data; |
681 | if (data) { | 683 | if (data && data->flags & MMC_DATA_READ) { |
682 | xfer_bytes = data->blksz * data->blocks; | 684 | xfer_bytes = data->blksz * data->blocks; |
683 | if (data->flags & MMC_DATA_READ) { | 685 | WARN_ON(xfer_bytes > host->bounce_buf_size); |
684 | WARN_ON(xfer_bytes > host->bounce_buf_size); | 686 | sg_copy_from_buffer(data->sg, data->sg_len, |
685 | sg_copy_from_buffer(data->sg, data->sg_len, | 687 | host->bounce_buf, xfer_bytes); |
686 | host->bounce_buf, xfer_bytes); | 688 | data->bytes_xfered = xfer_bytes; |
687 | data->bytes_xfered = xfer_bytes; | ||
688 | } | ||
689 | } | 689 | } |
690 | 690 | ||
691 | meson_mmc_read_resp(host->mmc, cmd); | 691 | meson_mmc_read_resp(host->mmc, cmd); |
@@ -694,7 +694,7 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) | |||
694 | else | 694 | else |
695 | meson_mmc_start_cmd(host->mmc, data->stop); | 695 | meson_mmc_start_cmd(host->mmc, data->stop); |
696 | 696 | ||
697 | return ret; | 697 | return IRQ_HANDLED; |
698 | } | 698 | } |
699 | 699 | ||
700 | /* | 700 | /* |
@@ -742,7 +742,8 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
742 | 742 | ||
743 | ret = mmc_of_parse(mmc); | 743 | ret = mmc_of_parse(mmc); |
744 | if (ret) { | 744 | if (ret) { |
745 | dev_warn(&pdev->dev, "error parsing DT: %d\n", ret); | 745 | if (ret != -EPROBE_DEFER) |
746 | dev_warn(&pdev->dev, "error parsing DT: %d\n", ret); | ||
746 | goto free_host; | 747 | goto free_host; |
747 | } | 748 | } |
748 | 749 | ||
@@ -780,6 +781,7 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
780 | /* clear, ack, enable all interrupts */ | 781 | /* clear, ack, enable all interrupts */ |
781 | writel(0, host->regs + SD_EMMC_IRQ_EN); | 782 | writel(0, host->regs + SD_EMMC_IRQ_EN); |
782 | writel(IRQ_EN_MASK, host->regs + SD_EMMC_STATUS); | 783 | writel(IRQ_EN_MASK, host->regs + SD_EMMC_STATUS); |
784 | writel(IRQ_EN_MASK, host->regs + SD_EMMC_IRQ_EN); | ||
783 | 785 | ||
784 | ret = devm_request_threaded_irq(&pdev->dev, host->irq, | 786 | ret = devm_request_threaded_irq(&pdev->dev, host->irq, |
785 | meson_mmc_irq, meson_mmc_irq_thread, | 787 | meson_mmc_irq, meson_mmc_irq_thread, |
@@ -787,8 +789,11 @@ static int meson_mmc_probe(struct platform_device *pdev) | |||
787 | if (ret) | 789 | if (ret) |
788 | goto free_host; | 790 | goto free_host; |
789 | 791 | ||
792 | mmc->max_blk_count = CMD_CFG_LENGTH_MASK; | ||
793 | mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size; | ||
794 | |||
790 | /* data bounce buffer */ | 795 | /* data bounce buffer */ |
791 | host->bounce_buf_size = SZ_512K; | 796 | host->bounce_buf_size = mmc->max_req_size; |
792 | host->bounce_buf = | 797 | host->bounce_buf = |
793 | dma_alloc_coherent(host->dev, host->bounce_buf_size, | 798 | dma_alloc_coherent(host->dev, host->bounce_buf_size, |
794 | &host->bounce_dma_addr, GFP_KERNEL); | 799 | &host->bounce_dma_addr, GFP_KERNEL); |
@@ -814,12 +819,11 @@ static int meson_mmc_remove(struct platform_device *pdev) | |||
814 | { | 819 | { |
815 | struct meson_host *host = dev_get_drvdata(&pdev->dev); | 820 | struct meson_host *host = dev_get_drvdata(&pdev->dev); |
816 | 821 | ||
817 | if (WARN_ON(!host)) | 822 | /* disable interrupts */ |
818 | return 0; | 823 | writel(0, host->regs + SD_EMMC_IRQ_EN); |
819 | 824 | ||
820 | if (host->bounce_buf) | 825 | dma_free_coherent(host->dev, host->bounce_buf_size, |
821 | dma_free_coherent(host->dev, host->bounce_buf_size, | 826 | host->bounce_buf, host->bounce_dma_addr); |
822 | host->bounce_buf, host->bounce_dma_addr); | ||
823 | 827 | ||
824 | clk_disable_unprepare(host->cfg_div_clk); | 828 | clk_disable_unprepare(host->cfg_div_clk); |
825 | clk_disable_unprepare(host->core_clk); | 829 | clk_disable_unprepare(host->core_clk); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b5972440c1bf..0c6420bb2f00 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -507,6 +507,7 @@ static void mmci_dma_data_error(struct mmci_host *host) | |||
507 | { | 507 | { |
508 | dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); | 508 | dev_err(mmc_dev(host->mmc), "error during DMA transfer!\n"); |
509 | dmaengine_terminate_all(host->dma_current); | 509 | dmaengine_terminate_all(host->dma_current); |
510 | host->dma_in_progress = false; | ||
510 | host->dma_current = NULL; | 511 | host->dma_current = NULL; |
511 | host->dma_desc_current = NULL; | 512 | host->dma_desc_current = NULL; |
512 | host->data->host_cookie = 0; | 513 | host->data->host_cookie = 0; |
@@ -565,6 +566,7 @@ static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) | |||
565 | mmci_dma_release(host); | 566 | mmci_dma_release(host); |
566 | } | 567 | } |
567 | 568 | ||
569 | host->dma_in_progress = false; | ||
568 | host->dma_current = NULL; | 570 | host->dma_current = NULL; |
569 | host->dma_desc_current = NULL; | 571 | host->dma_desc_current = NULL; |
570 | } | 572 | } |
@@ -665,6 +667,7 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) | |||
665 | dev_vdbg(mmc_dev(host->mmc), | 667 | dev_vdbg(mmc_dev(host->mmc), |
666 | "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", | 668 | "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", |
667 | data->sg_len, data->blksz, data->blocks, data->flags); | 669 | data->sg_len, data->blksz, data->blocks, data->flags); |
670 | host->dma_in_progress = true; | ||
668 | dmaengine_submit(host->dma_desc_current); | 671 | dmaengine_submit(host->dma_desc_current); |
669 | dma_async_issue_pending(host->dma_current); | 672 | dma_async_issue_pending(host->dma_current); |
670 | 673 | ||
@@ -740,8 +743,10 @@ static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, | |||
740 | if (host->dma_desc_current == next->dma_desc) | 743 | if (host->dma_desc_current == next->dma_desc) |
741 | host->dma_desc_current = NULL; | 744 | host->dma_desc_current = NULL; |
742 | 745 | ||
743 | if (host->dma_current == next->dma_chan) | 746 | if (host->dma_current == next->dma_chan) { |
747 | host->dma_in_progress = false; | ||
744 | host->dma_current = NULL; | 748 | host->dma_current = NULL; |
749 | } | ||
745 | 750 | ||
746 | next->dma_desc = NULL; | 751 | next->dma_desc = NULL; |
747 | next->dma_chan = NULL; | 752 | next->dma_chan = NULL; |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 56322c6afba4..4a8bef1aac8f 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -245,8 +245,9 @@ struct mmci_host { | |||
245 | struct dma_chan *dma_tx_channel; | 245 | struct dma_chan *dma_tx_channel; |
246 | struct dma_async_tx_descriptor *dma_desc_current; | 246 | struct dma_async_tx_descriptor *dma_desc_current; |
247 | struct mmci_host_next next_data; | 247 | struct mmci_host_next next_data; |
248 | bool dma_in_progress; | ||
248 | 249 | ||
249 | #define dma_inprogress(host) ((host)->dma_current) | 250 | #define dma_inprogress(host) ((host)->dma_in_progress) |
250 | #else | 251 | #else |
251 | #define dma_inprogress(host) (0) | 252 | #define dma_inprogress(host) (0) |
252 | #endif | 253 | #endif |
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 10ef2ae1d2f6..8e32580c12b5 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/regulator/consumer.h> | 28 | #include <linux/regulator/consumer.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/interrupt.h> | ||
31 | 32 | ||
32 | #include <linux/mmc/card.h> | 33 | #include <linux/mmc/card.h> |
33 | #include <linux/mmc/core.h> | 34 | #include <linux/mmc/core.h> |
@@ -1074,11 +1075,8 @@ static int msdc_card_busy(struct mmc_host *mmc) | |||
1074 | struct msdc_host *host = mmc_priv(mmc); | 1075 | struct msdc_host *host = mmc_priv(mmc); |
1075 | u32 status = readl(host->base + MSDC_PS); | 1076 | u32 status = readl(host->base + MSDC_PS); |
1076 | 1077 | ||
1077 | /* check if any pin between dat[0:3] is low */ | 1078 | /* only check if data0 is low */ |
1078 | if (((status >> 16) & 0xf) != 0xf) | 1079 | return !(status & BIT(16)); |
1079 | return 1; | ||
1080 | |||
1081 | return 0; | ||
1082 | } | 1080 | } |
1083 | 1081 | ||
1084 | static void msdc_request_timeout(struct work_struct *work) | 1082 | static void msdc_request_timeout(struct work_struct *work) |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index c8b8ac66ff7e..add1e70195ea 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -153,7 +153,11 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host) | |||
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
156 | if (data) { | 156 | if (cmd == mrq->sbc) { |
157 | /* Finished CMD23, now send actual command. */ | ||
158 | mxs_mmc_start_cmd(host, mrq->cmd); | ||
159 | return; | ||
160 | } else if (data) { | ||
157 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 161 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
158 | data->sg_len, ssp->dma_dir); | 162 | data->sg_len, ssp->dma_dir); |
159 | /* | 163 | /* |
@@ -166,7 +170,7 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host) | |||
166 | data->bytes_xfered = 0; | 170 | data->bytes_xfered = 0; |
167 | 171 | ||
168 | host->data = NULL; | 172 | host->data = NULL; |
169 | if (mrq->stop) { | 173 | if (data->stop && (data->error || !mrq->sbc)) { |
170 | mxs_mmc_start_cmd(host, mrq->stop); | 174 | mxs_mmc_start_cmd(host, mrq->stop); |
171 | return; | 175 | return; |
172 | } | 176 | } |
@@ -495,7 +499,11 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
495 | 499 | ||
496 | WARN_ON(host->mrq != NULL); | 500 | WARN_ON(host->mrq != NULL); |
497 | host->mrq = mrq; | 501 | host->mrq = mrq; |
498 | mxs_mmc_start_cmd(host, mrq->cmd); | 502 | |
503 | if (mrq->sbc) | ||
504 | mxs_mmc_start_cmd(host, mrq->sbc); | ||
505 | else | ||
506 | mxs_mmc_start_cmd(host, mrq->cmd); | ||
499 | } | 507 | } |
500 | 508 | ||
501 | static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 509 | static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
@@ -642,7 +650,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
642 | /* set mmc core parameters */ | 650 | /* set mmc core parameters */ |
643 | mmc->ops = &mxs_mmc_ops; | 651 | mmc->ops = &mxs_mmc_ops; |
644 | mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | | 652 | mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | |
645 | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; | 653 | MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL | MMC_CAP_CMD23; |
646 | 654 | ||
647 | host->broken_cd = of_property_read_bool(np, "broken-cd"); | 655 | host->broken_cd = of_property_read_bool(np, "broken-cd"); |
648 | 656 | ||
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index be3c49fa7382..bd49f34d7654 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -893,7 +893,7 @@ static void mmc_omap_cover_handler(unsigned long param) | |||
893 | * If no card is inserted, we postpone polling until | 893 | * If no card is inserted, we postpone polling until |
894 | * the cover has been closed. | 894 | * the cover has been closed. |
895 | */ | 895 | */ |
896 | if (slot->mmc->card == NULL || !mmc_card_present(slot->mmc->card)) | 896 | if (slot->mmc->card == NULL) |
897 | return; | 897 | return; |
898 | 898 | ||
899 | mod_timer(&slot->cover_timer, | 899 | mod_timer(&slot->cover_timer, |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index ad11c4cc12ed..a58bd653ed8b 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -1162,7 +1162,7 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) | |||
1162 | if (status & ERR_EN) { | 1162 | if (status & ERR_EN) { |
1163 | omap_hsmmc_dbg_report_irq(host, status); | 1163 | omap_hsmmc_dbg_report_irq(host, status); |
1164 | 1164 | ||
1165 | if (status & (CTO_EN | CCRC_EN)) | 1165 | if (status & (CTO_EN | CCRC_EN | CEB_EN)) |
1166 | end_cmd = 1; | 1166 | end_cmd = 1; |
1167 | if (host->data || host->response_busy) { | 1167 | if (host->data || host->response_busy) { |
1168 | end_trans = !end_cmd; | 1168 | end_trans = !end_cmd; |
@@ -1469,10 +1469,11 @@ static int omap_hsmmc_setup_dma_transfer(struct omap_hsmmc_host *host, | |||
1469 | } | 1469 | } |
1470 | 1470 | ||
1471 | static void set_data_timeout(struct omap_hsmmc_host *host, | 1471 | static void set_data_timeout(struct omap_hsmmc_host *host, |
1472 | unsigned int timeout_ns, | 1472 | unsigned long long timeout_ns, |
1473 | unsigned int timeout_clks) | 1473 | unsigned int timeout_clks) |
1474 | { | 1474 | { |
1475 | unsigned int timeout, cycle_ns; | 1475 | unsigned long long timeout = timeout_ns; |
1476 | unsigned int cycle_ns; | ||
1476 | uint32_t reg, clkd, dto = 0; | 1477 | uint32_t reg, clkd, dto = 0; |
1477 | 1478 | ||
1478 | reg = OMAP_HSMMC_READ(host->base, SYSCTL); | 1479 | reg = OMAP_HSMMC_READ(host->base, SYSCTL); |
@@ -1481,7 +1482,7 @@ static void set_data_timeout(struct omap_hsmmc_host *host, | |||
1481 | clkd = 1; | 1482 | clkd = 1; |
1482 | 1483 | ||
1483 | cycle_ns = 1000000000 / (host->clk_rate / clkd); | 1484 | cycle_ns = 1000000000 / (host->clk_rate / clkd); |
1484 | timeout = timeout_ns / cycle_ns; | 1485 | do_div(timeout, cycle_ns); |
1485 | timeout += timeout_clks; | 1486 | timeout += timeout_clks; |
1486 | if (timeout) { | 1487 | if (timeout) { |
1487 | while ((timeout & 0x80000000) == 0) { | 1488 | while ((timeout & 0x80000000) == 0) { |
@@ -1527,16 +1528,24 @@ static int | |||
1527 | omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) | 1528 | omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) |
1528 | { | 1529 | { |
1529 | int ret; | 1530 | int ret; |
1531 | unsigned long long timeout; | ||
1532 | |||
1530 | host->data = req->data; | 1533 | host->data = req->data; |
1531 | 1534 | ||
1532 | if (req->data == NULL) { | 1535 | if (req->data == NULL) { |
1533 | OMAP_HSMMC_WRITE(host->base, BLK, 0); | 1536 | OMAP_HSMMC_WRITE(host->base, BLK, 0); |
1534 | /* | 1537 | if (req->cmd->flags & MMC_RSP_BUSY) { |
1535 | * Set an arbitrary 100ms data timeout for commands with | 1538 | timeout = req->cmd->busy_timeout * NSEC_PER_MSEC; |
1536 | * busy signal. | 1539 | |
1537 | */ | 1540 | /* |
1538 | if (req->cmd->flags & MMC_RSP_BUSY) | 1541 | * Set an arbitrary 100ms data timeout for commands with |
1539 | set_data_timeout(host, 100000000U, 0); | 1542 | * busy signal and no indication of busy_timeout. |
1543 | */ | ||
1544 | if (!timeout) | ||
1545 | timeout = 100000000U; | ||
1546 | |||
1547 | set_data_timeout(host, timeout, 0); | ||
1548 | } | ||
1540 | return 0; | 1549 | return 0; |
1541 | } | 1550 | } |
1542 | 1551 | ||
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index ecb99a8d2fa2..41b57713b620 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -707,7 +707,7 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, | |||
707 | u8 opcode, u8 sample_point) | 707 | u8 opcode, u8 sample_point) |
708 | { | 708 | { |
709 | int err; | 709 | int err; |
710 | struct mmc_command cmd = {0}; | 710 | struct mmc_command cmd = {}; |
711 | 711 | ||
712 | err = sd_change_phase(host, sample_point, true); | 712 | err = sd_change_phase(host, sample_point, true); |
713 | if (err < 0) | 713 | if (err < 0) |
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c index dc1abd14acbc..12d2fbe9c520 100644 --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c | |||
@@ -682,7 +682,7 @@ static int sd_tuning_rx_cmd(struct rtsx_usb_sdmmc *host, | |||
682 | u8 opcode, u8 sample_point) | 682 | u8 opcode, u8 sample_point) |
683 | { | 683 | { |
684 | int err; | 684 | int err; |
685 | struct mmc_command cmd = {0}; | 685 | struct mmc_command cmd = {}; |
686 | 686 | ||
687 | err = sd_change_phase(host, sample_point, 0); | 687 | err = sd_change_phase(host, sample_point, 0); |
688 | if (err) | 688 | if (err) |
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 932a4b1fed33..7a173f8c455b 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/debugfs.h> | 21 | #include <linux/debugfs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/interrupt.h> | ||
24 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
25 | #include <linux/io.h> | 26 | #include <linux/io.h> |
26 | 27 | ||
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 278a5a435ab7..9dcb7048e3b1 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -467,7 +467,10 @@ static int sdhci_acpi_probe(struct platform_device *pdev) | |||
467 | if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { | 467 | if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { |
468 | bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL); | 468 | bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL); |
469 | 469 | ||
470 | if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL)) { | 470 | err = mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL); |
471 | if (err) { | ||
472 | if (err == -EPROBE_DEFER) | ||
473 | goto err_free; | ||
471 | dev_warn(dev, "failed to setup card detect gpio\n"); | 474 | dev_warn(dev, "failed to setup card detect gpio\n"); |
472 | c->use_runtime_pm = false; | 475 | c->use_runtime_pm = false; |
473 | } | 476 | } |
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c index 4b0ecb981842..316cfec3f005 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/iopoll.h> | 17 | #include <linux/iopoll.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
20 | #include <linux/mmc/mmc.h> | ||
20 | 21 | ||
21 | #include "sdhci-pltfm.h" | 22 | #include "sdhci-pltfm.h" |
22 | 23 | ||
@@ -25,7 +26,7 @@ | |||
25 | #define SDHCI_CDNS_HRS04_ACK BIT(26) | 26 | #define SDHCI_CDNS_HRS04_ACK BIT(26) |
26 | #define SDHCI_CDNS_HRS04_RD BIT(25) | 27 | #define SDHCI_CDNS_HRS04_RD BIT(25) |
27 | #define SDHCI_CDNS_HRS04_WR BIT(24) | 28 | #define SDHCI_CDNS_HRS04_WR BIT(24) |
28 | #define SDHCI_CDNS_HRS04_RDATA_SHIFT 12 | 29 | #define SDHCI_CDNS_HRS04_RDATA_SHIFT 16 |
29 | #define SDHCI_CDNS_HRS04_WDATA_SHIFT 8 | 30 | #define SDHCI_CDNS_HRS04_WDATA_SHIFT 8 |
30 | #define SDHCI_CDNS_HRS04_ADDR_SHIFT 0 | 31 | #define SDHCI_CDNS_HRS04_ADDR_SHIFT 0 |
31 | 32 | ||
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index de132e281753..ece8b37e51dd 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h | |||
@@ -24,30 +24,36 @@ | |||
24 | SDHCI_QUIRK_PIO_NEEDS_DELAY | \ | 24 | SDHCI_QUIRK_PIO_NEEDS_DELAY | \ |
25 | SDHCI_QUIRK_NO_HISPD_BIT) | 25 | SDHCI_QUIRK_NO_HISPD_BIT) |
26 | 26 | ||
27 | #define ESDHC_PROCTL 0x28 | ||
28 | |||
29 | #define ESDHC_SYSTEM_CONTROL 0x2c | ||
30 | #define ESDHC_CLOCK_MASK 0x0000fff0 | ||
31 | #define ESDHC_PREDIV_SHIFT 8 | ||
32 | #define ESDHC_DIVIDER_SHIFT 4 | ||
33 | #define ESDHC_CLOCK_PEREN 0x00000004 | ||
34 | #define ESDHC_CLOCK_HCKEN 0x00000002 | ||
35 | #define ESDHC_CLOCK_IPGEN 0x00000001 | ||
36 | |||
37 | /* pltfm-specific */ | 27 | /* pltfm-specific */ |
38 | #define ESDHC_HOST_CONTROL_LE 0x20 | 28 | #define ESDHC_HOST_CONTROL_LE 0x20 |
39 | 29 | ||
40 | /* | 30 | /* |
41 | * P2020 interpretation of the SDHCI_HOST_CONTROL register | 31 | * eSDHC register definition |
42 | */ | 32 | */ |
43 | #define ESDHC_CTRL_4BITBUS (0x1 << 1) | ||
44 | #define ESDHC_CTRL_8BITBUS (0x2 << 1) | ||
45 | #define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1) | ||
46 | |||
47 | /* OF-specific */ | ||
48 | #define ESDHC_DMA_SYSCTL 0x40c | ||
49 | #define ESDHC_DMA_SNOOP 0x00000040 | ||
50 | 33 | ||
51 | #define ESDHC_HOST_CONTROL_RES 0x01 | 34 | /* Present State Register */ |
35 | #define ESDHC_PRSSTAT 0x24 | ||
36 | #define ESDHC_CLOCK_STABLE 0x00000008 | ||
37 | |||
38 | /* Protocol Control Register */ | ||
39 | #define ESDHC_PROCTL 0x28 | ||
40 | #define ESDHC_CTRL_4BITBUS (0x1 << 1) | ||
41 | #define ESDHC_CTRL_8BITBUS (0x2 << 1) | ||
42 | #define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1) | ||
43 | #define ESDHC_HOST_CONTROL_RES 0x01 | ||
44 | |||
45 | /* System Control Register */ | ||
46 | #define ESDHC_SYSTEM_CONTROL 0x2c | ||
47 | #define ESDHC_CLOCK_MASK 0x0000fff0 | ||
48 | #define ESDHC_PREDIV_SHIFT 8 | ||
49 | #define ESDHC_DIVIDER_SHIFT 4 | ||
50 | #define ESDHC_CLOCK_SDCLKEN 0x00000008 | ||
51 | #define ESDHC_CLOCK_PEREN 0x00000004 | ||
52 | #define ESDHC_CLOCK_HCKEN 0x00000002 | ||
53 | #define ESDHC_CLOCK_IPGEN 0x00000001 | ||
54 | |||
55 | /* Control Register for DMA transfer */ | ||
56 | #define ESDHC_DMA_SYSCTL 0x40c | ||
57 | #define ESDHC_DMA_SNOOP 0x00000040 | ||
52 | 58 | ||
53 | #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */ | 59 | #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */ |
diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c index d7046d67415a..3275d4995812 100644 --- a/drivers/mmc/host/sdhci-iproc.c +++ b/drivers/mmc/host/sdhci-iproc.c | |||
@@ -211,14 +211,19 @@ static const struct sdhci_iproc_data iproc_data = { | |||
211 | static const struct sdhci_pltfm_data sdhci_bcm2835_pltfm_data = { | 211 | static const struct sdhci_pltfm_data sdhci_bcm2835_pltfm_data = { |
212 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | | 212 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | |
213 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | | 213 | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | |
214 | SDHCI_QUIRK_MISSING_CAPS, | 214 | SDHCI_QUIRK_MISSING_CAPS | |
215 | SDHCI_QUIRK_NO_HISPD_BIT, | ||
215 | .ops = &sdhci_iproc_32only_ops, | 216 | .ops = &sdhci_iproc_32only_ops, |
216 | }; | 217 | }; |
217 | 218 | ||
218 | static const struct sdhci_iproc_data bcm2835_data = { | 219 | static const struct sdhci_iproc_data bcm2835_data = { |
219 | .pdata = &sdhci_bcm2835_pltfm_data, | 220 | .pdata = &sdhci_bcm2835_pltfm_data, |
220 | .caps = SDHCI_CAN_VDD_330, | 221 | .caps = ((0x1 << SDHCI_MAX_BLOCK_SHIFT) |
221 | .caps1 = 0x00000000, | 222 | & SDHCI_MAX_BLOCK_MASK) | |
223 | SDHCI_CAN_VDD_330 | | ||
224 | SDHCI_CAN_DO_HISPD, | ||
225 | .caps1 = SDHCI_DRIVER_TYPE_A | | ||
226 | SDHCI_DRIVER_TYPE_C, | ||
222 | .mmc_caps = 0x00000000, | 227 | .mmc_caps = 0x00000000, |
223 | }; | 228 | }; |
224 | 229 | ||
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 32879b845b75..10cdc84d5113 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #define CORE_DLL_CLOCK_DISABLE BIT(21) | 69 | #define CORE_DLL_CLOCK_DISABLE BIT(21) |
70 | 70 | ||
71 | #define CORE_VENDOR_SPEC 0x10c | 71 | #define CORE_VENDOR_SPEC 0x10c |
72 | #define CORE_VENDOR_SPEC_POR_VAL 0xa1c | ||
72 | #define CORE_CLK_PWRSAVE BIT(1) | 73 | #define CORE_CLK_PWRSAVE BIT(1) |
73 | #define CORE_HC_MCLK_SEL_DFLT (2 << 8) | 74 | #define CORE_HC_MCLK_SEL_DFLT (2 << 8) |
74 | #define CORE_HC_MCLK_SEL_HS400 (3 << 8) | 75 | #define CORE_HC_MCLK_SEL_HS400 (3 << 8) |
@@ -102,6 +103,7 @@ | |||
102 | 103 | ||
103 | #define CORE_DDR_200_CFG 0x184 | 104 | #define CORE_DDR_200_CFG 0x184 |
104 | #define CORE_CDC_T4_DLY_SEL BIT(0) | 105 | #define CORE_CDC_T4_DLY_SEL BIT(0) |
106 | #define CORE_CMDIN_RCLK_EN BIT(1) | ||
105 | #define CORE_START_CDC_TRAFFIC BIT(6) | 107 | #define CORE_START_CDC_TRAFFIC BIT(6) |
106 | #define CORE_VENDOR_SPEC3 0x1b0 | 108 | #define CORE_VENDOR_SPEC3 0x1b0 |
107 | #define CORE_PWRSAVE_DLL BIT(3) | 109 | #define CORE_PWRSAVE_DLL BIT(3) |
@@ -138,6 +140,46 @@ struct sdhci_msm_host { | |||
138 | bool use_cdclp533; | 140 | bool use_cdclp533; |
139 | }; | 141 | }; |
140 | 142 | ||
143 | static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host, | ||
144 | unsigned int clock) | ||
145 | { | ||
146 | struct mmc_ios ios = host->mmc->ios; | ||
147 | /* | ||
148 | * The SDHC requires internal clock frequency to be double the | ||
149 | * actual clock that will be set for DDR mode. The controller | ||
150 | * uses the faster clock(100/400MHz) for some of its parts and | ||
151 | * send the actual required clock (50/200MHz) to the card. | ||
152 | */ | ||
153 | if (ios.timing == MMC_TIMING_UHS_DDR50 || | ||
154 | ios.timing == MMC_TIMING_MMC_DDR52 || | ||
155 | ios.timing == MMC_TIMING_MMC_HS400 || | ||
156 | host->flags & SDHCI_HS400_TUNING) | ||
157 | clock *= 2; | ||
158 | return clock; | ||
159 | } | ||
160 | |||
161 | static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host, | ||
162 | unsigned int clock) | ||
163 | { | ||
164 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
165 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
166 | struct mmc_ios curr_ios = host->mmc->ios; | ||
167 | int rc; | ||
168 | |||
169 | clock = msm_get_clock_rate_for_bus_mode(host, clock); | ||
170 | rc = clk_set_rate(msm_host->clk, clock); | ||
171 | if (rc) { | ||
172 | pr_err("%s: Failed to set clock at rate %u at timing %d\n", | ||
173 | mmc_hostname(host->mmc), clock, | ||
174 | curr_ios.timing); | ||
175 | return; | ||
176 | } | ||
177 | msm_host->clk_rate = clock; | ||
178 | pr_debug("%s: Setting clock at rate %lu at timing %d\n", | ||
179 | mmc_hostname(host->mmc), clk_get_rate(msm_host->clk), | ||
180 | curr_ios.timing); | ||
181 | } | ||
182 | |||
141 | /* Platform specific tuning */ | 183 | /* Platform specific tuning */ |
142 | static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll) | 184 | static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll) |
143 | { | 185 | { |
@@ -464,6 +506,122 @@ static int msm_init_cm_dll(struct sdhci_host *host) | |||
464 | return 0; | 506 | return 0; |
465 | } | 507 | } |
466 | 508 | ||
509 | static void msm_hc_select_default(struct sdhci_host *host) | ||
510 | { | ||
511 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
512 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
513 | u32 config; | ||
514 | |||
515 | if (!msm_host->use_cdclp533) { | ||
516 | config = readl_relaxed(host->ioaddr + | ||
517 | CORE_VENDOR_SPEC3); | ||
518 | config &= ~CORE_PWRSAVE_DLL; | ||
519 | writel_relaxed(config, host->ioaddr + | ||
520 | CORE_VENDOR_SPEC3); | ||
521 | } | ||
522 | |||
523 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
524 | config &= ~CORE_HC_MCLK_SEL_MASK; | ||
525 | config |= CORE_HC_MCLK_SEL_DFLT; | ||
526 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
527 | |||
528 | /* | ||
529 | * Disable HC_SELECT_IN to be able to use the UHS mode select | ||
530 | * configuration from Host Control2 register for all other | ||
531 | * modes. | ||
532 | * Write 0 to HC_SELECT_IN and HC_SELECT_IN_EN field | ||
533 | * in VENDOR_SPEC_FUNC | ||
534 | */ | ||
535 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
536 | config &= ~CORE_HC_SELECT_IN_EN; | ||
537 | config &= ~CORE_HC_SELECT_IN_MASK; | ||
538 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
539 | |||
540 | /* | ||
541 | * Make sure above writes impacting free running MCLK are completed | ||
542 | * before changing the clk_rate at GCC. | ||
543 | */ | ||
544 | wmb(); | ||
545 | } | ||
546 | |||
547 | static void msm_hc_select_hs400(struct sdhci_host *host) | ||
548 | { | ||
549 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
550 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
551 | struct mmc_ios ios = host->mmc->ios; | ||
552 | u32 config, dll_lock; | ||
553 | int rc; | ||
554 | |||
555 | /* Select the divided clock (free running MCLK/2) */ | ||
556 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
557 | config &= ~CORE_HC_MCLK_SEL_MASK; | ||
558 | config |= CORE_HC_MCLK_SEL_HS400; | ||
559 | |||
560 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
561 | /* | ||
562 | * Select HS400 mode using the HC_SELECT_IN from VENDOR SPEC | ||
563 | * register | ||
564 | */ | ||
565 | if ((msm_host->tuning_done || ios.enhanced_strobe) && | ||
566 | !msm_host->calibration_done) { | ||
567 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
568 | config |= CORE_HC_SELECT_IN_HS400; | ||
569 | config |= CORE_HC_SELECT_IN_EN; | ||
570 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
571 | } | ||
572 | if (!msm_host->clk_rate && !msm_host->use_cdclp533) { | ||
573 | /* | ||
574 | * Poll on DLL_LOCK or DDR_DLL_LOCK bits in | ||
575 | * CORE_DLL_STATUS to be set. This should get set | ||
576 | * within 15 us at 200 MHz. | ||
577 | */ | ||
578 | rc = readl_relaxed_poll_timeout(host->ioaddr + | ||
579 | CORE_DLL_STATUS, | ||
580 | dll_lock, | ||
581 | (dll_lock & | ||
582 | (CORE_DLL_LOCK | | ||
583 | CORE_DDR_DLL_LOCK)), 10, | ||
584 | 1000); | ||
585 | if (rc == -ETIMEDOUT) | ||
586 | pr_err("%s: Unable to get DLL_LOCK/DDR_DLL_LOCK, dll_status: 0x%08x\n", | ||
587 | mmc_hostname(host->mmc), dll_lock); | ||
588 | } | ||
589 | /* | ||
590 | * Make sure above writes impacting free running MCLK are completed | ||
591 | * before changing the clk_rate at GCC. | ||
592 | */ | ||
593 | wmb(); | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * sdhci_msm_hc_select_mode :- In general all timing modes are | ||
598 | * controlled via UHS mode select in Host Control2 register. | ||
599 | * eMMC specific HS200/HS400 doesn't have their respective modes | ||
600 | * defined here, hence we use these values. | ||
601 | * | ||
602 | * HS200 - SDR104 (Since they both are equivalent in functionality) | ||
603 | * HS400 - This involves multiple configurations | ||
604 | * Initially SDR104 - when tuning is required as HS200 | ||
605 | * Then when switching to DDR @ 400MHz (HS400) we use | ||
606 | * the vendor specific HC_SELECT_IN to control the mode. | ||
607 | * | ||
608 | * In addition to controlling the modes we also need to select the | ||
609 | * correct input clock for DLL depending on the mode. | ||
610 | * | ||
611 | * HS400 - divided clock (free running MCLK/2) | ||
612 | * All other modes - default (free running MCLK) | ||
613 | */ | ||
614 | void sdhci_msm_hc_select_mode(struct sdhci_host *host) | ||
615 | { | ||
616 | struct mmc_ios ios = host->mmc->ios; | ||
617 | |||
618 | if (ios.timing == MMC_TIMING_MMC_HS400 || | ||
619 | host->flags & SDHCI_HS400_TUNING) | ||
620 | msm_hc_select_hs400(host); | ||
621 | else | ||
622 | msm_hc_select_default(host); | ||
623 | } | ||
624 | |||
467 | static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host) | 625 | static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host) |
468 | { | 626 | { |
469 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 627 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
@@ -506,19 +664,7 @@ static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host) | |||
506 | config &= ~CORE_START_CDC_TRAFFIC; | 664 | config &= ~CORE_START_CDC_TRAFFIC; |
507 | writel_relaxed(config, host->ioaddr + CORE_DDR_200_CFG); | 665 | writel_relaxed(config, host->ioaddr + CORE_DDR_200_CFG); |
508 | 666 | ||
509 | /* | 667 | /* Perform CDC Register Initialization Sequence */ |
510 | * Perform CDC Register Initialization Sequence | ||
511 | * | ||
512 | * CORE_CSR_CDC_CTLR_CFG0 0x11800EC | ||
513 | * CORE_CSR_CDC_CTLR_CFG1 0x3011111 | ||
514 | * CORE_CSR_CDC_CAL_TIMER_CFG0 0x1201000 | ||
515 | * CORE_CSR_CDC_CAL_TIMER_CFG1 0x4 | ||
516 | * CORE_CSR_CDC_REFCOUNT_CFG 0xCB732020 | ||
517 | * CORE_CSR_CDC_COARSE_CAL_CFG 0xB19 | ||
518 | * CORE_CSR_CDC_DELAY_CFG 0x3AC | ||
519 | * CORE_CDC_OFFSET_CFG 0x0 | ||
520 | * CORE_CDC_SLAVE_DDA_CFG 0x16334 | ||
521 | */ | ||
522 | 668 | ||
523 | writel_relaxed(0x11800EC, host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | 669 | writel_relaxed(0x11800EC, host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); |
524 | writel_relaxed(0x3011111, host->ioaddr + CORE_CSR_CDC_CTLR_CFG1); | 670 | writel_relaxed(0x3011111, host->ioaddr + CORE_CSR_CDC_CTLR_CFG1); |
@@ -526,7 +672,7 @@ static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host) | |||
526 | writel_relaxed(0x4, host->ioaddr + CORE_CSR_CDC_CAL_TIMER_CFG1); | 672 | writel_relaxed(0x4, host->ioaddr + CORE_CSR_CDC_CAL_TIMER_CFG1); |
527 | writel_relaxed(0xCB732020, host->ioaddr + CORE_CSR_CDC_REFCOUNT_CFG); | 673 | writel_relaxed(0xCB732020, host->ioaddr + CORE_CSR_CDC_REFCOUNT_CFG); |
528 | writel_relaxed(0xB19, host->ioaddr + CORE_CSR_CDC_COARSE_CAL_CFG); | 674 | writel_relaxed(0xB19, host->ioaddr + CORE_CSR_CDC_COARSE_CAL_CFG); |
529 | writel_relaxed(0x3AC, host->ioaddr + CORE_CSR_CDC_DELAY_CFG); | 675 | writel_relaxed(0x4E2, host->ioaddr + CORE_CSR_CDC_DELAY_CFG); |
530 | writel_relaxed(0x0, host->ioaddr + CORE_CDC_OFFSET_CFG); | 676 | writel_relaxed(0x0, host->ioaddr + CORE_CDC_OFFSET_CFG); |
531 | writel_relaxed(0x16334, host->ioaddr + CORE_CDC_SLAVE_DDA_CFG); | 677 | writel_relaxed(0x16334, host->ioaddr + CORE_CDC_SLAVE_DDA_CFG); |
532 | 678 | ||
@@ -579,6 +725,7 @@ out: | |||
579 | 725 | ||
580 | static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host) | 726 | static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host) |
581 | { | 727 | { |
728 | struct mmc_host *mmc = host->mmc; | ||
582 | u32 dll_status, config; | 729 | u32 dll_status, config; |
583 | int ret; | 730 | int ret; |
584 | 731 | ||
@@ -593,6 +740,12 @@ static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host) | |||
593 | */ | 740 | */ |
594 | writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr + CORE_DDR_CONFIG); | 741 | writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr + CORE_DDR_CONFIG); |
595 | 742 | ||
743 | if (mmc->ios.enhanced_strobe) { | ||
744 | config = readl_relaxed(host->ioaddr + CORE_DDR_200_CFG); | ||
745 | config |= CORE_CMDIN_RCLK_EN; | ||
746 | writel_relaxed(config, host->ioaddr + CORE_DDR_200_CFG); | ||
747 | } | ||
748 | |||
596 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG_2); | 749 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG_2); |
597 | config |= CORE_DDR_CAL_EN; | 750 | config |= CORE_DDR_CAL_EN; |
598 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG_2); | 751 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG_2); |
@@ -627,6 +780,7 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host) | |||
627 | { | 780 | { |
628 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 781 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
629 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 782 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
783 | struct mmc_host *mmc = host->mmc; | ||
630 | int ret; | 784 | int ret; |
631 | u32 config; | 785 | u32 config; |
632 | 786 | ||
@@ -640,14 +794,17 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host) | |||
640 | if (ret) | 794 | if (ret) |
641 | goto out; | 795 | goto out; |
642 | 796 | ||
643 | /* Set the selected phase in delay line hw block */ | 797 | if (!mmc->ios.enhanced_strobe) { |
644 | ret = msm_config_cm_dll_phase(host, msm_host->saved_tuning_phase); | 798 | /* Set the selected phase in delay line hw block */ |
645 | if (ret) | 799 | ret = msm_config_cm_dll_phase(host, |
646 | goto out; | 800 | msm_host->saved_tuning_phase); |
801 | if (ret) | ||
802 | goto out; | ||
803 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG); | ||
804 | config |= CORE_CMD_DAT_TRACK_SEL; | ||
805 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG); | ||
806 | } | ||
647 | 807 | ||
648 | config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG); | ||
649 | config |= CORE_CMD_DAT_TRACK_SEL; | ||
650 | writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG); | ||
651 | if (msm_host->use_cdclp533) | 808 | if (msm_host->use_cdclp533) |
652 | ret = sdhci_msm_cdclp533_calibration(host); | 809 | ret = sdhci_msm_cdclp533_calibration(host); |
653 | else | 810 | else |
@@ -658,12 +815,12 @@ out: | |||
658 | return ret; | 815 | return ret; |
659 | } | 816 | } |
660 | 817 | ||
661 | static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode) | 818 | static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) |
662 | { | 819 | { |
820 | struct sdhci_host *host = mmc_priv(mmc); | ||
663 | int tuning_seq_cnt = 3; | 821 | int tuning_seq_cnt = 3; |
664 | u8 phase, tuned_phases[16], tuned_phase_cnt = 0; | 822 | u8 phase, tuned_phases[16], tuned_phase_cnt = 0; |
665 | int rc; | 823 | int rc; |
666 | struct mmc_host *mmc = host->mmc; | ||
667 | struct mmc_ios ios = host->mmc->ios; | 824 | struct mmc_ios ios = host->mmc->ios; |
668 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 825 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
669 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 826 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
@@ -678,6 +835,17 @@ static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode) | |||
678 | ios.timing == MMC_TIMING_UHS_SDR104)) | 835 | ios.timing == MMC_TIMING_UHS_SDR104)) |
679 | return 0; | 836 | return 0; |
680 | 837 | ||
838 | /* | ||
839 | * For HS400 tuning in HS200 timing requires: | ||
840 | * - select MCLK/2 in VENDOR_SPEC | ||
841 | * - program MCLK to 400MHz (or nearest supported) in GCC | ||
842 | */ | ||
843 | if (host->flags & SDHCI_HS400_TUNING) { | ||
844 | sdhci_msm_hc_select_mode(host); | ||
845 | msm_set_clock_rate_for_bus_mode(host, ios.clock); | ||
846 | host->flags &= ~SDHCI_HS400_TUNING; | ||
847 | } | ||
848 | |||
681 | retry: | 849 | retry: |
682 | /* First of all reset the tuning block */ | 850 | /* First of all reset the tuning block */ |
683 | rc = msm_init_cm_dll(host); | 851 | rc = msm_init_cm_dll(host); |
@@ -732,6 +900,30 @@ retry: | |||
732 | return rc; | 900 | return rc; |
733 | } | 901 | } |
734 | 902 | ||
903 | /* | ||
904 | * sdhci_msm_hs400 - Calibrate the DLL for HS400 bus speed mode operation. | ||
905 | * This needs to be done for both tuning and enhanced_strobe mode. | ||
906 | * DLL operation is only needed for clock > 100MHz. For clock <= 100MHz | ||
907 | * fixed feedback clock is used. | ||
908 | */ | ||
909 | static void sdhci_msm_hs400(struct sdhci_host *host, struct mmc_ios *ios) | ||
910 | { | ||
911 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
912 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | ||
913 | int ret; | ||
914 | |||
915 | if (host->clock > CORE_FREQ_100MHZ && | ||
916 | (msm_host->tuning_done || ios->enhanced_strobe) && | ||
917 | !msm_host->calibration_done) { | ||
918 | ret = sdhci_msm_hs400_dll_calibration(host); | ||
919 | if (!ret) | ||
920 | msm_host->calibration_done = true; | ||
921 | else | ||
922 | pr_err("%s: Failed to calibrate DLL for hs400 mode (%d)\n", | ||
923 | mmc_hostname(host->mmc), ret); | ||
924 | } | ||
925 | } | ||
926 | |||
735 | static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, | 927 | static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, |
736 | unsigned int uhs) | 928 | unsigned int uhs) |
737 | { | 929 | { |
@@ -800,12 +992,10 @@ static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, | |||
800 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); | 992 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); |
801 | 993 | ||
802 | spin_unlock_irq(&host->lock); | 994 | spin_unlock_irq(&host->lock); |
803 | /* CDCLP533 HW calibration is only required for HS400 mode*/ | 995 | |
804 | if (host->clock > CORE_FREQ_100MHZ && | 996 | if (mmc->ios.timing == MMC_TIMING_MMC_HS400) |
805 | msm_host->tuning_done && !msm_host->calibration_done && | 997 | sdhci_msm_hs400(host, &mmc->ios); |
806 | mmc->ios.timing == MMC_TIMING_MMC_HS400) | 998 | |
807 | if (!sdhci_msm_hs400_dll_calibration(host)) | ||
808 | msm_host->calibration_done = true; | ||
809 | spin_lock_irq(&host->lock); | 999 | spin_lock_irq(&host->lock); |
810 | } | 1000 | } |
811 | 1001 | ||
@@ -893,9 +1083,6 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) | |||
893 | { | 1083 | { |
894 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 1084 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
895 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | 1085 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
896 | struct mmc_ios curr_ios = host->mmc->ios; | ||
897 | u32 config, dll_lock; | ||
898 | int rc; | ||
899 | 1086 | ||
900 | if (!clock) { | 1087 | if (!clock) { |
901 | msm_host->clk_rate = clock; | 1088 | msm_host->clk_rate = clock; |
@@ -903,117 +1090,11 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) | |||
903 | } | 1090 | } |
904 | 1091 | ||
905 | spin_unlock_irq(&host->lock); | 1092 | spin_unlock_irq(&host->lock); |
906 | /* | ||
907 | * The SDHC requires internal clock frequency to be double the | ||
908 | * actual clock that will be set for DDR mode. The controller | ||
909 | * uses the faster clock(100/400MHz) for some of its parts and | ||
910 | * send the actual required clock (50/200MHz) to the card. | ||
911 | */ | ||
912 | if (curr_ios.timing == MMC_TIMING_UHS_DDR50 || | ||
913 | curr_ios.timing == MMC_TIMING_MMC_DDR52 || | ||
914 | curr_ios.timing == MMC_TIMING_MMC_HS400) | ||
915 | clock *= 2; | ||
916 | /* | ||
917 | * In general all timing modes are controlled via UHS mode select in | ||
918 | * Host Control2 register. eMMC specific HS200/HS400 doesn't have | ||
919 | * their respective modes defined here, hence we use these values. | ||
920 | * | ||
921 | * HS200 - SDR104 (Since they both are equivalent in functionality) | ||
922 | * HS400 - This involves multiple configurations | ||
923 | * Initially SDR104 - when tuning is required as HS200 | ||
924 | * Then when switching to DDR @ 400MHz (HS400) we use | ||
925 | * the vendor specific HC_SELECT_IN to control the mode. | ||
926 | * | ||
927 | * In addition to controlling the modes we also need to select the | ||
928 | * correct input clock for DLL depending on the mode. | ||
929 | * | ||
930 | * HS400 - divided clock (free running MCLK/2) | ||
931 | * All other modes - default (free running MCLK) | ||
932 | */ | ||
933 | if (curr_ios.timing == MMC_TIMING_MMC_HS400) { | ||
934 | /* Select the divided clock (free running MCLK/2) */ | ||
935 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
936 | config &= ~CORE_HC_MCLK_SEL_MASK; | ||
937 | config |= CORE_HC_MCLK_SEL_HS400; | ||
938 | 1093 | ||
939 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | 1094 | sdhci_msm_hc_select_mode(host); |
940 | /* | ||
941 | * Select HS400 mode using the HC_SELECT_IN from VENDOR SPEC | ||
942 | * register | ||
943 | */ | ||
944 | if (msm_host->tuning_done && !msm_host->calibration_done) { | ||
945 | /* | ||
946 | * Write 0x6 to HC_SELECT_IN and 1 to HC_SELECT_IN_EN | ||
947 | * field in VENDOR_SPEC_FUNC | ||
948 | */ | ||
949 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
950 | config |= CORE_HC_SELECT_IN_HS400; | ||
951 | config |= CORE_HC_SELECT_IN_EN; | ||
952 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
953 | } | ||
954 | if (!msm_host->clk_rate && !msm_host->use_cdclp533) { | ||
955 | /* | ||
956 | * Poll on DLL_LOCK or DDR_DLL_LOCK bits in | ||
957 | * CORE_DLL_STATUS to be set. This should get set | ||
958 | * within 15 us at 200 MHz. | ||
959 | */ | ||
960 | rc = readl_relaxed_poll_timeout(host->ioaddr + | ||
961 | CORE_DLL_STATUS, | ||
962 | dll_lock, | ||
963 | (dll_lock & | ||
964 | (CORE_DLL_LOCK | | ||
965 | CORE_DDR_DLL_LOCK)), 10, | ||
966 | 1000); | ||
967 | if (rc == -ETIMEDOUT) | ||
968 | pr_err("%s: Unable to get DLL_LOCK/DDR_DLL_LOCK, dll_status: 0x%08x\n", | ||
969 | mmc_hostname(host->mmc), dll_lock); | ||
970 | } | ||
971 | } else { | ||
972 | if (!msm_host->use_cdclp533) { | ||
973 | config = readl_relaxed(host->ioaddr + | ||
974 | CORE_VENDOR_SPEC3); | ||
975 | config &= ~CORE_PWRSAVE_DLL; | ||
976 | writel_relaxed(config, host->ioaddr + | ||
977 | CORE_VENDOR_SPEC3); | ||
978 | } | ||
979 | 1095 | ||
980 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | 1096 | msm_set_clock_rate_for_bus_mode(host, clock); |
981 | config &= ~CORE_HC_MCLK_SEL_MASK; | ||
982 | config |= CORE_HC_MCLK_SEL_DFLT; | ||
983 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
984 | 1097 | ||
985 | /* | ||
986 | * Disable HC_SELECT_IN to be able to use the UHS mode select | ||
987 | * configuration from Host Control2 register for all other | ||
988 | * modes. | ||
989 | * Write 0 to HC_SELECT_IN and HC_SELECT_IN_EN field | ||
990 | * in VENDOR_SPEC_FUNC | ||
991 | */ | ||
992 | config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC); | ||
993 | config &= ~CORE_HC_SELECT_IN_EN; | ||
994 | config &= ~CORE_HC_SELECT_IN_MASK; | ||
995 | writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC); | ||
996 | } | ||
997 | |||
998 | /* | ||
999 | * Make sure above writes impacting free running MCLK are completed | ||
1000 | * before changing the clk_rate at GCC. | ||
1001 | */ | ||
1002 | wmb(); | ||
1003 | |||
1004 | rc = clk_set_rate(msm_host->clk, clock); | ||
1005 | if (rc) { | ||
1006 | pr_err("%s: Failed to set clock at rate %u at timing %d\n", | ||
1007 | mmc_hostname(host->mmc), clock, | ||
1008 | curr_ios.timing); | ||
1009 | goto out_lock; | ||
1010 | } | ||
1011 | msm_host->clk_rate = clock; | ||
1012 | pr_debug("%s: Setting clock at rate %lu at timing %d\n", | ||
1013 | mmc_hostname(host->mmc), clk_get_rate(msm_host->clk), | ||
1014 | curr_ios.timing); | ||
1015 | |||
1016 | out_lock: | ||
1017 | spin_lock_irq(&host->lock); | 1098 | spin_lock_irq(&host->lock); |
1018 | out: | 1099 | out: |
1019 | __sdhci_msm_set_clock(host, clock); | 1100 | __sdhci_msm_set_clock(host, clock); |
@@ -1027,7 +1108,6 @@ static const struct of_device_id sdhci_msm_dt_match[] = { | |||
1027 | MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match); | 1108 | MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match); |
1028 | 1109 | ||
1029 | static const struct sdhci_ops sdhci_msm_ops = { | 1110 | static const struct sdhci_ops sdhci_msm_ops = { |
1030 | .platform_execute_tuning = sdhci_msm_execute_tuning, | ||
1031 | .reset = sdhci_reset, | 1111 | .reset = sdhci_reset, |
1032 | .set_clock = sdhci_msm_set_clock, | 1112 | .set_clock = sdhci_msm_set_clock, |
1033 | .get_min_clock = sdhci_msm_get_min_clock, | 1113 | .get_min_clock = sdhci_msm_get_min_clock, |
@@ -1134,17 +1214,9 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1134 | goto clk_disable; | 1214 | goto clk_disable; |
1135 | } | 1215 | } |
1136 | 1216 | ||
1137 | config = readl_relaxed(msm_host->core_mem + CORE_POWER); | 1217 | /* Reset the vendor spec register to power on reset state */ |
1138 | config |= CORE_SW_RST; | 1218 | writel_relaxed(CORE_VENDOR_SPEC_POR_VAL, |
1139 | writel_relaxed(config, msm_host->core_mem + CORE_POWER); | 1219 | host->ioaddr + CORE_VENDOR_SPEC); |
1140 | |||
1141 | /* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */ | ||
1142 | usleep_range(1000, 5000); | ||
1143 | if (readl(msm_host->core_mem + CORE_POWER) & CORE_SW_RST) { | ||
1144 | dev_err(&pdev->dev, "Stuck in reset\n"); | ||
1145 | ret = -ETIMEDOUT; | ||
1146 | goto clk_disable; | ||
1147 | } | ||
1148 | 1220 | ||
1149 | /* Set HC_MODE_EN bit in HC_MODE register */ | 1221 | /* Set HC_MODE_EN bit in HC_MODE register */ |
1150 | writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE)); | 1222 | writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE)); |
@@ -1210,6 +1282,7 @@ static int sdhci_msm_probe(struct platform_device *pdev) | |||
1210 | MSM_MMC_AUTOSUSPEND_DELAY_MS); | 1282 | MSM_MMC_AUTOSUSPEND_DELAY_MS); |
1211 | pm_runtime_use_autosuspend(&pdev->dev); | 1283 | pm_runtime_use_autosuspend(&pdev->dev); |
1212 | 1284 | ||
1285 | host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning; | ||
1213 | ret = sdhci_add_host(host); | 1286 | ret = sdhci_add_host(host); |
1214 | if (ret) | 1287 | if (ret) |
1215 | goto pm_runtime_disable; | 1288 | goto pm_runtime_disable; |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 9a6eb4492172..d3aa67142839 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -431,6 +431,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) | |||
431 | struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); | 431 | struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); |
432 | int pre_div = 1; | 432 | int pre_div = 1; |
433 | int div = 1; | 433 | int div = 1; |
434 | u32 timeout; | ||
434 | u32 temp; | 435 | u32 temp; |
435 | 436 | ||
436 | host->mmc->actual_clock = 0; | 437 | host->mmc->actual_clock = 0; |
@@ -451,8 +452,8 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) | |||
451 | } | 452 | } |
452 | 453 | ||
453 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); | 454 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); |
454 | temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | 455 | temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | |
455 | | ESDHC_CLOCK_MASK); | 456 | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); |
456 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); | 457 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); |
457 | 458 | ||
458 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) | 459 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) |
@@ -472,7 +473,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) | |||
472 | | (div << ESDHC_DIVIDER_SHIFT) | 473 | | (div << ESDHC_DIVIDER_SHIFT) |
473 | | (pre_div << ESDHC_PREDIV_SHIFT)); | 474 | | (pre_div << ESDHC_PREDIV_SHIFT)); |
474 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); | 475 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); |
475 | mdelay(1); | 476 | |
477 | /* Wait max 20 ms */ | ||
478 | timeout = 20; | ||
479 | while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) { | ||
480 | if (timeout == 0) { | ||
481 | pr_err("%s: Internal clock never stabilised.\n", | ||
482 | mmc_hostname(host->mmc)); | ||
483 | return; | ||
484 | } | ||
485 | timeout--; | ||
486 | mdelay(1); | ||
487 | } | ||
488 | |||
489 | temp |= ESDHC_CLOCK_SDCLKEN; | ||
490 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); | ||
476 | } | 491 | } |
477 | 492 | ||
478 | static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) | 493 | static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) |
@@ -569,16 +584,19 @@ static const struct sdhci_ops sdhci_esdhc_le_ops = { | |||
569 | }; | 584 | }; |
570 | 585 | ||
571 | static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { | 586 | static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = { |
572 | .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION | 587 | .quirks = ESDHC_DEFAULT_QUIRKS | |
573 | | SDHCI_QUIRK_NO_CARD_NO_RESET | 588 | #ifdef CONFIG_PPC |
574 | | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 589 | SDHCI_QUIRK_BROKEN_CARD_DETECTION | |
590 | #endif | ||
591 | SDHCI_QUIRK_NO_CARD_NO_RESET | | ||
592 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | ||
575 | .ops = &sdhci_esdhc_be_ops, | 593 | .ops = &sdhci_esdhc_be_ops, |
576 | }; | 594 | }; |
577 | 595 | ||
578 | static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { | 596 | static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { |
579 | .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION | 597 | .quirks = ESDHC_DEFAULT_QUIRKS | |
580 | | SDHCI_QUIRK_NO_CARD_NO_RESET | 598 | SDHCI_QUIRK_NO_CARD_NO_RESET | |
581 | | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 599 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
582 | .ops = &sdhci_esdhc_le_ops, | 600 | .ops = &sdhci_esdhc_le_ops, |
583 | }; | 601 | }; |
584 | 602 | ||
@@ -643,8 +661,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) | |||
643 | of_device_is_compatible(np, "fsl,p5020-esdhc") || | 661 | of_device_is_compatible(np, "fsl,p5020-esdhc") || |
644 | of_device_is_compatible(np, "fsl,p4080-esdhc") || | 662 | of_device_is_compatible(np, "fsl,p4080-esdhc") || |
645 | of_device_is_compatible(np, "fsl,p1020-esdhc") || | 663 | of_device_is_compatible(np, "fsl,p1020-esdhc") || |
646 | of_device_is_compatible(np, "fsl,t1040-esdhc") || | 664 | of_device_is_compatible(np, "fsl,t1040-esdhc")) |
647 | of_device_is_compatible(np, "fsl,ls1021a-esdhc")) | ||
648 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | 665 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
649 | 666 | ||
650 | if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) | 667 | if (of_device_is_compatible(np, "fsl,ls1021a-esdhc")) |
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index 1a72d32af07f..982b3e349426 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c | |||
@@ -424,7 +424,6 @@ static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot) | |||
424 | static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) | 424 | static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) |
425 | { | 425 | { |
426 | slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; | 426 | slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; |
427 | slot->cd_con_id = NULL; | ||
428 | slot->cd_idx = 0; | 427 | slot->cd_idx = 0; |
429 | slot->cd_override_level = true; | 428 | slot->cd_override_level = true; |
430 | if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXT_SD || | 429 | if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXT_SD || |
@@ -866,6 +865,86 @@ enum amd_chipset_gen { | |||
866 | AMD_CHIPSET_UNKNOWN, | 865 | AMD_CHIPSET_UNKNOWN, |
867 | }; | 866 | }; |
868 | 867 | ||
868 | /* AMD registers */ | ||
869 | #define AMD_SD_AUTO_PATTERN 0xB8 | ||
870 | #define AMD_MSLEEP_DURATION 4 | ||
871 | #define AMD_SD_MISC_CONTROL 0xD0 | ||
872 | #define AMD_MAX_TUNE_VALUE 0x0B | ||
873 | #define AMD_AUTO_TUNE_SEL 0x10800 | ||
874 | #define AMD_FIFO_PTR 0x30 | ||
875 | #define AMD_BIT_MASK 0x1F | ||
876 | |||
877 | static void amd_tuning_reset(struct sdhci_host *host) | ||
878 | { | ||
879 | unsigned int val; | ||
880 | |||
881 | val = sdhci_readw(host, SDHCI_HOST_CONTROL2); | ||
882 | val |= SDHCI_CTRL_PRESET_VAL_ENABLE | SDHCI_CTRL_EXEC_TUNING; | ||
883 | sdhci_writew(host, val, SDHCI_HOST_CONTROL2); | ||
884 | |||
885 | val = sdhci_readw(host, SDHCI_HOST_CONTROL2); | ||
886 | val &= ~SDHCI_CTRL_EXEC_TUNING; | ||
887 | sdhci_writew(host, val, SDHCI_HOST_CONTROL2); | ||
888 | } | ||
889 | |||
890 | static void amd_config_tuning_phase(struct pci_dev *pdev, u8 phase) | ||
891 | { | ||
892 | unsigned int val; | ||
893 | |||
894 | pci_read_config_dword(pdev, AMD_SD_AUTO_PATTERN, &val); | ||
895 | val &= ~AMD_BIT_MASK; | ||
896 | val |= (AMD_AUTO_TUNE_SEL | (phase << 1)); | ||
897 | pci_write_config_dword(pdev, AMD_SD_AUTO_PATTERN, val); | ||
898 | } | ||
899 | |||
900 | static void amd_enable_manual_tuning(struct pci_dev *pdev) | ||
901 | { | ||
902 | unsigned int val; | ||
903 | |||
904 | pci_read_config_dword(pdev, AMD_SD_MISC_CONTROL, &val); | ||
905 | val |= AMD_FIFO_PTR; | ||
906 | pci_write_config_dword(pdev, AMD_SD_MISC_CONTROL, val); | ||
907 | } | ||
908 | |||
909 | static int amd_execute_tuning(struct sdhci_host *host, u32 opcode) | ||
910 | { | ||
911 | struct sdhci_pci_slot *slot = sdhci_priv(host); | ||
912 | struct pci_dev *pdev = slot->chip->pdev; | ||
913 | u8 valid_win = 0; | ||
914 | u8 valid_win_max = 0; | ||
915 | u8 valid_win_end = 0; | ||
916 | u8 ctrl, tune_around; | ||
917 | |||
918 | amd_tuning_reset(host); | ||
919 | |||
920 | for (tune_around = 0; tune_around < 12; tune_around++) { | ||
921 | amd_config_tuning_phase(pdev, tune_around); | ||
922 | |||
923 | if (mmc_send_tuning(host->mmc, opcode, NULL)) { | ||
924 | valid_win = 0; | ||
925 | msleep(AMD_MSLEEP_DURATION); | ||
926 | ctrl = SDHCI_RESET_CMD | SDHCI_RESET_DATA; | ||
927 | sdhci_writeb(host, ctrl, SDHCI_SOFTWARE_RESET); | ||
928 | } else if (++valid_win > valid_win_max) { | ||
929 | valid_win_max = valid_win; | ||
930 | valid_win_end = tune_around; | ||
931 | } | ||
932 | } | ||
933 | |||
934 | if (!valid_win_max) { | ||
935 | dev_err(&pdev->dev, "no tuning point found\n"); | ||
936 | return -EIO; | ||
937 | } | ||
938 | |||
939 | amd_config_tuning_phase(pdev, valid_win_end - valid_win_max / 2); | ||
940 | |||
941 | amd_enable_manual_tuning(pdev); | ||
942 | |||
943 | host->mmc->retune_period = 0; | ||
944 | |||
945 | return 0; | ||
946 | } | ||
947 | |||
869 | static int amd_probe(struct sdhci_pci_chip *chip) | 948 | static int amd_probe(struct sdhci_pci_chip *chip) |
870 | { | 949 | { |
871 | struct pci_dev *smbus_dev; | 950 | struct pci_dev *smbus_dev; |
@@ -888,16 +967,24 @@ static int amd_probe(struct sdhci_pci_chip *chip) | |||
888 | } | 967 | } |
889 | } | 968 | } |
890 | 969 | ||
891 | if ((gen == AMD_CHIPSET_BEFORE_ML) || (gen == AMD_CHIPSET_CZ)) { | 970 | if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ) |
892 | chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; | 971 | chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; |
893 | chip->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; | ||
894 | } | ||
895 | 972 | ||
896 | return 0; | 973 | return 0; |
897 | } | 974 | } |
898 | 975 | ||
976 | static const struct sdhci_ops amd_sdhci_pci_ops = { | ||
977 | .set_clock = sdhci_set_clock, | ||
978 | .enable_dma = sdhci_pci_enable_dma, | ||
979 | .set_bus_width = sdhci_pci_set_bus_width, | ||
980 | .reset = sdhci_reset, | ||
981 | .set_uhs_signaling = sdhci_set_uhs_signaling, | ||
982 | .platform_execute_tuning = amd_execute_tuning, | ||
983 | }; | ||
984 | |||
899 | static const struct sdhci_pci_fixes sdhci_amd = { | 985 | static const struct sdhci_pci_fixes sdhci_amd = { |
900 | .probe = amd_probe, | 986 | .probe = amd_probe, |
987 | .ops = &amd_sdhci_pci_ops, | ||
901 | }; | 988 | }; |
902 | 989 | ||
903 | static const struct pci_device_id pci_ids[] = { | 990 | static const struct pci_device_id pci_ids[] = { |
@@ -1817,7 +1904,7 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot( | |||
1817 | host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; | 1904 | host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; |
1818 | 1905 | ||
1819 | if (slot->cd_idx >= 0) { | 1906 | if (slot->cd_idx >= 0) { |
1820 | ret = mmc_gpiod_request_cd(host->mmc, slot->cd_con_id, slot->cd_idx, | 1907 | ret = mmc_gpiod_request_cd(host->mmc, NULL, slot->cd_idx, |
1821 | slot->cd_override_level, 0, NULL); | 1908 | slot->cd_override_level, 0, NULL); |
1822 | if (ret == -EPROBE_DEFER) | 1909 | if (ret == -EPROBE_DEFER) |
1823 | goto remove; | 1910 | goto remove; |
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index 4abdaed72bd4..36f743464fcc 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
@@ -81,7 +81,6 @@ struct sdhci_pci_slot { | |||
81 | int cd_gpio; | 81 | int cd_gpio; |
82 | int cd_irq; | 82 | int cd_irq; |
83 | 83 | ||
84 | char *cd_con_id; | ||
85 | int cd_idx; | 84 | int cd_idx; |
86 | bool cd_override_level; | 85 | bool cd_override_level; |
87 | 86 | ||
diff --git a/drivers/mmc/host/sdhci-s3c-regs.h b/drivers/mmc/host/sdhci-s3c-regs.h deleted file mode 100644 index e34049ad44cc..000000000000 --- a/drivers/mmc/host/sdhci-s3c-regs.h +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | /* linux/arch/arm/plat-s3c/include/plat/regs-sdhci.h | ||
2 | * | ||
3 | * Copyright 2008 Openmoko, Inc. | ||
4 | * Copyright 2008 Simtec Electronics | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * Ben Dooks <ben@simtec.co.uk> | ||
7 | * | ||
8 | * S3C Platform - SDHCI (HSMMC) register definitions | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PLAT_S3C_SDHCI_REGS_H | ||
16 | #define __PLAT_S3C_SDHCI_REGS_H __FILE__ | ||
17 | |||
18 | #define S3C_SDHCI_CONTROL2 (0x80) | ||
19 | #define S3C_SDHCI_CONTROL3 (0x84) | ||
20 | #define S3C64XX_SDHCI_CONTROL4 (0x8C) | ||
21 | |||
22 | #define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR (1 << 31) | ||
23 | #define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK (1 << 30) | ||
24 | #define S3C_SDHCI_CTRL2_CDINVRXD3 (1 << 29) | ||
25 | #define S3C_SDHCI_CTRL2_SLCARDOUT (1 << 28) | ||
26 | |||
27 | #define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK (0xf << 24) | ||
28 | #define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT (24) | ||
29 | #define S3C_SDHCI_CTRL2_FLTCLKSEL(_x) ((_x) << 24) | ||
30 | |||
31 | #define S3C_SDHCI_CTRL2_LVLDAT_MASK (0xff << 16) | ||
32 | #define S3C_SDHCI_CTRL2_LVLDAT_SHIFT (16) | ||
33 | #define S3C_SDHCI_CTRL2_LVLDAT(_x) ((_x) << 16) | ||
34 | |||
35 | #define S3C_SDHCI_CTRL2_ENFBCLKTX (1 << 15) | ||
36 | #define S3C_SDHCI_CTRL2_ENFBCLKRX (1 << 14) | ||
37 | #define S3C_SDHCI_CTRL2_SDCDSEL (1 << 13) | ||
38 | #define S3C_SDHCI_CTRL2_SDSIGPC (1 << 12) | ||
39 | #define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART (1 << 11) | ||
40 | |||
41 | #define S3C_SDHCI_CTRL2_DFCNT_MASK (0x3 << 9) | ||
42 | #define S3C_SDHCI_CTRL2_DFCNT_SHIFT (9) | ||
43 | #define S3C_SDHCI_CTRL2_DFCNT_NONE (0x0 << 9) | ||
44 | #define S3C_SDHCI_CTRL2_DFCNT_4SDCLK (0x1 << 9) | ||
45 | #define S3C_SDHCI_CTRL2_DFCNT_16SDCLK (0x2 << 9) | ||
46 | #define S3C_SDHCI_CTRL2_DFCNT_64SDCLK (0x3 << 9) | ||
47 | |||
48 | #define S3C_SDHCI_CTRL2_ENCLKOUTHOLD (1 << 8) | ||
49 | #define S3C_SDHCI_CTRL2_RWAITMODE (1 << 7) | ||
50 | #define S3C_SDHCI_CTRL2_DISBUFRD (1 << 6) | ||
51 | #define S3C_SDHCI_CTRL2_SELBASECLK_MASK (0x3 << 4) | ||
52 | #define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT (4) | ||
53 | #define S3C_SDHCI_CTRL2_PWRSYNC (1 << 3) | ||
54 | #define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON (1 << 1) | ||
55 | #define S3C_SDHCI_CTRL2_HWINITFIN (1 << 0) | ||
56 | |||
57 | #define S3C_SDHCI_CTRL3_FCSEL3 (1 << 31) | ||
58 | #define S3C_SDHCI_CTRL3_FCSEL2 (1 << 23) | ||
59 | #define S3C_SDHCI_CTRL3_FCSEL1 (1 << 15) | ||
60 | #define S3C_SDHCI_CTRL3_FCSEL0 (1 << 7) | ||
61 | |||
62 | #define S3C_SDHCI_CTRL3_FIA3_MASK (0x7f << 24) | ||
63 | #define S3C_SDHCI_CTRL3_FIA3_SHIFT (24) | ||
64 | #define S3C_SDHCI_CTRL3_FIA3(_x) ((_x) << 24) | ||
65 | |||
66 | #define S3C_SDHCI_CTRL3_FIA2_MASK (0x7f << 16) | ||
67 | #define S3C_SDHCI_CTRL3_FIA2_SHIFT (16) | ||
68 | #define S3C_SDHCI_CTRL3_FIA2(_x) ((_x) << 16) | ||
69 | |||
70 | #define S3C_SDHCI_CTRL3_FIA1_MASK (0x7f << 8) | ||
71 | #define S3C_SDHCI_CTRL3_FIA1_SHIFT (8) | ||
72 | #define S3C_SDHCI_CTRL3_FIA1(_x) ((_x) << 8) | ||
73 | |||
74 | #define S3C_SDHCI_CTRL3_FIA0_MASK (0x7f << 0) | ||
75 | #define S3C_SDHCI_CTRL3_FIA0_SHIFT (0) | ||
76 | #define S3C_SDHCI_CTRL3_FIA0(_x) ((_x) << 0) | ||
77 | |||
78 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK (0x3 << 16) | ||
79 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT (16) | ||
80 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA (0x0 << 16) | ||
81 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA (0x1 << 16) | ||
82 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA (0x2 << 16) | ||
83 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16) | ||
84 | |||
85 | #define S3C64XX_SDHCI_CONTROL4_BUSY (1) | ||
86 | |||
87 | #endif /* __PLAT_S3C_SDHCI_REGS_H */ | ||
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index de219ca7ea7c..3e5c83d435ae 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -29,11 +29,80 @@ | |||
29 | 29 | ||
30 | #include <linux/mmc/host.h> | 30 | #include <linux/mmc/host.h> |
31 | 31 | ||
32 | #include "sdhci-s3c-regs.h" | ||
33 | #include "sdhci.h" | 32 | #include "sdhci.h" |
34 | 33 | ||
35 | #define MAX_BUS_CLK (4) | 34 | #define MAX_BUS_CLK (4) |
36 | 35 | ||
36 | #define S3C_SDHCI_CONTROL2 (0x80) | ||
37 | #define S3C_SDHCI_CONTROL3 (0x84) | ||
38 | #define S3C64XX_SDHCI_CONTROL4 (0x8C) | ||
39 | |||
40 | #define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR BIT(31) | ||
41 | #define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK BIT(30) | ||
42 | #define S3C_SDHCI_CTRL2_CDINVRXD3 BIT(29) | ||
43 | #define S3C_SDHCI_CTRL2_SLCARDOUT BIT(28) | ||
44 | |||
45 | #define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK (0xf << 24) | ||
46 | #define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT (24) | ||
47 | #define S3C_SDHCI_CTRL2_FLTCLKSEL(_x) ((_x) << 24) | ||
48 | |||
49 | #define S3C_SDHCI_CTRL2_LVLDAT_MASK (0xff << 16) | ||
50 | #define S3C_SDHCI_CTRL2_LVLDAT_SHIFT (16) | ||
51 | #define S3C_SDHCI_CTRL2_LVLDAT(_x) ((_x) << 16) | ||
52 | |||
53 | #define S3C_SDHCI_CTRL2_ENFBCLKTX BIT(15) | ||
54 | #define S3C_SDHCI_CTRL2_ENFBCLKRX BIT(14) | ||
55 | #define S3C_SDHCI_CTRL2_SDCDSEL BIT(13) | ||
56 | #define S3C_SDHCI_CTRL2_SDSIGPC BIT(12) | ||
57 | #define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART BIT(11) | ||
58 | |||
59 | #define S3C_SDHCI_CTRL2_DFCNT_MASK (0x3 << 9) | ||
60 | #define S3C_SDHCI_CTRL2_DFCNT_SHIFT (9) | ||
61 | #define S3C_SDHCI_CTRL2_DFCNT_NONE (0x0 << 9) | ||
62 | #define S3C_SDHCI_CTRL2_DFCNT_4SDCLK (0x1 << 9) | ||
63 | #define S3C_SDHCI_CTRL2_DFCNT_16SDCLK (0x2 << 9) | ||
64 | #define S3C_SDHCI_CTRL2_DFCNT_64SDCLK (0x3 << 9) | ||
65 | |||
66 | #define S3C_SDHCI_CTRL2_ENCLKOUTHOLD BIT(8) | ||
67 | #define S3C_SDHCI_CTRL2_RWAITMODE BIT(7) | ||
68 | #define S3C_SDHCI_CTRL2_DISBUFRD BIT(6) | ||
69 | |||
70 | #define S3C_SDHCI_CTRL2_SELBASECLK_MASK (0x3 << 4) | ||
71 | #define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT (4) | ||
72 | #define S3C_SDHCI_CTRL2_PWRSYNC BIT(3) | ||
73 | #define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON BIT(1) | ||
74 | #define S3C_SDHCI_CTRL2_HWINITFIN BIT(0) | ||
75 | |||
76 | #define S3C_SDHCI_CTRL3_FCSEL3 BIT(31) | ||
77 | #define S3C_SDHCI_CTRL3_FCSEL2 BIT(23) | ||
78 | #define S3C_SDHCI_CTRL3_FCSEL1 BIT(15) | ||
79 | #define S3C_SDHCI_CTRL3_FCSEL0 BIT(7) | ||
80 | |||
81 | #define S3C_SDHCI_CTRL3_FIA3_MASK (0x7f << 24) | ||
82 | #define S3C_SDHCI_CTRL3_FIA3_SHIFT (24) | ||
83 | #define S3C_SDHCI_CTRL3_FIA3(_x) ((_x) << 24) | ||
84 | |||
85 | #define S3C_SDHCI_CTRL3_FIA2_MASK (0x7f << 16) | ||
86 | #define S3C_SDHCI_CTRL3_FIA2_SHIFT (16) | ||
87 | #define S3C_SDHCI_CTRL3_FIA2(_x) ((_x) << 16) | ||
88 | |||
89 | #define S3C_SDHCI_CTRL3_FIA1_MASK (0x7f << 8) | ||
90 | #define S3C_SDHCI_CTRL3_FIA1_SHIFT (8) | ||
91 | #define S3C_SDHCI_CTRL3_FIA1(_x) ((_x) << 8) | ||
92 | |||
93 | #define S3C_SDHCI_CTRL3_FIA0_MASK (0x7f << 0) | ||
94 | #define S3C_SDHCI_CTRL3_FIA0_SHIFT (0) | ||
95 | #define S3C_SDHCI_CTRL3_FIA0(_x) ((_x) << 0) | ||
96 | |||
97 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK (0x3 << 16) | ||
98 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT (16) | ||
99 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA (0x0 << 16) | ||
100 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA (0x1 << 16) | ||
101 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA (0x2 << 16) | ||
102 | #define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16) | ||
103 | |||
104 | #define S3C64XX_SDHCI_CONTROL4_BUSY (1) | ||
105 | |||
37 | /** | 106 | /** |
38 | * struct sdhci_s3c - S3C SDHCI instance | 107 | * struct sdhci_s3c - S3C SDHCI instance |
39 | * @host: The SDHCI host created | 108 | * @host: The SDHCI host created |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0def99590d16..6fdd7a70f229 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -2021,8 +2021,8 @@ static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode, | |||
2021 | unsigned long flags) | 2021 | unsigned long flags) |
2022 | { | 2022 | { |
2023 | struct mmc_host *mmc = host->mmc; | 2023 | struct mmc_host *mmc = host->mmc; |
2024 | struct mmc_command cmd = {0}; | 2024 | struct mmc_command cmd = {}; |
2025 | struct mmc_request mrq = {NULL}; | 2025 | struct mmc_request mrq = {}; |
2026 | 2026 | ||
2027 | cmd.opcode = opcode; | 2027 | cmd.opcode = opcode; |
2028 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 2028 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
@@ -2114,7 +2114,6 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
2114 | spin_lock_irqsave(&host->lock, flags); | 2114 | spin_lock_irqsave(&host->lock, flags); |
2115 | 2115 | ||
2116 | hs400_tuning = host->flags & SDHCI_HS400_TUNING; | 2116 | hs400_tuning = host->flags & SDHCI_HS400_TUNING; |
2117 | host->flags &= ~SDHCI_HS400_TUNING; | ||
2118 | 2117 | ||
2119 | if (host->tuning_mode == SDHCI_TUNING_MODE_1) | 2118 | if (host->tuning_mode == SDHCI_TUNING_MODE_1) |
2120 | tuning_count = host->tuning_count; | 2119 | tuning_count = host->tuning_count; |
@@ -2156,7 +2155,9 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
2156 | 2155 | ||
2157 | if (host->ops->platform_execute_tuning) { | 2156 | if (host->ops->platform_execute_tuning) { |
2158 | spin_unlock_irqrestore(&host->lock, flags); | 2157 | spin_unlock_irqrestore(&host->lock, flags); |
2159 | return host->ops->platform_execute_tuning(host, opcode); | 2158 | err = host->ops->platform_execute_tuning(host, opcode); |
2159 | spin_lock_irqsave(&host->lock, flags); | ||
2160 | goto out_unlock; | ||
2160 | } | 2161 | } |
2161 | 2162 | ||
2162 | host->mmc->retune_period = tuning_count; | 2163 | host->mmc->retune_period = tuning_count; |
@@ -2167,6 +2168,7 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
2167 | 2168 | ||
2168 | sdhci_end_tuning(host); | 2169 | sdhci_end_tuning(host); |
2169 | out_unlock: | 2170 | out_unlock: |
2171 | host->flags &= ~SDHCI_HS400_TUNING; | ||
2170 | spin_unlock_irqrestore(&host->lock, flags); | 2172 | spin_unlock_irqrestore(&host->lock, flags); |
2171 | 2173 | ||
2172 | return err; | 2174 | return err; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 0b66f210ae82..edf3adfbc213 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/leds.h> | ||
21 | #include <linux/interrupt.h> | ||
20 | 22 | ||
21 | #include <linux/mmc/host.h> | 23 | #include <linux/mmc/host.h> |
22 | 24 | ||
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 900778421be6..4062d6bef3c8 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
@@ -1079,26 +1079,10 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1079 | host->state = STATE_IDLE; | 1079 | host->state = STATE_IDLE; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | static int sh_mmcif_get_cd(struct mmc_host *mmc) | ||
1083 | { | ||
1084 | struct sh_mmcif_host *host = mmc_priv(mmc); | ||
1085 | struct device *dev = sh_mmcif_host_to_dev(host); | ||
1086 | struct sh_mmcif_plat_data *p = dev->platform_data; | ||
1087 | int ret = mmc_gpio_get_cd(mmc); | ||
1088 | |||
1089 | if (ret >= 0) | ||
1090 | return ret; | ||
1091 | |||
1092 | if (!p || !p->get_cd) | ||
1093 | return -ENOSYS; | ||
1094 | else | ||
1095 | return p->get_cd(host->pd); | ||
1096 | } | ||
1097 | |||
1098 | static struct mmc_host_ops sh_mmcif_ops = { | 1082 | static struct mmc_host_ops sh_mmcif_ops = { |
1099 | .request = sh_mmcif_request, | 1083 | .request = sh_mmcif_request, |
1100 | .set_ios = sh_mmcif_set_ios, | 1084 | .set_ios = sh_mmcif_set_ios, |
1101 | .get_cd = sh_mmcif_get_cd, | 1085 | .get_cd = mmc_gpio_get_cd, |
1102 | }; | 1086 | }; |
1103 | 1087 | ||
1104 | static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host) | 1088 | static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host) |
@@ -1443,8 +1427,8 @@ static int sh_mmcif_probe(struct platform_device *pdev) | |||
1443 | host->mmc = mmc; | 1427 | host->mmc = mmc; |
1444 | host->addr = reg; | 1428 | host->addr = reg; |
1445 | host->timeout = msecs_to_jiffies(10000); | 1429 | host->timeout = msecs_to_jiffies(10000); |
1446 | host->ccs_enable = !pd || !pd->ccs_unsupported; | 1430 | host->ccs_enable = true; |
1447 | host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; | 1431 | host->clk_ctrl2_enable = false; |
1448 | 1432 | ||
1449 | host->pd = pdev; | 1433 | host->pd = pdev; |
1450 | 1434 | ||
@@ -1509,12 +1493,6 @@ static int sh_mmcif_probe(struct platform_device *pdev) | |||
1509 | } | 1493 | } |
1510 | } | 1494 | } |
1511 | 1495 | ||
1512 | if (pd && pd->use_cd_gpio) { | ||
1513 | ret = mmc_gpio_request_cd(mmc, pd->cd_gpio, 0); | ||
1514 | if (ret < 0) | ||
1515 | goto err_clk; | ||
1516 | } | ||
1517 | |||
1518 | mutex_init(&host->thread_lock); | 1496 | mutex_init(&host->thread_lock); |
1519 | 1497 | ||
1520 | ret = mmc_add_host(mmc); | 1498 | ret = mmc_add_host(mmc); |
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index d46c2d00c182..bc6be0dbea39 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c | |||
@@ -143,6 +143,7 @@ MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match); | |||
143 | 143 | ||
144 | struct sh_mobile_sdhi { | 144 | struct sh_mobile_sdhi { |
145 | struct clk *clk; | 145 | struct clk *clk; |
146 | struct clk *clk_cd; | ||
146 | struct tmio_mmc_data mmc_data; | 147 | struct tmio_mmc_data mmc_data; |
147 | struct tmio_mmc_dma dma_priv; | 148 | struct tmio_mmc_dma dma_priv; |
148 | struct pinctrl *pinctrl; | 149 | struct pinctrl *pinctrl; |
@@ -190,6 +191,12 @@ static int sh_mobile_sdhi_clk_enable(struct tmio_mmc_host *host) | |||
190 | if (ret < 0) | 191 | if (ret < 0) |
191 | return ret; | 192 | return ret; |
192 | 193 | ||
194 | ret = clk_prepare_enable(priv->clk_cd); | ||
195 | if (ret < 0) { | ||
196 | clk_disable_unprepare(priv->clk); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
193 | /* | 200 | /* |
194 | * The clock driver may not know what maximum frequency | 201 | * The clock driver may not know what maximum frequency |
195 | * actually works, so it should be set with the max-frequency | 202 | * actually works, so it should be set with the max-frequency |
@@ -255,6 +262,7 @@ static void sh_mobile_sdhi_clk_disable(struct tmio_mmc_host *host) | |||
255 | struct sh_mobile_sdhi *priv = host_to_priv(host); | 262 | struct sh_mobile_sdhi *priv = host_to_priv(host); |
256 | 263 | ||
257 | clk_disable_unprepare(priv->clk); | 264 | clk_disable_unprepare(priv->clk); |
265 | clk_disable_unprepare(priv->clk_cd); | ||
258 | } | 266 | } |
259 | 267 | ||
260 | static int sh_mobile_sdhi_card_busy(struct mmc_host *mmc) | 268 | static int sh_mobile_sdhi_card_busy(struct mmc_host *mmc) |
@@ -335,9 +343,6 @@ static unsigned int sh_mobile_sdhi_init_tuning(struct tmio_mmc_host *host) | |||
335 | { | 343 | { |
336 | struct sh_mobile_sdhi *priv; | 344 | struct sh_mobile_sdhi *priv; |
337 | 345 | ||
338 | if (!(host->mmc->caps & MMC_CAP_UHS_SDR104)) | ||
339 | return 0; | ||
340 | |||
341 | priv = host_to_priv(host); | 346 | priv = host_to_priv(host); |
342 | 347 | ||
343 | /* set sampling clock selection range */ | 348 | /* set sampling clock selection range */ |
@@ -444,12 +449,7 @@ static int sh_mobile_sdhi_select_tuning(struct tmio_mmc_host *host) | |||
444 | 449 | ||
445 | static bool sh_mobile_sdhi_check_scc_error(struct tmio_mmc_host *host) | 450 | static bool sh_mobile_sdhi_check_scc_error(struct tmio_mmc_host *host) |
446 | { | 451 | { |
447 | struct sh_mobile_sdhi *priv; | 452 | struct sh_mobile_sdhi *priv = host_to_priv(host); |
448 | |||
449 | if (!(host->mmc->caps & MMC_CAP_UHS_SDR104)) | ||
450 | return 0; | ||
451 | |||
452 | priv = host_to_priv(host); | ||
453 | 453 | ||
454 | /* Check SCC error */ | 454 | /* Check SCC error */ |
455 | if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL) & | 455 | if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_RVSCNTL) & |
@@ -468,9 +468,6 @@ static void sh_mobile_sdhi_hw_reset(struct tmio_mmc_host *host) | |||
468 | { | 468 | { |
469 | struct sh_mobile_sdhi *priv; | 469 | struct sh_mobile_sdhi *priv; |
470 | 470 | ||
471 | if (!(host->mmc->caps & MMC_CAP_UHS_SDR104)) | ||
472 | return; | ||
473 | |||
474 | priv = host_to_priv(host); | 471 | priv = host_to_priv(host); |
475 | 472 | ||
476 | /* Reset SCC */ | 473 | /* Reset SCC */ |
@@ -556,8 +553,7 @@ static void sh_mobile_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable) | |||
556 | 553 | ||
557 | static int sh_mobile_sdhi_probe(struct platform_device *pdev) | 554 | static int sh_mobile_sdhi_probe(struct platform_device *pdev) |
558 | { | 555 | { |
559 | const struct of_device_id *of_id = | 556 | const struct sh_mobile_sdhi_of_data *of_data = of_device_get_match_data(&pdev->dev); |
560 | of_match_device(sh_mobile_sdhi_of_match, &pdev->dev); | ||
561 | struct sh_mobile_sdhi *priv; | 557 | struct sh_mobile_sdhi *priv; |
562 | struct tmio_mmc_data *mmc_data; | 558 | struct tmio_mmc_data *mmc_data; |
563 | struct tmio_mmc_data *mmd = pdev->dev.platform_data; | 559 | struct tmio_mmc_data *mmd = pdev->dev.platform_data; |
@@ -584,6 +580,21 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
584 | goto eprobe; | 580 | goto eprobe; |
585 | } | 581 | } |
586 | 582 | ||
583 | /* | ||
584 | * Some controllers provide a 2nd clock just to run the internal card | ||
585 | * detection logic. Unfortunately, the existing driver architecture does | ||
586 | * not support a separation of clocks for runtime PM usage. When | ||
587 | * native hotplug is used, the tmio driver assumes that the core | ||
588 | * must continue to run for card detect to stay active, so we cannot | ||
589 | * disable it. | ||
590 | * Additionally, it is prohibited to supply a clock to the core but not | ||
591 | * to the card detect circuit. That leaves us with if separate clocks | ||
592 | * are presented, we must treat them both as virtually 1 clock. | ||
593 | */ | ||
594 | priv->clk_cd = devm_clk_get(&pdev->dev, "cd"); | ||
595 | if (IS_ERR(priv->clk_cd)) | ||
596 | priv->clk_cd = NULL; | ||
597 | |||
587 | priv->pinctrl = devm_pinctrl_get(&pdev->dev); | 598 | priv->pinctrl = devm_pinctrl_get(&pdev->dev); |
588 | if (!IS_ERR(priv->pinctrl)) { | 599 | if (!IS_ERR(priv->pinctrl)) { |
589 | priv->pins_default = pinctrl_lookup_state(priv->pinctrl, | 600 | priv->pins_default = pinctrl_lookup_state(priv->pinctrl, |
@@ -598,9 +609,8 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
598 | goto eprobe; | 609 | goto eprobe; |
599 | } | 610 | } |
600 | 611 | ||
601 | if (of_id && of_id->data) { | ||
602 | const struct sh_mobile_sdhi_of_data *of_data = of_id->data; | ||
603 | 612 | ||
613 | if (of_data) { | ||
604 | mmc_data->flags |= of_data->tmio_flags; | 614 | mmc_data->flags |= of_data->tmio_flags; |
605 | mmc_data->ocr_mask = of_data->tmio_ocr_mask; | 615 | mmc_data->ocr_mask = of_data->tmio_ocr_mask; |
606 | mmc_data->capabilities |= of_data->capabilities; | 616 | mmc_data->capabilities |= of_data->capabilities; |
@@ -623,11 +633,6 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
623 | host->card_busy = sh_mobile_sdhi_card_busy; | 633 | host->card_busy = sh_mobile_sdhi_card_busy; |
624 | host->start_signal_voltage_switch = | 634 | host->start_signal_voltage_switch = |
625 | sh_mobile_sdhi_start_signal_voltage_switch; | 635 | sh_mobile_sdhi_start_signal_voltage_switch; |
626 | host->init_tuning = sh_mobile_sdhi_init_tuning; | ||
627 | host->prepare_tuning = sh_mobile_sdhi_prepare_tuning; | ||
628 | host->select_tuning = sh_mobile_sdhi_select_tuning; | ||
629 | host->check_scc_error = sh_mobile_sdhi_check_scc_error; | ||
630 | host->hw_reset = sh_mobile_sdhi_hw_reset; | ||
631 | } | 636 | } |
632 | 637 | ||
633 | /* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */ | 638 | /* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */ |
@@ -659,40 +664,40 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
659 | */ | 664 | */ |
660 | mmc_data->flags |= TMIO_MMC_HAVE_CMD12_CTRL; | 665 | mmc_data->flags |= TMIO_MMC_HAVE_CMD12_CTRL; |
661 | 666 | ||
662 | /* | 667 | /* All SDHI have SDIO status bits which must be 1 */ |
663 | * All SDHI need SDIO_INFO1 reserved bit | 668 | mmc_data->flags |= TMIO_MMC_SDIO_STATUS_SETBITS; |
664 | */ | ||
665 | mmc_data->flags |= TMIO_MMC_SDIO_STATUS_QUIRK; | ||
666 | 669 | ||
667 | ret = tmio_mmc_host_probe(host, mmc_data); | 670 | ret = tmio_mmc_host_probe(host, mmc_data); |
668 | if (ret < 0) | 671 | if (ret < 0) |
669 | goto efree; | 672 | goto efree; |
670 | 673 | ||
671 | if (host->mmc->caps & MMC_CAP_UHS_SDR104) { | 674 | /* Enable tuning iff we have an SCC and a supported mode */ |
675 | if (of_data && of_data->scc_offset && | ||
676 | (host->mmc->caps & MMC_CAP_UHS_SDR104 || | ||
677 | host->mmc->caps2 & MMC_CAP2_HS200_1_8V_SDR)) { | ||
678 | const struct sh_mobile_sdhi_scc *taps = of_data->taps; | ||
679 | bool hit = false; | ||
680 | |||
672 | host->mmc->caps |= MMC_CAP_HW_RESET; | 681 | host->mmc->caps |= MMC_CAP_HW_RESET; |
673 | 682 | ||
674 | if (of_id && of_id->data) { | 683 | for (i = 0; i < of_data->taps_num; i++) { |
675 | const struct sh_mobile_sdhi_of_data *of_data; | 684 | if (taps[i].clk_rate == 0 || |
676 | const struct sh_mobile_sdhi_scc *taps; | 685 | taps[i].clk_rate == host->mmc->f_max) { |
677 | bool hit = false; | 686 | host->scc_tappos = taps->tap; |
678 | 687 | hit = true; | |
679 | of_data = of_id->data; | 688 | break; |
680 | taps = of_data->taps; | ||
681 | |||
682 | for (i = 0; i < of_data->taps_num; i++) { | ||
683 | if (taps[i].clk_rate == 0 || | ||
684 | taps[i].clk_rate == host->mmc->f_max) { | ||
685 | host->scc_tappos = taps->tap; | ||
686 | hit = true; | ||
687 | break; | ||
688 | } | ||
689 | } | 689 | } |
690 | } | ||
690 | 691 | ||
691 | if (!hit) | 692 | if (!hit) |
692 | dev_warn(&host->pdev->dev, "Unknown clock rate for SDR104\n"); | 693 | dev_warn(&host->pdev->dev, "Unknown clock rate for SDR104\n"); |
693 | 694 | ||
694 | priv->scc_ctl = host->ctl + of_data->scc_offset; | 695 | priv->scc_ctl = host->ctl + of_data->scc_offset; |
695 | } | 696 | host->init_tuning = sh_mobile_sdhi_init_tuning; |
697 | host->prepare_tuning = sh_mobile_sdhi_prepare_tuning; | ||
698 | host->select_tuning = sh_mobile_sdhi_select_tuning; | ||
699 | host->check_scc_error = sh_mobile_sdhi_check_scc_error; | ||
700 | host->hw_reset = sh_mobile_sdhi_hw_reset; | ||
696 | } | 701 | } |
697 | 702 | ||
698 | i = 0; | 703 | i = 0; |
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index b1d1303389a7..6ffcd2838272 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch> | 5 | * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch> |
6 | * (C) Copyright 2013-2014 David Lanzend�rfer <david.lanzendoerfer@o2s.ch> | 6 | * (C) Copyright 2013-2014 David Lanzend�rfer <david.lanzendoerfer@o2s.ch> |
7 | * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com> | 7 | * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com> |
8 | * (C) Copyright 2017 Sootech SA | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License as | 11 | * modify it under the terms of the GNU General Public License as |
@@ -101,6 +102,7 @@ | |||
101 | (SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET) | 102 | (SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET) |
102 | 103 | ||
103 | /* clock control bits */ | 104 | /* clock control bits */ |
105 | #define SDXC_MASK_DATA0 BIT(31) | ||
104 | #define SDXC_CARD_CLOCK_ON BIT(16) | 106 | #define SDXC_CARD_CLOCK_ON BIT(16) |
105 | #define SDXC_LOW_POWER_ON BIT(17) | 107 | #define SDXC_LOW_POWER_ON BIT(17) |
106 | 108 | ||
@@ -253,6 +255,11 @@ struct sunxi_mmc_cfg { | |||
253 | 255 | ||
254 | /* does the IP block support autocalibration? */ | 256 | /* does the IP block support autocalibration? */ |
255 | bool can_calibrate; | 257 | bool can_calibrate; |
258 | |||
259 | /* Does DATA0 needs to be masked while the clock is updated */ | ||
260 | bool mask_data0; | ||
261 | |||
262 | bool needs_new_timings; | ||
256 | }; | 263 | }; |
257 | 264 | ||
258 | struct sunxi_mmc_host { | 265 | struct sunxi_mmc_host { |
@@ -654,11 +661,16 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) | |||
654 | unsigned long expire = jiffies + msecs_to_jiffies(750); | 661 | unsigned long expire = jiffies + msecs_to_jiffies(750); |
655 | u32 rval; | 662 | u32 rval; |
656 | 663 | ||
664 | dev_dbg(mmc_dev(host->mmc), "%sabling the clock\n", | ||
665 | oclk_en ? "en" : "dis"); | ||
666 | |||
657 | rval = mmc_readl(host, REG_CLKCR); | 667 | rval = mmc_readl(host, REG_CLKCR); |
658 | rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON); | 668 | rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0); |
659 | 669 | ||
660 | if (oclk_en) | 670 | if (oclk_en) |
661 | rval |= SDXC_CARD_CLOCK_ON; | 671 | rval |= SDXC_CARD_CLOCK_ON; |
672 | if (host->cfg->mask_data0) | ||
673 | rval |= SDXC_MASK_DATA0; | ||
662 | 674 | ||
663 | mmc_writel(host, REG_CLKCR, rval); | 675 | mmc_writel(host, REG_CLKCR, rval); |
664 | 676 | ||
@@ -678,46 +690,29 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) | |||
678 | return -EIO; | 690 | return -EIO; |
679 | } | 691 | } |
680 | 692 | ||
693 | if (host->cfg->mask_data0) { | ||
694 | rval = mmc_readl(host, REG_CLKCR); | ||
695 | mmc_writel(host, REG_CLKCR, rval & ~SDXC_MASK_DATA0); | ||
696 | } | ||
697 | |||
681 | return 0; | 698 | return 0; |
682 | } | 699 | } |
683 | 700 | ||
684 | static int sunxi_mmc_calibrate(struct sunxi_mmc_host *host, int reg_off) | 701 | static int sunxi_mmc_calibrate(struct sunxi_mmc_host *host, int reg_off) |
685 | { | 702 | { |
686 | u32 reg = readl(host->reg_base + reg_off); | ||
687 | u32 delay; | ||
688 | unsigned long timeout; | ||
689 | |||
690 | if (!host->cfg->can_calibrate) | 703 | if (!host->cfg->can_calibrate) |
691 | return 0; | 704 | return 0; |
692 | 705 | ||
693 | reg &= ~(SDXC_CAL_DL_MASK << SDXC_CAL_DL_SW_SHIFT); | 706 | /* |
694 | reg &= ~SDXC_CAL_DL_SW_EN; | 707 | * FIXME: |
695 | 708 | * This is not clear how the calibration is supposed to work | |
696 | writel(reg | SDXC_CAL_START, host->reg_base + reg_off); | 709 | * yet. The best rate have been obtained by simply setting the |
697 | 710 | * delay to 0, as Allwinner does in its BSP. | |
698 | dev_dbg(mmc_dev(host->mmc), "calibration started\n"); | 711 | * |
699 | 712 | * The only mode that doesn't have such a delay is HS400, that | |
700 | timeout = jiffies + HZ * SDXC_CAL_TIMEOUT; | 713 | * is in itself a TODO. |
701 | 714 | */ | |
702 | while (!((reg = readl(host->reg_base + reg_off)) & SDXC_CAL_DONE)) { | 715 | writel(SDXC_CAL_DL_SW_EN, host->reg_base + reg_off); |
703 | if (time_before(jiffies, timeout)) | ||
704 | cpu_relax(); | ||
705 | else { | ||
706 | reg &= ~SDXC_CAL_START; | ||
707 | writel(reg, host->reg_base + reg_off); | ||
708 | |||
709 | return -ETIMEDOUT; | ||
710 | } | ||
711 | } | ||
712 | |||
713 | delay = (reg >> SDXC_CAL_DL_SHIFT) & SDXC_CAL_DL_MASK; | ||
714 | |||
715 | reg &= ~SDXC_CAL_START; | ||
716 | reg |= (delay << SDXC_CAL_DL_SW_SHIFT) | SDXC_CAL_DL_SW_EN; | ||
717 | |||
718 | writel(reg, host->reg_base + reg_off); | ||
719 | |||
720 | dev_dbg(mmc_dev(host->mmc), "calibration ended, reg is 0x%x\n", reg); | ||
721 | 716 | ||
722 | return 0; | 717 | return 0; |
723 | } | 718 | } |
@@ -745,6 +740,7 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host, | |||
745 | index = SDXC_CLK_50M_DDR; | 740 | index = SDXC_CLK_50M_DDR; |
746 | } | 741 | } |
747 | } else { | 742 | } else { |
743 | dev_dbg(mmc_dev(host->mmc), "Invalid clock... returning\n"); | ||
748 | return -EINVAL; | 744 | return -EINVAL; |
749 | } | 745 | } |
750 | 746 | ||
@@ -757,10 +753,21 @@ static int sunxi_mmc_clk_set_phase(struct sunxi_mmc_host *host, | |||
757 | static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | 753 | static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, |
758 | struct mmc_ios *ios) | 754 | struct mmc_ios *ios) |
759 | { | 755 | { |
756 | struct mmc_host *mmc = host->mmc; | ||
760 | long rate; | 757 | long rate; |
761 | u32 rval, clock = ios->clock; | 758 | u32 rval, clock = ios->clock; |
762 | int ret; | 759 | int ret; |
763 | 760 | ||
761 | ret = sunxi_mmc_oclk_onoff(host, 0); | ||
762 | if (ret) | ||
763 | return ret; | ||
764 | |||
765 | /* Our clock is gated now */ | ||
766 | mmc->actual_clock = 0; | ||
767 | |||
768 | if (!ios->clock) | ||
769 | return 0; | ||
770 | |||
764 | /* 8 bit DDR requires a higher module clock */ | 771 | /* 8 bit DDR requires a higher module clock */ |
765 | if (ios->timing == MMC_TIMING_MMC_DDR52 && | 772 | if (ios->timing == MMC_TIMING_MMC_DDR52 && |
766 | ios->bus_width == MMC_BUS_WIDTH_8) | 773 | ios->bus_width == MMC_BUS_WIDTH_8) |
@@ -768,25 +775,21 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | |||
768 | 775 | ||
769 | rate = clk_round_rate(host->clk_mmc, clock); | 776 | rate = clk_round_rate(host->clk_mmc, clock); |
770 | if (rate < 0) { | 777 | if (rate < 0) { |
771 | dev_err(mmc_dev(host->mmc), "error rounding clk to %d: %ld\n", | 778 | dev_err(mmc_dev(mmc), "error rounding clk to %d: %ld\n", |
772 | clock, rate); | 779 | clock, rate); |
773 | return rate; | 780 | return rate; |
774 | } | 781 | } |
775 | dev_dbg(mmc_dev(host->mmc), "setting clk to %d, rounded %ld\n", | 782 | dev_dbg(mmc_dev(mmc), "setting clk to %d, rounded %ld\n", |
776 | clock, rate); | 783 | clock, rate); |
777 | 784 | ||
778 | /* setting clock rate */ | 785 | /* setting clock rate */ |
779 | ret = clk_set_rate(host->clk_mmc, rate); | 786 | ret = clk_set_rate(host->clk_mmc, rate); |
780 | if (ret) { | 787 | if (ret) { |
781 | dev_err(mmc_dev(host->mmc), "error setting clk to %ld: %d\n", | 788 | dev_err(mmc_dev(mmc), "error setting clk to %ld: %d\n", |
782 | rate, ret); | 789 | rate, ret); |
783 | return ret; | 790 | return ret; |
784 | } | 791 | } |
785 | 792 | ||
786 | ret = sunxi_mmc_oclk_onoff(host, 0); | ||
787 | if (ret) | ||
788 | return ret; | ||
789 | |||
790 | /* clear internal divider */ | 793 | /* clear internal divider */ |
791 | rval = mmc_readl(host, REG_CLKCR); | 794 | rval = mmc_readl(host, REG_CLKCR); |
792 | rval &= ~0xff; | 795 | rval &= ~0xff; |
@@ -798,6 +801,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | |||
798 | } | 801 | } |
799 | mmc_writel(host, REG_CLKCR, rval); | 802 | mmc_writel(host, REG_CLKCR, rval); |
800 | 803 | ||
804 | if (host->cfg->needs_new_timings) | ||
805 | mmc_writel(host, REG_SD_NTSR, SDXC_2X_TIMING_MODE); | ||
806 | |||
801 | ret = sunxi_mmc_clk_set_phase(host, ios, rate); | 807 | ret = sunxi_mmc_clk_set_phase(host, ios, rate); |
802 | if (ret) | 808 | if (ret) |
803 | return ret; | 809 | return ret; |
@@ -806,9 +812,22 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | |||
806 | if (ret) | 812 | if (ret) |
807 | return ret; | 813 | return ret; |
808 | 814 | ||
809 | /* TODO: enable calibrate on sdc2 SDXC_REG_DS_DL_REG of A64 */ | 815 | /* |
816 | * FIXME: | ||
817 | * | ||
818 | * In HS400 we'll also need to calibrate the data strobe | ||
819 | * signal. This should only happen on the MMC2 controller (at | ||
820 | * least on the A64). | ||
821 | */ | ||
822 | |||
823 | ret = sunxi_mmc_oclk_onoff(host, 1); | ||
824 | if (ret) | ||
825 | return ret; | ||
826 | |||
827 | /* And we just enabled our clock back */ | ||
828 | mmc->actual_clock = rate; | ||
810 | 829 | ||
811 | return sunxi_mmc_oclk_onoff(host, 1); | 830 | return 0; |
812 | } | 831 | } |
813 | 832 | ||
814 | static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 833 | static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
@@ -882,7 +901,7 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
882 | mmc_writel(host, REG_GCTRL, rval); | 901 | mmc_writel(host, REG_GCTRL, rval); |
883 | 902 | ||
884 | /* set up clock */ | 903 | /* set up clock */ |
885 | if (ios->clock && ios->power_mode) { | 904 | if (ios->power_mode) { |
886 | host->ferror = sunxi_mmc_clk_set_rate(host, ios); | 905 | host->ferror = sunxi_mmc_clk_set_rate(host, ios); |
887 | /* Android code had a usleep_range(50000, 55000); here */ | 906 | /* Android code had a usleep_range(50000, 55000); here */ |
888 | } | 907 | } |
@@ -1089,6 +1108,14 @@ static const struct sunxi_mmc_cfg sun50i_a64_cfg = { | |||
1089 | .idma_des_size_bits = 16, | 1108 | .idma_des_size_bits = 16, |
1090 | .clk_delays = NULL, | 1109 | .clk_delays = NULL, |
1091 | .can_calibrate = true, | 1110 | .can_calibrate = true, |
1111 | .mask_data0 = true, | ||
1112 | .needs_new_timings = true, | ||
1113 | }; | ||
1114 | |||
1115 | static const struct sunxi_mmc_cfg sun50i_a64_emmc_cfg = { | ||
1116 | .idma_des_size_bits = 13, | ||
1117 | .clk_delays = NULL, | ||
1118 | .can_calibrate = true, | ||
1092 | }; | 1119 | }; |
1093 | 1120 | ||
1094 | static const struct of_device_id sunxi_mmc_of_match[] = { | 1121 | static const struct of_device_id sunxi_mmc_of_match[] = { |
@@ -1097,6 +1124,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = { | |||
1097 | { .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg }, | 1124 | { .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg }, |
1098 | { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg }, | 1125 | { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg }, |
1099 | { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg }, | 1126 | { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg }, |
1127 | { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg }, | ||
1100 | { /* sentinel */ } | 1128 | { /* sentinel */ } |
1101 | }; | 1129 | }; |
1102 | MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match); | 1130 | MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match); |
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9e20bcf3aa8d..2b349d48fb9a 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/pagemap.h> | 24 | #include <linux/pagemap.h> |
25 | #include <linux/scatterlist.h> | 25 | #include <linux/scatterlist.h> |
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/interrupt.h> | ||
27 | 28 | ||
28 | #define CTL_SD_CMD 0x00 | 29 | #define CTL_SD_CMD 0x00 |
29 | #define CTL_ARG_REG 0x04 | 30 | #define CTL_ARG_REG 0x04 |
@@ -90,6 +91,8 @@ | |||
90 | #define TMIO_SDIO_STAT_EXWT 0x8000 | 91 | #define TMIO_SDIO_STAT_EXWT 0x8000 |
91 | #define TMIO_SDIO_MASK_ALL 0xc007 | 92 | #define TMIO_SDIO_MASK_ALL 0xc007 |
92 | 93 | ||
94 | #define TMIO_SDIO_SETBITS_MASK 0x0006 | ||
95 | |||
93 | /* Define some IRQ masks */ | 96 | /* Define some IRQ masks */ |
94 | /* This is the mask used at reset by the chip */ | 97 | /* This is the mask used at reset by the chip */ |
95 | #define TMIO_MASK_ALL 0x837f031d | 98 | #define TMIO_MASK_ALL 0x837f031d |
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 2064fa1a5bf1..6b789a739d4d 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -134,18 +134,25 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
134 | struct tmio_mmc_host *host = mmc_priv(mmc); | 134 | struct tmio_mmc_host *host = mmc_priv(mmc); |
135 | 135 | ||
136 | if (enable && !host->sdio_irq_enabled) { | 136 | if (enable && !host->sdio_irq_enabled) { |
137 | u16 sdio_status; | ||
138 | |||
137 | /* Keep device active while SDIO irq is enabled */ | 139 | /* Keep device active while SDIO irq is enabled */ |
138 | pm_runtime_get_sync(mmc_dev(mmc)); | 140 | pm_runtime_get_sync(mmc_dev(mmc)); |
139 | host->sdio_irq_enabled = true; | ||
140 | 141 | ||
142 | host->sdio_irq_enabled = true; | ||
141 | host->sdio_irq_mask = TMIO_SDIO_MASK_ALL & | 143 | host->sdio_irq_mask = TMIO_SDIO_MASK_ALL & |
142 | ~TMIO_SDIO_STAT_IOIRQ; | 144 | ~TMIO_SDIO_STAT_IOIRQ; |
143 | sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001); | 145 | |
146 | /* Clear obsolete interrupts before enabling */ | ||
147 | sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS) & ~TMIO_SDIO_MASK_ALL; | ||
148 | if (host->pdata->flags & TMIO_MMC_SDIO_STATUS_SETBITS) | ||
149 | sdio_status |= TMIO_SDIO_SETBITS_MASK; | ||
150 | sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status); | ||
151 | |||
144 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); | 152 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); |
145 | } else if (!enable && host->sdio_irq_enabled) { | 153 | } else if (!enable && host->sdio_irq_enabled) { |
146 | host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; | 154 | host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; |
147 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); | 155 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); |
148 | sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000); | ||
149 | 156 | ||
150 | host->sdio_irq_enabled = false; | 157 | host->sdio_irq_enabled = false; |
151 | pm_runtime_mark_last_busy(mmc_dev(mmc)); | 158 | pm_runtime_mark_last_busy(mmc_dev(mmc)); |
@@ -711,9 +718,8 @@ static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host, | |||
711 | return false; | 718 | return false; |
712 | } | 719 | } |
713 | 720 | ||
714 | static void tmio_mmc_sdio_irq(int irq, void *devid) | 721 | static void __tmio_mmc_sdio_irq(struct tmio_mmc_host *host) |
715 | { | 722 | { |
716 | struct tmio_mmc_host *host = devid; | ||
717 | struct mmc_host *mmc = host->mmc; | 723 | struct mmc_host *mmc = host->mmc; |
718 | struct tmio_mmc_data *pdata = host->pdata; | 724 | struct tmio_mmc_data *pdata = host->pdata; |
719 | unsigned int ireg, status; | 725 | unsigned int ireg, status; |
@@ -726,8 +732,8 @@ static void tmio_mmc_sdio_irq(int irq, void *devid) | |||
726 | ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdio_irq_mask; | 732 | ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdio_irq_mask; |
727 | 733 | ||
728 | sdio_status = status & ~TMIO_SDIO_MASK_ALL; | 734 | sdio_status = status & ~TMIO_SDIO_MASK_ALL; |
729 | if (pdata->flags & TMIO_MMC_SDIO_STATUS_QUIRK) | 735 | if (pdata->flags & TMIO_MMC_SDIO_STATUS_SETBITS) |
730 | sdio_status |= 6; | 736 | sdio_status |= TMIO_SDIO_SETBITS_MASK; |
731 | 737 | ||
732 | sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status); | 738 | sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status); |
733 | 739 | ||
@@ -754,7 +760,7 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
754 | if (__tmio_mmc_sdcard_irq(host, ireg, status)) | 760 | if (__tmio_mmc_sdcard_irq(host, ireg, status)) |
755 | return IRQ_HANDLED; | 761 | return IRQ_HANDLED; |
756 | 762 | ||
757 | tmio_mmc_sdio_irq(irq, devid); | 763 | __tmio_mmc_sdio_irq(host); |
758 | 764 | ||
759 | return IRQ_HANDLED; | 765 | return IRQ_HANDLED; |
760 | } | 766 | } |
@@ -902,6 +908,12 @@ static int tmio_mmc_clk_enable(struct tmio_mmc_host *host) | |||
902 | return host->clk_enable(host); | 908 | return host->clk_enable(host); |
903 | } | 909 | } |
904 | 910 | ||
911 | static void tmio_mmc_clk_disable(struct tmio_mmc_host *host) | ||
912 | { | ||
913 | if (host->clk_disable) | ||
914 | host->clk_disable(host); | ||
915 | } | ||
916 | |||
905 | static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd) | 917 | static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd) |
906 | { | 918 | { |
907 | struct mmc_host *mmc = host->mmc; | 919 | struct mmc_host *mmc = host->mmc; |
@@ -1145,7 +1157,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | |||
1145 | 1157 | ||
1146 | ret = mmc_of_parse(mmc); | 1158 | ret = mmc_of_parse(mmc); |
1147 | if (ret < 0) | 1159 | if (ret < 0) |
1148 | goto host_free; | 1160 | return ret; |
1149 | 1161 | ||
1150 | _host->pdata = pdata; | 1162 | _host->pdata = pdata; |
1151 | platform_set_drvdata(pdev, mmc); | 1163 | platform_set_drvdata(pdev, mmc); |
@@ -1155,14 +1167,12 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | |||
1155 | 1167 | ||
1156 | ret = tmio_mmc_init_ocr(_host); | 1168 | ret = tmio_mmc_init_ocr(_host); |
1157 | if (ret < 0) | 1169 | if (ret < 0) |
1158 | goto host_free; | 1170 | return ret; |
1159 | 1171 | ||
1160 | _host->ctl = devm_ioremap(&pdev->dev, | 1172 | _host->ctl = devm_ioremap(&pdev->dev, |
1161 | res_ctl->start, resource_size(res_ctl)); | 1173 | res_ctl->start, resource_size(res_ctl)); |
1162 | if (!_host->ctl) { | 1174 | if (!_host->ctl) |
1163 | ret = -ENOMEM; | 1175 | return -ENOMEM; |
1164 | goto host_free; | ||
1165 | } | ||
1166 | 1176 | ||
1167 | tmio_mmc_ops.card_busy = _host->card_busy; | 1177 | tmio_mmc_ops.card_busy = _host->card_busy; |
1168 | tmio_mmc_ops.start_signal_voltage_switch = _host->start_signal_voltage_switch; | 1178 | tmio_mmc_ops.start_signal_voltage_switch = _host->start_signal_voltage_switch; |
@@ -1179,8 +1189,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | |||
1179 | 1189 | ||
1180 | _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD || | 1190 | _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD || |
1181 | mmc->caps & MMC_CAP_NEEDS_POLL || | 1191 | mmc->caps & MMC_CAP_NEEDS_POLL || |
1182 | !mmc_card_is_removable(mmc) || | 1192 | !mmc_card_is_removable(mmc)); |
1183 | mmc->slot.cd_irq >= 0); | ||
1184 | 1193 | ||
1185 | /* | 1194 | /* |
1186 | * On Gen2+, eMMC with NONREMOVABLE currently fails because native | 1195 | * On Gen2+, eMMC with NONREMOVABLE currently fails because native |
@@ -1200,10 +1209,8 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | |||
1200 | * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from | 1209 | * Check the sanity of mmc->f_min to prevent tmio_mmc_set_clock() from |
1201 | * looping forever... | 1210 | * looping forever... |
1202 | */ | 1211 | */ |
1203 | if (mmc->f_min == 0) { | 1212 | if (mmc->f_min == 0) |
1204 | ret = -EINVAL; | 1213 | return -EINVAL; |
1205 | goto host_free; | ||
1206 | } | ||
1207 | 1214 | ||
1208 | /* | 1215 | /* |
1209 | * While using internal tmio hardware logic for card detection, we need | 1216 | * While using internal tmio hardware logic for card detection, we need |
@@ -1232,7 +1239,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | |||
1232 | if (pdata->flags & TMIO_MMC_SDIO_IRQ) { | 1239 | if (pdata->flags & TMIO_MMC_SDIO_IRQ) { |
1233 | _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; | 1240 | _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; |
1234 | sd_ctrl_write16(_host, CTL_SDIO_IRQ_MASK, _host->sdio_irq_mask); | 1241 | sd_ctrl_write16(_host, CTL_SDIO_IRQ_MASK, _host->sdio_irq_mask); |
1235 | sd_ctrl_write16(_host, CTL_TRANSACTION_CTL, 0x0000); | 1242 | sd_ctrl_write16(_host, CTL_TRANSACTION_CTL, 0x0001); |
1236 | } | 1243 | } |
1237 | 1244 | ||
1238 | spin_lock_init(&_host->lock); | 1245 | spin_lock_init(&_host->lock); |
@@ -1268,10 +1275,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | |||
1268 | } | 1275 | } |
1269 | 1276 | ||
1270 | return 0; | 1277 | return 0; |
1271 | |||
1272 | host_free: | ||
1273 | |||
1274 | return ret; | ||
1275 | } | 1278 | } |
1276 | EXPORT_SYMBOL(tmio_mmc_host_probe); | 1279 | EXPORT_SYMBOL(tmio_mmc_host_probe); |
1277 | 1280 | ||
@@ -1280,6 +1283,9 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) | |||
1280 | struct platform_device *pdev = host->pdev; | 1283 | struct platform_device *pdev = host->pdev; |
1281 | struct mmc_host *mmc = host->mmc; | 1284 | struct mmc_host *mmc = host->mmc; |
1282 | 1285 | ||
1286 | if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) | ||
1287 | sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000); | ||
1288 | |||
1283 | if (!host->native_hotplug) | 1289 | if (!host->native_hotplug) |
1284 | pm_runtime_get_sync(&pdev->dev); | 1290 | pm_runtime_get_sync(&pdev->dev); |
1285 | 1291 | ||
@@ -1292,6 +1298,8 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) | |||
1292 | 1298 | ||
1293 | pm_runtime_put_sync(&pdev->dev); | 1299 | pm_runtime_put_sync(&pdev->dev); |
1294 | pm_runtime_disable(&pdev->dev); | 1300 | pm_runtime_disable(&pdev->dev); |
1301 | |||
1302 | tmio_mmc_clk_disable(host); | ||
1295 | } | 1303 | } |
1296 | EXPORT_SYMBOL(tmio_mmc_host_remove); | 1304 | EXPORT_SYMBOL(tmio_mmc_host_remove); |
1297 | 1305 | ||
@@ -1306,8 +1314,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev) | |||
1306 | if (host->clk_cache) | 1314 | if (host->clk_cache) |
1307 | tmio_mmc_clk_stop(host); | 1315 | tmio_mmc_clk_stop(host); |
1308 | 1316 | ||
1309 | if (host->clk_disable) | 1317 | tmio_mmc_clk_disable(host); |
1310 | host->clk_disable(host); | ||
1311 | 1318 | ||
1312 | return 0; | 1319 | return 0; |
1313 | } | 1320 | } |
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index 63fac78b3d46..6380044c0628 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/dma-mapping.h> | 13 | #include <linux/dma-mapping.h> |
14 | #include <linux/highmem.h> | 14 | #include <linux/highmem.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/interrupt.h> | ||
16 | 17 | ||
17 | #include <linux/mmc/host.h> | 18 | #include <linux/mmc/host.h> |
18 | 19 | ||
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index bb3e0d1dd355..c061e7c704be 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c | |||
@@ -640,8 +640,6 @@ static void __vub300_irqpoll_response(struct vub300_mmc_host *vub300) | |||
640 | mutex_lock(&vub300->irq_mutex); | 640 | mutex_lock(&vub300->irq_mutex); |
641 | if (vub300->irq_enabled) | 641 | if (vub300->irq_enabled) |
642 | mmc_signal_sdio_irq(vub300->mmc); | 642 | mmc_signal_sdio_irq(vub300->mmc); |
643 | else if (vub300->irqs_queued) | ||
644 | vub300->irqs_queued += 1; | ||
645 | else | 643 | else |
646 | vub300->irqs_queued += 1; | 644 | vub300->irqs_queued += 1; |
647 | vub300->irq_disabled = 0; | 645 | vub300->irq_disabled = 0; |
@@ -728,8 +726,7 @@ static void vub300_deadwork_thread(struct work_struct *work) | |||
728 | */ | 726 | */ |
729 | } else if (vub300->card_present) { | 727 | } else if (vub300->card_present) { |
730 | check_vub300_port_status(vub300); | 728 | check_vub300_port_status(vub300); |
731 | } else if (vub300->mmc && vub300->mmc->card && | 729 | } else if (vub300->mmc && vub300->mmc->card) { |
732 | mmc_card_present(vub300->mmc->card)) { | ||
733 | /* | 730 | /* |
734 | * the MMC core must not have responded | 731 | * the MMC core must not have responded |
735 | * to the previous indication - lets | 732 | * to the previous indication - lets |
@@ -1756,8 +1753,7 @@ static void vub300_cmndwork_thread(struct work_struct *work) | |||
1756 | int data_length; | 1753 | int data_length; |
1757 | mutex_lock(&vub300->cmd_mutex); | 1754 | mutex_lock(&vub300->cmd_mutex); |
1758 | init_completion(&vub300->command_complete); | 1755 | init_completion(&vub300->command_complete); |
1759 | if (likely(vub300->vub_name[0]) || !vub300->mmc->card || | 1756 | if (likely(vub300->vub_name[0]) || !vub300->mmc->card) { |
1760 | !mmc_card_present(vub300->mmc->card)) { | ||
1761 | /* | 1757 | /* |
1762 | * the name of the EMPTY Pseudo firmware file | 1758 | * the name of the EMPTY Pseudo firmware file |
1763 | * is used as a flag to indicate that the file | 1759 | * is used as a flag to indicate that the file |
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 80a3b11f3217..bd04e8bae010 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -1437,11 +1437,14 @@ err: | |||
1437 | 1437 | ||
1438 | static void wbsd_release_dma(struct wbsd_host *host) | 1438 | static void wbsd_release_dma(struct wbsd_host *host) |
1439 | { | 1439 | { |
1440 | if (!dma_mapping_error(mmc_dev(host->mmc), host->dma_addr)) { | 1440 | /* |
1441 | * host->dma_addr is valid here iff host->dma_buffer is not NULL. | ||
1442 | */ | ||
1443 | if (host->dma_buffer) { | ||
1441 | dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, | 1444 | dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, |
1442 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); | 1445 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); |
1446 | kfree(host->dma_buffer); | ||
1443 | } | 1447 | } |
1444 | kfree(host->dma_buffer); | ||
1445 | if (host->dma >= 0) | 1448 | if (host->dma >= 0) |
1446 | free_dma(host->dma); | 1449 | free_dma(host->dma); |
1447 | 1450 | ||
diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index 5af00559e9d6..21ebba88679c 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/interrupt.h> | ||
23 | 24 | ||
24 | #include <linux/of.h> | 25 | #include <linux/of.h> |
25 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index fba44abd05ba..a1520d88ebf3 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h | |||
@@ -94,10 +94,8 @@ | |||
94 | */ | 94 | */ |
95 | #define TMIO_MMC_HAVE_CMD12_CTRL (1 << 7) | 95 | #define TMIO_MMC_HAVE_CMD12_CTRL (1 << 7) |
96 | 96 | ||
97 | /* | 97 | /* Controller has some SDIO status bits which must be 1 */ |
98 | * Some controllers needs to set 1 on SDIO status reserved bits | 98 | #define TMIO_MMC_SDIO_STATUS_SETBITS (1 << 8) |
99 | */ | ||
100 | #define TMIO_MMC_SDIO_STATUS_QUIRK (1 << 8) | ||
101 | 99 | ||
102 | /* | 100 | /* |
103 | * Some controllers have a 32-bit wide data port register | 101 | * Some controllers have a 32-bit wide data port register |
diff --git a/include/linux/mmc/boot.h b/include/linux/mmc/boot.h deleted file mode 100644 index 23acc3baa07d..000000000000 --- a/include/linux/mmc/boot.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | #ifndef LINUX_MMC_BOOT_H | ||
2 | #define LINUX_MMC_BOOT_H | ||
3 | |||
4 | enum { MMC_PROGRESS_ENTER, MMC_PROGRESS_INIT, | ||
5 | MMC_PROGRESS_LOAD, MMC_PROGRESS_DONE }; | ||
6 | |||
7 | #endif /* LINUX_MMC_BOOT_H */ | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 95d69d498296..77e61e0a216a 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -11,7 +11,6 @@ | |||
11 | #define LINUX_MMC_CARD_H | 11 | #define LINUX_MMC_CARD_H |
12 | 12 | ||
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/mmc/core.h> | ||
15 | #include <linux/mod_devicetable.h> | 14 | #include <linux/mod_devicetable.h> |
16 | 15 | ||
17 | struct mmc_cid { | 16 | struct mmc_cid { |
@@ -84,6 +83,7 @@ struct mmc_ext_csd { | |||
84 | unsigned int hpi_cmd; /* cmd used as HPI */ | 83 | unsigned int hpi_cmd; /* cmd used as HPI */ |
85 | bool bkops; /* background support bit */ | 84 | bool bkops; /* background support bit */ |
86 | bool man_bkops_en; /* manual bkops enable bit */ | 85 | bool man_bkops_en; /* manual bkops enable bit */ |
86 | bool auto_bkops_en; /* auto bkops enable bit */ | ||
87 | unsigned int data_sector_size; /* 512 bytes or 4KB */ | 87 | unsigned int data_sector_size; /* 512 bytes or 4KB */ |
88 | unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ | 88 | unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ |
89 | unsigned int boot_ro_lock; /* ro lock support */ | 89 | unsigned int boot_ro_lock; /* ro lock support */ |
@@ -121,6 +121,9 @@ struct mmc_ext_csd { | |||
121 | u8 raw_pwr_cl_ddr_200_360; /* 253 */ | 121 | u8 raw_pwr_cl_ddr_200_360; /* 253 */ |
122 | u8 raw_bkops_status; /* 246 */ | 122 | u8 raw_bkops_status; /* 246 */ |
123 | u8 raw_sectors[4]; /* 212 - 4 bytes */ | 123 | u8 raw_sectors[4]; /* 212 - 4 bytes */ |
124 | u8 pre_eol_info; /* 267 */ | ||
125 | u8 device_life_time_est_typ_a; /* 268 */ | ||
126 | u8 device_life_time_est_typ_b; /* 269 */ | ||
124 | 127 | ||
125 | unsigned int feature_support; | 128 | unsigned int feature_support; |
126 | #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ | 129 | #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ |
@@ -203,7 +206,6 @@ struct sdio_cis { | |||
203 | }; | 206 | }; |
204 | 207 | ||
205 | struct mmc_host; | 208 | struct mmc_host; |
206 | struct mmc_ios; | ||
207 | struct sdio_func; | 209 | struct sdio_func; |
208 | struct sdio_func_tuple; | 210 | struct sdio_func_tuple; |
209 | 211 | ||
@@ -247,13 +249,6 @@ struct mmc_card { | |||
247 | #define MMC_TYPE_SDIO 2 /* SDIO card */ | 249 | #define MMC_TYPE_SDIO 2 /* SDIO card */ |
248 | #define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ | 250 | #define MMC_TYPE_SD_COMBO 3 /* SD combo (IO+mem) card */ |
249 | unsigned int state; /* (our) card state */ | 251 | unsigned int state; /* (our) card state */ |
250 | #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ | ||
251 | #define MMC_STATE_READONLY (1<<1) /* card is read-only */ | ||
252 | #define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */ | ||
253 | #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ | ||
254 | #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ | ||
255 | #define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ | ||
256 | #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ | ||
257 | unsigned int quirks; /* card quirks */ | 252 | unsigned int quirks; /* card quirks */ |
258 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ | 253 | #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ |
259 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ | 254 | #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ |
@@ -272,7 +267,6 @@ struct mmc_card { | |||
272 | #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ | 267 | #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ |
273 | #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ | 268 | #define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ |
274 | 269 | ||
275 | |||
276 | unsigned int erase_size; /* erase size in sectors */ | 270 | unsigned int erase_size; /* erase size in sectors */ |
277 | unsigned int erase_shift; /* if erase unit is power 2 */ | 271 | unsigned int erase_shift; /* if erase unit is power 2 */ |
278 | unsigned int pref_erase; /* in sectors */ | 272 | unsigned int pref_erase; /* in sectors */ |
@@ -308,245 +302,13 @@ struct mmc_card { | |||
308 | unsigned int nr_parts; | 302 | unsigned int nr_parts; |
309 | }; | 303 | }; |
310 | 304 | ||
311 | /* | ||
312 | * This function fill contents in mmc_part. | ||
313 | */ | ||
314 | static inline void mmc_part_add(struct mmc_card *card, unsigned int size, | ||
315 | unsigned int part_cfg, char *name, int idx, bool ro, | ||
316 | int area_type) | ||
317 | { | ||
318 | card->part[card->nr_parts].size = size; | ||
319 | card->part[card->nr_parts].part_cfg = part_cfg; | ||
320 | sprintf(card->part[card->nr_parts].name, name, idx); | ||
321 | card->part[card->nr_parts].force_ro = ro; | ||
322 | card->part[card->nr_parts].area_type = area_type; | ||
323 | card->nr_parts++; | ||
324 | } | ||
325 | |||
326 | static inline bool mmc_large_sector(struct mmc_card *card) | 305 | static inline bool mmc_large_sector(struct mmc_card *card) |
327 | { | 306 | { |
328 | return card->ext_csd.data_sector_size == 4096; | 307 | return card->ext_csd.data_sector_size == 4096; |
329 | } | 308 | } |
330 | 309 | ||
331 | /* | ||
332 | * The world is not perfect and supplies us with broken mmc/sdio devices. | ||
333 | * For at least some of these bugs we need a work-around. | ||
334 | */ | ||
335 | |||
336 | struct mmc_fixup { | ||
337 | /* CID-specific fields. */ | ||
338 | const char *name; | ||
339 | |||
340 | /* Valid revision range */ | ||
341 | u64 rev_start, rev_end; | ||
342 | |||
343 | unsigned int manfid; | ||
344 | unsigned short oemid; | ||
345 | |||
346 | /* SDIO-specfic fields. You can use SDIO_ANY_ID here of course */ | ||
347 | u16 cis_vendor, cis_device; | ||
348 | |||
349 | /* for MMC cards */ | ||
350 | unsigned int ext_csd_rev; | ||
351 | |||
352 | void (*vendor_fixup)(struct mmc_card *card, int data); | ||
353 | int data; | ||
354 | }; | ||
355 | |||
356 | #define CID_MANFID_ANY (-1u) | ||
357 | #define CID_OEMID_ANY ((unsigned short) -1) | ||
358 | #define CID_NAME_ANY (NULL) | ||
359 | |||
360 | #define EXT_CSD_REV_ANY (-1u) | ||
361 | |||
362 | #define CID_MANFID_SANDISK 0x2 | ||
363 | #define CID_MANFID_TOSHIBA 0x11 | ||
364 | #define CID_MANFID_MICRON 0x13 | ||
365 | #define CID_MANFID_SAMSUNG 0x15 | ||
366 | #define CID_MANFID_KINGSTON 0x70 | ||
367 | #define CID_MANFID_HYNIX 0x90 | ||
368 | |||
369 | #define END_FIXUP { NULL } | ||
370 | |||
371 | #define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ | ||
372 | _cis_vendor, _cis_device, \ | ||
373 | _fixup, _data, _ext_csd_rev) \ | ||
374 | { \ | ||
375 | .name = (_name), \ | ||
376 | .manfid = (_manfid), \ | ||
377 | .oemid = (_oemid), \ | ||
378 | .rev_start = (_rev_start), \ | ||
379 | .rev_end = (_rev_end), \ | ||
380 | .cis_vendor = (_cis_vendor), \ | ||
381 | .cis_device = (_cis_device), \ | ||
382 | .vendor_fixup = (_fixup), \ | ||
383 | .data = (_data), \ | ||
384 | .ext_csd_rev = (_ext_csd_rev), \ | ||
385 | } | ||
386 | |||
387 | #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ | ||
388 | _fixup, _data, _ext_csd_rev) \ | ||
389 | _FIXUP_EXT(_name, _manfid, \ | ||
390 | _oemid, _rev_start, _rev_end, \ | ||
391 | SDIO_ANY_ID, SDIO_ANY_ID, \ | ||
392 | _fixup, _data, _ext_csd_rev) \ | ||
393 | |||
394 | #define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \ | ||
395 | MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ | ||
396 | EXT_CSD_REV_ANY) | ||
397 | |||
398 | #define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \ | ||
399 | _ext_csd_rev) \ | ||
400 | MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ | ||
401 | _ext_csd_rev) | ||
402 | |||
403 | #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ | ||
404 | _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ | ||
405 | CID_OEMID_ANY, 0, -1ull, \ | ||
406 | _vendor, _device, \ | ||
407 | _fixup, _data, EXT_CSD_REV_ANY) \ | ||
408 | |||
409 | #define cid_rev(hwrev, fwrev, year, month) \ | ||
410 | (((u64) hwrev) << 40 | \ | ||
411 | ((u64) fwrev) << 32 | \ | ||
412 | ((u64) year) << 16 | \ | ||
413 | ((u64) month)) | ||
414 | |||
415 | #define cid_rev_card(card) \ | ||
416 | cid_rev(card->cid.hwrev, \ | ||
417 | card->cid.fwrev, \ | ||
418 | card->cid.year, \ | ||
419 | card->cid.month) | ||
420 | |||
421 | /* | ||
422 | * Unconditionally quirk add/remove. | ||
423 | */ | ||
424 | |||
425 | static inline void __maybe_unused add_quirk(struct mmc_card *card, int data) | ||
426 | { | ||
427 | card->quirks |= data; | ||
428 | } | ||
429 | |||
430 | static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) | ||
431 | { | ||
432 | card->quirks &= ~data; | ||
433 | } | ||
434 | |||
435 | #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) | 310 | #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) |
436 | #define mmc_card_sd(c) ((c)->type == MMC_TYPE_SD) | 311 | #define mmc_card_sd(c) ((c)->type == MMC_TYPE_SD) |
437 | #define mmc_card_sdio(c) ((c)->type == MMC_TYPE_SDIO) | 312 | #define mmc_card_sdio(c) ((c)->type == MMC_TYPE_SDIO) |
438 | 313 | ||
439 | #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) | ||
440 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) | ||
441 | #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) | ||
442 | #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) | ||
443 | #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) | ||
444 | #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) | ||
445 | #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) | ||
446 | |||
447 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) | ||
448 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) | ||
449 | #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) | ||
450 | #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) | ||
451 | #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) | ||
452 | #define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS) | ||
453 | #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) | ||
454 | #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) | ||
455 | #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) | ||
456 | |||
457 | /* | ||
458 | * Quirk add/remove for MMC products. | ||
459 | */ | ||
460 | |||
461 | static inline void __maybe_unused add_quirk_mmc(struct mmc_card *card, int data) | ||
462 | { | ||
463 | if (mmc_card_mmc(card)) | ||
464 | card->quirks |= data; | ||
465 | } | ||
466 | |||
467 | static inline void __maybe_unused remove_quirk_mmc(struct mmc_card *card, | ||
468 | int data) | ||
469 | { | ||
470 | if (mmc_card_mmc(card)) | ||
471 | card->quirks &= ~data; | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * Quirk add/remove for SD products. | ||
476 | */ | ||
477 | |||
478 | static inline void __maybe_unused add_quirk_sd(struct mmc_card *card, int data) | ||
479 | { | ||
480 | if (mmc_card_sd(card)) | ||
481 | card->quirks |= data; | ||
482 | } | ||
483 | |||
484 | static inline void __maybe_unused remove_quirk_sd(struct mmc_card *card, | ||
485 | int data) | ||
486 | { | ||
487 | if (mmc_card_sd(card)) | ||
488 | card->quirks &= ~data; | ||
489 | } | ||
490 | |||
491 | static inline int mmc_card_lenient_fn0(const struct mmc_card *c) | ||
492 | { | ||
493 | return c->quirks & MMC_QUIRK_LENIENT_FN0; | ||
494 | } | ||
495 | |||
496 | static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c) | ||
497 | { | ||
498 | return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; | ||
499 | } | ||
500 | |||
501 | static inline int mmc_card_disable_cd(const struct mmc_card *c) | ||
502 | { | ||
503 | return c->quirks & MMC_QUIRK_DISABLE_CD; | ||
504 | } | ||
505 | |||
506 | static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c) | ||
507 | { | ||
508 | return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF; | ||
509 | } | ||
510 | |||
511 | static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c) | ||
512 | { | ||
513 | return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512; | ||
514 | } | ||
515 | |||
516 | static inline int mmc_card_long_read_time(const struct mmc_card *c) | ||
517 | { | ||
518 | return c->quirks & MMC_QUIRK_LONG_READ_TIME; | ||
519 | } | ||
520 | |||
521 | static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) | ||
522 | { | ||
523 | return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING; | ||
524 | } | ||
525 | |||
526 | static inline int mmc_card_broken_hpi(const struct mmc_card *c) | ||
527 | { | ||
528 | return c->quirks & MMC_QUIRK_BROKEN_HPI; | ||
529 | } | ||
530 | |||
531 | #define mmc_card_name(c) ((c)->cid.prod_name) | ||
532 | #define mmc_card_id(c) (dev_name(&(c)->dev)) | ||
533 | |||
534 | #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev) | ||
535 | |||
536 | /* | ||
537 | * MMC device driver (e.g., Flash card, I/O card...) | ||
538 | */ | ||
539 | struct mmc_driver { | ||
540 | struct device_driver drv; | ||
541 | int (*probe)(struct mmc_card *); | ||
542 | void (*remove)(struct mmc_card *); | ||
543 | void (*shutdown)(struct mmc_card *); | ||
544 | }; | ||
545 | |||
546 | extern int mmc_register_driver(struct mmc_driver *); | ||
547 | extern void mmc_unregister_driver(struct mmc_driver *); | ||
548 | |||
549 | extern void mmc_fixup_device(struct mmc_card *card, | ||
550 | const struct mmc_fixup *table); | ||
551 | |||
552 | #endif /* LINUX_MMC_CARD_H */ | 314 | #endif /* LINUX_MMC_CARD_H */ |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index e33cc748dcfe..a0c63ea28796 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -8,10 +8,9 @@ | |||
8 | #ifndef LINUX_MMC_CORE_H | 8 | #ifndef LINUX_MMC_CORE_H |
9 | #define LINUX_MMC_CORE_H | 9 | #define LINUX_MMC_CORE_H |
10 | 10 | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/completion.h> | 11 | #include <linux/completion.h> |
12 | #include <linux/types.h> | ||
13 | 13 | ||
14 | struct request; | ||
15 | struct mmc_data; | 14 | struct mmc_data; |
16 | struct mmc_request; | 15 | struct mmc_request; |
17 | 16 | ||
@@ -159,79 +158,14 @@ struct mmc_request { | |||
159 | struct mmc_card; | 158 | struct mmc_card; |
160 | struct mmc_async_req; | 159 | struct mmc_async_req; |
161 | 160 | ||
162 | extern int mmc_stop_bkops(struct mmc_card *); | 161 | struct mmc_async_req *mmc_start_areq(struct mmc_host *host, |
163 | extern int mmc_read_bkops_status(struct mmc_card *); | 162 | struct mmc_async_req *areq, |
164 | extern struct mmc_async_req *mmc_start_req(struct mmc_host *, | 163 | enum mmc_blk_status *ret_stat); |
165 | struct mmc_async_req *, | 164 | void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq); |
166 | enum mmc_blk_status *); | 165 | int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, |
167 | extern int mmc_interrupt_hpi(struct mmc_card *); | 166 | int retries); |
168 | extern void mmc_wait_for_req(struct mmc_host *, struct mmc_request *); | 167 | |
169 | extern void mmc_wait_for_req_done(struct mmc_host *host, | 168 | int mmc_hw_reset(struct mmc_host *host); |
170 | struct mmc_request *mrq); | 169 | void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card); |
171 | extern bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq); | ||
172 | extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); | ||
173 | extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); | ||
174 | extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, | ||
175 | struct mmc_command *, int); | ||
176 | extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); | ||
177 | extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); | ||
178 | extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); | ||
179 | extern int mmc_abort_tuning(struct mmc_host *host, u32 opcode); | ||
180 | extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); | ||
181 | |||
182 | #define MMC_ERASE_ARG 0x00000000 | ||
183 | #define MMC_SECURE_ERASE_ARG 0x80000000 | ||
184 | #define MMC_TRIM_ARG 0x00000001 | ||
185 | #define MMC_DISCARD_ARG 0x00000003 | ||
186 | #define MMC_SECURE_TRIM1_ARG 0x80000001 | ||
187 | #define MMC_SECURE_TRIM2_ARG 0x80008000 | ||
188 | |||
189 | #define MMC_SECURE_ARGS 0x80000000 | ||
190 | #define MMC_TRIM_ARGS 0x00008001 | ||
191 | |||
192 | extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, | ||
193 | unsigned int arg); | ||
194 | extern int mmc_can_erase(struct mmc_card *card); | ||
195 | extern int mmc_can_trim(struct mmc_card *card); | ||
196 | extern int mmc_can_discard(struct mmc_card *card); | ||
197 | extern int mmc_can_sanitize(struct mmc_card *card); | ||
198 | extern int mmc_can_secure_erase_trim(struct mmc_card *card); | ||
199 | extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, | ||
200 | unsigned int nr); | ||
201 | extern unsigned int mmc_calc_max_discard(struct mmc_card *card); | ||
202 | |||
203 | extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); | ||
204 | extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, | ||
205 | bool is_rel_write); | ||
206 | extern int mmc_hw_reset(struct mmc_host *host); | ||
207 | extern int mmc_can_reset(struct mmc_card *card); | ||
208 | |||
209 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); | ||
210 | extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); | ||
211 | |||
212 | extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort); | ||
213 | extern void mmc_release_host(struct mmc_host *host); | ||
214 | |||
215 | extern void mmc_get_card(struct mmc_card *card); | ||
216 | extern void mmc_put_card(struct mmc_card *card); | ||
217 | |||
218 | extern int mmc_flush_cache(struct mmc_card *); | ||
219 | |||
220 | extern int mmc_detect_card_removed(struct mmc_host *host); | ||
221 | |||
222 | /** | ||
223 | * mmc_claim_host - exclusively claim a host | ||
224 | * @host: mmc host to claim | ||
225 | * | ||
226 | * Claim a host for a set of operations. | ||
227 | */ | ||
228 | static inline void mmc_claim_host(struct mmc_host *host) | ||
229 | { | ||
230 | __mmc_claim_host(host, NULL); | ||
231 | } | ||
232 | |||
233 | struct device_node; | ||
234 | extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); | ||
235 | extern int mmc_of_parse_voltage(struct device_node *np, u32 *mask); | ||
236 | 170 | ||
237 | #endif /* LINUX_MMC_CORE_H */ | 171 | #endif /* LINUX_MMC_CORE_H */ |
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h deleted file mode 100644 index 15db6f83f53f..000000000000 --- a/include/linux/mmc/dw_mmc.h +++ /dev/null | |||
@@ -1,274 +0,0 @@ | |||
1 | /* | ||
2 | * Synopsys DesignWare Multimedia Card Interface driver | ||
3 | * (Based on NXP driver for lpc 31xx) | ||
4 | * | ||
5 | * Copyright (C) 2009 NXP Semiconductors | ||
6 | * Copyright (C) 2009, 2010 Imagination Technologies Ltd. | ||
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 | |||
14 | #ifndef LINUX_MMC_DW_MMC_H | ||
15 | #define LINUX_MMC_DW_MMC_H | ||
16 | |||
17 | #include <linux/scatterlist.h> | ||
18 | #include <linux/mmc/core.h> | ||
19 | #include <linux/dmaengine.h> | ||
20 | #include <linux/reset.h> | ||
21 | |||
22 | #define MAX_MCI_SLOTS 2 | ||
23 | |||
24 | enum dw_mci_state { | ||
25 | STATE_IDLE = 0, | ||
26 | STATE_SENDING_CMD, | ||
27 | STATE_SENDING_DATA, | ||
28 | STATE_DATA_BUSY, | ||
29 | STATE_SENDING_STOP, | ||
30 | STATE_DATA_ERROR, | ||
31 | STATE_SENDING_CMD11, | ||
32 | STATE_WAITING_CMD11_DONE, | ||
33 | }; | ||
34 | |||
35 | enum { | ||
36 | EVENT_CMD_COMPLETE = 0, | ||
37 | EVENT_XFER_COMPLETE, | ||
38 | EVENT_DATA_COMPLETE, | ||
39 | EVENT_DATA_ERROR, | ||
40 | }; | ||
41 | |||
42 | enum dw_mci_cookie { | ||
43 | COOKIE_UNMAPPED, | ||
44 | COOKIE_PRE_MAPPED, /* mapped by pre_req() of dwmmc */ | ||
45 | COOKIE_MAPPED, /* mapped by prepare_data() of dwmmc */ | ||
46 | }; | ||
47 | |||
48 | struct mmc_data; | ||
49 | |||
50 | enum { | ||
51 | TRANS_MODE_PIO = 0, | ||
52 | TRANS_MODE_IDMAC, | ||
53 | TRANS_MODE_EDMAC | ||
54 | }; | ||
55 | |||
56 | struct dw_mci_dma_slave { | ||
57 | struct dma_chan *ch; | ||
58 | enum dma_transfer_direction direction; | ||
59 | }; | ||
60 | |||
61 | /** | ||
62 | * struct dw_mci - MMC controller state shared between all slots | ||
63 | * @lock: Spinlock protecting the queue and associated data. | ||
64 | * @irq_lock: Spinlock protecting the INTMASK setting. | ||
65 | * @regs: Pointer to MMIO registers. | ||
66 | * @fifo_reg: Pointer to MMIO registers for data FIFO | ||
67 | * @sg: Scatterlist entry currently being processed by PIO code, if any. | ||
68 | * @sg_miter: PIO mapping scatterlist iterator. | ||
69 | * @cur_slot: The slot which is currently using the controller. | ||
70 | * @mrq: The request currently being processed on @cur_slot, | ||
71 | * or NULL if the controller is idle. | ||
72 | * @cmd: The command currently being sent to the card, or NULL. | ||
73 | * @data: The data currently being transferred, or NULL if no data | ||
74 | * transfer is in progress. | ||
75 | * @stop_abort: The command currently prepared for stoping transfer. | ||
76 | * @prev_blksz: The former transfer blksz record. | ||
77 | * @timing: Record of current ios timing. | ||
78 | * @use_dma: Whether DMA channel is initialized or not. | ||
79 | * @using_dma: Whether DMA is in use for the current transfer. | ||
80 | * @dma_64bit_address: Whether DMA supports 64-bit address mode or not. | ||
81 | * @sg_dma: Bus address of DMA buffer. | ||
82 | * @sg_cpu: Virtual address of DMA buffer. | ||
83 | * @dma_ops: Pointer to platform-specific DMA callbacks. | ||
84 | * @cmd_status: Snapshot of SR taken upon completion of the current | ||
85 | * @ring_size: Buffer size for idma descriptors. | ||
86 | * command. Only valid when EVENT_CMD_COMPLETE is pending. | ||
87 | * @dms: structure of slave-dma private data. | ||
88 | * @phy_regs: physical address of controller's register map | ||
89 | * @data_status: Snapshot of SR taken upon completion of the current | ||
90 | * data transfer. Only valid when EVENT_DATA_COMPLETE or | ||
91 | * EVENT_DATA_ERROR is pending. | ||
92 | * @stop_cmdr: Value to be loaded into CMDR when the stop command is | ||
93 | * to be sent. | ||
94 | * @dir_status: Direction of current transfer. | ||
95 | * @tasklet: Tasklet running the request state machine. | ||
96 | * @pending_events: Bitmask of events flagged by the interrupt handler | ||
97 | * to be processed by the tasklet. | ||
98 | * @completed_events: Bitmask of events which the state machine has | ||
99 | * processed. | ||
100 | * @state: Tasklet state. | ||
101 | * @queue: List of slots waiting for access to the controller. | ||
102 | * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus | ||
103 | * rate and timeout calculations. | ||
104 | * @current_speed: Configured rate of the controller. | ||
105 | * @num_slots: Number of slots available. | ||
106 | * @fifoth_val: The value of FIFOTH register. | ||
107 | * @verid: Denote Version ID. | ||
108 | * @dev: Device associated with the MMC controller. | ||
109 | * @pdata: Platform data associated with the MMC controller. | ||
110 | * @drv_data: Driver specific data for identified variant of the controller | ||
111 | * @priv: Implementation defined private data. | ||
112 | * @biu_clk: Pointer to bus interface unit clock instance. | ||
113 | * @ciu_clk: Pointer to card interface unit clock instance. | ||
114 | * @slot: Slots sharing this MMC controller. | ||
115 | * @fifo_depth: depth of FIFO. | ||
116 | * @data_shift: log2 of FIFO item size. | ||
117 | * @part_buf_start: Start index in part_buf. | ||
118 | * @part_buf_count: Bytes of partial data in part_buf. | ||
119 | * @part_buf: Simple buffer for partial fifo reads/writes. | ||
120 | * @push_data: Pointer to FIFO push function. | ||
121 | * @pull_data: Pointer to FIFO pull function. | ||
122 | * @vqmmc_enabled: Status of vqmmc, should be true or false. | ||
123 | * @irq_flags: The flags to be passed to request_irq. | ||
124 | * @irq: The irq value to be passed to request_irq. | ||
125 | * @sdio_id0: Number of slot0 in the SDIO interrupt registers. | ||
126 | * @cmd11_timer: Timer for SD3.0 voltage switch over scheme. | ||
127 | * @dto_timer: Timer for broken data transfer over scheme. | ||
128 | * | ||
129 | * Locking | ||
130 | * ======= | ||
131 | * | ||
132 | * @lock is a softirq-safe spinlock protecting @queue as well as | ||
133 | * @cur_slot, @mrq and @state. These must always be updated | ||
134 | * at the same time while holding @lock. | ||
135 | * | ||
136 | * @irq_lock is an irq-safe spinlock protecting the INTMASK register | ||
137 | * to allow the interrupt handler to modify it directly. Held for only long | ||
138 | * enough to read-modify-write INTMASK and no other locks are grabbed when | ||
139 | * holding this one. | ||
140 | * | ||
141 | * The @mrq field of struct dw_mci_slot is also protected by @lock, | ||
142 | * and must always be written at the same time as the slot is added to | ||
143 | * @queue. | ||
144 | * | ||
145 | * @pending_events and @completed_events are accessed using atomic bit | ||
146 | * operations, so they don't need any locking. | ||
147 | * | ||
148 | * None of the fields touched by the interrupt handler need any | ||
149 | * locking. However, ordering is important: Before EVENT_DATA_ERROR or | ||
150 | * EVENT_DATA_COMPLETE is set in @pending_events, all data-related | ||
151 | * interrupts must be disabled and @data_status updated with a | ||
152 | * snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the | ||
153 | * CMDRDY interrupt must be disabled and @cmd_status updated with a | ||
154 | * snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the | ||
155 | * bytes_xfered field of @data must be written. This is ensured by | ||
156 | * using barriers. | ||
157 | */ | ||
158 | struct dw_mci { | ||
159 | spinlock_t lock; | ||
160 | spinlock_t irq_lock; | ||
161 | void __iomem *regs; | ||
162 | void __iomem *fifo_reg; | ||
163 | |||
164 | struct scatterlist *sg; | ||
165 | struct sg_mapping_iter sg_miter; | ||
166 | |||
167 | struct dw_mci_slot *cur_slot; | ||
168 | struct mmc_request *mrq; | ||
169 | struct mmc_command *cmd; | ||
170 | struct mmc_data *data; | ||
171 | struct mmc_command stop_abort; | ||
172 | unsigned int prev_blksz; | ||
173 | unsigned char timing; | ||
174 | |||
175 | /* DMA interface members*/ | ||
176 | int use_dma; | ||
177 | int using_dma; | ||
178 | int dma_64bit_address; | ||
179 | |||
180 | dma_addr_t sg_dma; | ||
181 | void *sg_cpu; | ||
182 | const struct dw_mci_dma_ops *dma_ops; | ||
183 | /* For idmac */ | ||
184 | unsigned int ring_size; | ||
185 | |||
186 | /* For edmac */ | ||
187 | struct dw_mci_dma_slave *dms; | ||
188 | /* Registers's physical base address */ | ||
189 | resource_size_t phy_regs; | ||
190 | |||
191 | u32 cmd_status; | ||
192 | u32 data_status; | ||
193 | u32 stop_cmdr; | ||
194 | u32 dir_status; | ||
195 | struct tasklet_struct tasklet; | ||
196 | unsigned long pending_events; | ||
197 | unsigned long completed_events; | ||
198 | enum dw_mci_state state; | ||
199 | struct list_head queue; | ||
200 | |||
201 | u32 bus_hz; | ||
202 | u32 current_speed; | ||
203 | u32 num_slots; | ||
204 | u32 fifoth_val; | ||
205 | u16 verid; | ||
206 | struct device *dev; | ||
207 | struct dw_mci_board *pdata; | ||
208 | const struct dw_mci_drv_data *drv_data; | ||
209 | void *priv; | ||
210 | struct clk *biu_clk; | ||
211 | struct clk *ciu_clk; | ||
212 | struct dw_mci_slot *slot[MAX_MCI_SLOTS]; | ||
213 | |||
214 | /* FIFO push and pull */ | ||
215 | int fifo_depth; | ||
216 | int data_shift; | ||
217 | u8 part_buf_start; | ||
218 | u8 part_buf_count; | ||
219 | union { | ||
220 | u16 part_buf16; | ||
221 | u32 part_buf32; | ||
222 | u64 part_buf; | ||
223 | }; | ||
224 | void (*push_data)(struct dw_mci *host, void *buf, int cnt); | ||
225 | void (*pull_data)(struct dw_mci *host, void *buf, int cnt); | ||
226 | |||
227 | bool vqmmc_enabled; | ||
228 | unsigned long irq_flags; /* IRQ flags */ | ||
229 | int irq; | ||
230 | |||
231 | int sdio_id0; | ||
232 | |||
233 | struct timer_list cmd11_timer; | ||
234 | struct timer_list dto_timer; | ||
235 | }; | ||
236 | |||
237 | /* DMA ops for Internal/External DMAC interface */ | ||
238 | struct dw_mci_dma_ops { | ||
239 | /* DMA Ops */ | ||
240 | int (*init)(struct dw_mci *host); | ||
241 | int (*start)(struct dw_mci *host, unsigned int sg_len); | ||
242 | void (*complete)(void *host); | ||
243 | void (*stop)(struct dw_mci *host); | ||
244 | void (*cleanup)(struct dw_mci *host); | ||
245 | void (*exit)(struct dw_mci *host); | ||
246 | }; | ||
247 | |||
248 | struct dma_pdata; | ||
249 | |||
250 | /* Board platform data */ | ||
251 | struct dw_mci_board { | ||
252 | u32 num_slots; | ||
253 | |||
254 | unsigned int bus_hz; /* Clock speed at the cclk_in pad */ | ||
255 | |||
256 | u32 caps; /* Capabilities */ | ||
257 | u32 caps2; /* More capabilities */ | ||
258 | u32 pm_caps; /* PM capabilities */ | ||
259 | /* | ||
260 | * Override fifo depth. If 0, autodetect it from the FIFOTH register, | ||
261 | * but note that this may not be reliable after a bootloader has used | ||
262 | * it. | ||
263 | */ | ||
264 | unsigned int fifo_depth; | ||
265 | |||
266 | /* delay in mS before detecting cards after interrupt */ | ||
267 | u32 detect_delay_ms; | ||
268 | |||
269 | struct reset_control *rstc; | ||
270 | struct dw_mci_dma_ops *dma_ops; | ||
271 | struct dma_pdata *data; | ||
272 | }; | ||
273 | |||
274 | #endif /* LINUX_MMC_DW_MMC_H */ | ||
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8bc884121465..83f1c4a9f03b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -10,16 +10,12 @@ | |||
10 | #ifndef LINUX_MMC_HOST_H | 10 | #ifndef LINUX_MMC_HOST_H |
11 | #define LINUX_MMC_HOST_H | 11 | #define LINUX_MMC_HOST_H |
12 | 12 | ||
13 | #include <linux/leds.h> | ||
14 | #include <linux/mutex.h> | ||
15 | #include <linux/timer.h> | ||
16 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
17 | #include <linux/device.h> | 14 | #include <linux/device.h> |
18 | #include <linux/fault-inject.h> | 15 | #include <linux/fault-inject.h> |
19 | 16 | ||
20 | #include <linux/mmc/core.h> | 17 | #include <linux/mmc/core.h> |
21 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
22 | #include <linux/mmc/mmc.h> | ||
23 | #include <linux/mmc/pm.h> | 19 | #include <linux/mmc/pm.h> |
24 | 20 | ||
25 | struct mmc_ios { | 21 | struct mmc_ios { |
@@ -82,6 +78,8 @@ struct mmc_ios { | |||
82 | bool enhanced_strobe; /* hs400es selection */ | 78 | bool enhanced_strobe; /* hs400es selection */ |
83 | }; | 79 | }; |
84 | 80 | ||
81 | struct mmc_host; | ||
82 | |||
85 | struct mmc_host_ops { | 83 | struct mmc_host_ops { |
86 | /* | 84 | /* |
87 | * It is optional for the host to implement pre_req and post_req in | 85 | * It is optional for the host to implement pre_req and post_req in |
@@ -162,9 +160,6 @@ struct mmc_host_ops { | |||
162 | unsigned int direction, int blk_size); | 160 | unsigned int direction, int blk_size); |
163 | }; | 161 | }; |
164 | 162 | ||
165 | struct mmc_card; | ||
166 | struct device; | ||
167 | |||
168 | struct mmc_async_req { | 163 | struct mmc_async_req { |
169 | /* active mmc request */ | 164 | /* active mmc request */ |
170 | struct mmc_request *mrq; | 165 | struct mmc_request *mrq; |
@@ -264,17 +259,16 @@ struct mmc_host { | |||
264 | #define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ | 259 | #define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ |
265 | #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ | 260 | #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ |
266 | #define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */ | 261 | #define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */ |
267 | #define MMC_CAP_1_8V_DDR (1 << 11) /* can support */ | 262 | #define MMC_CAP_3_3V_DDR (1 << 11) /* Host supports eMMC DDR 3.3V */ |
268 | /* DDR mode at 1.8V */ | 263 | #define MMC_CAP_1_8V_DDR (1 << 12) /* Host supports eMMC DDR 1.8V */ |
269 | #define MMC_CAP_1_2V_DDR (1 << 12) /* can support */ | 264 | #define MMC_CAP_1_2V_DDR (1 << 13) /* Host supports eMMC DDR 1.2V */ |
270 | /* DDR mode at 1.2V */ | 265 | #define MMC_CAP_POWER_OFF_CARD (1 << 14) /* Can power off after boot */ |
271 | #define MMC_CAP_POWER_OFF_CARD (1 << 13) /* Can power off after boot */ | 266 | #define MMC_CAP_BUS_WIDTH_TEST (1 << 15) /* CMD14/CMD19 bus width ok */ |
272 | #define MMC_CAP_BUS_WIDTH_TEST (1 << 14) /* CMD14/CMD19 bus width ok */ | 267 | #define MMC_CAP_UHS_SDR12 (1 << 16) /* Host supports UHS SDR12 mode */ |
273 | #define MMC_CAP_UHS_SDR12 (1 << 15) /* Host supports UHS SDR12 mode */ | 268 | #define MMC_CAP_UHS_SDR25 (1 << 17) /* Host supports UHS SDR25 mode */ |
274 | #define MMC_CAP_UHS_SDR25 (1 << 16) /* Host supports UHS SDR25 mode */ | 269 | #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ |
275 | #define MMC_CAP_UHS_SDR50 (1 << 17) /* Host supports UHS SDR50 mode */ | 270 | #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ |
276 | #define MMC_CAP_UHS_SDR104 (1 << 18) /* Host supports UHS SDR104 mode */ | 271 | #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ |
277 | #define MMC_CAP_UHS_DDR50 (1 << 19) /* Host supports UHS DDR50 mode */ | ||
278 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ | 272 | #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ |
279 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ | 273 | #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ |
280 | #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ | 274 | #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ |
@@ -397,11 +391,14 @@ struct mmc_host { | |||
397 | unsigned long private[0] ____cacheline_aligned; | 391 | unsigned long private[0] ____cacheline_aligned; |
398 | }; | 392 | }; |
399 | 393 | ||
394 | struct device_node; | ||
395 | |||
400 | struct mmc_host *mmc_alloc_host(int extra, struct device *); | 396 | struct mmc_host *mmc_alloc_host(int extra, struct device *); |
401 | int mmc_add_host(struct mmc_host *); | 397 | int mmc_add_host(struct mmc_host *); |
402 | void mmc_remove_host(struct mmc_host *); | 398 | void mmc_remove_host(struct mmc_host *); |
403 | void mmc_free_host(struct mmc_host *); | 399 | void mmc_free_host(struct mmc_host *); |
404 | int mmc_of_parse(struct mmc_host *host); | 400 | int mmc_of_parse(struct mmc_host *host); |
401 | int mmc_of_parse_voltage(struct device_node *np, u32 *mask); | ||
405 | 402 | ||
406 | static inline void *mmc_priv(struct mmc_host *host) | 403 | static inline void *mmc_priv(struct mmc_host *host) |
407 | { | 404 | { |
@@ -457,6 +454,7 @@ static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc, | |||
457 | } | 454 | } |
458 | #endif | 455 | #endif |
459 | 456 | ||
457 | u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max); | ||
460 | int mmc_regulator_get_supply(struct mmc_host *mmc); | 458 | int mmc_regulator_get_supply(struct mmc_host *mmc); |
461 | 459 | ||
462 | static inline int mmc_card_is_removable(struct mmc_host *host) | 460 | static inline int mmc_card_is_removable(struct mmc_host *host) |
@@ -474,56 +472,20 @@ static inline int mmc_card_wake_sdio_irq(struct mmc_host *host) | |||
474 | return host->pm_flags & MMC_PM_WAKE_SDIO_IRQ; | 472 | return host->pm_flags & MMC_PM_WAKE_SDIO_IRQ; |
475 | } | 473 | } |
476 | 474 | ||
477 | static inline int mmc_host_cmd23(struct mmc_host *host) | 475 | /* TODO: Move to private header */ |
478 | { | ||
479 | return host->caps & MMC_CAP_CMD23; | ||
480 | } | ||
481 | |||
482 | static inline int mmc_boot_partition_access(struct mmc_host *host) | ||
483 | { | ||
484 | return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); | ||
485 | } | ||
486 | |||
487 | static inline int mmc_host_uhs(struct mmc_host *host) | ||
488 | { | ||
489 | return host->caps & | ||
490 | (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
491 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | | ||
492 | MMC_CAP_UHS_DDR50); | ||
493 | } | ||
494 | |||
495 | static inline int mmc_card_hs(struct mmc_card *card) | 476 | static inline int mmc_card_hs(struct mmc_card *card) |
496 | { | 477 | { |
497 | return card->host->ios.timing == MMC_TIMING_SD_HS || | 478 | return card->host->ios.timing == MMC_TIMING_SD_HS || |
498 | card->host->ios.timing == MMC_TIMING_MMC_HS; | 479 | card->host->ios.timing == MMC_TIMING_MMC_HS; |
499 | } | 480 | } |
500 | 481 | ||
482 | /* TODO: Move to private header */ | ||
501 | static inline int mmc_card_uhs(struct mmc_card *card) | 483 | static inline int mmc_card_uhs(struct mmc_card *card) |
502 | { | 484 | { |
503 | return card->host->ios.timing >= MMC_TIMING_UHS_SDR12 && | 485 | return card->host->ios.timing >= MMC_TIMING_UHS_SDR12 && |
504 | card->host->ios.timing <= MMC_TIMING_UHS_DDR50; | 486 | card->host->ios.timing <= MMC_TIMING_UHS_DDR50; |
505 | } | 487 | } |
506 | 488 | ||
507 | static inline bool mmc_card_hs200(struct mmc_card *card) | ||
508 | { | ||
509 | return card->host->ios.timing == MMC_TIMING_MMC_HS200; | ||
510 | } | ||
511 | |||
512 | static inline bool mmc_card_ddr52(struct mmc_card *card) | ||
513 | { | ||
514 | return card->host->ios.timing == MMC_TIMING_MMC_DDR52; | ||
515 | } | ||
516 | |||
517 | static inline bool mmc_card_hs400(struct mmc_card *card) | ||
518 | { | ||
519 | return card->host->ios.timing == MMC_TIMING_MMC_HS400; | ||
520 | } | ||
521 | |||
522 | static inline bool mmc_card_hs400es(struct mmc_card *card) | ||
523 | { | ||
524 | return card->host->ios.enhanced_strobe; | ||
525 | } | ||
526 | |||
527 | void mmc_retune_timer_stop(struct mmc_host *host); | 489 | void mmc_retune_timer_stop(struct mmc_host *host); |
528 | 490 | ||
529 | static inline void mmc_retune_needed(struct mmc_host *host) | 491 | static inline void mmc_retune_needed(struct mmc_host *host) |
@@ -532,18 +494,12 @@ static inline void mmc_retune_needed(struct mmc_host *host) | |||
532 | host->need_retune = 1; | 494 | host->need_retune = 1; |
533 | } | 495 | } |
534 | 496 | ||
535 | static inline void mmc_retune_recheck(struct mmc_host *host) | ||
536 | { | ||
537 | if (host->hold_retune <= 1) | ||
538 | host->retune_now = 1; | ||
539 | } | ||
540 | |||
541 | static inline bool mmc_can_retune(struct mmc_host *host) | 497 | static inline bool mmc_can_retune(struct mmc_host *host) |
542 | { | 498 | { |
543 | return host->can_retune == 1; | 499 | return host->can_retune == 1; |
544 | } | 500 | } |
545 | 501 | ||
546 | void mmc_retune_pause(struct mmc_host *host); | 502 | int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); |
547 | void mmc_retune_unpause(struct mmc_host *host); | 503 | int mmc_abort_tuning(struct mmc_host *host, u32 opcode); |
548 | 504 | ||
549 | #endif /* LINUX_MMC_HOST_H */ | 505 | #endif /* LINUX_MMC_HOST_H */ |
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 672730acc705..3ffc27aaeeaf 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
@@ -24,6 +24,8 @@ | |||
24 | #ifndef LINUX_MMC_MMC_H | 24 | #ifndef LINUX_MMC_MMC_H |
25 | #define LINUX_MMC_MMC_H | 25 | #define LINUX_MMC_MMC_H |
26 | 26 | ||
27 | #include <linux/types.h> | ||
28 | |||
27 | /* Standard MMC commands (4.1) type argument response */ | 29 | /* Standard MMC commands (4.1) type argument response */ |
28 | /* class 1 */ | 30 | /* class 1 */ |
29 | #define MMC_GO_IDLE_STATE 0 /* bc */ | 31 | #define MMC_GO_IDLE_STATE 0 /* bc */ |
@@ -182,50 +184,6 @@ static inline bool mmc_op_multi(u32 opcode) | |||
182 | #define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */ | 184 | #define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */ |
183 | #define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE | 185 | #define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE |
184 | 186 | ||
185 | /* These are unpacked versions of the actual responses */ | ||
186 | |||
187 | struct _mmc_csd { | ||
188 | u8 csd_structure; | ||
189 | u8 spec_vers; | ||
190 | u8 taac; | ||
191 | u8 nsac; | ||
192 | u8 tran_speed; | ||
193 | u16 ccc; | ||
194 | u8 read_bl_len; | ||
195 | u8 read_bl_partial; | ||
196 | u8 write_blk_misalign; | ||
197 | u8 read_blk_misalign; | ||
198 | u8 dsr_imp; | ||
199 | u16 c_size; | ||
200 | u8 vdd_r_curr_min; | ||
201 | u8 vdd_r_curr_max; | ||
202 | u8 vdd_w_curr_min; | ||
203 | u8 vdd_w_curr_max; | ||
204 | u8 c_size_mult; | ||
205 | union { | ||
206 | struct { /* MMC system specification version 3.1 */ | ||
207 | u8 erase_grp_size; | ||
208 | u8 erase_grp_mult; | ||
209 | } v31; | ||
210 | struct { /* MMC system specification version 2.2 */ | ||
211 | u8 sector_size; | ||
212 | u8 erase_grp_size; | ||
213 | } v22; | ||
214 | } erase; | ||
215 | u8 wp_grp_size; | ||
216 | u8 wp_grp_enable; | ||
217 | u8 default_ecc; | ||
218 | u8 r2w_factor; | ||
219 | u8 write_bl_len; | ||
220 | u8 write_bl_partial; | ||
221 | u8 file_format_grp; | ||
222 | u8 copy; | ||
223 | u8 perm_write_protect; | ||
224 | u8 tmp_write_protect; | ||
225 | u8 file_format; | ||
226 | u8 ecc; | ||
227 | }; | ||
228 | |||
229 | /* | 187 | /* |
230 | * OCR bits are mostly in host.h | 188 | * OCR bits are mostly in host.h |
231 | */ | 189 | */ |
@@ -339,6 +297,9 @@ struct _mmc_csd { | |||
339 | #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ | 297 | #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ |
340 | #define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */ | 298 | #define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */ |
341 | #define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */ | 299 | #define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */ |
300 | #define EXT_CSD_PRE_EOL_INFO 267 /* RO */ | ||
301 | #define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A 268 /* RO */ | ||
302 | #define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 269 /* RO */ | ||
342 | #define EXT_CSD_CMDQ_DEPTH 307 /* RO */ | 303 | #define EXT_CSD_CMDQ_DEPTH 307 /* RO */ |
343 | #define EXT_CSD_CMDQ_SUPPORT 308 /* RO */ | 304 | #define EXT_CSD_CMDQ_SUPPORT 308 /* RO */ |
344 | #define EXT_CSD_SUPPORTED_MODE 493 /* RO */ | 305 | #define EXT_CSD_SUPPORTED_MODE 493 /* RO */ |
@@ -446,6 +407,7 @@ struct _mmc_csd { | |||
446 | * BKOPS modes | 407 | * BKOPS modes |
447 | */ | 408 | */ |
448 | #define EXT_CSD_MANUAL_BKOPS_MASK 0x01 | 409 | #define EXT_CSD_MANUAL_BKOPS_MASK 0x01 |
410 | #define EXT_CSD_AUTO_BKOPS_MASK 0x02 | ||
449 | 411 | ||
450 | /* | 412 | /* |
451 | * Command Queue | 413 | * Command Queue |
@@ -457,12 +419,23 @@ struct _mmc_csd { | |||
457 | /* | 419 | /* |
458 | * MMC_SWITCH access modes | 420 | * MMC_SWITCH access modes |
459 | */ | 421 | */ |
460 | |||
461 | #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ | 422 | #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ |
462 | #define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ | 423 | #define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ |
463 | #define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ | 424 | #define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ |
464 | #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ | 425 | #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ |
465 | 426 | ||
427 | /* | ||
428 | * Erase/trim/discard | ||
429 | */ | ||
430 | #define MMC_ERASE_ARG 0x00000000 | ||
431 | #define MMC_SECURE_ERASE_ARG 0x80000000 | ||
432 | #define MMC_TRIM_ARG 0x00000001 | ||
433 | #define MMC_DISCARD_ARG 0x00000003 | ||
434 | #define MMC_SECURE_TRIM1_ARG 0x80000001 | ||
435 | #define MMC_SECURE_TRIM2_ARG 0x80008000 | ||
436 | #define MMC_SECURE_ARGS 0x80000000 | ||
437 | #define MMC_TRIM_ARGS 0x00008001 | ||
438 | |||
466 | #define mmc_driver_type_mask(n) (1 << (n)) | 439 | #define mmc_driver_type_mask(n) (1 << (n)) |
467 | 440 | ||
468 | #endif /* LINUX_MMC_MMC_H */ | 441 | #endif /* LINUX_MMC_MMC_H */ |
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index d43ef96bf075..46794a7a531c 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 | 51 | #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 |
52 | #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 | 52 | #define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 |
53 | #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 | 53 | #define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 |
54 | #define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 | ||
54 | 55 | ||
55 | #define SDIO_VENDOR_ID_SIANO 0x039a | 56 | #define SDIO_VENDOR_ID_SIANO 0x039a |
56 | #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 | 57 | #define SDIO_DEVICE_ID_SIANO_NOVA_B0 0x0201 |
@@ -60,4 +61,10 @@ | |||
60 | #define SDIO_DEVICE_ID_SIANO_NOVA_A0 0x1100 | 61 | #define SDIO_DEVICE_ID_SIANO_NOVA_A0 0x1100 |
61 | #define SDIO_DEVICE_ID_SIANO_STELLAR 0x5347 | 62 | #define SDIO_DEVICE_ID_SIANO_STELLAR 0x5347 |
62 | 63 | ||
64 | #define SDIO_VENDOR_ID_TI 0x0097 | ||
65 | #define SDIO_DEVICE_ID_TI_WL1271 0x4076 | ||
66 | |||
67 | #define SDIO_VENDOR_ID_STE 0x0020 | ||
68 | #define SDIO_DEVICE_ID_STE_CW1200 0x2280 | ||
69 | |||
63 | #endif /* LINUX_MMC_SDIO_IDS_H */ | 70 | #endif /* LINUX_MMC_SDIO_IDS_H */ |
diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h index ccd8fb2cad52..a7baa29484c3 100644 --- a/include/linux/mmc/sh_mmcif.h +++ b/include/linux/mmc/sh_mmcif.h | |||
@@ -32,13 +32,8 @@ | |||
32 | */ | 32 | */ |
33 | 33 | ||
34 | struct sh_mmcif_plat_data { | 34 | struct sh_mmcif_plat_data { |
35 | int (*get_cd)(struct platform_device *pdef); | ||
36 | unsigned int slave_id_tx; /* embedded slave_id_[tr]x */ | 35 | unsigned int slave_id_tx; /* embedded slave_id_[tr]x */ |
37 | unsigned int slave_id_rx; | 36 | unsigned int slave_id_rx; |
38 | bool use_cd_gpio : 1; | ||
39 | bool ccs_unsupported : 1; | ||
40 | bool clk_ctrl2_present : 1; | ||
41 | unsigned int cd_gpio; | ||
42 | u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */ | 37 | u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */ |
43 | unsigned long caps; | 38 | unsigned long caps; |
44 | u32 ocr; | 39 | u32 ocr; |
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h index a7972cd3bc14..82f0d289f110 100644 --- a/include/linux/mmc/slot-gpio.h +++ b/include/linux/mmc/slot-gpio.h | |||
@@ -11,6 +11,9 @@ | |||
11 | #ifndef MMC_SLOT_GPIO_H | 11 | #ifndef MMC_SLOT_GPIO_H |
12 | #define MMC_SLOT_GPIO_H | 12 | #define MMC_SLOT_GPIO_H |
13 | 13 | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/irqreturn.h> | ||
16 | |||
14 | struct mmc_host; | 17 | struct mmc_host; |
15 | 18 | ||
16 | int mmc_gpio_get_ro(struct mmc_host *host); | 19 | int mmc_gpio_get_ro(struct mmc_host *host); |
diff --git a/include/linux/platform_data/mmc-mxcmmc.h b/include/linux/platform_data/mmc-mxcmmc.h index 29115f405af9..b0fdaa9bd185 100644 --- a/include/linux/platform_data/mmc-mxcmmc.h +++ b/include/linux/platform_data/mmc-mxcmmc.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef ASMARM_ARCH_MMC_H | 1 | #ifndef ASMARM_ARCH_MMC_H |
2 | #define ASMARM_ARCH_MMC_H | 2 | #define ASMARM_ARCH_MMC_H |
3 | 3 | ||
4 | #include <linux/interrupt.h> | ||
4 | #include <linux/mmc/host.h> | 5 | #include <linux/mmc/host.h> |
5 | 6 | ||
6 | struct device; | 7 | struct device; |