diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 13:56:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 13:56:48 -0500 |
commit | aa7ed01f93ff7e149cad46f13f66b269d59c9bc0 (patch) | |
tree | ab46a44f3c83c75e1c81f211acd0d68ffe60dd7c | |
parent | 7796c11c728ad40ba4151d559a949c002deffb9a (diff) | |
parent | 017210d1c0dc2e2d3b142985cb31d90b98dc0f0f (diff) |
Merge tag 'mmc-v3.20-1' of git://git.linaro.org/people/ulf.hansson/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Support for MMC power sequences.
- SDIO function devicetree subnode parsing.
- Refactor the hardware reset routines and enable it for SD cards.
- Various code quality improvements, especially for slot-gpio.
MMC host:
- dw_mmc: Various fixes and cleanups.
- dw_mmc: Convert to mmc_send_tuning().
- moxart: Fix probe logic.
- sdhci: Various fixes and cleanups
- sdhci: Asynchronous request handling support.
- sdhci-pxav3: Various fixes and cleanups.
- sdhci-tegra: Fixes for T114, T124 and T132.
- rtsx: Various fixes and cleanups.
- rtsx: Support for SDIO.
- sdhi/tmio: Refactor and cleanup of header files.
- omap_hsmmc: Use slot-gpio and common MMC DT parser.
- Make all hosts to deal with errors from mmc_of_parse().
- sunxi: Various fixes and cleanups.
- sdhci: Support for Fujitsu SDHCI controller f_sdh30"
* tag 'mmc-v3.20-1' of git://git.linaro.org/people/ulf.hansson/mmc: (117 commits)
mmc: sdhci-s3c: solve problem with sleeping in atomic context
mmc: pwrseq: add driver for emmc hardware reset
mmc: moxart: fix probe logic
mmc: core: Invoke mmc_pwrseq_post_power_on() prior MMC_POWER_ON state
mmc: pwrseq_simple: Add optional reference clock support
mmc: pwrseq: Document optional clock for the simple power sequence
mmc: pwrseq_simple: Extend to support more pins
mmc: pwrseq: Document that simple sequence support more than one GPIO
mmc: Add hardware dependencies for sdhci-pxav3 and sdhci-pxav2
mmc: sdhci-pxav3: Modify clock settings for the SDR50 and DDR50 modes
mmc: sdhci-pxav3: Extend binding with SDIO3 conf reg for the Armada 38x
mmc: sdhci-pxav3: Fix Armada 38x controller's caps according to erratum ERR-7878951
mmc: sdhci-pxav3: Fix SDR50 and DDR50 capabilities for the Armada 38x flavor
mmc: sdhci: switch voltage before sdhci_set_ios in runtime resume
mmc: tegra: Write xfer_mode, CMD regs in together
mmc: Resolve BKOPS compatability issue
mmc: sdhci-pxav3: fix setting of pdata->clk_delay_cycles
mmc: dw_mmc: rockchip: remove incorrect __exit_p()
mmc: dw_mmc: exynos: remove incorrect __exit_p()
mmc: Fix menuconfig alignment of MMC_SDHCI_* options
...
68 files changed, 2152 insertions, 1180 deletions
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-emmc.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-emmc.txt new file mode 100644 index 000000000000..0cb827bf9435 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-emmc.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | * The simple eMMC hardware reset provider | ||
2 | |||
3 | The purpose of this driver is to perform standard eMMC hw reset | ||
4 | procedure, as descibed by Jedec 4.4 specification. This procedure is | ||
5 | performed just after MMC core enabled power to the given mmc host (to | ||
6 | fix possible issues if bootloader has left eMMC card in initialized or | ||
7 | unknown state), and before performing complete system reboot (also in | ||
8 | case of emergency reboot call). The latter is needed on boards, which | ||
9 | doesn't have hardware reset logic connected to emmc card and (limited or | ||
10 | broken) ROM bootloaders are unable to read second stage from the emmc | ||
11 | card if the card is left in unknown or already initialized state. | ||
12 | |||
13 | Required properties: | ||
14 | - compatible : contains "mmc-pwrseq-emmc". | ||
15 | - reset-gpios : contains a GPIO specifier. The reset GPIO is asserted | ||
16 | and then deasserted to perform eMMC card reset. To perform | ||
17 | reset procedure as described in Jedec 4.4 specification, the | ||
18 | gpio line should be defined as GPIO_ACTIVE_LOW. | ||
19 | |||
20 | Example: | ||
21 | |||
22 | sdhci0_pwrseq { | ||
23 | compatible = "mmc-pwrseq-emmc"; | ||
24 | reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; | ||
25 | } | ||
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt new file mode 100644 index 000000000000..a462c50f19a8 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | * The simple MMC power sequence provider | ||
2 | |||
3 | The purpose of the simple MMC power sequence provider is to supports a set of | ||
4 | common properties between various SOC designs. It thus enables us to use the | ||
5 | same provider for several SOC designs. | ||
6 | |||
7 | Required properties: | ||
8 | - compatible : contains "mmc-pwrseq-simple". | ||
9 | |||
10 | Optional properties: | ||
11 | - reset-gpios : contains a list of GPIO specifiers. The reset GPIOs are asserted | ||
12 | at initialization and prior we start the power up procedure of the card. | ||
13 | They will be de-asserted right after the power has been provided to the | ||
14 | card. | ||
15 | - clocks : Must contain an entry for the entry in clock-names. | ||
16 | See ../clocks/clock-bindings.txt for details. | ||
17 | - clock-names : Must include the following entry: | ||
18 | "ext_clock" (External clock provided to the card). | ||
19 | |||
20 | Example: | ||
21 | |||
22 | sdhci0_pwrseq { | ||
23 | compatible = "mmc-pwrseq-simple"; | ||
24 | reset-gpios = <&gpio1 12 0>; | ||
25 | } | ||
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index b52628b18a53..438899e8829b 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt | |||
@@ -64,7 +64,43 @@ Optional SDIO properties: | |||
64 | - keep-power-in-suspend: Preserves card power during a suspend/resume cycle | 64 | - keep-power-in-suspend: Preserves card power during a suspend/resume cycle |
65 | - enable-sdio-wakeup: Enables wake up of host system on SDIO IRQ assertion | 65 | - enable-sdio-wakeup: Enables wake up of host system on SDIO IRQ assertion |
66 | 66 | ||
67 | Example: | 67 | |
68 | MMC power sequences: | ||
69 | -------------------- | ||
70 | |||
71 | System on chip designs may specify a specific MMC power sequence. To | ||
72 | successfully detect an (e)MMC/SD/SDIO card, that power sequence must be | ||
73 | maintained while initializing the card. | ||
74 | |||
75 | Optional property: | ||
76 | - mmc-pwrseq: phandle to the MMC power sequence node. See "mmc-pwrseq-*" | ||
77 | for documentation of MMC power sequence bindings. | ||
78 | |||
79 | |||
80 | Use of Function subnodes | ||
81 | ------------------------ | ||
82 | |||
83 | On embedded systems the cards connected to a host may need additional | ||
84 | properties. These can be specified in subnodes to the host controller node. | ||
85 | The subnodes are identified by the standard 'reg' property. | ||
86 | Which information exactly can be specified depends on the bindings for the | ||
87 | SDIO function driver for the subnode, as specified by the compatible string. | ||
88 | |||
89 | Required host node properties when using function subnodes: | ||
90 | - #address-cells: should be one. The cell is the slot id. | ||
91 | - #size-cells: should be zero. | ||
92 | |||
93 | Required function subnode properties: | ||
94 | - compatible: name of SDIO function following generic names recommended practice | ||
95 | - reg: Must contain the SDIO function number of the function this subnode | ||
96 | describes. A value of 0 denotes the memory SD function, values from | ||
97 | 1 to 7 denote the SDIO functions. | ||
98 | |||
99 | |||
100 | Examples | ||
101 | -------- | ||
102 | |||
103 | Basic example: | ||
68 | 104 | ||
69 | sdhci@ab000000 { | 105 | sdhci@ab000000 { |
70 | compatible = "sdhci"; | 106 | compatible = "sdhci"; |
@@ -77,4 +113,28 @@ sdhci@ab000000 { | |||
77 | max-frequency = <50000000>; | 113 | max-frequency = <50000000>; |
78 | keep-power-in-suspend; | 114 | keep-power-in-suspend; |
79 | enable-sdio-wakeup; | 115 | enable-sdio-wakeup; |
116 | mmc-pwrseq = <&sdhci0_pwrseq> | ||
80 | } | 117 | } |
118 | |||
119 | Example with sdio function subnode: | ||
120 | |||
121 | mmc3: mmc@01c12000 { | ||
122 | #address-cells = <1>; | ||
123 | #size-cells = <0>; | ||
124 | |||
125 | pinctrl-names = "default"; | ||
126 | pinctrl-0 = <&mmc3_pins_a>; | ||
127 | vmmc-supply = <®_vmmc3>; | ||
128 | bus-width = <4>; | ||
129 | non-removable; | ||
130 | mmc-pwrseq = <&sdhci0_pwrseq> | ||
131 | status = "okay"; | ||
132 | |||
133 | brcmf: bcrmf@1 { | ||
134 | reg = <1>; | ||
135 | compatible = "brcm,bcm43xx-fmac"; | ||
136 | interrupt-parent = <&pio>; | ||
137 | interrupts = <10 8>; /* PH10 / EINT10 */ | ||
138 | interrupt-names = "host-wake"; | ||
139 | }; | ||
140 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt new file mode 100644 index 000000000000..de2c53cff4f1 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sdhci-fujitsu.txt | |||
@@ -0,0 +1,30 @@ | |||
1 | * Fujitsu SDHCI controller | ||
2 | |||
3 | This file documents differences between the core properties in mmc.txt | ||
4 | and the properties used by the sdhci_f_sdh30 driver. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: "fujitsu,mb86s70-sdhci-3.0" | ||
8 | - clocks: Must contain an entry for each entry in clock-names. It is a | ||
9 | list of phandles and clock-specifier pairs. | ||
10 | See ../clocks/clock-bindings.txt for details. | ||
11 | - clock-names: Should contain the following two entries: | ||
12 | "iface" - clock used for sdhci interface | ||
13 | "core" - core clock for sdhci controller | ||
14 | |||
15 | Optional properties: | ||
16 | - vqmmc-supply: phandle to the regulator device tree node, mentioned | ||
17 | as the VCCQ/VDD_IO supply in the eMMC/SD specs. | ||
18 | |||
19 | Example: | ||
20 | |||
21 | sdhci1: mmc@36600000 { | ||
22 | compatible = "fujitsu,mb86s70-sdhci-3.0"; | ||
23 | reg = <0 0x36600000 0x1000>; | ||
24 | interrupts = <0 172 0x4>, | ||
25 | <0 173 0x4>; | ||
26 | bus-width = <4>; | ||
27 | vqmmc-supply = <&vccq_sdhci1>; | ||
28 | clocks = <&clock 2 2 0>, <&clock 2 3 0>; | ||
29 | clock-names = "iface", "core"; | ||
30 | }; | ||
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt index 4dd6deb90719..3d1b449d6097 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt | |||
@@ -9,9 +9,13 @@ Required properties: | |||
9 | - reg: | 9 | - reg: |
10 | * for "mrvl,pxav2-mmc" and "mrvl,pxav3-mmc", one register area for | 10 | * for "mrvl,pxav2-mmc" and "mrvl,pxav3-mmc", one register area for |
11 | the SDHCI registers. | 11 | the SDHCI registers. |
12 | * for "marvell,armada-380-sdhci", two register areas. The first one | 12 | |
13 | for the SDHCI registers themselves, and the second one for the | 13 | * for "marvell,armada-380-sdhci", three register areas. The first |
14 | AXI/Mbus bridge registers of the SDHCI unit. | 14 | one for the SDHCI registers themselves, the second one for the |
15 | AXI/Mbus bridge registers of the SDHCI unit, the third one for the | ||
16 | SDIO3 Configuration register | ||
17 | - reg names: should be "sdhci", "mbus", "conf-sdio3". only mandatory | ||
18 | for "marvell,armada-380-sdhci" | ||
15 | - clocks: Array of clocks required for SDHCI; requires at least one for | 19 | - clocks: Array of clocks required for SDHCI; requires at least one for |
16 | I/O clock. | 20 | I/O clock. |
17 | - clock-names: Array of names corresponding to clocks property; shall be | 21 | - clock-names: Array of names corresponding to clocks property; shall be |
@@ -35,7 +39,10 @@ sdhci@d4280800 { | |||
35 | 39 | ||
36 | sdhci@d8000 { | 40 | sdhci@d8000 { |
37 | compatible = "marvell,armada-380-sdhci"; | 41 | compatible = "marvell,armada-380-sdhci"; |
38 | reg = <0xd8000 0x1000>, <0xdc000 0x100>; | 42 | reg-names = "sdhci", "mbus", "conf-sdio3"; |
43 | reg = <0xd8000 0x1000>, | ||
44 | <0xdc000 0x100>; | ||
45 | <0x18454 0x4>; | ||
39 | interrupts = <0 25 0x4>; | 46 | interrupts = <0 25 0x4>; |
40 | clocks = <&gateclk 17>; | 47 | clocks = <&gateclk 17>; |
41 | clock-names = "io"; | 48 | clock-names = "io"; |
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 7f1708738c30..969e1003dd92 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -254,12 +254,14 @@ static void pandora_wl1251_init_card(struct mmc_card *card) | |||
254 | * We have TI wl1251 attached to MMC3. Pass this information to | 254 | * We have TI wl1251 attached to MMC3. Pass this information to |
255 | * SDIO core because it can't be probed by normal methods. | 255 | * SDIO core because it can't be probed by normal methods. |
256 | */ | 256 | */ |
257 | card->quirks |= MMC_QUIRK_NONSTD_SDIO; | 257 | if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) { |
258 | card->cccr.wide_bus = 1; | 258 | card->quirks |= MMC_QUIRK_NONSTD_SDIO; |
259 | card->cis.vendor = 0x104c; | 259 | card->cccr.wide_bus = 1; |
260 | card->cis.device = 0x9066; | 260 | card->cis.vendor = 0x104c; |
261 | card->cis.blksize = 512; | 261 | card->cis.device = 0x9066; |
262 | card->cis.max_dtr = 20000000; | 262 | card->cis.blksize = 512; |
263 | card->cis.max_dtr = 20000000; | ||
264 | } | ||
263 | } | 265 | } |
264 | 266 | ||
265 | static struct omap2_hsmmc_info omap3pandora_mmc[] = { | 267 | static struct omap2_hsmmc_info omap3pandora_mmc[] = { |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 4409d79ed650..c69afb5e264e 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -2147,7 +2147,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
2147 | */ | 2147 | */ |
2148 | 2148 | ||
2149 | snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), | 2149 | snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), |
2150 | "mmcblk%d%s", md->name_idx, subname ? subname : ""); | 2150 | "mmcblk%u%s", md->name_idx, subname ? subname : ""); |
2151 | 2151 | ||
2152 | if (mmc_card_mmc(card)) | 2152 | if (mmc_card_mmc(card)) |
2153 | blk_queue_logical_block_size(md->queue.queue, | 2153 | blk_queue_logical_block_size(md->queue.queue, |
@@ -2193,7 +2193,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
2193 | static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | 2193 | static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) |
2194 | { | 2194 | { |
2195 | sector_t size; | 2195 | sector_t size; |
2196 | struct mmc_blk_data *md; | ||
2197 | 2196 | ||
2198 | if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { | 2197 | if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { |
2199 | /* | 2198 | /* |
@@ -2209,9 +2208,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
2209 | size = card->csd.capacity << (card->csd.read_blkbits - 9); | 2208 | size = card->csd.capacity << (card->csd.read_blkbits - 9); |
2210 | } | 2209 | } |
2211 | 2210 | ||
2212 | md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL, | 2211 | return mmc_blk_alloc_req(card, &card->dev, size, false, NULL, |
2213 | MMC_BLK_DATA_AREA_MAIN); | 2212 | MMC_BLK_DATA_AREA_MAIN); |
2214 | return md; | ||
2215 | } | 2213 | } |
2216 | 2214 | ||
2217 | static int mmc_blk_alloc_part(struct mmc_card *card, | 2215 | static int mmc_blk_alloc_part(struct mmc_card *card, |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 0a7430f94d29..7dac4695163b 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -2342,20 +2342,16 @@ static int mmc_test_hw_reset(struct mmc_test_card *test) | |||
2342 | struct mmc_host *host = card->host; | 2342 | struct mmc_host *host = card->host; |
2343 | int err; | 2343 | int err; |
2344 | 2344 | ||
2345 | err = mmc_hw_reset_check(host); | 2345 | if (!mmc_card_mmc(card) || !mmc_can_reset(card)) |
2346 | return RESULT_UNSUP_CARD; | ||
2347 | |||
2348 | err = mmc_hw_reset(host); | ||
2346 | if (!err) | 2349 | if (!err) |
2347 | return RESULT_OK; | 2350 | return RESULT_OK; |
2351 | else if (err == -EOPNOTSUPP) | ||
2352 | return RESULT_UNSUP_HOST; | ||
2348 | 2353 | ||
2349 | if (err == -ENOSYS) | 2354 | return RESULT_FAIL; |
2350 | return RESULT_FAIL; | ||
2351 | |||
2352 | if (err != -EOPNOTSUPP) | ||
2353 | return err; | ||
2354 | |||
2355 | if (!mmc_can_reset(card)) | ||
2356 | return RESULT_UNSUP_CARD; | ||
2357 | |||
2358 | return RESULT_UNSUP_HOST; | ||
2359 | } | 2355 | } |
2360 | 2356 | ||
2361 | static const struct mmc_test_case mmc_test_cases[] = { | 2357 | static const struct mmc_test_case mmc_test_cases[] = { |
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 38ed210ce2f3..2c25138f28b7 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile | |||
@@ -8,5 +8,5 @@ mmc_core-y := core.o bus.o host.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 | quirks.o slot-gpio.o |
11 | 11 | mmc_core-$(CONFIG_OF) += pwrseq.o pwrseq_simple.o pwrseq_emmc.o | |
12 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o | 12 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 86d271148528..c5ef10065a4a 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/stat.h> | 18 | #include <linux/stat.h> |
19 | #include <linux/of.h> | ||
19 | #include <linux/pm_runtime.h> | 20 | #include <linux/pm_runtime.h> |
20 | 21 | ||
21 | #include <linux/mmc/card.h> | 22 | #include <linux/mmc/card.h> |
@@ -321,6 +322,8 @@ int mmc_add_card(struct mmc_card *card) | |||
321 | #endif | 322 | #endif |
322 | mmc_init_context_info(card->host); | 323 | mmc_init_context_info(card->host); |
323 | 324 | ||
325 | card->dev.of_node = mmc_of_find_child_device(card->host, 0); | ||
326 | |||
324 | ret = device_add(&card->dev); | 327 | ret = device_add(&card->dev); |
325 | if (ret) | 328 | if (ret) |
326 | return ret; | 329 | return ret; |
@@ -349,6 +352,7 @@ void mmc_remove_card(struct mmc_card *card) | |||
349 | mmc_hostname(card->host), card->rca); | 352 | mmc_hostname(card->host), card->rca); |
350 | } | 353 | } |
351 | device_del(&card->dev); | 354 | device_del(&card->dev); |
355 | of_node_put(card->dev.of_node); | ||
352 | } | 356 | } |
353 | 357 | ||
354 | put_device(&card->dev); | 358 | put_device(&card->dev); |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 9584bffa8b22..23f10f72e5f3 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "bus.h" | 40 | #include "bus.h" |
41 | #include "host.h" | 41 | #include "host.h" |
42 | #include "sdio_bus.h" | 42 | #include "sdio_bus.h" |
43 | #include "pwrseq.h" | ||
43 | 44 | ||
44 | #include "mmc_ops.h" | 45 | #include "mmc_ops.h" |
45 | #include "sd_ops.h" | 46 | #include "sd_ops.h" |
@@ -185,13 +186,14 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
185 | 186 | ||
186 | EXPORT_SYMBOL(mmc_request_done); | 187 | EXPORT_SYMBOL(mmc_request_done); |
187 | 188 | ||
188 | static void | 189 | static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) |
189 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | ||
190 | { | 190 | { |
191 | #ifdef CONFIG_MMC_DEBUG | 191 | #ifdef CONFIG_MMC_DEBUG |
192 | unsigned int i, sz; | 192 | unsigned int i, sz; |
193 | struct scatterlist *sg; | 193 | struct scatterlist *sg; |
194 | #endif | 194 | #endif |
195 | if (mmc_card_removed(host->card)) | ||
196 | return -ENOMEDIUM; | ||
195 | 197 | ||
196 | if (mrq->sbc) { | 198 | if (mrq->sbc) { |
197 | pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n", | 199 | pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n", |
@@ -251,6 +253,8 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | |||
251 | mmc_host_clk_hold(host); | 253 | mmc_host_clk_hold(host); |
252 | led_trigger_event(host->led, LED_FULL); | 254 | led_trigger_event(host->led, LED_FULL); |
253 | host->ops->request(host, mrq); | 255 | host->ops->request(host, mrq); |
256 | |||
257 | return 0; | ||
254 | } | 258 | } |
255 | 259 | ||
256 | /** | 260 | /** |
@@ -271,7 +275,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception) | |||
271 | 275 | ||
272 | BUG_ON(!card); | 276 | BUG_ON(!card); |
273 | 277 | ||
274 | if (!card->ext_csd.bkops_en || mmc_card_doing_bkops(card)) | 278 | if (!card->ext_csd.man_bkops_en || mmc_card_doing_bkops(card)) |
275 | return; | 279 | return; |
276 | 280 | ||
277 | err = mmc_read_bkops_status(card); | 281 | err = mmc_read_bkops_status(card); |
@@ -345,29 +349,34 @@ static void mmc_wait_done(struct mmc_request *mrq) | |||
345 | */ | 349 | */ |
346 | static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq) | 350 | static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq) |
347 | { | 351 | { |
352 | int err; | ||
353 | |||
348 | mrq->done = mmc_wait_data_done; | 354 | mrq->done = mmc_wait_data_done; |
349 | mrq->host = host; | 355 | mrq->host = host; |
350 | if (mmc_card_removed(host->card)) { | 356 | |
351 | mrq->cmd->error = -ENOMEDIUM; | 357 | err = mmc_start_request(host, mrq); |
358 | if (err) { | ||
359 | mrq->cmd->error = err; | ||
352 | mmc_wait_data_done(mrq); | 360 | mmc_wait_data_done(mrq); |
353 | return -ENOMEDIUM; | ||
354 | } | 361 | } |
355 | mmc_start_request(host, mrq); | ||
356 | 362 | ||
357 | return 0; | 363 | return err; |
358 | } | 364 | } |
359 | 365 | ||
360 | static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) | 366 | static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) |
361 | { | 367 | { |
368 | int err; | ||
369 | |||
362 | init_completion(&mrq->completion); | 370 | init_completion(&mrq->completion); |
363 | mrq->done = mmc_wait_done; | 371 | mrq->done = mmc_wait_done; |
364 | if (mmc_card_removed(host->card)) { | 372 | |
365 | mrq->cmd->error = -ENOMEDIUM; | 373 | err = mmc_start_request(host, mrq); |
374 | if (err) { | ||
375 | mrq->cmd->error = err; | ||
366 | complete(&mrq->completion); | 376 | complete(&mrq->completion); |
367 | return -ENOMEDIUM; | ||
368 | } | 377 | } |
369 | mmc_start_request(host, mrq); | 378 | |
370 | return 0; | 379 | return err; |
371 | } | 380 | } |
372 | 381 | ||
373 | /* | 382 | /* |
@@ -1077,6 +1086,30 @@ void mmc_set_ungated(struct mmc_host *host) | |||
1077 | } | 1086 | } |
1078 | #endif | 1087 | #endif |
1079 | 1088 | ||
1089 | int mmc_execute_tuning(struct mmc_card *card) | ||
1090 | { | ||
1091 | struct mmc_host *host = card->host; | ||
1092 | u32 opcode; | ||
1093 | int err; | ||
1094 | |||
1095 | if (!host->ops->execute_tuning) | ||
1096 | return 0; | ||
1097 | |||
1098 | if (mmc_card_mmc(card)) | ||
1099 | opcode = MMC_SEND_TUNING_BLOCK_HS200; | ||
1100 | else | ||
1101 | opcode = MMC_SEND_TUNING_BLOCK; | ||
1102 | |||
1103 | mmc_host_clk_hold(host); | ||
1104 | err = host->ops->execute_tuning(host, opcode); | ||
1105 | mmc_host_clk_release(host); | ||
1106 | |||
1107 | if (err) | ||
1108 | pr_err("%s: tuning execution failed\n", mmc_hostname(host)); | ||
1109 | |||
1110 | return err; | ||
1111 | } | ||
1112 | |||
1080 | /* | 1113 | /* |
1081 | * Change the bus mode (open drain/push-pull) of a host. | 1114 | * Change the bus mode (open drain/push-pull) of a host. |
1082 | */ | 1115 | */ |
@@ -1232,6 +1265,34 @@ EXPORT_SYMBOL(mmc_of_parse_voltage); | |||
1232 | 1265 | ||
1233 | #endif /* CONFIG_OF */ | 1266 | #endif /* CONFIG_OF */ |
1234 | 1267 | ||
1268 | static int mmc_of_get_func_num(struct device_node *node) | ||
1269 | { | ||
1270 | u32 reg; | ||
1271 | int ret; | ||
1272 | |||
1273 | ret = of_property_read_u32(node, "reg", ®); | ||
1274 | if (ret < 0) | ||
1275 | return ret; | ||
1276 | |||
1277 | return reg; | ||
1278 | } | ||
1279 | |||
1280 | struct device_node *mmc_of_find_child_device(struct mmc_host *host, | ||
1281 | unsigned func_num) | ||
1282 | { | ||
1283 | struct device_node *node; | ||
1284 | |||
1285 | if (!host->parent || !host->parent->of_node) | ||
1286 | return NULL; | ||
1287 | |||
1288 | for_each_child_of_node(host->parent->of_node, node) { | ||
1289 | if (mmc_of_get_func_num(node) == func_num) | ||
1290 | return node; | ||
1291 | } | ||
1292 | |||
1293 | return NULL; | ||
1294 | } | ||
1295 | |||
1235 | #ifdef CONFIG_REGULATOR | 1296 | #ifdef CONFIG_REGULATOR |
1236 | 1297 | ||
1237 | /** | 1298 | /** |
@@ -1555,6 +1616,8 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
1555 | 1616 | ||
1556 | mmc_host_clk_hold(host); | 1617 | mmc_host_clk_hold(host); |
1557 | 1618 | ||
1619 | mmc_pwrseq_pre_power_on(host); | ||
1620 | |||
1558 | host->ios.vdd = fls(ocr) - 1; | 1621 | host->ios.vdd = fls(ocr) - 1; |
1559 | host->ios.power_mode = MMC_POWER_UP; | 1622 | host->ios.power_mode = MMC_POWER_UP; |
1560 | /* Set initial state and call mmc_set_ios */ | 1623 | /* Set initial state and call mmc_set_ios */ |
@@ -1574,6 +1637,8 @@ void mmc_power_up(struct mmc_host *host, u32 ocr) | |||
1574 | */ | 1637 | */ |
1575 | mmc_delay(10); | 1638 | mmc_delay(10); |
1576 | 1639 | ||
1640 | mmc_pwrseq_post_power_on(host); | ||
1641 | |||
1577 | host->ios.clock = host->f_init; | 1642 | host->ios.clock = host->f_init; |
1578 | 1643 | ||
1579 | host->ios.power_mode = MMC_POWER_ON; | 1644 | host->ios.power_mode = MMC_POWER_ON; |
@@ -1595,6 +1660,8 @@ void mmc_power_off(struct mmc_host *host) | |||
1595 | 1660 | ||
1596 | mmc_host_clk_hold(host); | 1661 | mmc_host_clk_hold(host); |
1597 | 1662 | ||
1663 | mmc_pwrseq_power_off(host); | ||
1664 | |||
1598 | host->ios.clock = 0; | 1665 | host->ios.clock = 0; |
1599 | host->ios.vdd = 0; | 1666 | host->ios.vdd = 0; |
1600 | 1667 | ||
@@ -2245,67 +2312,28 @@ static void mmc_hw_reset_for_init(struct mmc_host *host) | |||
2245 | mmc_host_clk_release(host); | 2312 | mmc_host_clk_release(host); |
2246 | } | 2313 | } |
2247 | 2314 | ||
2248 | int mmc_can_reset(struct mmc_card *card) | 2315 | int mmc_hw_reset(struct mmc_host *host) |
2249 | { | ||
2250 | u8 rst_n_function; | ||
2251 | |||
2252 | if (!mmc_card_mmc(card)) | ||
2253 | return 0; | ||
2254 | rst_n_function = card->ext_csd.rst_n_function; | ||
2255 | if ((rst_n_function & EXT_CSD_RST_N_EN_MASK) != EXT_CSD_RST_N_ENABLED) | ||
2256 | return 0; | ||
2257 | return 1; | ||
2258 | } | ||
2259 | EXPORT_SYMBOL(mmc_can_reset); | ||
2260 | |||
2261 | static int mmc_do_hw_reset(struct mmc_host *host, int check) | ||
2262 | { | 2316 | { |
2263 | struct mmc_card *card = host->card; | 2317 | int ret; |
2264 | |||
2265 | if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) | ||
2266 | return -EOPNOTSUPP; | ||
2267 | 2318 | ||
2268 | if (!card) | 2319 | if (!host->card) |
2269 | return -EINVAL; | 2320 | return -EINVAL; |
2270 | 2321 | ||
2271 | if (!mmc_can_reset(card)) | 2322 | mmc_bus_get(host); |
2323 | if (!host->bus_ops || host->bus_dead || !host->bus_ops->reset) { | ||
2324 | mmc_bus_put(host); | ||
2272 | return -EOPNOTSUPP; | 2325 | return -EOPNOTSUPP; |
2273 | |||
2274 | mmc_host_clk_hold(host); | ||
2275 | mmc_set_clock(host, host->f_init); | ||
2276 | |||
2277 | host->ops->hw_reset(host); | ||
2278 | |||
2279 | /* If the reset has happened, then a status command will fail */ | ||
2280 | if (check) { | ||
2281 | u32 status; | ||
2282 | |||
2283 | if (!mmc_send_status(card, &status)) { | ||
2284 | mmc_host_clk_release(host); | ||
2285 | return -ENOSYS; | ||
2286 | } | ||
2287 | } | 2326 | } |
2288 | 2327 | ||
2289 | /* Set initial state and call mmc_set_ios */ | 2328 | ret = host->bus_ops->reset(host); |
2290 | mmc_set_initial_state(host); | 2329 | mmc_bus_put(host); |
2291 | 2330 | ||
2292 | mmc_host_clk_release(host); | 2331 | pr_warn("%s: tried to reset card\n", mmc_hostname(host)); |
2293 | 2332 | ||
2294 | return host->bus_ops->power_restore(host); | 2333 | return ret; |
2295 | } | ||
2296 | |||
2297 | int mmc_hw_reset(struct mmc_host *host) | ||
2298 | { | ||
2299 | return mmc_do_hw_reset(host, 0); | ||
2300 | } | 2334 | } |
2301 | EXPORT_SYMBOL(mmc_hw_reset); | 2335 | EXPORT_SYMBOL(mmc_hw_reset); |
2302 | 2336 | ||
2303 | int mmc_hw_reset_check(struct mmc_host *host) | ||
2304 | { | ||
2305 | return mmc_do_hw_reset(host, 1); | ||
2306 | } | ||
2307 | EXPORT_SYMBOL(mmc_hw_reset_check); | ||
2308 | |||
2309 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) | 2337 | static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) |
2310 | { | 2338 | { |
2311 | host->f_init = freq; | 2339 | host->f_init = freq; |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index d76597c65e3a..cfba3c05aab1 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -27,11 +27,15 @@ struct mmc_bus_ops { | |||
27 | int (*power_restore)(struct mmc_host *); | 27 | int (*power_restore)(struct mmc_host *); |
28 | int (*alive)(struct mmc_host *); | 28 | int (*alive)(struct mmc_host *); |
29 | int (*shutdown)(struct mmc_host *); | 29 | int (*shutdown)(struct mmc_host *); |
30 | int (*reset)(struct mmc_host *); | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 33 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
33 | void mmc_detach_bus(struct mmc_host *host); | 34 | void mmc_detach_bus(struct mmc_host *host); |
34 | 35 | ||
36 | struct device_node *mmc_of_find_child_device(struct mmc_host *host, | ||
37 | unsigned func_num); | ||
38 | |||
35 | void mmc_init_erase(struct mmc_card *card); | 39 | void mmc_init_erase(struct mmc_card *card); |
36 | 40 | ||
37 | void mmc_set_chip_select(struct mmc_host *host, int mode); | 41 | void mmc_set_chip_select(struct mmc_host *host, int mode); |
@@ -82,5 +86,8 @@ void mmc_add_card_debugfs(struct mmc_card *card); | |||
82 | void mmc_remove_card_debugfs(struct mmc_card *card); | 86 | void mmc_remove_card_debugfs(struct mmc_card *card); |
83 | 87 | ||
84 | void mmc_init_context_info(struct mmc_host *host); | 88 | void mmc_init_context_info(struct mmc_host *host); |
89 | |||
90 | int mmc_execute_tuning(struct mmc_card *card); | ||
91 | |||
85 | #endif | 92 | #endif |
86 | 93 | ||
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 270d58a4c43d..8be0df758e68 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -29,13 +29,20 @@ | |||
29 | 29 | ||
30 | #include "core.h" | 30 | #include "core.h" |
31 | #include "host.h" | 31 | #include "host.h" |
32 | #include "slot-gpio.h" | ||
33 | #include "pwrseq.h" | ||
32 | 34 | ||
33 | #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) | 35 | #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) |
34 | 36 | ||
37 | static DEFINE_IDR(mmc_host_idr); | ||
38 | static DEFINE_SPINLOCK(mmc_host_lock); | ||
39 | |||
35 | static void mmc_host_classdev_release(struct device *dev) | 40 | static void mmc_host_classdev_release(struct device *dev) |
36 | { | 41 | { |
37 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | 42 | struct mmc_host *host = cls_dev_to_mmc_host(dev); |
38 | mutex_destroy(&host->slot.lock); | 43 | spin_lock(&mmc_host_lock); |
44 | idr_remove(&mmc_host_idr, host->index); | ||
45 | spin_unlock(&mmc_host_lock); | ||
39 | kfree(host); | 46 | kfree(host); |
40 | } | 47 | } |
41 | 48 | ||
@@ -54,9 +61,6 @@ void mmc_unregister_host_class(void) | |||
54 | class_unregister(&mmc_host_class); | 61 | class_unregister(&mmc_host_class); |
55 | } | 62 | } |
56 | 63 | ||
57 | static DEFINE_IDR(mmc_host_idr); | ||
58 | static DEFINE_SPINLOCK(mmc_host_lock); | ||
59 | |||
60 | #ifdef CONFIG_MMC_CLKGATE | 64 | #ifdef CONFIG_MMC_CLKGATE |
61 | static ssize_t clkgate_delay_show(struct device *dev, | 65 | static ssize_t clkgate_delay_show(struct device *dev, |
62 | struct device_attribute *attr, char *buf) | 66 | struct device_attribute *attr, char *buf) |
@@ -367,16 +371,10 @@ int mmc_of_parse(struct mmc_host *host) | |||
367 | 371 | ||
368 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, | 372 | ret = mmc_gpiod_request_cd(host, "cd", 0, true, |
369 | 0, &cd_gpio_invert); | 373 | 0, &cd_gpio_invert); |
370 | if (ret) { | 374 | if (!ret) |
371 | if (ret == -EPROBE_DEFER) | ||
372 | return ret; | ||
373 | if (ret != -ENOENT) { | ||
374 | dev_err(host->parent, | ||
375 | "Failed to request CD GPIO: %d\n", | ||
376 | ret); | ||
377 | } | ||
378 | } else | ||
379 | dev_info(host->parent, "Got CD GPIO\n"); | 375 | dev_info(host->parent, "Got CD GPIO\n"); |
376 | else if (ret != -ENOENT) | ||
377 | return ret; | ||
380 | 378 | ||
381 | /* | 379 | /* |
382 | * There are two ways to flag that the CD line is inverted: | 380 | * There are two ways to flag that the CD line is inverted: |
@@ -397,16 +395,10 @@ int mmc_of_parse(struct mmc_host *host) | |||
397 | ro_cap_invert = of_property_read_bool(np, "wp-inverted"); | 395 | ro_cap_invert = of_property_read_bool(np, "wp-inverted"); |
398 | 396 | ||
399 | ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert); | 397 | ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert); |
400 | if (ret) { | 398 | if (!ret) |
401 | if (ret == -EPROBE_DEFER) | ||
402 | goto out; | ||
403 | if (ret != -ENOENT) { | ||
404 | dev_err(host->parent, | ||
405 | "Failed to request WP GPIO: %d\n", | ||
406 | ret); | ||
407 | } | ||
408 | } else | ||
409 | dev_info(host->parent, "Got WP GPIO\n"); | 399 | dev_info(host->parent, "Got WP GPIO\n"); |
400 | else if (ret != -ENOENT) | ||
401 | return ret; | ||
410 | 402 | ||
411 | /* See the comment on CD inversion above */ | 403 | /* See the comment on CD inversion above */ |
412 | if (ro_cap_invert ^ ro_gpio_invert) | 404 | if (ro_cap_invert ^ ro_gpio_invert) |
@@ -457,11 +449,7 @@ int mmc_of_parse(struct mmc_host *host) | |||
457 | host->dsr_req = 0; | 449 | host->dsr_req = 0; |
458 | } | 450 | } |
459 | 451 | ||
460 | return 0; | 452 | return mmc_pwrseq_alloc(host); |
461 | |||
462 | out: | ||
463 | mmc_gpio_free_cd(host); | ||
464 | return ret; | ||
465 | } | 453 | } |
466 | 454 | ||
467 | EXPORT_SYMBOL(mmc_of_parse); | 455 | EXPORT_SYMBOL(mmc_of_parse); |
@@ -491,8 +479,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
491 | host->index = err; | 479 | host->index = err; |
492 | spin_unlock(&mmc_host_lock); | 480 | spin_unlock(&mmc_host_lock); |
493 | idr_preload_end(); | 481 | idr_preload_end(); |
494 | if (err < 0) | 482 | if (err < 0) { |
495 | goto free; | 483 | kfree(host); |
484 | return NULL; | ||
485 | } | ||
496 | 486 | ||
497 | dev_set_name(&host->class_dev, "mmc%d", host->index); | 487 | dev_set_name(&host->class_dev, "mmc%d", host->index); |
498 | 488 | ||
@@ -501,10 +491,12 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
501 | host->class_dev.class = &mmc_host_class; | 491 | host->class_dev.class = &mmc_host_class; |
502 | device_initialize(&host->class_dev); | 492 | device_initialize(&host->class_dev); |
503 | 493 | ||
504 | mmc_host_clk_init(host); | 494 | if (mmc_gpio_alloc(host)) { |
495 | put_device(&host->class_dev); | ||
496 | return NULL; | ||
497 | } | ||
505 | 498 | ||
506 | mutex_init(&host->slot.lock); | 499 | mmc_host_clk_init(host); |
507 | host->slot.cd_irq = -EINVAL; | ||
508 | 500 | ||
509 | spin_lock_init(&host->lock); | 501 | spin_lock_init(&host->lock); |
510 | init_waitqueue_head(&host->wq); | 502 | init_waitqueue_head(&host->wq); |
@@ -525,10 +517,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
525 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | 517 | host->max_blk_count = PAGE_CACHE_SIZE / 512; |
526 | 518 | ||
527 | return host; | 519 | return host; |
528 | |||
529 | free: | ||
530 | kfree(host); | ||
531 | return NULL; | ||
532 | } | 520 | } |
533 | 521 | ||
534 | EXPORT_SYMBOL(mmc_alloc_host); | 522 | EXPORT_SYMBOL(mmc_alloc_host); |
@@ -601,10 +589,7 @@ EXPORT_SYMBOL(mmc_remove_host); | |||
601 | */ | 589 | */ |
602 | void mmc_free_host(struct mmc_host *host) | 590 | void mmc_free_host(struct mmc_host *host) |
603 | { | 591 | { |
604 | spin_lock(&mmc_host_lock); | 592 | mmc_pwrseq_free(host); |
605 | idr_remove(&mmc_host_idr, host->index); | ||
606 | spin_unlock(&mmc_host_lock); | ||
607 | |||
608 | put_device(&host->class_dev); | 593 | put_device(&host->class_dev); |
609 | } | 594 | } |
610 | 595 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 7466ce098e60..1d41e8541f38 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -483,11 +483,13 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
483 | /* check whether the eMMC card supports BKOPS */ | 483 | /* check whether the eMMC card supports BKOPS */ |
484 | if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { | 484 | if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { |
485 | card->ext_csd.bkops = 1; | 485 | card->ext_csd.bkops = 1; |
486 | card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN]; | 486 | card->ext_csd.man_bkops_en = |
487 | (ext_csd[EXT_CSD_BKOPS_EN] & | ||
488 | EXT_CSD_MANUAL_BKOPS_MASK); | ||
487 | card->ext_csd.raw_bkops_status = | 489 | card->ext_csd.raw_bkops_status = |
488 | ext_csd[EXT_CSD_BKOPS_STATUS]; | 490 | ext_csd[EXT_CSD_BKOPS_STATUS]; |
489 | if (!card->ext_csd.bkops_en) | 491 | if (!card->ext_csd.man_bkops_en) |
490 | pr_info("%s: BKOPS_EN bit is not set\n", | 492 | pr_info("%s: MAN_BKOPS_EN bit is not set\n", |
491 | mmc_hostname(card->host)); | 493 | mmc_hostname(card->host)); |
492 | } | 494 | } |
493 | 495 | ||
@@ -1155,38 +1157,6 @@ bus_speed: | |||
1155 | return err; | 1157 | return err; |
1156 | } | 1158 | } |
1157 | 1159 | ||
1158 | const u8 tuning_blk_pattern_4bit[MMC_TUNING_BLK_PATTERN_4BIT_SIZE] = { | ||
1159 | 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, | ||
1160 | 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, | ||
1161 | 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, | ||
1162 | 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, | ||
1163 | 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, | ||
1164 | 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, | ||
1165 | 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, | ||
1166 | 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, | ||
1167 | }; | ||
1168 | EXPORT_SYMBOL(tuning_blk_pattern_4bit); | ||
1169 | |||
1170 | const u8 tuning_blk_pattern_8bit[MMC_TUNING_BLK_PATTERN_8BIT_SIZE] = { | ||
1171 | 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, | ||
1172 | 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, | ||
1173 | 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, | ||
1174 | 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, | ||
1175 | 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, | ||
1176 | 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, | ||
1177 | 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, | ||
1178 | 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, | ||
1179 | 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, | ||
1180 | 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, | ||
1181 | 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, | ||
1182 | 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, | ||
1183 | 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, | ||
1184 | 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, | ||
1185 | 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, | ||
1186 | 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, | ||
1187 | }; | ||
1188 | EXPORT_SYMBOL(tuning_blk_pattern_8bit); | ||
1189 | |||
1190 | /* | 1160 | /* |
1191 | * Execute tuning sequence to seek the proper bus operating | 1161 | * Execute tuning sequence to seek the proper bus operating |
1192 | * conditions for HS200 and HS400, which sends CMD21 to the device. | 1162 | * conditions for HS200 and HS400, which sends CMD21 to the device. |
@@ -1194,7 +1164,6 @@ EXPORT_SYMBOL(tuning_blk_pattern_8bit); | |||
1194 | static int mmc_hs200_tuning(struct mmc_card *card) | 1164 | static int mmc_hs200_tuning(struct mmc_card *card) |
1195 | { | 1165 | { |
1196 | struct mmc_host *host = card->host; | 1166 | struct mmc_host *host = card->host; |
1197 | int err = 0; | ||
1198 | 1167 | ||
1199 | /* | 1168 | /* |
1200 | * Timing should be adjusted to the HS400 target | 1169 | * Timing should be adjusted to the HS400 target |
@@ -1205,18 +1174,7 @@ static int mmc_hs200_tuning(struct mmc_card *card) | |||
1205 | if (host->ops->prepare_hs400_tuning) | 1174 | if (host->ops->prepare_hs400_tuning) |
1206 | host->ops->prepare_hs400_tuning(host, &host->ios); | 1175 | host->ops->prepare_hs400_tuning(host, &host->ios); |
1207 | 1176 | ||
1208 | if (host->ops->execute_tuning) { | 1177 | return mmc_execute_tuning(card); |
1209 | mmc_host_clk_hold(host); | ||
1210 | err = host->ops->execute_tuning(host, | ||
1211 | MMC_SEND_TUNING_BLOCK_HS200); | ||
1212 | mmc_host_clk_release(host); | ||
1213 | |||
1214 | if (err) | ||
1215 | pr_err("%s: tuning execution failed\n", | ||
1216 | mmc_hostname(host)); | ||
1217 | } | ||
1218 | |||
1219 | return err; | ||
1220 | } | 1178 | } |
1221 | 1179 | ||
1222 | /* | 1180 | /* |
@@ -1297,6 +1255,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1297 | } | 1255 | } |
1298 | 1256 | ||
1299 | /* | 1257 | /* |
1258 | * Call the optional HC's init_card function to handle quirks. | ||
1259 | */ | ||
1260 | if (host->ops->init_card) | ||
1261 | host->ops->init_card(host, card); | ||
1262 | |||
1263 | /* | ||
1300 | * For native busses: set card RCA and quit open drain mode. | 1264 | * For native busses: set card RCA and quit open drain mode. |
1301 | */ | 1265 | */ |
1302 | if (!mmc_host_is_spi(host)) { | 1266 | if (!mmc_host_is_spi(host)) { |
@@ -1821,6 +1785,46 @@ static int mmc_power_restore(struct mmc_host *host) | |||
1821 | return ret; | 1785 | return ret; |
1822 | } | 1786 | } |
1823 | 1787 | ||
1788 | int mmc_can_reset(struct mmc_card *card) | ||
1789 | { | ||
1790 | u8 rst_n_function; | ||
1791 | |||
1792 | rst_n_function = card->ext_csd.rst_n_function; | ||
1793 | if ((rst_n_function & EXT_CSD_RST_N_EN_MASK) != EXT_CSD_RST_N_ENABLED) | ||
1794 | return 0; | ||
1795 | return 1; | ||
1796 | } | ||
1797 | EXPORT_SYMBOL(mmc_can_reset); | ||
1798 | |||
1799 | static int mmc_reset(struct mmc_host *host) | ||
1800 | { | ||
1801 | struct mmc_card *card = host->card; | ||
1802 | u32 status; | ||
1803 | |||
1804 | if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) | ||
1805 | return -EOPNOTSUPP; | ||
1806 | |||
1807 | if (!mmc_can_reset(card)) | ||
1808 | return -EOPNOTSUPP; | ||
1809 | |||
1810 | mmc_host_clk_hold(host); | ||
1811 | mmc_set_clock(host, host->f_init); | ||
1812 | |||
1813 | host->ops->hw_reset(host); | ||
1814 | |||
1815 | /* If the reset has happened, then a status command will fail */ | ||
1816 | if (!mmc_send_status(card, &status)) { | ||
1817 | mmc_host_clk_release(host); | ||
1818 | return -ENOSYS; | ||
1819 | } | ||
1820 | |||
1821 | /* Set initial state and call mmc_set_ios */ | ||
1822 | mmc_set_initial_state(host); | ||
1823 | mmc_host_clk_release(host); | ||
1824 | |||
1825 | return mmc_power_restore(host); | ||
1826 | } | ||
1827 | |||
1824 | static const struct mmc_bus_ops mmc_ops = { | 1828 | static const struct mmc_bus_ops mmc_ops = { |
1825 | .remove = mmc_remove, | 1829 | .remove = mmc_remove, |
1826 | .detect = mmc_detect, | 1830 | .detect = mmc_detect, |
@@ -1831,6 +1835,7 @@ static const struct mmc_bus_ops mmc_ops = { | |||
1831 | .power_restore = mmc_power_restore, | 1835 | .power_restore = mmc_power_restore, |
1832 | .alive = mmc_alive, | 1836 | .alive = mmc_alive, |
1833 | .shutdown = mmc_shutdown, | 1837 | .shutdown = mmc_shutdown, |
1838 | .reset = mmc_reset, | ||
1834 | }; | 1839 | }; |
1835 | 1840 | ||
1836 | /* | 1841 | /* |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 3b044c5b029c..0ea042dc7443 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -23,6 +23,36 @@ | |||
23 | 23 | ||
24 | #define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ | 24 | #define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ |
25 | 25 | ||
26 | static const u8 tuning_blk_pattern_4bit[] = { | ||
27 | 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, | ||
28 | 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, | ||
29 | 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, | ||
30 | 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, | ||
31 | 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, | ||
32 | 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, | ||
33 | 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, | ||
34 | 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, | ||
35 | }; | ||
36 | |||
37 | static const u8 tuning_blk_pattern_8bit[] = { | ||
38 | 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, | ||
39 | 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, | ||
40 | 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, | ||
41 | 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, | ||
42 | 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, | ||
43 | 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, | ||
44 | 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, | ||
45 | 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, | ||
46 | 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, | ||
47 | 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, | ||
48 | 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, | ||
49 | 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, | ||
50 | 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, | ||
51 | 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, | ||
52 | 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, | ||
53 | 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, | ||
54 | }; | ||
55 | |||
26 | static inline int __mmc_send_status(struct mmc_card *card, u32 *status, | 56 | static inline int __mmc_send_status(struct mmc_card *card, u32 *status, |
27 | bool ignore_crc) | 57 | bool ignore_crc) |
28 | { | 58 | { |
diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c new file mode 100644 index 000000000000..862356123d78 --- /dev/null +++ b/drivers/mmc/core/pwrseq.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd | ||
3 | * | ||
4 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
5 | * | ||
6 | * License terms: GNU General Public License (GPL) version 2 | ||
7 | * | ||
8 | * MMC power sequence management | ||
9 | */ | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/of.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | |||
16 | #include <linux/mmc/host.h> | ||
17 | |||
18 | #include "pwrseq.h" | ||
19 | |||
20 | struct mmc_pwrseq_match { | ||
21 | const char *compatible; | ||
22 | int (*alloc)(struct mmc_host *host, struct device *dev); | ||
23 | }; | ||
24 | |||
25 | static struct mmc_pwrseq_match pwrseq_match[] = { | ||
26 | { | ||
27 | .compatible = "mmc-pwrseq-simple", | ||
28 | .alloc = mmc_pwrseq_simple_alloc, | ||
29 | }, { | ||
30 | .compatible = "mmc-pwrseq-emmc", | ||
31 | .alloc = mmc_pwrseq_emmc_alloc, | ||
32 | }, | ||
33 | }; | ||
34 | |||
35 | static struct mmc_pwrseq_match *mmc_pwrseq_find(struct device_node *np) | ||
36 | { | ||
37 | struct mmc_pwrseq_match *match = ERR_PTR(-ENODEV); | ||
38 | int i; | ||
39 | |||
40 | for (i = 0; i < ARRAY_SIZE(pwrseq_match); i++) { | ||
41 | if (of_device_is_compatible(np, pwrseq_match[i].compatible)) { | ||
42 | match = &pwrseq_match[i]; | ||
43 | break; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | return match; | ||
48 | } | ||
49 | |||
50 | int mmc_pwrseq_alloc(struct mmc_host *host) | ||
51 | { | ||
52 | struct platform_device *pdev; | ||
53 | struct device_node *np; | ||
54 | struct mmc_pwrseq_match *match; | ||
55 | int ret = 0; | ||
56 | |||
57 | np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0); | ||
58 | if (!np) | ||
59 | return 0; | ||
60 | |||
61 | pdev = of_find_device_by_node(np); | ||
62 | if (!pdev) { | ||
63 | ret = -ENODEV; | ||
64 | goto err; | ||
65 | } | ||
66 | |||
67 | match = mmc_pwrseq_find(np); | ||
68 | if (IS_ERR(match)) { | ||
69 | ret = PTR_ERR(match); | ||
70 | goto err; | ||
71 | } | ||
72 | |||
73 | ret = match->alloc(host, &pdev->dev); | ||
74 | if (!ret) | ||
75 | dev_info(host->parent, "allocated mmc-pwrseq\n"); | ||
76 | |||
77 | err: | ||
78 | of_node_put(np); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | void mmc_pwrseq_pre_power_on(struct mmc_host *host) | ||
83 | { | ||
84 | struct mmc_pwrseq *pwrseq = host->pwrseq; | ||
85 | |||
86 | if (pwrseq && pwrseq->ops && pwrseq->ops->pre_power_on) | ||
87 | pwrseq->ops->pre_power_on(host); | ||
88 | } | ||
89 | |||
90 | void mmc_pwrseq_post_power_on(struct mmc_host *host) | ||
91 | { | ||
92 | struct mmc_pwrseq *pwrseq = host->pwrseq; | ||
93 | |||
94 | if (pwrseq && pwrseq->ops && pwrseq->ops->post_power_on) | ||
95 | pwrseq->ops->post_power_on(host); | ||
96 | } | ||
97 | |||
98 | void mmc_pwrseq_power_off(struct mmc_host *host) | ||
99 | { | ||
100 | struct mmc_pwrseq *pwrseq = host->pwrseq; | ||
101 | |||
102 | if (pwrseq && pwrseq->ops && pwrseq->ops->power_off) | ||
103 | pwrseq->ops->power_off(host); | ||
104 | } | ||
105 | |||
106 | void mmc_pwrseq_free(struct mmc_host *host) | ||
107 | { | ||
108 | struct mmc_pwrseq *pwrseq = host->pwrseq; | ||
109 | |||
110 | if (pwrseq && pwrseq->ops && pwrseq->ops->free) | ||
111 | pwrseq->ops->free(host); | ||
112 | } | ||
diff --git a/drivers/mmc/core/pwrseq.h b/drivers/mmc/core/pwrseq.h new file mode 100644 index 000000000000..aba3409e8d6e --- /dev/null +++ b/drivers/mmc/core/pwrseq.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd | ||
3 | * | ||
4 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
5 | * | ||
6 | * License terms: GNU General Public License (GPL) version 2 | ||
7 | */ | ||
8 | #ifndef _MMC_CORE_PWRSEQ_H | ||
9 | #define _MMC_CORE_PWRSEQ_H | ||
10 | |||
11 | struct mmc_pwrseq_ops { | ||
12 | void (*pre_power_on)(struct mmc_host *host); | ||
13 | void (*post_power_on)(struct mmc_host *host); | ||
14 | void (*power_off)(struct mmc_host *host); | ||
15 | void (*free)(struct mmc_host *host); | ||
16 | }; | ||
17 | |||
18 | struct mmc_pwrseq { | ||
19 | struct mmc_pwrseq_ops *ops; | ||
20 | }; | ||
21 | |||
22 | #ifdef CONFIG_OF | ||
23 | |||
24 | int mmc_pwrseq_alloc(struct mmc_host *host); | ||
25 | void mmc_pwrseq_pre_power_on(struct mmc_host *host); | ||
26 | void mmc_pwrseq_post_power_on(struct mmc_host *host); | ||
27 | void mmc_pwrseq_power_off(struct mmc_host *host); | ||
28 | void mmc_pwrseq_free(struct mmc_host *host); | ||
29 | |||
30 | int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev); | ||
31 | int mmc_pwrseq_emmc_alloc(struct mmc_host *host, struct device *dev); | ||
32 | |||
33 | #else | ||
34 | |||
35 | static inline int mmc_pwrseq_alloc(struct mmc_host *host) { return 0; } | ||
36 | static inline void mmc_pwrseq_pre_power_on(struct mmc_host *host) {} | ||
37 | static inline void mmc_pwrseq_post_power_on(struct mmc_host *host) {} | ||
38 | static inline void mmc_pwrseq_power_off(struct mmc_host *host) {} | ||
39 | static inline void mmc_pwrseq_free(struct mmc_host *host) {} | ||
40 | |||
41 | #endif | ||
42 | |||
43 | #endif | ||
diff --git a/drivers/mmc/core/pwrseq_emmc.c b/drivers/mmc/core/pwrseq_emmc.c new file mode 100644 index 000000000000..a2d545904fbf --- /dev/null +++ b/drivers/mmc/core/pwrseq_emmc.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015, Samsung Electronics Co., Ltd. | ||
3 | * | ||
4 | * Author: Marek Szyprowski <m.szyprowski@samsung.com> | ||
5 | * | ||
6 | * License terms: GNU General Public License (GPL) version 2 | ||
7 | * | ||
8 | * Simple eMMC hardware reset provider | ||
9 | */ | ||
10 | #include <linux/delay.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/gpio/consumer.h> | ||
16 | #include <linux/reboot.h> | ||
17 | |||
18 | #include <linux/mmc/host.h> | ||
19 | |||
20 | #include "pwrseq.h" | ||
21 | |||
22 | struct mmc_pwrseq_emmc { | ||
23 | struct mmc_pwrseq pwrseq; | ||
24 | struct notifier_block reset_nb; | ||
25 | struct gpio_desc *reset_gpio; | ||
26 | }; | ||
27 | |||
28 | static void __mmc_pwrseq_emmc_reset(struct mmc_pwrseq_emmc *pwrseq) | ||
29 | { | ||
30 | gpiod_set_value(pwrseq->reset_gpio, 1); | ||
31 | udelay(1); | ||
32 | gpiod_set_value(pwrseq->reset_gpio, 0); | ||
33 | udelay(200); | ||
34 | } | ||
35 | |||
36 | static void mmc_pwrseq_emmc_reset(struct mmc_host *host) | ||
37 | { | ||
38 | struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq, | ||
39 | struct mmc_pwrseq_emmc, pwrseq); | ||
40 | |||
41 | __mmc_pwrseq_emmc_reset(pwrseq); | ||
42 | } | ||
43 | |||
44 | static void mmc_pwrseq_emmc_free(struct mmc_host *host) | ||
45 | { | ||
46 | struct mmc_pwrseq_emmc *pwrseq = container_of(host->pwrseq, | ||
47 | struct mmc_pwrseq_emmc, pwrseq); | ||
48 | |||
49 | unregister_restart_handler(&pwrseq->reset_nb); | ||
50 | gpiod_put(pwrseq->reset_gpio); | ||
51 | kfree(pwrseq); | ||
52 | host->pwrseq = NULL; | ||
53 | } | ||
54 | |||
55 | static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { | ||
56 | .post_power_on = mmc_pwrseq_emmc_reset, | ||
57 | .free = mmc_pwrseq_emmc_free, | ||
58 | }; | ||
59 | |||
60 | static int mmc_pwrseq_emmc_reset_nb(struct notifier_block *this, | ||
61 | unsigned long mode, void *cmd) | ||
62 | { | ||
63 | struct mmc_pwrseq_emmc *pwrseq = container_of(this, | ||
64 | struct mmc_pwrseq_emmc, reset_nb); | ||
65 | |||
66 | __mmc_pwrseq_emmc_reset(pwrseq); | ||
67 | return NOTIFY_DONE; | ||
68 | } | ||
69 | |||
70 | int mmc_pwrseq_emmc_alloc(struct mmc_host *host, struct device *dev) | ||
71 | { | ||
72 | struct mmc_pwrseq_emmc *pwrseq; | ||
73 | int ret = 0; | ||
74 | |||
75 | pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL); | ||
76 | if (!pwrseq) | ||
77 | return -ENOMEM; | ||
78 | |||
79 | pwrseq->reset_gpio = gpiod_get_index(dev, "reset", 0, GPIOD_OUT_LOW); | ||
80 | if (IS_ERR(pwrseq->reset_gpio)) { | ||
81 | ret = PTR_ERR(pwrseq->reset_gpio); | ||
82 | goto free; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * register reset handler to ensure emmc reset also from | ||
87 | * emergency_reboot(), priority 129 schedules it just before | ||
88 | * system reboot | ||
89 | */ | ||
90 | pwrseq->reset_nb.notifier_call = mmc_pwrseq_emmc_reset_nb; | ||
91 | pwrseq->reset_nb.priority = 129; | ||
92 | register_restart_handler(&pwrseq->reset_nb); | ||
93 | |||
94 | pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; | ||
95 | host->pwrseq = &pwrseq->pwrseq; | ||
96 | |||
97 | return 0; | ||
98 | free: | ||
99 | kfree(pwrseq); | ||
100 | return ret; | ||
101 | } | ||
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c new file mode 100644 index 000000000000..e9f1d8d84613 --- /dev/null +++ b/drivers/mmc/core/pwrseq_simple.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd | ||
3 | * | ||
4 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
5 | * | ||
6 | * License terms: GNU General Public License (GPL) version 2 | ||
7 | * | ||
8 | * Simple MMC power sequence management | ||
9 | */ | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/of_gpio.h> | ||
16 | #include <linux/gpio/consumer.h> | ||
17 | |||
18 | #include <linux/mmc/host.h> | ||
19 | |||
20 | #include "pwrseq.h" | ||
21 | |||
22 | struct mmc_pwrseq_simple { | ||
23 | struct mmc_pwrseq pwrseq; | ||
24 | bool clk_enabled; | ||
25 | struct clk *ext_clk; | ||
26 | int nr_gpios; | ||
27 | struct gpio_desc *reset_gpios[0]; | ||
28 | }; | ||
29 | |||
30 | static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq, | ||
31 | int value) | ||
32 | { | ||
33 | int i; | ||
34 | |||
35 | for (i = 0; i < pwrseq->nr_gpios; i++) | ||
36 | if (!IS_ERR(pwrseq->reset_gpios[i])) | ||
37 | gpiod_set_value_cansleep(pwrseq->reset_gpios[i], value); | ||
38 | } | ||
39 | |||
40 | static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host) | ||
41 | { | ||
42 | struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, | ||
43 | struct mmc_pwrseq_simple, pwrseq); | ||
44 | |||
45 | if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) { | ||
46 | clk_prepare_enable(pwrseq->ext_clk); | ||
47 | pwrseq->clk_enabled = true; | ||
48 | } | ||
49 | |||
50 | mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); | ||
51 | } | ||
52 | |||
53 | static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host) | ||
54 | { | ||
55 | struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, | ||
56 | struct mmc_pwrseq_simple, pwrseq); | ||
57 | |||
58 | mmc_pwrseq_simple_set_gpios_value(pwrseq, 0); | ||
59 | } | ||
60 | |||
61 | static void mmc_pwrseq_simple_power_off(struct mmc_host *host) | ||
62 | { | ||
63 | struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, | ||
64 | struct mmc_pwrseq_simple, pwrseq); | ||
65 | |||
66 | mmc_pwrseq_simple_set_gpios_value(pwrseq, 1); | ||
67 | |||
68 | if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) { | ||
69 | clk_disable_unprepare(pwrseq->ext_clk); | ||
70 | pwrseq->clk_enabled = false; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | static void mmc_pwrseq_simple_free(struct mmc_host *host) | ||
75 | { | ||
76 | struct mmc_pwrseq_simple *pwrseq = container_of(host->pwrseq, | ||
77 | struct mmc_pwrseq_simple, pwrseq); | ||
78 | int i; | ||
79 | |||
80 | for (i = 0; i < pwrseq->nr_gpios; i++) | ||
81 | if (!IS_ERR(pwrseq->reset_gpios[i])) | ||
82 | gpiod_put(pwrseq->reset_gpios[i]); | ||
83 | |||
84 | if (!IS_ERR(pwrseq->ext_clk)) | ||
85 | clk_put(pwrseq->ext_clk); | ||
86 | |||
87 | kfree(pwrseq); | ||
88 | host->pwrseq = NULL; | ||
89 | } | ||
90 | |||
91 | static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { | ||
92 | .pre_power_on = mmc_pwrseq_simple_pre_power_on, | ||
93 | .post_power_on = mmc_pwrseq_simple_post_power_on, | ||
94 | .power_off = mmc_pwrseq_simple_power_off, | ||
95 | .free = mmc_pwrseq_simple_free, | ||
96 | }; | ||
97 | |||
98 | int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev) | ||
99 | { | ||
100 | struct mmc_pwrseq_simple *pwrseq; | ||
101 | int i, nr_gpios, ret = 0; | ||
102 | |||
103 | nr_gpios = of_gpio_named_count(dev->of_node, "reset-gpios"); | ||
104 | if (nr_gpios < 0) | ||
105 | nr_gpios = 0; | ||
106 | |||
107 | pwrseq = kzalloc(sizeof(struct mmc_pwrseq_simple) + nr_gpios * | ||
108 | sizeof(struct gpio_desc *), GFP_KERNEL); | ||
109 | if (!pwrseq) | ||
110 | return -ENOMEM; | ||
111 | |||
112 | pwrseq->ext_clk = clk_get(dev, "ext_clock"); | ||
113 | if (IS_ERR(pwrseq->ext_clk) && | ||
114 | PTR_ERR(pwrseq->ext_clk) != -ENOENT) { | ||
115 | ret = PTR_ERR(pwrseq->ext_clk); | ||
116 | goto free; | ||
117 | } | ||
118 | |||
119 | for (i = 0; i < nr_gpios; i++) { | ||
120 | pwrseq->reset_gpios[i] = gpiod_get_index(dev, "reset", i, | ||
121 | GPIOD_OUT_HIGH); | ||
122 | if (IS_ERR(pwrseq->reset_gpios[i]) && | ||
123 | PTR_ERR(pwrseq->reset_gpios[i]) != -ENOENT && | ||
124 | PTR_ERR(pwrseq->reset_gpios[i]) != -ENOSYS) { | ||
125 | ret = PTR_ERR(pwrseq->reset_gpios[i]); | ||
126 | |||
127 | while (--i) | ||
128 | gpiod_put(pwrseq->reset_gpios[i]); | ||
129 | |||
130 | goto clk_put; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | pwrseq->nr_gpios = nr_gpios; | ||
135 | pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; | ||
136 | host->pwrseq = &pwrseq->pwrseq; | ||
137 | |||
138 | return 0; | ||
139 | clk_put: | ||
140 | if (!IS_ERR(pwrseq->ext_clk)) | ||
141 | clk_put(pwrseq->ext_clk); | ||
142 | free: | ||
143 | kfree(pwrseq); | ||
144 | return ret; | ||
145 | } | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index d90a6de7901d..ad4d43eae99d 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -660,15 +660,10 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) | |||
660 | * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and | 660 | * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and |
661 | * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. | 661 | * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. |
662 | */ | 662 | */ |
663 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning && | 663 | if (!mmc_host_is_spi(card->host) && |
664 | (card->sd_bus_speed == UHS_SDR50_BUS_SPEED || | 664 | (card->sd_bus_speed == UHS_SDR50_BUS_SPEED || |
665 | card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) { | 665 | card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) |
666 | mmc_host_clk_hold(card->host); | 666 | err = mmc_execute_tuning(card); |
667 | err = card->host->ops->execute_tuning(card->host, | ||
668 | MMC_SEND_TUNING_BLOCK); | ||
669 | mmc_host_clk_release(card->host); | ||
670 | } | ||
671 | |||
672 | out: | 667 | out: |
673 | kfree(status); | 668 | kfree(status); |
674 | 669 | ||
@@ -933,6 +928,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
933 | } | 928 | } |
934 | 929 | ||
935 | /* | 930 | /* |
931 | * Call the optional HC's init_card function to handle quirks. | ||
932 | */ | ||
933 | if (host->ops->init_card) | ||
934 | host->ops->init_card(host, card); | ||
935 | |||
936 | /* | ||
936 | * For native busses: get card RCA and quit open drain mode. | 937 | * For native busses: get card RCA and quit open drain mode. |
937 | */ | 938 | */ |
938 | if (!mmc_host_is_spi(host)) { | 939 | if (!mmc_host_is_spi(host)) { |
@@ -1191,6 +1192,12 @@ static int mmc_sd_power_restore(struct mmc_host *host) | |||
1191 | return ret; | 1192 | return ret; |
1192 | } | 1193 | } |
1193 | 1194 | ||
1195 | static int mmc_sd_reset(struct mmc_host *host) | ||
1196 | { | ||
1197 | mmc_power_cycle(host, host->card->ocr); | ||
1198 | return mmc_sd_power_restore(host); | ||
1199 | } | ||
1200 | |||
1194 | static const struct mmc_bus_ops mmc_sd_ops = { | 1201 | static const struct mmc_bus_ops mmc_sd_ops = { |
1195 | .remove = mmc_sd_remove, | 1202 | .remove = mmc_sd_remove, |
1196 | .detect = mmc_sd_detect, | 1203 | .detect = mmc_sd_detect, |
@@ -1201,6 +1208,7 @@ static const struct mmc_bus_ops mmc_sd_ops = { | |||
1201 | .power_restore = mmc_sd_power_restore, | 1208 | .power_restore = mmc_sd_power_restore, |
1202 | .alive = mmc_sd_alive, | 1209 | .alive = mmc_sd_alive, |
1203 | .shutdown = mmc_sd_suspend, | 1210 | .shutdown = mmc_sd_suspend, |
1211 | .reset = mmc_sd_reset, | ||
1204 | }; | 1212 | }; |
1205 | 1213 | ||
1206 | /* | 1214 | /* |
@@ -1271,4 +1279,3 @@ err: | |||
1271 | 1279 | ||
1272 | return err; | 1280 | return err; |
1273 | } | 1281 | } |
1274 | |||
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index fd0750b5a634..ce6cc47206b0 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -567,17 +567,11 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card) | |||
567 | * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and | 567 | * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and |
568 | * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. | 568 | * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. |
569 | */ | 569 | */ |
570 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning && | 570 | if (!mmc_host_is_spi(card->host) && |
571 | ((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) || | 571 | ((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) || |
572 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104))) { | 572 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104))) |
573 | mmc_host_clk_hold(card->host); | 573 | err = mmc_execute_tuning(card); |
574 | err = card->host->ops->execute_tuning(card->host, | ||
575 | MMC_SEND_TUNING_BLOCK); | ||
576 | mmc_host_clk_release(card->host); | ||
577 | } | ||
578 | |||
579 | out: | 574 | out: |
580 | |||
581 | return err; | 575 | return err; |
582 | } | 576 | } |
583 | 577 | ||
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 60885316afba..bee02e644d62 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -22,7 +22,9 @@ | |||
22 | #include <linux/mmc/card.h> | 22 | #include <linux/mmc/card.h> |
23 | #include <linux/mmc/host.h> | 23 | #include <linux/mmc/host.h> |
24 | #include <linux/mmc/sdio_func.h> | 24 | #include <linux/mmc/sdio_func.h> |
25 | #include <linux/of.h> | ||
25 | 26 | ||
27 | #include "core.h" | ||
26 | #include "sdio_cis.h" | 28 | #include "sdio_cis.h" |
27 | #include "sdio_bus.h" | 29 | #include "sdio_bus.h" |
28 | 30 | ||
@@ -295,6 +297,13 @@ static void sdio_acpi_set_handle(struct sdio_func *func) | |||
295 | static inline void sdio_acpi_set_handle(struct sdio_func *func) {} | 297 | static inline void sdio_acpi_set_handle(struct sdio_func *func) {} |
296 | #endif | 298 | #endif |
297 | 299 | ||
300 | static void sdio_set_of_node(struct sdio_func *func) | ||
301 | { | ||
302 | struct mmc_host *host = func->card->host; | ||
303 | |||
304 | func->dev.of_node = mmc_of_find_child_device(host, func->num); | ||
305 | } | ||
306 | |||
298 | /* | 307 | /* |
299 | * Register a new SDIO function with the driver model. | 308 | * Register a new SDIO function with the driver model. |
300 | */ | 309 | */ |
@@ -304,6 +313,7 @@ int sdio_add_func(struct sdio_func *func) | |||
304 | 313 | ||
305 | dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num); | 314 | dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num); |
306 | 315 | ||
316 | sdio_set_of_node(func); | ||
307 | sdio_acpi_set_handle(func); | 317 | sdio_acpi_set_handle(func); |
308 | ret = device_add(&func->dev); | 318 | ret = device_add(&func->dev); |
309 | if (ret == 0) { | 319 | if (ret == 0) { |
@@ -327,6 +337,7 @@ void sdio_remove_func(struct sdio_func *func) | |||
327 | 337 | ||
328 | dev_pm_domain_detach(&func->dev, false); | 338 | dev_pm_domain_detach(&func->dev, false); |
329 | device_del(&func->dev); | 339 | device_del(&func->dev); |
340 | of_node_put(func->dev.of_node); | ||
330 | put_device(&func->dev); | 341 | put_device(&func->dev); |
331 | } | 342 | } |
332 | 343 | ||
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 69bbf2adb329..27117ba47073 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c | |||
@@ -18,11 +18,14 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | 20 | ||
21 | #include "slot-gpio.h" | ||
22 | |||
21 | struct mmc_gpio { | 23 | struct mmc_gpio { |
22 | struct gpio_desc *ro_gpio; | 24 | struct gpio_desc *ro_gpio; |
23 | struct gpio_desc *cd_gpio; | 25 | struct gpio_desc *cd_gpio; |
24 | bool override_ro_active_level; | 26 | bool override_ro_active_level; |
25 | bool override_cd_active_level; | 27 | bool override_cd_active_level; |
28 | irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); | ||
26 | char *ro_label; | 29 | char *ro_label; |
27 | char cd_label[0]; | 30 | char cd_label[0]; |
28 | }; | 31 | }; |
@@ -38,32 +41,20 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) | |||
38 | return IRQ_HANDLED; | 41 | return IRQ_HANDLED; |
39 | } | 42 | } |
40 | 43 | ||
41 | static int mmc_gpio_alloc(struct mmc_host *host) | 44 | int mmc_gpio_alloc(struct mmc_host *host) |
42 | { | 45 | { |
43 | size_t len = strlen(dev_name(host->parent)) + 4; | 46 | size_t len = strlen(dev_name(host->parent)) + 4; |
44 | struct mmc_gpio *ctx; | 47 | struct mmc_gpio *ctx = devm_kzalloc(host->parent, |
45 | 48 | sizeof(*ctx) + 2 * len, GFP_KERNEL); | |
46 | mutex_lock(&host->slot.lock); | 49 | |
47 | 50 | if (ctx) { | |
48 | ctx = host->slot.handler_priv; | 51 | ctx->ro_label = ctx->cd_label + len; |
49 | if (!ctx) { | 52 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); |
50 | /* | 53 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); |
51 | * devm_kzalloc() can be called after device_initialize(), even | 54 | host->slot.handler_priv = ctx; |
52 | * before device_add(), i.e., between mmc_alloc_host() and | 55 | host->slot.cd_irq = -EINVAL; |
53 | * mmc_add_host() | ||
54 | */ | ||
55 | ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len, | ||
56 | GFP_KERNEL); | ||
57 | if (ctx) { | ||
58 | ctx->ro_label = ctx->cd_label + len; | ||
59 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); | ||
60 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); | ||
61 | host->slot.handler_priv = ctx; | ||
62 | } | ||
63 | } | 56 | } |
64 | 57 | ||
65 | mutex_unlock(&host->slot.lock); | ||
66 | |||
67 | return ctx ? 0 : -ENOMEM; | 58 | return ctx ? 0 : -ENOMEM; |
68 | } | 59 | } |
69 | 60 | ||
@@ -103,29 +94,19 @@ EXPORT_SYMBOL(mmc_gpio_get_cd); | |||
103 | * @gpio: gpio number requested | 94 | * @gpio: gpio number requested |
104 | * | 95 | * |
105 | * As devm_* managed functions are used in mmc_gpio_request_ro(), client | 96 | * As devm_* managed functions are used in mmc_gpio_request_ro(), client |
106 | * drivers do not need to explicitly call mmc_gpio_free_ro() for freeing up, | 97 | * drivers do not need to worry about freeing up memory. |
107 | * if the requesting and freeing are only needed at probing and unbinding time | ||
108 | * for once. However, if client drivers do something special like runtime | ||
109 | * switching for write-protection, they are responsible for calling | ||
110 | * mmc_gpio_request_ro() and mmc_gpio_free_ro() as a pair on their own. | ||
111 | * | 98 | * |
112 | * Returns zero on success, else an error. | 99 | * Returns zero on success, else an error. |
113 | */ | 100 | */ |
114 | int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) | 101 | int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) |
115 | { | 102 | { |
116 | struct mmc_gpio *ctx; | 103 | struct mmc_gpio *ctx = host->slot.handler_priv; |
117 | int ret; | 104 | int ret; |
118 | 105 | ||
119 | if (!gpio_is_valid(gpio)) | 106 | if (!gpio_is_valid(gpio)) |
120 | return -EINVAL; | 107 | return -EINVAL; |
121 | 108 | ||
122 | ret = mmc_gpio_alloc(host); | 109 | ret = devm_gpio_request_one(host->parent, gpio, GPIOF_DIR_IN, |
123 | if (ret < 0) | ||
124 | return ret; | ||
125 | |||
126 | ctx = host->slot.handler_priv; | ||
127 | |||
128 | ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, | ||
129 | ctx->ro_label); | 110 | ctx->ro_label); |
130 | if (ret < 0) | 111 | if (ret < 0) |
131 | return ret; | 112 | return ret; |
@@ -156,8 +137,10 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host) | |||
156 | irq = -EINVAL; | 137 | irq = -EINVAL; |
157 | 138 | ||
158 | if (irq >= 0) { | 139 | if (irq >= 0) { |
159 | ret = devm_request_threaded_irq(&host->class_dev, irq, | 140 | if (!ctx->cd_gpio_isr) |
160 | NULL, mmc_gpio_cd_irqt, | 141 | ctx->cd_gpio_isr = mmc_gpio_cd_irqt; |
142 | ret = devm_request_threaded_irq(host->parent, irq, | ||
143 | NULL, ctx->cd_gpio_isr, | ||
161 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 144 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
162 | ctx->cd_label, host); | 145 | ctx->cd_label, host); |
163 | if (ret < 0) | 146 | if (ret < 0) |
@@ -171,6 +154,19 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host) | |||
171 | } | 154 | } |
172 | EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); | 155 | EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); |
173 | 156 | ||
157 | /* Register an alternate interrupt service routine for | ||
158 | * the card-detect GPIO. | ||
159 | */ | ||
160 | void mmc_gpio_set_cd_isr(struct mmc_host *host, | ||
161 | irqreturn_t (*isr)(int irq, void *dev_id)) | ||
162 | { | ||
163 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
164 | |||
165 | WARN_ON(ctx->cd_gpio_isr); | ||
166 | ctx->cd_gpio_isr = isr; | ||
167 | } | ||
168 | EXPORT_SYMBOL(mmc_gpio_set_cd_isr); | ||
169 | |||
174 | /** | 170 | /** |
175 | * mmc_gpio_request_cd - request a gpio for card-detection | 171 | * mmc_gpio_request_cd - request a gpio for card-detection |
176 | * @host: mmc host | 172 | * @host: mmc host |
@@ -178,11 +174,7 @@ EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); | |||
178 | * @debounce: debounce time in microseconds | 174 | * @debounce: debounce time in microseconds |
179 | * | 175 | * |
180 | * As devm_* managed functions are used in mmc_gpio_request_cd(), client | 176 | * As devm_* managed functions are used in mmc_gpio_request_cd(), client |
181 | * drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up, | 177 | * drivers do not need to worry about freeing up memory. |
182 | * if the requesting and freeing are only needed at probing and unbinding time | ||
183 | * for once. However, if client drivers do something special like runtime | ||
184 | * switching for card-detection, they are responsible for calling | ||
185 | * mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own. | ||
186 | * | 178 | * |
187 | * If GPIO debouncing is desired, set the debounce parameter to a non-zero | 179 | * If GPIO debouncing is desired, set the debounce parameter to a non-zero |
188 | * value. The caller is responsible for ensuring that the GPIO driver associated | 180 | * value. The caller is responsible for ensuring that the GPIO driver associated |
@@ -193,16 +185,10 @@ EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); | |||
193 | int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | 185 | int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, |
194 | unsigned int debounce) | 186 | unsigned int debounce) |
195 | { | 187 | { |
196 | struct mmc_gpio *ctx; | 188 | struct mmc_gpio *ctx = host->slot.handler_priv; |
197 | int ret; | 189 | int ret; |
198 | 190 | ||
199 | ret = mmc_gpio_alloc(host); | 191 | ret = devm_gpio_request_one(host->parent, gpio, GPIOF_DIR_IN, |
200 | if (ret < 0) | ||
201 | return ret; | ||
202 | |||
203 | ctx = host->slot.handler_priv; | ||
204 | |||
205 | ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, | ||
206 | ctx->cd_label); | 192 | ctx->cd_label); |
207 | if (ret < 0) | 193 | if (ret < 0) |
208 | /* | 194 | /* |
@@ -226,55 +212,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | |||
226 | EXPORT_SYMBOL(mmc_gpio_request_cd); | 212 | EXPORT_SYMBOL(mmc_gpio_request_cd); |
227 | 213 | ||
228 | /** | 214 | /** |
229 | * mmc_gpio_free_ro - free the write-protection gpio | ||
230 | * @host: mmc host | ||
231 | * | ||
232 | * It's provided only for cases that client drivers need to manually free | ||
233 | * up the write-protection gpio requested by mmc_gpio_request_ro(). | ||
234 | */ | ||
235 | void mmc_gpio_free_ro(struct mmc_host *host) | ||
236 | { | ||
237 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
238 | int gpio; | ||
239 | |||
240 | if (!ctx || !ctx->ro_gpio) | ||
241 | return; | ||
242 | |||
243 | gpio = desc_to_gpio(ctx->ro_gpio); | ||
244 | ctx->ro_gpio = NULL; | ||
245 | |||
246 | devm_gpio_free(&host->class_dev, gpio); | ||
247 | } | ||
248 | EXPORT_SYMBOL(mmc_gpio_free_ro); | ||
249 | |||
250 | /** | ||
251 | * mmc_gpio_free_cd - free the card-detection gpio | ||
252 | * @host: mmc host | ||
253 | * | ||
254 | * It's provided only for cases that client drivers need to manually free | ||
255 | * up the card-detection gpio requested by mmc_gpio_request_cd(). | ||
256 | */ | ||
257 | void mmc_gpio_free_cd(struct mmc_host *host) | ||
258 | { | ||
259 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
260 | int gpio; | ||
261 | |||
262 | if (!ctx || !ctx->cd_gpio) | ||
263 | return; | ||
264 | |||
265 | if (host->slot.cd_irq >= 0) { | ||
266 | devm_free_irq(&host->class_dev, host->slot.cd_irq, host); | ||
267 | host->slot.cd_irq = -EINVAL; | ||
268 | } | ||
269 | |||
270 | gpio = desc_to_gpio(ctx->cd_gpio); | ||
271 | ctx->cd_gpio = NULL; | ||
272 | |||
273 | devm_gpio_free(&host->class_dev, gpio); | ||
274 | } | ||
275 | EXPORT_SYMBOL(mmc_gpio_free_cd); | ||
276 | |||
277 | /** | ||
278 | * mmc_gpiod_request_cd - request a gpio descriptor for card-detection | 215 | * mmc_gpiod_request_cd - request a gpio descriptor for card-detection |
279 | * @host: mmc host | 216 | * @host: mmc host |
280 | * @con_id: function within the GPIO consumer | 217 | * @con_id: function within the GPIO consumer |
@@ -285,8 +222,7 @@ EXPORT_SYMBOL(mmc_gpio_free_cd); | |||
285 | * to NULL to ignore | 222 | * to NULL to ignore |
286 | * | 223 | * |
287 | * Use this function in place of mmc_gpio_request_cd() to use the GPIO | 224 | * Use this function in place of mmc_gpio_request_cd() to use the GPIO |
288 | * descriptor API. Note that it is paired with mmc_gpiod_free_cd() not | 225 | * descriptor API. Note that it must be called prior to mmc_add_host() |
289 | * mmc_gpio_free_cd(). Note also that it must be called prior to mmc_add_host() | ||
290 | * otherwise the caller must also call mmc_gpiod_request_cd_irq(). | 226 | * otherwise the caller must also call mmc_gpiod_request_cd_irq(). |
291 | * | 227 | * |
292 | * Returns zero on success, else an error. | 228 | * Returns zero on success, else an error. |
@@ -295,16 +231,10 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | |||
295 | unsigned int idx, bool override_active_level, | 231 | unsigned int idx, bool override_active_level, |
296 | unsigned int debounce, bool *gpio_invert) | 232 | unsigned int debounce, bool *gpio_invert) |
297 | { | 233 | { |
298 | struct mmc_gpio *ctx; | 234 | struct mmc_gpio *ctx = host->slot.handler_priv; |
299 | struct gpio_desc *desc; | 235 | struct gpio_desc *desc; |
300 | int ret; | 236 | int ret; |
301 | 237 | ||
302 | ret = mmc_gpio_alloc(host); | ||
303 | if (ret < 0) | ||
304 | return ret; | ||
305 | |||
306 | ctx = host->slot.handler_priv; | ||
307 | |||
308 | if (!con_id) | 238 | if (!con_id) |
309 | con_id = ctx->cd_label; | 239 | con_id = ctx->cd_label; |
310 | 240 | ||
@@ -339,8 +269,7 @@ EXPORT_SYMBOL(mmc_gpiod_request_cd); | |||
339 | * set to NULL to ignore | 269 | * set to NULL to ignore |
340 | * | 270 | * |
341 | * Use this function in place of mmc_gpio_request_ro() to use the GPIO | 271 | * Use this function in place of mmc_gpio_request_ro() to use the GPIO |
342 | * descriptor API. Note that it is paired with mmc_gpiod_free_ro() not | 272 | * descriptor API. |
343 | * mmc_gpio_free_ro(). | ||
344 | * | 273 | * |
345 | * Returns zero on success, else an error. | 274 | * Returns zero on success, else an error. |
346 | */ | 275 | */ |
@@ -348,16 +277,10 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, | |||
348 | unsigned int idx, bool override_active_level, | 277 | unsigned int idx, bool override_active_level, |
349 | unsigned int debounce, bool *gpio_invert) | 278 | unsigned int debounce, bool *gpio_invert) |
350 | { | 279 | { |
351 | struct mmc_gpio *ctx; | 280 | struct mmc_gpio *ctx = host->slot.handler_priv; |
352 | struct gpio_desc *desc; | 281 | struct gpio_desc *desc; |
353 | int ret; | 282 | int ret; |
354 | 283 | ||
355 | ret = mmc_gpio_alloc(host); | ||
356 | if (ret < 0) | ||
357 | return ret; | ||
358 | |||
359 | ctx = host->slot.handler_priv; | ||
360 | |||
361 | if (!con_id) | 284 | if (!con_id) |
362 | con_id = ctx->ro_label; | 285 | con_id = ctx->ro_label; |
363 | 286 | ||
@@ -380,28 +303,3 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, | |||
380 | return 0; | 303 | return 0; |
381 | } | 304 | } |
382 | EXPORT_SYMBOL(mmc_gpiod_request_ro); | 305 | EXPORT_SYMBOL(mmc_gpiod_request_ro); |
383 | |||
384 | /** | ||
385 | * mmc_gpiod_free_cd - free the card-detection gpio descriptor | ||
386 | * @host: mmc host | ||
387 | * | ||
388 | * It's provided only for cases that client drivers need to manually free | ||
389 | * up the card-detection gpio requested by mmc_gpiod_request_cd(). | ||
390 | */ | ||
391 | void mmc_gpiod_free_cd(struct mmc_host *host) | ||
392 | { | ||
393 | struct mmc_gpio *ctx = host->slot.handler_priv; | ||
394 | |||
395 | if (!ctx || !ctx->cd_gpio) | ||
396 | return; | ||
397 | |||
398 | if (host->slot.cd_irq >= 0) { | ||
399 | devm_free_irq(&host->class_dev, host->slot.cd_irq, host); | ||
400 | host->slot.cd_irq = -EINVAL; | ||
401 | } | ||
402 | |||
403 | devm_gpiod_put(host->parent, ctx->cd_gpio); | ||
404 | |||
405 | ctx->cd_gpio = NULL; | ||
406 | } | ||
407 | EXPORT_SYMBOL(mmc_gpiod_free_cd); | ||
diff --git a/drivers/mmc/core/slot-gpio.h b/drivers/mmc/core/slot-gpio.h new file mode 100644 index 000000000000..8c1854dc5d58 --- /dev/null +++ b/drivers/mmc/core/slot-gpio.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Linaro Ltd | ||
3 | * | ||
4 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
5 | * | ||
6 | * License terms: GNU General Public License (GPL) version 2 | ||
7 | */ | ||
8 | #ifndef _MMC_CORE_SLOTGPIO_H | ||
9 | #define _MMC_CORE_SLOTGPIO_H | ||
10 | |||
11 | int mmc_gpio_alloc(struct mmc_host *host); | ||
12 | |||
13 | #endif | ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 2d6fbdd11803..61ac63a3776a 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -57,6 +57,7 @@ config MMC_SDHCI_IO_ACCESSORS | |||
57 | 57 | ||
58 | config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER | 58 | config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER |
59 | bool | 59 | bool |
60 | depends on MMC_SDHCI | ||
60 | select MMC_SDHCI_IO_ACCESSORS | 61 | select MMC_SDHCI_IO_ACCESSORS |
61 | help | 62 | help |
62 | This option is selected by drivers running on big endian hosts | 63 | This option is selected by drivers running on big endian hosts |
@@ -82,6 +83,7 @@ config MMC_SDHCI_PCI | |||
82 | config MMC_RICOH_MMC | 83 | config MMC_RICOH_MMC |
83 | bool "Ricoh MMC Controller Disabler" | 84 | bool "Ricoh MMC Controller Disabler" |
84 | depends on MMC_SDHCI_PCI | 85 | depends on MMC_SDHCI_PCI |
86 | default y | ||
85 | help | 87 | help |
86 | This adds a pci quirk to disable Ricoh MMC Controller. This | 88 | This adds a pci quirk to disable Ricoh MMC Controller. This |
87 | proprietary controller is unnecessary because the SDHCI driver | 89 | proprietary controller is unnecessary because the SDHCI driver |
@@ -228,6 +230,7 @@ config MMC_SDHCI_PXAV3 | |||
228 | tristate "Marvell MMP2 SD Host Controller support (PXAV3)" | 230 | tristate "Marvell MMP2 SD Host Controller support (PXAV3)" |
229 | depends on CLKDEV_LOOKUP | 231 | depends on CLKDEV_LOOKUP |
230 | depends on MMC_SDHCI_PLTFM | 232 | depends on MMC_SDHCI_PLTFM |
233 | depends on ARCH_MMP || COMPILE_TEST | ||
231 | default CPU_MMP2 | 234 | default CPU_MMP2 |
232 | help | 235 | help |
233 | This selects the Marvell(R) PXAV3 SD Host Controller. | 236 | This selects the Marvell(R) PXAV3 SD Host Controller. |
@@ -240,6 +243,7 @@ config MMC_SDHCI_PXAV2 | |||
240 | tristate "Marvell PXA9XX SD Host Controller support (PXAV2)" | 243 | tristate "Marvell PXA9XX SD Host Controller support (PXAV2)" |
241 | depends on CLKDEV_LOOKUP | 244 | depends on CLKDEV_LOOKUP |
242 | depends on MMC_SDHCI_PLTFM | 245 | depends on MMC_SDHCI_PLTFM |
246 | depends on ARCH_MMP || COMPILE_TEST | ||
243 | default CPU_PXA910 | 247 | default CPU_PXA910 |
244 | help | 248 | help |
245 | This selects the Marvell(R) PXAV2 SD Host Controller. | 249 | This selects the Marvell(R) PXAV2 SD Host Controller. |
@@ -292,6 +296,17 @@ config MMC_SDHCI_BCM2835 | |||
292 | 296 | ||
293 | If unsure, say N. | 297 | If unsure, say N. |
294 | 298 | ||
299 | config MMC_SDHCI_F_SDH30 | ||
300 | tristate "SDHCI support for Fujitsu Semiconductor F_SDH30" | ||
301 | depends on MMC_SDHCI_PLTFM | ||
302 | depends on OF | ||
303 | help | ||
304 | This selects the Secure Digital Host Controller Interface (SDHCI) | ||
305 | Needed by some Fujitsu SoC for MMC / SD / SDIO support. | ||
306 | If you have a controller with this interface, say Y or M here. | ||
307 | |||
308 | If unsure, say N. | ||
309 | |||
295 | config MMC_MOXART | 310 | config MMC_MOXART |
296 | tristate "MOXART SD/MMC Host Controller support" | 311 | tristate "MOXART SD/MMC Host Controller support" |
297 | depends on ARCH_MOXART && MMC | 312 | depends on ARCH_MOXART && MMC |
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index f7b0a77cf419..6a7cfe0de332 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -16,6 +16,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o | |||
16 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o | 16 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o |
17 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o | 17 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o |
18 | obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o | 18 | obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o |
19 | obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o | ||
19 | obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o | 20 | obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o |
20 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | 21 | obj-$(CONFIG_MMC_WBSD) += wbsd.o |
21 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o | 22 | obj-$(CONFIG_MMC_AU1X) += au1xmmc.o |
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 509365cb22c6..fe32948c6114 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c | |||
@@ -21,43 +21,7 @@ | |||
21 | 21 | ||
22 | #include "dw_mmc.h" | 22 | #include "dw_mmc.h" |
23 | #include "dw_mmc-pltfm.h" | 23 | #include "dw_mmc-pltfm.h" |
24 | 24 | #include "dw_mmc-exynos.h" | |
25 | #define NUM_PINS(x) (x + 2) | ||
26 | |||
27 | #define SDMMC_CLKSEL 0x09C | ||
28 | #define SDMMC_CLKSEL64 0x0A8 | ||
29 | #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) | ||
30 | #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) | ||
31 | #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) | ||
32 | #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) | ||
33 | #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ | ||
34 | SDMMC_CLKSEL_CCLK_DRIVE(y) | \ | ||
35 | SDMMC_CLKSEL_CCLK_DIVIDER(z)) | ||
36 | #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) | ||
37 | |||
38 | #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 | ||
39 | #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 | ||
40 | |||
41 | /* Block number in eMMC */ | ||
42 | #define DWMCI_BLOCK_NUM 0xFFFFFFFF | ||
43 | |||
44 | #define SDMMC_EMMCP_BASE 0x1000 | ||
45 | #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) | ||
46 | #define SDMMC_MPSBEGIN0 (SDMMC_EMMCP_BASE + 0x0200) | ||
47 | #define SDMMC_MPSEND0 (SDMMC_EMMCP_BASE + 0x0204) | ||
48 | #define SDMMC_MPSCTRL0 (SDMMC_EMMCP_BASE + 0x020C) | ||
49 | |||
50 | /* SMU control bits */ | ||
51 | #define DWMCI_MPSCTRL_SECURE_READ_BIT BIT(7) | ||
52 | #define DWMCI_MPSCTRL_SECURE_WRITE_BIT BIT(6) | ||
53 | #define DWMCI_MPSCTRL_NON_SECURE_READ_BIT BIT(5) | ||
54 | #define DWMCI_MPSCTRL_NON_SECURE_WRITE_BIT BIT(4) | ||
55 | #define DWMCI_MPSCTRL_USE_FUSE_KEY BIT(3) | ||
56 | #define DWMCI_MPSCTRL_ECB_MODE BIT(2) | ||
57 | #define DWMCI_MPSCTRL_ENCRYPTION BIT(1) | ||
58 | #define DWMCI_MPSCTRL_VALID BIT(0) | ||
59 | |||
60 | #define EXYNOS_CCLKIN_MIN 50000000 /* unit: HZ */ | ||
61 | 25 | ||
62 | /* Variations in Exynos specific dw-mshc controller */ | 26 | /* Variations in Exynos specific dw-mshc controller */ |
63 | enum dw_mci_exynos_type { | 27 | enum dw_mci_exynos_type { |
@@ -114,11 +78,11 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) | |||
114 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU || | 78 | if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5420_SMU || |
115 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) { | 79 | priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) { |
116 | mci_writel(host, MPSBEGIN0, 0); | 80 | mci_writel(host, MPSBEGIN0, 0); |
117 | mci_writel(host, MPSEND0, DWMCI_BLOCK_NUM); | 81 | mci_writel(host, MPSEND0, SDMMC_ENDING_SEC_NR_MAX); |
118 | mci_writel(host, MPSCTRL0, DWMCI_MPSCTRL_SECURE_WRITE_BIT | | 82 | mci_writel(host, MPSCTRL0, SDMMC_MPSCTRL_SECURE_WRITE_BIT | |
119 | DWMCI_MPSCTRL_NON_SECURE_READ_BIT | | 83 | SDMMC_MPSCTRL_NON_SECURE_READ_BIT | |
120 | DWMCI_MPSCTRL_VALID | | 84 | SDMMC_MPSCTRL_VALID | |
121 | DWMCI_MPSCTRL_NON_SECURE_WRITE_BIT); | 85 | SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); |
122 | } | 86 | } |
123 | 87 | ||
124 | return 0; | 88 | return 0; |
@@ -127,9 +91,9 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) | |||
127 | static int dw_mci_exynos_setup_clock(struct dw_mci *host) | 91 | static int dw_mci_exynos_setup_clock(struct dw_mci *host) |
128 | { | 92 | { |
129 | struct dw_mci_exynos_priv_data *priv = host->priv; | 93 | struct dw_mci_exynos_priv_data *priv = host->priv; |
130 | unsigned long rate = clk_get_rate(host->ciu_clk); | ||
131 | 94 | ||
132 | host->bus_hz = rate / (priv->ciu_div + 1); | 95 | host->bus_hz /= (priv->ciu_div + 1); |
96 | |||
133 | return 0; | 97 | return 0; |
134 | } | 98 | } |
135 | 99 | ||
@@ -232,8 +196,11 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) | |||
232 | mci_writel(host, CLKSEL, priv->sdr_timing); | 196 | mci_writel(host, CLKSEL, priv->sdr_timing); |
233 | } | 197 | } |
234 | 198 | ||
235 | /* Don't care if wanted clock is zero */ | 199 | /* |
236 | if (!wanted) | 200 | * Don't care if wanted clock is zero or |
201 | * ciu clock is unavailable | ||
202 | */ | ||
203 | if (!wanted || IS_ERR(host->ciu_clk)) | ||
237 | return; | 204 | return; |
238 | 205 | ||
239 | /* Guaranteed minimum frequency for cclkin */ | 206 | /* Guaranteed minimum frequency for cclkin */ |
@@ -263,10 +230,8 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) | |||
263 | int ret; | 230 | int ret; |
264 | 231 | ||
265 | priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); | 232 | priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); |
266 | if (!priv) { | 233 | if (!priv) |
267 | dev_err(host->dev, "mem alloc failed for private data\n"); | ||
268 | return -ENOMEM; | 234 | return -ENOMEM; |
269 | } | ||
270 | 235 | ||
271 | for (idx = 0; idx < ARRAY_SIZE(exynos_compat); idx++) { | 236 | for (idx = 0; idx < ARRAY_SIZE(exynos_compat); idx++) { |
272 | if (of_device_is_compatible(np, exynos_compat[idx].compatible)) | 237 | if (of_device_is_compatible(np, exynos_compat[idx].compatible)) |
@@ -375,64 +340,23 @@ out: | |||
375 | return loc; | 340 | return loc; |
376 | } | 341 | } |
377 | 342 | ||
378 | static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode, | 343 | static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) |
379 | struct dw_mci_tuning_data *tuning_data) | ||
380 | { | 344 | { |
381 | struct dw_mci *host = slot->host; | 345 | struct dw_mci *host = slot->host; |
382 | struct mmc_host *mmc = slot->mmc; | 346 | struct mmc_host *mmc = slot->mmc; |
383 | const u8 *blk_pattern = tuning_data->blk_pattern; | ||
384 | u8 *blk_test; | ||
385 | unsigned int blksz = tuning_data->blksz; | ||
386 | u8 start_smpl, smpl, candiates = 0; | 347 | u8 start_smpl, smpl, candiates = 0; |
387 | s8 found = -1; | 348 | s8 found = -1; |
388 | int ret = 0; | 349 | int ret = 0; |
389 | 350 | ||
390 | blk_test = kmalloc(blksz, GFP_KERNEL); | ||
391 | if (!blk_test) | ||
392 | return -ENOMEM; | ||
393 | |||
394 | start_smpl = dw_mci_exynos_get_clksmpl(host); | 351 | start_smpl = dw_mci_exynos_get_clksmpl(host); |
395 | 352 | ||
396 | do { | 353 | do { |
397 | struct mmc_request mrq = {NULL}; | ||
398 | struct mmc_command cmd = {0}; | ||
399 | struct mmc_command stop = {0}; | ||
400 | struct mmc_data data = {0}; | ||
401 | struct scatterlist sg; | ||
402 | |||
403 | cmd.opcode = opcode; | ||
404 | cmd.arg = 0; | ||
405 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
406 | |||
407 | stop.opcode = MMC_STOP_TRANSMISSION; | ||
408 | stop.arg = 0; | ||
409 | stop.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
410 | |||
411 | data.blksz = blksz; | ||
412 | data.blocks = 1; | ||
413 | data.flags = MMC_DATA_READ; | ||
414 | data.sg = &sg; | ||
415 | data.sg_len = 1; | ||
416 | |||
417 | sg_init_one(&sg, blk_test, blksz); | ||
418 | mrq.cmd = &cmd; | ||
419 | mrq.stop = &stop; | ||
420 | mrq.data = &data; | ||
421 | host->mrq = &mrq; | ||
422 | |||
423 | mci_writel(host, TMOUT, ~0); | 354 | mci_writel(host, TMOUT, ~0); |
424 | smpl = dw_mci_exynos_move_next_clksmpl(host); | 355 | smpl = dw_mci_exynos_move_next_clksmpl(host); |
425 | 356 | ||
426 | mmc_wait_for_req(mmc, &mrq); | 357 | if (!mmc_send_tuning(mmc)) |
358 | candiates |= (1 << smpl); | ||
427 | 359 | ||
428 | if (!cmd.error && !data.error) { | ||
429 | if (!memcmp(blk_pattern, blk_test, blksz)) | ||
430 | candiates |= (1 << smpl); | ||
431 | } else { | ||
432 | dev_dbg(host->dev, | ||
433 | "Tuning error: cmd.error:%d, data.error:%d\n", | ||
434 | cmd.error, data.error); | ||
435 | } | ||
436 | } while (start_smpl != smpl); | 360 | } while (start_smpl != smpl); |
437 | 361 | ||
438 | found = dw_mci_exynos_get_best_clksmpl(candiates); | 362 | found = dw_mci_exynos_get_best_clksmpl(candiates); |
@@ -441,7 +365,6 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot, u32 opcode, | |||
441 | else | 365 | else |
442 | ret = -EIO; | 366 | ret = -EIO; |
443 | 367 | ||
444 | kfree(blk_test); | ||
445 | return ret; | 368 | return ret; |
446 | } | 369 | } |
447 | 370 | ||
@@ -499,7 +422,7 @@ static const struct dev_pm_ops dw_mci_exynos_pmops = { | |||
499 | 422 | ||
500 | static struct platform_driver dw_mci_exynos_pltfm_driver = { | 423 | static struct platform_driver dw_mci_exynos_pltfm_driver = { |
501 | .probe = dw_mci_exynos_probe, | 424 | .probe = dw_mci_exynos_probe, |
502 | .remove = __exit_p(dw_mci_pltfm_remove), | 425 | .remove = dw_mci_pltfm_remove, |
503 | .driver = { | 426 | .driver = { |
504 | .name = "dwmmc_exynos", | 427 | .name = "dwmmc_exynos", |
505 | .of_match_table = dw_mci_exynos_match, | 428 | .of_match_table = dw_mci_exynos_match, |
diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h new file mode 100644 index 000000000000..7872ce586b55 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-exynos.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Exynos Specific Extensions for Synopsys DW Multimedia Card Interface driver | ||
3 | * | ||
4 | * Copyright (C) 2012-2014 Samsung Electronics Co., Ltd. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef _DW_MMC_EXYNOS_H_ | ||
13 | #define _DW_MMC_EXYNOS_H_ | ||
14 | |||
15 | /* Extended Register's Offset */ | ||
16 | #define SDMMC_CLKSEL 0x09C | ||
17 | #define SDMMC_CLKSEL64 0x0A8 | ||
18 | |||
19 | /* CLKSEL register defines */ | ||
20 | #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) | ||
21 | #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) | ||
22 | #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) | ||
23 | #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) | ||
24 | #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ | ||
25 | SDMMC_CLKSEL_CCLK_DRIVE(y) | \ | ||
26 | SDMMC_CLKSEL_CCLK_DIVIDER(z)) | ||
27 | #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) | ||
28 | |||
29 | /* Protector Register */ | ||
30 | #define SDMMC_EMMCP_BASE 0x1000 | ||
31 | #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) | ||
32 | #define SDMMC_MPSBEGIN0 (SDMMC_EMMCP_BASE + 0x0200) | ||
33 | #define SDMMC_MPSEND0 (SDMMC_EMMCP_BASE + 0x0204) | ||
34 | #define SDMMC_MPSCTRL0 (SDMMC_EMMCP_BASE + 0x020C) | ||
35 | |||
36 | /* SMU control defines */ | ||
37 | #define SDMMC_MPSCTRL_SECURE_READ_BIT BIT(7) | ||
38 | #define SDMMC_MPSCTRL_SECURE_WRITE_BIT BIT(6) | ||
39 | #define SDMMC_MPSCTRL_NON_SECURE_READ_BIT BIT(5) | ||
40 | #define SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT BIT(4) | ||
41 | #define SDMMC_MPSCTRL_USE_FUSE_KEY BIT(3) | ||
42 | #define SDMMC_MPSCTRL_ECB_MODE BIT(2) | ||
43 | #define SDMMC_MPSCTRL_ENCRYPTION BIT(1) | ||
44 | #define SDMMC_MPSCTRL_VALID BIT(0) | ||
45 | |||
46 | /* Maximum number of Ending sector */ | ||
47 | #define SDMMC_ENDING_SEC_NR_MAX 0xFFFFFFFF | ||
48 | |||
49 | /* Fixed clock divider */ | ||
50 | #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 | ||
51 | #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 | ||
52 | |||
53 | /* Minimal required clock frequency for cclkin, unit: HZ */ | ||
54 | #define EXYNOS_CCLKIN_MIN 50000000 | ||
55 | |||
56 | #endif /* _DW_MMC_EXYNOS_H_ */ | ||
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 5650ac488cf3..e2a726a503ee 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c | |||
@@ -133,7 +133,7 @@ static SIMPLE_DEV_PM_OPS(dw_mci_rockchip_pmops, | |||
133 | 133 | ||
134 | static struct platform_driver dw_mci_rockchip_pltfm_driver = { | 134 | static struct platform_driver dw_mci_rockchip_pltfm_driver = { |
135 | .probe = dw_mci_rockchip_probe, | 135 | .probe = dw_mci_rockchip_probe, |
136 | .remove = __exit_p(dw_mci_pltfm_remove), | 136 | .remove = dw_mci_pltfm_remove, |
137 | .driver = { | 137 | .driver = { |
138 | .name = "dwmmc_rockchip", | 138 | .name = "dwmmc_rockchip", |
139 | .of_match_table = dw_mci_rockchip_match, | 139 | .of_match_table = dw_mci_rockchip_match, |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 67c04518ec4c..4d2e3c2e1830 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/stat.h> | 27 | #include <linux/stat.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
30 | #include <linux/mmc/card.h> | ||
30 | #include <linux/mmc/host.h> | 31 | #include <linux/mmc/host.h> |
31 | #include <linux/mmc/mmc.h> | 32 | #include <linux/mmc/mmc.h> |
32 | #include <linux/mmc/sd.h> | 33 | #include <linux/mmc/sd.h> |
@@ -313,7 +314,9 @@ static u32 dw_mci_prep_stop_abort(struct dw_mci *host, struct mmc_command *cmd) | |||
313 | if (cmdr == MMC_READ_SINGLE_BLOCK || | 314 | if (cmdr == MMC_READ_SINGLE_BLOCK || |
314 | cmdr == MMC_READ_MULTIPLE_BLOCK || | 315 | cmdr == MMC_READ_MULTIPLE_BLOCK || |
315 | cmdr == MMC_WRITE_BLOCK || | 316 | cmdr == MMC_WRITE_BLOCK || |
316 | cmdr == MMC_WRITE_MULTIPLE_BLOCK) { | 317 | cmdr == MMC_WRITE_MULTIPLE_BLOCK || |
318 | cmdr == MMC_SEND_TUNING_BLOCK || | ||
319 | cmdr == MMC_SEND_TUNING_BLOCK_HS200) { | ||
317 | stop->opcode = MMC_STOP_TRANSMISSION; | 320 | stop->opcode = MMC_STOP_TRANSMISSION; |
318 | stop->arg = 0; | 321 | stop->arg = 0; |
319 | stop->flags = MMC_RSP_R1B | MMC_CMD_AC; | 322 | stop->flags = MMC_RSP_R1B | MMC_CMD_AC; |
@@ -758,6 +761,7 @@ disable: | |||
758 | 761 | ||
759 | static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) | 762 | static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) |
760 | { | 763 | { |
764 | unsigned long irqflags; | ||
761 | int sg_len; | 765 | int sg_len; |
762 | u32 temp; | 766 | u32 temp; |
763 | 767 | ||
@@ -794,9 +798,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) | |||
794 | mci_writel(host, CTRL, temp); | 798 | mci_writel(host, CTRL, temp); |
795 | 799 | ||
796 | /* Disable RX/TX IRQs, let DMA handle it */ | 800 | /* Disable RX/TX IRQs, let DMA handle it */ |
801 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
797 | temp = mci_readl(host, INTMASK); | 802 | temp = mci_readl(host, INTMASK); |
798 | temp &= ~(SDMMC_INT_RXDR | SDMMC_INT_TXDR); | 803 | temp &= ~(SDMMC_INT_RXDR | SDMMC_INT_TXDR); |
799 | mci_writel(host, INTMASK, temp); | 804 | mci_writel(host, INTMASK, temp); |
805 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
800 | 806 | ||
801 | host->dma_ops->start(host, sg_len); | 807 | host->dma_ops->start(host, sg_len); |
802 | 808 | ||
@@ -805,6 +811,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) | |||
805 | 811 | ||
806 | static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) | 812 | static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) |
807 | { | 813 | { |
814 | unsigned long irqflags; | ||
808 | u32 temp; | 815 | u32 temp; |
809 | 816 | ||
810 | data->error = -EINPROGRESS; | 817 | data->error = -EINPROGRESS; |
@@ -833,9 +840,12 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) | |||
833 | host->part_buf_count = 0; | 840 | host->part_buf_count = 0; |
834 | 841 | ||
835 | mci_writel(host, RINTSTS, SDMMC_INT_TXDR | SDMMC_INT_RXDR); | 842 | mci_writel(host, RINTSTS, SDMMC_INT_TXDR | SDMMC_INT_RXDR); |
843 | |||
844 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
836 | temp = mci_readl(host, INTMASK); | 845 | temp = mci_readl(host, INTMASK); |
837 | temp |= SDMMC_INT_TXDR | SDMMC_INT_RXDR; | 846 | temp |= SDMMC_INT_TXDR | SDMMC_INT_RXDR; |
838 | mci_writel(host, INTMASK, temp); | 847 | mci_writel(host, INTMASK, temp); |
848 | spin_unlock_irqrestore(&host->irq_lock, irqflags); | ||
839 | 849 | ||
840 | temp = mci_readl(host, CTRL); | 850 | temp = mci_readl(host, CTRL); |
841 | temp &= ~SDMMC_CTRL_DMA_ENABLE; | 851 | temp &= ~SDMMC_CTRL_DMA_ENABLE; |
@@ -926,7 +936,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | |||
926 | 936 | ||
927 | /* enable clock; only low power if no SDIO */ | 937 | /* enable clock; only low power if no SDIO */ |
928 | clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; | 938 | clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; |
929 | if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->sdio_id))) | 939 | if (!test_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags)) |
930 | clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; | 940 | clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; |
931 | mci_writel(host, CLKENA, clk_en_a); | 941 | mci_writel(host, CLKENA, clk_en_a); |
932 | 942 | ||
@@ -1109,6 +1119,12 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1109 | return; | 1119 | return; |
1110 | } | 1120 | } |
1111 | } | 1121 | } |
1122 | set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags); | ||
1123 | regs = mci_readl(slot->host, PWREN); | ||
1124 | regs |= (1 << slot->id); | ||
1125 | mci_writel(slot->host, PWREN, regs); | ||
1126 | break; | ||
1127 | case MMC_POWER_ON: | ||
1112 | if (!IS_ERR(mmc->supply.vqmmc) && !slot->host->vqmmc_enabled) { | 1128 | if (!IS_ERR(mmc->supply.vqmmc) && !slot->host->vqmmc_enabled) { |
1113 | ret = regulator_enable(mmc->supply.vqmmc); | 1129 | ret = regulator_enable(mmc->supply.vqmmc); |
1114 | if (ret < 0) | 1130 | if (ret < 0) |
@@ -1117,10 +1133,6 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1117 | else | 1133 | else |
1118 | slot->host->vqmmc_enabled = true; | 1134 | slot->host->vqmmc_enabled = true; |
1119 | } | 1135 | } |
1120 | set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags); | ||
1121 | regs = mci_readl(slot->host, PWREN); | ||
1122 | regs |= (1 << slot->id); | ||
1123 | mci_writel(slot->host, PWREN, regs); | ||
1124 | break; | 1136 | break; |
1125 | case MMC_POWER_OFF: | 1137 | case MMC_POWER_OFF: |
1126 | if (!IS_ERR(mmc->supply.vmmc)) | 1138 | if (!IS_ERR(mmc->supply.vmmc)) |
@@ -1245,27 +1257,37 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
1245 | return present; | 1257 | return present; |
1246 | } | 1258 | } |
1247 | 1259 | ||
1248 | /* | 1260 | static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card) |
1249 | * Disable lower power mode. | ||
1250 | * | ||
1251 | * Low power mode will stop the card clock when idle. According to the | ||
1252 | * description of the CLKENA register we should disable low power mode | ||
1253 | * for SDIO cards if we need SDIO interrupts to work. | ||
1254 | * | ||
1255 | * This function is fast if low power mode is already disabled. | ||
1256 | */ | ||
1257 | static void dw_mci_disable_low_power(struct dw_mci_slot *slot) | ||
1258 | { | 1261 | { |
1262 | struct dw_mci_slot *slot = mmc_priv(mmc); | ||
1259 | struct dw_mci *host = slot->host; | 1263 | struct dw_mci *host = slot->host; |
1260 | u32 clk_en_a; | ||
1261 | const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id; | ||
1262 | 1264 | ||
1263 | clk_en_a = mci_readl(host, CLKENA); | 1265 | /* |
1266 | * Low power mode will stop the card clock when idle. According to the | ||
1267 | * description of the CLKENA register we should disable low power mode | ||
1268 | * for SDIO cards if we need SDIO interrupts to work. | ||
1269 | */ | ||
1270 | if (mmc->caps & MMC_CAP_SDIO_IRQ) { | ||
1271 | const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id; | ||
1272 | u32 clk_en_a_old; | ||
1273 | u32 clk_en_a; | ||
1264 | 1274 | ||
1265 | if (clk_en_a & clken_low_pwr) { | 1275 | clk_en_a_old = mci_readl(host, CLKENA); |
1266 | mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr); | 1276 | |
1267 | mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | | 1277 | if (card->type == MMC_TYPE_SDIO || |
1268 | SDMMC_CMD_PRV_DAT_WAIT, 0); | 1278 | card->type == MMC_TYPE_SD_COMBO) { |
1279 | set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags); | ||
1280 | clk_en_a = clk_en_a_old & ~clken_low_pwr; | ||
1281 | } else { | ||
1282 | clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags); | ||
1283 | clk_en_a = clk_en_a_old | clken_low_pwr; | ||
1284 | } | ||
1285 | |||
1286 | if (clk_en_a != clk_en_a_old) { | ||
1287 | mci_writel(host, CLKENA, clk_en_a); | ||
1288 | mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | | ||
1289 | SDMMC_CMD_PRV_DAT_WAIT, 0); | ||
1290 | } | ||
1269 | } | 1291 | } |
1270 | } | 1292 | } |
1271 | 1293 | ||
@@ -1273,25 +1295,20 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) | |||
1273 | { | 1295 | { |
1274 | struct dw_mci_slot *slot = mmc_priv(mmc); | 1296 | struct dw_mci_slot *slot = mmc_priv(mmc); |
1275 | struct dw_mci *host = slot->host; | 1297 | struct dw_mci *host = slot->host; |
1298 | unsigned long irqflags; | ||
1276 | u32 int_mask; | 1299 | u32 int_mask; |
1277 | 1300 | ||
1301 | spin_lock_irqsave(&host->irq_lock, irqflags); | ||
1302 | |||
1278 | /* Enable/disable Slot Specific SDIO interrupt */ | 1303 | /* Enable/disable Slot Specific SDIO interrupt */ |
1279 | int_mask = mci_readl(host, INTMASK); | 1304 | int_mask = mci_readl(host, INTMASK); |
1280 | if (enb) { | 1305 | if (enb) |
1281 | /* | 1306 | int_mask |= SDMMC_INT_SDIO(slot->sdio_id); |
1282 | * Turn off low power mode if it was enabled. This is a bit of | 1307 | else |
1283 | * a heavy operation and we disable / enable IRQs a lot, so | 1308 | int_mask &= ~SDMMC_INT_SDIO(slot->sdio_id); |
1284 | * we'll leave low power mode disabled and it will get | 1309 | mci_writel(host, INTMASK, int_mask); |
1285 | * re-enabled again in dw_mci_setup_bus(). | ||
1286 | */ | ||
1287 | dw_mci_disable_low_power(slot); | ||
1288 | 1310 | ||
1289 | mci_writel(host, INTMASK, | 1311 | spin_unlock_irqrestore(&host->irq_lock, irqflags); |
1290 | (int_mask | SDMMC_INT_SDIO(slot->sdio_id))); | ||
1291 | } else { | ||
1292 | mci_writel(host, INTMASK, | ||
1293 | (int_mask & ~SDMMC_INT_SDIO(slot->sdio_id))); | ||
1294 | } | ||
1295 | } | 1312 | } |
1296 | 1313 | ||
1297 | static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) | 1314 | static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) |
@@ -1299,30 +1316,10 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1299 | struct dw_mci_slot *slot = mmc_priv(mmc); | 1316 | struct dw_mci_slot *slot = mmc_priv(mmc); |
1300 | struct dw_mci *host = slot->host; | 1317 | struct dw_mci *host = slot->host; |
1301 | const struct dw_mci_drv_data *drv_data = host->drv_data; | 1318 | const struct dw_mci_drv_data *drv_data = host->drv_data; |
1302 | struct dw_mci_tuning_data tuning_data; | ||
1303 | int err = -ENOSYS; | 1319 | int err = -ENOSYS; |
1304 | 1320 | ||
1305 | if (opcode == MMC_SEND_TUNING_BLOCK_HS200) { | ||
1306 | if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) { | ||
1307 | tuning_data.blk_pattern = tuning_blk_pattern_8bit; | ||
1308 | tuning_data.blksz = sizeof(tuning_blk_pattern_8bit); | ||
1309 | } else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) { | ||
1310 | tuning_data.blk_pattern = tuning_blk_pattern_4bit; | ||
1311 | tuning_data.blksz = sizeof(tuning_blk_pattern_4bit); | ||
1312 | } else { | ||
1313 | return -EINVAL; | ||
1314 | } | ||
1315 | } else if (opcode == MMC_SEND_TUNING_BLOCK) { | ||
1316 | tuning_data.blk_pattern = tuning_blk_pattern_4bit; | ||
1317 | tuning_data.blksz = sizeof(tuning_blk_pattern_4bit); | ||
1318 | } else { | ||
1319 | dev_err(host->dev, | ||
1320 | "Undefined command(%d) for tuning\n", opcode); | ||
1321 | return -EINVAL; | ||
1322 | } | ||
1323 | |||
1324 | if (drv_data && drv_data->execute_tuning) | 1321 | if (drv_data && drv_data->execute_tuning) |
1325 | err = drv_data->execute_tuning(slot, opcode, &tuning_data); | 1322 | err = drv_data->execute_tuning(slot); |
1326 | return err; | 1323 | return err; |
1327 | } | 1324 | } |
1328 | 1325 | ||
@@ -1337,7 +1334,7 @@ static const struct mmc_host_ops dw_mci_ops = { | |||
1337 | .execute_tuning = dw_mci_execute_tuning, | 1334 | .execute_tuning = dw_mci_execute_tuning, |
1338 | .card_busy = dw_mci_card_busy, | 1335 | .card_busy = dw_mci_card_busy, |
1339 | .start_signal_voltage_switch = dw_mci_switch_voltage, | 1336 | .start_signal_voltage_switch = dw_mci_switch_voltage, |
1340 | 1337 | .init_card = dw_mci_init_card, | |
1341 | }; | 1338 | }; |
1342 | 1339 | ||
1343 | static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) | 1340 | static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) |
@@ -2319,9 +2316,9 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
2319 | #ifdef CONFIG_MMC_DW_IDMAC | 2316 | #ifdef CONFIG_MMC_DW_IDMAC |
2320 | mmc->max_segs = host->ring_size; | 2317 | mmc->max_segs = host->ring_size; |
2321 | mmc->max_blk_size = 65536; | 2318 | mmc->max_blk_size = 65536; |
2322 | mmc->max_blk_count = host->ring_size; | ||
2323 | mmc->max_seg_size = 0x1000; | 2319 | mmc->max_seg_size = 0x1000; |
2324 | mmc->max_req_size = mmc->max_seg_size * mmc->max_blk_count; | 2320 | mmc->max_req_size = mmc->max_seg_size * host->ring_size; |
2321 | mmc->max_blk_count = mmc->max_req_size / 512; | ||
2325 | #else | 2322 | #else |
2326 | mmc->max_segs = 64; | 2323 | mmc->max_segs = 64; |
2327 | mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */ | 2324 | mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */ |
@@ -2533,10 +2530,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
2533 | u32 clock_frequency; | 2530 | u32 clock_frequency; |
2534 | 2531 | ||
2535 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 2532 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
2536 | if (!pdata) { | 2533 | if (!pdata) |
2537 | dev_err(dev, "could not allocate memory for pdata\n"); | ||
2538 | return ERR_PTR(-ENOMEM); | 2534 | return ERR_PTR(-ENOMEM); |
2539 | } | ||
2540 | 2535 | ||
2541 | /* find out number of slots supported */ | 2536 | /* find out number of slots supported */ |
2542 | if (of_property_read_u32(dev->of_node, "num-slots", | 2537 | if (of_property_read_u32(dev->of_node, "num-slots", |
@@ -2660,6 +2655,7 @@ int dw_mci_probe(struct dw_mci *host) | |||
2660 | host->quirks = host->pdata->quirks; | 2655 | host->quirks = host->pdata->quirks; |
2661 | 2656 | ||
2662 | spin_lock_init(&host->lock); | 2657 | spin_lock_init(&host->lock); |
2658 | spin_lock_init(&host->irq_lock); | ||
2663 | INIT_LIST_HEAD(&host->queue); | 2659 | INIT_LIST_HEAD(&host->queue); |
2664 | 2660 | ||
2665 | /* | 2661 | /* |
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 0d0f7a271d63..18c4afe683b8 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
@@ -244,15 +244,11 @@ struct dw_mci_slot { | |||
244 | unsigned long flags; | 244 | unsigned long flags; |
245 | #define DW_MMC_CARD_PRESENT 0 | 245 | #define DW_MMC_CARD_PRESENT 0 |
246 | #define DW_MMC_CARD_NEED_INIT 1 | 246 | #define DW_MMC_CARD_NEED_INIT 1 |
247 | #define DW_MMC_CARD_NO_LOW_PWR 2 | ||
247 | int id; | 248 | int id; |
248 | int sdio_id; | 249 | int sdio_id; |
249 | }; | 250 | }; |
250 | 251 | ||
251 | struct dw_mci_tuning_data { | ||
252 | const u8 *blk_pattern; | ||
253 | unsigned int blksz; | ||
254 | }; | ||
255 | |||
256 | /** | 252 | /** |
257 | * dw_mci driver data - dw-mshc implementation specific driver data. | 253 | * dw_mci driver data - dw-mshc implementation specific driver data. |
258 | * @caps: mmc subsystem specified capabilities of the controller(s). | 254 | * @caps: mmc subsystem specified capabilities of the controller(s). |
@@ -274,7 +270,6 @@ struct dw_mci_drv_data { | |||
274 | void (*prepare_command)(struct dw_mci *host, u32 *cmdr); | 270 | void (*prepare_command)(struct dw_mci *host, u32 *cmdr); |
275 | void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); | 271 | void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); |
276 | int (*parse_dt)(struct dw_mci *host); | 272 | int (*parse_dt)(struct dw_mci *host); |
277 | int (*execute_tuning)(struct dw_mci_slot *slot, u32 opcode, | 273 | int (*execute_tuning)(struct dw_mci_slot *slot); |
278 | struct dw_mci_tuning_data *tuning_data); | ||
279 | }; | 274 | }; |
280 | #endif /* _DW_MMC_H_ */ | 275 | #endif /* _DW_MMC_H_ */ |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 8232e9a02d40..7fe16194ebc8 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -430,7 +430,6 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) | |||
430 | static void mmci_dma_setup(struct mmci_host *host) | 430 | static void mmci_dma_setup(struct mmci_host *host) |
431 | { | 431 | { |
432 | const char *rxname, *txname; | 432 | const char *rxname, *txname; |
433 | dma_cap_mask_t mask; | ||
434 | struct variant_data *variant = host->variant; | 433 | struct variant_data *variant = host->variant; |
435 | 434 | ||
436 | host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "rx"); | 435 | host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "rx"); |
@@ -439,10 +438,6 @@ static void mmci_dma_setup(struct mmci_host *host) | |||
439 | /* initialize pre request cookie */ | 438 | /* initialize pre request cookie */ |
440 | host->next_data.cookie = 1; | 439 | host->next_data.cookie = 1; |
441 | 440 | ||
442 | /* Try to acquire a generic DMA engine slave channel */ | ||
443 | dma_cap_zero(mask); | ||
444 | dma_cap_set(DMA_SLAVE, mask); | ||
445 | |||
446 | /* | 441 | /* |
447 | * If only an RX channel is specified, the driver will | 442 | * If only an RX channel is specified, the driver will |
448 | * attempt to use it bidirectionally, however if it is | 443 | * attempt to use it bidirectionally, however if it is |
@@ -1739,10 +1734,10 @@ static int mmci_probe(struct amba_device *dev, | |||
1739 | 1734 | ||
1740 | pm_runtime_set_autosuspend_delay(&dev->dev, 50); | 1735 | pm_runtime_set_autosuspend_delay(&dev->dev, 50); |
1741 | pm_runtime_use_autosuspend(&dev->dev); | 1736 | pm_runtime_use_autosuspend(&dev->dev); |
1742 | pm_runtime_put(&dev->dev); | ||
1743 | 1737 | ||
1744 | mmc_add_host(mmc); | 1738 | mmc_add_host(mmc); |
1745 | 1739 | ||
1740 | pm_runtime_put(&dev->dev); | ||
1746 | return 0; | 1741 | return 0; |
1747 | 1742 | ||
1748 | clk_disable: | 1743 | clk_disable: |
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index f3e18d08e852..006f1862444b 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.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/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/errno.h> | ||
20 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
21 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
22 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
@@ -562,7 +563,6 @@ static int moxart_probe(struct platform_device *pdev) | |||
562 | struct dma_slave_config cfg; | 563 | struct dma_slave_config cfg; |
563 | struct clk *clk; | 564 | struct clk *clk; |
564 | void __iomem *reg_mmc; | 565 | void __iomem *reg_mmc; |
565 | dma_cap_mask_t mask; | ||
566 | int irq, ret; | 566 | int irq, ret; |
567 | u32 i; | 567 | u32 i; |
568 | 568 | ||
@@ -586,9 +586,8 @@ static int moxart_probe(struct platform_device *pdev) | |||
586 | goto out; | 586 | goto out; |
587 | } | 587 | } |
588 | 588 | ||
589 | clk = of_clk_get(node, 0); | 589 | clk = devm_clk_get(dev, NULL); |
590 | if (IS_ERR(clk)) { | 590 | if (IS_ERR(clk)) { |
591 | dev_err(dev, "of_clk_get failed\n"); | ||
592 | ret = PTR_ERR(clk); | 591 | ret = PTR_ERR(clk); |
593 | goto out; | 592 | goto out; |
594 | } | 593 | } |
@@ -599,10 +598,9 @@ static int moxart_probe(struct platform_device *pdev) | |||
599 | goto out; | 598 | goto out; |
600 | } | 599 | } |
601 | 600 | ||
602 | mmc_of_parse(mmc); | 601 | ret = mmc_of_parse(mmc); |
603 | 602 | if (ret) | |
604 | dma_cap_zero(mask); | 603 | goto out; |
605 | dma_cap_set(DMA_SLAVE, mask); | ||
606 | 604 | ||
607 | host = mmc_priv(mmc); | 605 | host = mmc_priv(mmc); |
608 | host->mmc = mmc; | 606 | host->mmc = mmc; |
@@ -611,8 +609,8 @@ static int moxart_probe(struct platform_device *pdev) | |||
611 | host->timeout = msecs_to_jiffies(1000); | 609 | host->timeout = msecs_to_jiffies(1000); |
612 | host->sysclk = clk_get_rate(clk); | 610 | host->sysclk = clk_get_rate(clk); |
613 | host->fifo_width = readl(host->base + REG_FEATURE) << 2; | 611 | host->fifo_width = readl(host->base + REG_FEATURE) << 2; |
614 | host->dma_chan_tx = of_dma_request_slave_channel(node, "tx"); | 612 | host->dma_chan_tx = dma_request_slave_channel_reason(dev, "tx"); |
615 | host->dma_chan_rx = of_dma_request_slave_channel(node, "rx"); | 613 | host->dma_chan_rx = dma_request_slave_channel_reason(dev, "rx"); |
616 | 614 | ||
617 | spin_lock_init(&host->lock); | 615 | spin_lock_init(&host->lock); |
618 | 616 | ||
@@ -622,6 +620,11 @@ static int moxart_probe(struct platform_device *pdev) | |||
622 | mmc->ocr_avail = 0xffff00; /* Support 2.0v - 3.6v power. */ | 620 | mmc->ocr_avail = 0xffff00; /* Support 2.0v - 3.6v power. */ |
623 | 621 | ||
624 | if (IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { | 622 | if (IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { |
623 | if (PTR_ERR(host->dma_chan_tx) == -EPROBE_DEFER || | ||
624 | PTR_ERR(host->dma_chan_rx) == -EPROBE_DEFER) { | ||
625 | ret = -EPROBE_DEFER; | ||
626 | goto out; | ||
627 | } | ||
625 | dev_dbg(dev, "PIO mode transfer enabled\n"); | 628 | dev_dbg(dev, "PIO mode transfer enabled\n"); |
626 | host->have_dma = false; | 629 | host->have_dma = false; |
627 | } else { | 630 | } else { |
@@ -700,9 +703,6 @@ static int moxart_remove(struct platform_device *pdev) | |||
700 | writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, | 703 | writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, |
701 | host->base + REG_CLOCK_CONTROL); | 704 | host->base + REG_CLOCK_CONTROL); |
702 | } | 705 | } |
703 | |||
704 | kfree(host); | ||
705 | |||
706 | return 0; | 706 | return 0; |
707 | } | 707 | } |
708 | 708 | ||
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index 4f8618f4522d..a448498e3af2 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
26 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
27 | #include <linux/mmc/slot-gpio.h> | 27 | #include <linux/mmc/slot-gpio.h> |
28 | #include <linux/pinctrl/consumer.h> | ||
29 | 28 | ||
30 | #include <asm/sizes.h> | 29 | #include <asm/sizes.h> |
31 | #include <asm/unaligned.h> | 30 | #include <asm/unaligned.h> |
@@ -704,7 +703,6 @@ static int mvsd_probe(struct platform_device *pdev) | |||
704 | const struct mbus_dram_target_info *dram; | 703 | const struct mbus_dram_target_info *dram; |
705 | struct resource *r; | 704 | struct resource *r; |
706 | int ret, irq; | 705 | int ret, irq; |
707 | struct pinctrl *pinctrl; | ||
708 | 706 | ||
709 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 707 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
710 | irq = platform_get_irq(pdev, 0); | 708 | irq = platform_get_irq(pdev, 0); |
@@ -721,10 +719,6 @@ static int mvsd_probe(struct platform_device *pdev) | |||
721 | host->mmc = mmc; | 719 | host->mmc = mmc; |
722 | host->dev = &pdev->dev; | 720 | host->dev = &pdev->dev; |
723 | 721 | ||
724 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||
725 | if (IS_ERR(pinctrl)) | ||
726 | dev_warn(&pdev->dev, "no pins associated\n"); | ||
727 | |||
728 | /* | 722 | /* |
729 | * Some non-DT platforms do not pass a clock, and the clock | 723 | * Some non-DT platforms do not pass a clock, and the clock |
730 | * frequency is passed through platform_data. On DT platforms, | 724 | * frequency is passed through platform_data. On DT platforms, |
@@ -828,8 +822,6 @@ static int mvsd_probe(struct platform_device *pdev) | |||
828 | 822 | ||
829 | out: | 823 | out: |
830 | if (mmc) { | 824 | if (mmc) { |
831 | mmc_gpio_free_cd(mmc); | ||
832 | mmc_gpio_free_ro(mmc); | ||
833 | if (!IS_ERR(host->clk)) | 825 | if (!IS_ERR(host->clk)) |
834 | clk_disable_unprepare(host->clk); | 826 | clk_disable_unprepare(host->clk); |
835 | mmc_free_host(mmc); | 827 | mmc_free_host(mmc); |
@@ -844,8 +836,6 @@ static int mvsd_remove(struct platform_device *pdev) | |||
844 | 836 | ||
845 | struct mvsd_host *host = mmc_priv(mmc); | 837 | struct mvsd_host *host = mmc_priv(mmc); |
846 | 838 | ||
847 | mmc_gpio_free_cd(mmc); | ||
848 | mmc_gpio_free_ro(mmc); | ||
849 | mmc_remove_host(mmc); | 839 | mmc_remove_host(mmc); |
850 | del_timer_sync(&host->timer); | 840 | del_timer_sync(&host->timer); |
851 | mvsd_power_down(host); | 841 | mvsd_power_down(host); |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 60c4ca97a727..a82411a2c024 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -677,8 +677,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
677 | return 0; | 677 | return 0; |
678 | 678 | ||
679 | out_free_dma: | 679 | out_free_dma: |
680 | if (ssp->dmach) | 680 | dma_release_channel(ssp->dmach); |
681 | dma_release_channel(ssp->dmach); | ||
682 | out_clk_disable: | 681 | out_clk_disable: |
683 | clk_disable_unprepare(ssp->clk); | 682 | clk_disable_unprepare(ssp->clk); |
684 | out_mmc_free: | 683 | out_mmc_free: |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 7c71dcdcba8b..f84cfb01716d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/mmc/host.h> | 36 | #include <linux/mmc/host.h> |
37 | #include <linux/mmc/core.h> | 37 | #include <linux/mmc/core.h> |
38 | #include <linux/mmc/mmc.h> | 38 | #include <linux/mmc/mmc.h> |
39 | #include <linux/mmc/slot-gpio.h> | ||
39 | #include <linux/io.h> | 40 | #include <linux/io.h> |
40 | #include <linux/irq.h> | 41 | #include <linux/irq.h> |
41 | #include <linux/gpio.h> | 42 | #include <linux/gpio.h> |
@@ -251,55 +252,24 @@ static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); | |||
251 | static int omap_hsmmc_card_detect(struct device *dev) | 252 | static int omap_hsmmc_card_detect(struct device *dev) |
252 | { | 253 | { |
253 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 254 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
254 | struct omap_hsmmc_platform_data *mmc = host->pdata; | ||
255 | 255 | ||
256 | /* NOTE: assumes card detect signal is active-low */ | 256 | return mmc_gpio_get_cd(host->mmc); |
257 | return !gpio_get_value_cansleep(mmc->switch_pin); | ||
258 | } | 257 | } |
259 | 258 | ||
260 | static int omap_hsmmc_get_wp(struct device *dev) | 259 | static int omap_hsmmc_get_wp(struct device *dev) |
261 | { | 260 | { |
262 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 261 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
263 | struct omap_hsmmc_platform_data *mmc = host->pdata; | ||
264 | 262 | ||
265 | /* NOTE: assumes write protect signal is active-high */ | 263 | return mmc_gpio_get_ro(host->mmc); |
266 | return gpio_get_value_cansleep(mmc->gpio_wp); | ||
267 | } | 264 | } |
268 | 265 | ||
269 | static int omap_hsmmc_get_cover_state(struct device *dev) | 266 | static int omap_hsmmc_get_cover_state(struct device *dev) |
270 | { | 267 | { |
271 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 268 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
272 | struct omap_hsmmc_platform_data *mmc = host->pdata; | ||
273 | 269 | ||
274 | /* NOTE: assumes card detect signal is active-low */ | 270 | return mmc_gpio_get_cd(host->mmc); |
275 | return !gpio_get_value_cansleep(mmc->switch_pin); | ||
276 | } | 271 | } |
277 | 272 | ||
278 | #ifdef CONFIG_PM | ||
279 | |||
280 | static int omap_hsmmc_suspend_cdirq(struct device *dev) | ||
281 | { | ||
282 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | ||
283 | |||
284 | disable_irq(host->card_detect_irq); | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int omap_hsmmc_resume_cdirq(struct device *dev) | ||
289 | { | ||
290 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | ||
291 | |||
292 | enable_irq(host->card_detect_irq); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | #else | ||
297 | |||
298 | #define omap_hsmmc_suspend_cdirq NULL | ||
299 | #define omap_hsmmc_resume_cdirq NULL | ||
300 | |||
301 | #endif | ||
302 | |||
303 | #ifdef CONFIG_REGULATOR | 273 | #ifdef CONFIG_REGULATOR |
304 | 274 | ||
305 | static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) | 275 | static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd) |
@@ -464,7 +434,10 @@ static inline int omap_hsmmc_have_reg(void) | |||
464 | 434 | ||
465 | #endif | 435 | #endif |
466 | 436 | ||
467 | static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host, | 437 | static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id); |
438 | |||
439 | static int omap_hsmmc_gpio_init(struct mmc_host *mmc, | ||
440 | struct omap_hsmmc_host *host, | ||
468 | struct omap_hsmmc_platform_data *pdata) | 441 | struct omap_hsmmc_platform_data *pdata) |
469 | { | 442 | { |
470 | int ret; | 443 | int ret; |
@@ -477,46 +450,24 @@ static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host, | |||
477 | host->card_detect = omap_hsmmc_card_detect; | 450 | host->card_detect = omap_hsmmc_card_detect; |
478 | host->card_detect_irq = | 451 | host->card_detect_irq = |
479 | gpio_to_irq(pdata->switch_pin); | 452 | gpio_to_irq(pdata->switch_pin); |
480 | ret = gpio_request(pdata->switch_pin, "mmc_cd"); | 453 | mmc_gpio_set_cd_isr(mmc, omap_hsmmc_detect); |
454 | ret = mmc_gpio_request_cd(mmc, pdata->switch_pin, 0); | ||
481 | if (ret) | 455 | if (ret) |
482 | return ret; | 456 | return ret; |
483 | ret = gpio_direction_input(pdata->switch_pin); | ||
484 | if (ret) | ||
485 | goto err_free_sp; | ||
486 | } else { | 457 | } else { |
487 | pdata->switch_pin = -EINVAL; | 458 | pdata->switch_pin = -EINVAL; |
488 | } | 459 | } |
489 | 460 | ||
490 | if (gpio_is_valid(pdata->gpio_wp)) { | 461 | if (gpio_is_valid(pdata->gpio_wp)) { |
491 | host->get_ro = omap_hsmmc_get_wp; | 462 | host->get_ro = omap_hsmmc_get_wp; |
492 | ret = gpio_request(pdata->gpio_wp, "mmc_wp"); | 463 | ret = mmc_gpio_request_ro(mmc, pdata->gpio_wp); |
493 | if (ret) | ||
494 | goto err_free_cd; | ||
495 | ret = gpio_direction_input(pdata->gpio_wp); | ||
496 | if (ret) | 464 | if (ret) |
497 | goto err_free_wp; | 465 | return ret; |
498 | } else { | 466 | } else { |
499 | pdata->gpio_wp = -EINVAL; | 467 | pdata->gpio_wp = -EINVAL; |
500 | } | 468 | } |
501 | 469 | ||
502 | return 0; | 470 | return 0; |
503 | |||
504 | err_free_wp: | ||
505 | gpio_free(pdata->gpio_wp); | ||
506 | err_free_cd: | ||
507 | if (gpio_is_valid(pdata->switch_pin)) | ||
508 | err_free_sp: | ||
509 | gpio_free(pdata->switch_pin); | ||
510 | return ret; | ||
511 | } | ||
512 | |||
513 | static void omap_hsmmc_gpio_free(struct omap_hsmmc_host *host, | ||
514 | struct omap_hsmmc_platform_data *pdata) | ||
515 | { | ||
516 | if (gpio_is_valid(pdata->gpio_wp)) | ||
517 | gpio_free(pdata->gpio_wp); | ||
518 | if (gpio_is_valid(pdata->switch_pin)) | ||
519 | gpio_free(pdata->switch_pin); | ||
520 | } | 471 | } |
521 | 472 | ||
522 | /* | 473 | /* |
@@ -1978,13 +1929,6 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1978 | { | 1929 | { |
1979 | struct omap_hsmmc_platform_data *pdata; | 1930 | struct omap_hsmmc_platform_data *pdata; |
1980 | struct device_node *np = dev->of_node; | 1931 | struct device_node *np = dev->of_node; |
1981 | u32 bus_width, max_freq; | ||
1982 | int cd_gpio, wp_gpio; | ||
1983 | |||
1984 | cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); | ||
1985 | wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); | ||
1986 | if (cd_gpio == -EPROBE_DEFER || wp_gpio == -EPROBE_DEFER) | ||
1987 | return ERR_PTR(-EPROBE_DEFER); | ||
1988 | 1932 | ||
1989 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 1933 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
1990 | if (!pdata) | 1934 | if (!pdata) |
@@ -1993,34 +1937,20 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1993 | if (of_find_property(np, "ti,dual-volt", NULL)) | 1937 | if (of_find_property(np, "ti,dual-volt", NULL)) |
1994 | pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; | 1938 | pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; |
1995 | 1939 | ||
1996 | pdata->switch_pin = cd_gpio; | 1940 | pdata->switch_pin = -EINVAL; |
1997 | pdata->gpio_wp = wp_gpio; | 1941 | pdata->gpio_wp = -EINVAL; |
1998 | 1942 | ||
1999 | if (of_find_property(np, "ti,non-removable", NULL)) { | 1943 | if (of_find_property(np, "ti,non-removable", NULL)) { |
2000 | pdata->nonremovable = true; | 1944 | pdata->nonremovable = true; |
2001 | pdata->no_regulator_off_init = true; | 1945 | pdata->no_regulator_off_init = true; |
2002 | } | 1946 | } |
2003 | of_property_read_u32(np, "bus-width", &bus_width); | ||
2004 | if (bus_width == 4) | ||
2005 | pdata->caps |= MMC_CAP_4_BIT_DATA; | ||
2006 | else if (bus_width == 8) | ||
2007 | pdata->caps |= MMC_CAP_8_BIT_DATA; | ||
2008 | 1947 | ||
2009 | if (of_find_property(np, "ti,needs-special-reset", NULL)) | 1948 | if (of_find_property(np, "ti,needs-special-reset", NULL)) |
2010 | pdata->features |= HSMMC_HAS_UPDATED_RESET; | 1949 | pdata->features |= HSMMC_HAS_UPDATED_RESET; |
2011 | 1950 | ||
2012 | if (!of_property_read_u32(np, "max-frequency", &max_freq)) | ||
2013 | pdata->max_freq = max_freq; | ||
2014 | |||
2015 | if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) | 1951 | if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) |
2016 | pdata->features |= HSMMC_HAS_HSPE_SUPPORT; | 1952 | pdata->features |= HSMMC_HAS_HSPE_SUPPORT; |
2017 | 1953 | ||
2018 | if (of_find_property(np, "keep-power-in-suspend", NULL)) | ||
2019 | pdata->pm_caps |= MMC_PM_KEEP_POWER; | ||
2020 | |||
2021 | if (of_find_property(np, "enable-sdio-wakeup", NULL)) | ||
2022 | pdata->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; | ||
2023 | |||
2024 | return pdata; | 1954 | return pdata; |
2025 | } | 1955 | } |
2026 | #else | 1956 | #else |
@@ -2078,6 +2008,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2078 | goto err; | 2008 | goto err; |
2079 | } | 2009 | } |
2080 | 2010 | ||
2011 | ret = mmc_of_parse(mmc); | ||
2012 | if (ret) | ||
2013 | goto err1; | ||
2014 | |||
2081 | host = mmc_priv(mmc); | 2015 | host = mmc_priv(mmc); |
2082 | host->mmc = mmc; | 2016 | host->mmc = mmc; |
2083 | host->pdata = pdata; | 2017 | host->pdata = pdata; |
@@ -2091,7 +2025,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2091 | host->next_data.cookie = 1; | 2025 | host->next_data.cookie = 1; |
2092 | host->pbias_enabled = 0; | 2026 | host->pbias_enabled = 0; |
2093 | 2027 | ||
2094 | ret = omap_hsmmc_gpio_init(host, pdata); | 2028 | ret = omap_hsmmc_gpio_init(mmc, host, pdata); |
2095 | if (ret) | 2029 | if (ret) |
2096 | goto err_gpio; | 2030 | goto err_gpio; |
2097 | 2031 | ||
@@ -2106,7 +2040,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2106 | 2040 | ||
2107 | if (pdata->max_freq > 0) | 2041 | if (pdata->max_freq > 0) |
2108 | mmc->f_max = pdata->max_freq; | 2042 | mmc->f_max = pdata->max_freq; |
2109 | else | 2043 | else if (mmc->f_max == 0) |
2110 | mmc->f_max = OMAP_MMC_MAX_CLOCK; | 2044 | mmc->f_max = OMAP_MMC_MAX_CLOCK; |
2111 | 2045 | ||
2112 | spin_lock_init(&host->irq_lock); | 2046 | spin_lock_init(&host->irq_lock); |
@@ -2160,7 +2094,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2160 | if (mmc_pdata(host)->nonremovable) | 2094 | if (mmc_pdata(host)->nonremovable) |
2161 | mmc->caps |= MMC_CAP_NONREMOVABLE; | 2095 | mmc->caps |= MMC_CAP_NONREMOVABLE; |
2162 | 2096 | ||
2163 | mmc->pm_caps = mmc_pdata(host)->pm_caps; | 2097 | mmc->pm_caps |= mmc_pdata(host)->pm_caps; |
2164 | 2098 | ||
2165 | omap_hsmmc_conf_bus_power(host); | 2099 | omap_hsmmc_conf_bus_power(host); |
2166 | 2100 | ||
@@ -2222,22 +2156,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2222 | 2156 | ||
2223 | mmc->ocr_avail = mmc_pdata(host)->ocr_mask; | 2157 | mmc->ocr_avail = mmc_pdata(host)->ocr_mask; |
2224 | 2158 | ||
2225 | /* Request IRQ for card detect */ | ||
2226 | if (host->card_detect_irq) { | ||
2227 | ret = devm_request_threaded_irq(&pdev->dev, | ||
2228 | host->card_detect_irq, | ||
2229 | NULL, omap_hsmmc_detect, | ||
2230 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
2231 | mmc_hostname(mmc), host); | ||
2232 | if (ret) { | ||
2233 | dev_err(mmc_dev(host->mmc), | ||
2234 | "Unable to grab MMC CD IRQ\n"); | ||
2235 | goto err_irq_cd; | ||
2236 | } | ||
2237 | host->suspend = omap_hsmmc_suspend_cdirq; | ||
2238 | host->resume = omap_hsmmc_resume_cdirq; | ||
2239 | } | ||
2240 | |||
2241 | omap_hsmmc_disable_irq(host); | 2159 | omap_hsmmc_disable_irq(host); |
2242 | 2160 | ||
2243 | /* | 2161 | /* |
@@ -2276,7 +2194,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) | |||
2276 | 2194 | ||
2277 | err_slot_name: | 2195 | err_slot_name: |
2278 | mmc_remove_host(mmc); | 2196 | mmc_remove_host(mmc); |
2279 | err_irq_cd: | ||
2280 | if (host->use_reg) | 2197 | if (host->use_reg) |
2281 | omap_hsmmc_reg_put(host); | 2198 | omap_hsmmc_reg_put(host); |
2282 | err_irq: | 2199 | err_irq: |
@@ -2289,7 +2206,6 @@ err_irq: | |||
2289 | if (host->dbclk) | 2206 | if (host->dbclk) |
2290 | clk_disable_unprepare(host->dbclk); | 2207 | clk_disable_unprepare(host->dbclk); |
2291 | err1: | 2208 | err1: |
2292 | omap_hsmmc_gpio_free(host, pdata); | ||
2293 | err_gpio: | 2209 | err_gpio: |
2294 | mmc_free_host(mmc); | 2210 | mmc_free_host(mmc); |
2295 | err: | 2211 | err: |
@@ -2315,32 +2231,12 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
2315 | if (host->dbclk) | 2231 | if (host->dbclk) |
2316 | clk_disable_unprepare(host->dbclk); | 2232 | clk_disable_unprepare(host->dbclk); |
2317 | 2233 | ||
2318 | omap_hsmmc_gpio_free(host, host->pdata); | ||
2319 | mmc_free_host(host->mmc); | 2234 | mmc_free_host(host->mmc); |
2320 | 2235 | ||
2321 | return 0; | 2236 | return 0; |
2322 | } | 2237 | } |
2323 | 2238 | ||
2324 | #ifdef CONFIG_PM | 2239 | #ifdef CONFIG_PM |
2325 | static int omap_hsmmc_prepare(struct device *dev) | ||
2326 | { | ||
2327 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | ||
2328 | |||
2329 | if (host->suspend) | ||
2330 | return host->suspend(dev); | ||
2331 | |||
2332 | return 0; | ||
2333 | } | ||
2334 | |||
2335 | static void omap_hsmmc_complete(struct device *dev) | ||
2336 | { | ||
2337 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | ||
2338 | |||
2339 | if (host->resume) | ||
2340 | host->resume(dev); | ||
2341 | |||
2342 | } | ||
2343 | |||
2344 | static int omap_hsmmc_suspend(struct device *dev) | 2240 | static int omap_hsmmc_suspend(struct device *dev) |
2345 | { | 2241 | { |
2346 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | 2242 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); |
@@ -2398,8 +2294,6 @@ static int omap_hsmmc_resume(struct device *dev) | |||
2398 | } | 2294 | } |
2399 | 2295 | ||
2400 | #else | 2296 | #else |
2401 | #define omap_hsmmc_prepare NULL | ||
2402 | #define omap_hsmmc_complete NULL | ||
2403 | #define omap_hsmmc_suspend NULL | 2297 | #define omap_hsmmc_suspend NULL |
2404 | #define omap_hsmmc_resume NULL | 2298 | #define omap_hsmmc_resume NULL |
2405 | #endif | 2299 | #endif |
@@ -2484,8 +2378,6 @@ static int omap_hsmmc_runtime_resume(struct device *dev) | |||
2484 | static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { | 2378 | static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { |
2485 | .suspend = omap_hsmmc_suspend, | 2379 | .suspend = omap_hsmmc_suspend, |
2486 | .resume = omap_hsmmc_resume, | 2380 | .resume = omap_hsmmc_resume, |
2487 | .prepare = omap_hsmmc_prepare, | ||
2488 | .complete = omap_hsmmc_complete, | ||
2489 | .runtime_suspend = omap_hsmmc_runtime_suspend, | 2381 | .runtime_suspend = omap_hsmmc_runtime_suspend, |
2490 | .runtime_resume = omap_hsmmc_runtime_resume, | 2382 | .runtime_resume = omap_hsmmc_runtime_resume, |
2491 | }; | 2383 | }; |
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index c70b602f8f1e..1d3d6c4bfdc6 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | #include <linux/mmc/mmc.h> | 29 | #include <linux/mmc/mmc.h> |
30 | #include <linux/mmc/sd.h> | 30 | #include <linux/mmc/sd.h> |
31 | #include <linux/mmc/sdio.h> | ||
31 | #include <linux/mmc/card.h> | 32 | #include <linux/mmc/card.h> |
32 | #include <linux/mfd/rtsx_pci.h> | 33 | #include <linux/mfd/rtsx_pci.h> |
33 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
@@ -53,9 +54,9 @@ struct realtek_pci_sdmmc { | |||
53 | #define SDMMC_POWER_ON 1 | 54 | #define SDMMC_POWER_ON 1 |
54 | #define SDMMC_POWER_OFF 0 | 55 | #define SDMMC_POWER_OFF 0 |
55 | 56 | ||
56 | unsigned int sg_count; | 57 | int sg_count; |
57 | s32 cookie; | 58 | s32 cookie; |
58 | unsigned int cookie_sg_count; | 59 | int cookie_sg_count; |
59 | bool using_cookie; | 60 | bool using_cookie; |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -71,30 +72,83 @@ static inline void sd_clear_error(struct realtek_pci_sdmmc *host) | |||
71 | } | 72 | } |
72 | 73 | ||
73 | #ifdef DEBUG | 74 | #ifdef DEBUG |
74 | static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) | 75 | static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end) |
75 | { | 76 | { |
76 | struct rtsx_pcr *pcr = host->pcr; | 77 | u16 len = end - start + 1; |
77 | u16 i; | 78 | int i; |
78 | u8 *ptr; | 79 | u8 data[8]; |
80 | |||
81 | for (i = 0; i < len; i += 8) { | ||
82 | int j; | ||
83 | int n = min(8, len - i); | ||
84 | |||
85 | memset(&data, 0, sizeof(data)); | ||
86 | for (j = 0; j < n; j++) | ||
87 | rtsx_pci_read_register(host->pcr, start + i + j, | ||
88 | data + j); | ||
89 | dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n", | ||
90 | start + i, n, data); | ||
91 | } | ||
92 | } | ||
79 | 93 | ||
80 | /* Print SD host internal registers */ | 94 | static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) |
81 | rtsx_pci_init_cmd(pcr); | 95 | { |
82 | for (i = 0xFDA0; i <= 0xFDAE; i++) | 96 | dump_reg_range(host, 0xFDA0, 0xFDB3); |
83 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); | 97 | dump_reg_range(host, 0xFD52, 0xFD69); |
84 | for (i = 0xFD52; i <= 0xFD69; i++) | ||
85 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); | ||
86 | rtsx_pci_send_cmd(pcr, 100); | ||
87 | |||
88 | ptr = rtsx_pci_get_cmd_data(pcr); | ||
89 | for (i = 0xFDA0; i <= 0xFDAE; i++) | ||
90 | dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); | ||
91 | for (i = 0xFD52; i <= 0xFD69; i++) | ||
92 | dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); | ||
93 | } | 98 | } |
94 | #else | 99 | #else |
95 | #define sd_print_debug_regs(host) | 100 | #define sd_print_debug_regs(host) |
96 | #endif /* DEBUG */ | 101 | #endif /* DEBUG */ |
97 | 102 | ||
103 | static inline int sd_get_cd_int(struct realtek_pci_sdmmc *host) | ||
104 | { | ||
105 | return rtsx_pci_readl(host->pcr, RTSX_BIPR) & SD_EXIST; | ||
106 | } | ||
107 | |||
108 | static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd) | ||
109 | { | ||
110 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, | ||
111 | SD_CMD_START | cmd->opcode); | ||
112 | rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg); | ||
113 | } | ||
114 | |||
115 | static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz) | ||
116 | { | ||
117 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks); | ||
118 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8); | ||
119 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz); | ||
120 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8); | ||
121 | } | ||
122 | |||
123 | static int sd_response_type(struct mmc_command *cmd) | ||
124 | { | ||
125 | switch (mmc_resp_type(cmd)) { | ||
126 | case MMC_RSP_NONE: | ||
127 | return SD_RSP_TYPE_R0; | ||
128 | case MMC_RSP_R1: | ||
129 | return SD_RSP_TYPE_R1; | ||
130 | case MMC_RSP_R1 & ~MMC_RSP_CRC: | ||
131 | return SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7; | ||
132 | case MMC_RSP_R1B: | ||
133 | return SD_RSP_TYPE_R1b; | ||
134 | case MMC_RSP_R2: | ||
135 | return SD_RSP_TYPE_R2; | ||
136 | case MMC_RSP_R3: | ||
137 | return SD_RSP_TYPE_R3; | ||
138 | default: | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static int sd_status_index(int resp_type) | ||
144 | { | ||
145 | if (resp_type == SD_RSP_TYPE_R0) | ||
146 | return 0; | ||
147 | else if (resp_type == SD_RSP_TYPE_R2) | ||
148 | return 16; | ||
149 | |||
150 | return 5; | ||
151 | } | ||
98 | /* | 152 | /* |
99 | * sd_pre_dma_transfer - do dma_map_sg() or using cookie | 153 | * sd_pre_dma_transfer - do dma_map_sg() or using cookie |
100 | * | 154 | * |
@@ -166,123 +220,6 @@ static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | |||
166 | data->host_cookie = 0; | 220 | data->host_cookie = 0; |
167 | } | 221 | } |
168 | 222 | ||
169 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | ||
170 | u8 *buf, int buf_len, int timeout) | ||
171 | { | ||
172 | struct rtsx_pcr *pcr = host->pcr; | ||
173 | int err, i; | ||
174 | u8 trans_mode; | ||
175 | |||
176 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40); | ||
177 | |||
178 | if (!buf) | ||
179 | buf_len = 0; | ||
180 | |||
181 | if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK) | ||
182 | trans_mode = SD_TM_AUTO_TUNING; | ||
183 | else | ||
184 | trans_mode = SD_TM_NORMAL_READ; | ||
185 | |||
186 | rtsx_pci_init_cmd(pcr); | ||
187 | |||
188 | for (i = 0; i < 5; i++) | ||
189 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]); | ||
190 | |||
191 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); | ||
192 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, | ||
193 | 0xFF, (u8)(byte_cnt >> 8)); | ||
194 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); | ||
195 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); | ||
196 | |||
197 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
198 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
199 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | ||
200 | if (trans_mode != SD_TM_AUTO_TUNING) | ||
201 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
202 | CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); | ||
203 | |||
204 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, | ||
205 | 0xFF, trans_mode | SD_TRANSFER_START); | ||
206 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
207 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
208 | |||
209 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
210 | if (err < 0) { | ||
211 | sd_print_debug_regs(host); | ||
212 | dev_dbg(sdmmc_dev(host), | ||
213 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
214 | return err; | ||
215 | } | ||
216 | |||
217 | if (buf && buf_len) { | ||
218 | err = rtsx_pci_read_ppbuf(pcr, buf, buf_len); | ||
219 | if (err < 0) { | ||
220 | dev_dbg(sdmmc_dev(host), | ||
221 | "rtsx_pci_read_ppbuf fail (err = %d)\n", err); | ||
222 | return err; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | ||
230 | u8 *buf, int buf_len, int timeout) | ||
231 | { | ||
232 | struct rtsx_pcr *pcr = host->pcr; | ||
233 | int err, i; | ||
234 | u8 trans_mode; | ||
235 | |||
236 | if (!buf) | ||
237 | buf_len = 0; | ||
238 | |||
239 | if (buf && buf_len) { | ||
240 | err = rtsx_pci_write_ppbuf(pcr, buf, buf_len); | ||
241 | if (err < 0) { | ||
242 | dev_dbg(sdmmc_dev(host), | ||
243 | "rtsx_pci_write_ppbuf fail (err = %d)\n", err); | ||
244 | return err; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3; | ||
249 | rtsx_pci_init_cmd(pcr); | ||
250 | |||
251 | if (cmd) { | ||
252 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__, | ||
253 | cmd[0] - 0x40); | ||
254 | |||
255 | for (i = 0; i < 5; i++) | ||
256 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
257 | SD_CMD0 + i, 0xFF, cmd[i]); | ||
258 | } | ||
259 | |||
260 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); | ||
261 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, | ||
262 | 0xFF, (u8)(byte_cnt >> 8)); | ||
263 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); | ||
264 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); | ||
265 | |||
266 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
267 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
268 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | ||
269 | |||
270 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | ||
271 | trans_mode | SD_TRANSFER_START); | ||
272 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
273 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
274 | |||
275 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
276 | if (err < 0) { | ||
277 | sd_print_debug_regs(host); | ||
278 | dev_dbg(sdmmc_dev(host), | ||
279 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
280 | return err; | ||
281 | } | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | 223 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, |
287 | struct mmc_command *cmd) | 224 | struct mmc_command *cmd) |
288 | { | 225 | { |
@@ -293,47 +230,18 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
293 | int timeout = 100; | 230 | int timeout = 100; |
294 | int i; | 231 | int i; |
295 | u8 *ptr; | 232 | u8 *ptr; |
296 | int stat_idx = 0; | 233 | int rsp_type; |
297 | u8 rsp_type; | 234 | int stat_idx; |
298 | int rsp_len = 5; | ||
299 | bool clock_toggled = false; | 235 | bool clock_toggled = false; |
300 | 236 | ||
301 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | 237 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
302 | __func__, cmd_idx, arg); | 238 | __func__, cmd_idx, arg); |
303 | 239 | ||
304 | /* Response type: | 240 | rsp_type = sd_response_type(cmd); |
305 | * R0 | 241 | if (rsp_type < 0) |
306 | * R1, R5, R6, R7 | ||
307 | * R1b | ||
308 | * R2 | ||
309 | * R3, R4 | ||
310 | */ | ||
311 | switch (mmc_resp_type(cmd)) { | ||
312 | case MMC_RSP_NONE: | ||
313 | rsp_type = SD_RSP_TYPE_R0; | ||
314 | rsp_len = 0; | ||
315 | break; | ||
316 | case MMC_RSP_R1: | ||
317 | rsp_type = SD_RSP_TYPE_R1; | ||
318 | break; | ||
319 | case MMC_RSP_R1 & ~MMC_RSP_CRC: | ||
320 | rsp_type = SD_RSP_TYPE_R1 | SD_NO_CHECK_CRC7; | ||
321 | break; | ||
322 | case MMC_RSP_R1B: | ||
323 | rsp_type = SD_RSP_TYPE_R1b; | ||
324 | break; | ||
325 | case MMC_RSP_R2: | ||
326 | rsp_type = SD_RSP_TYPE_R2; | ||
327 | rsp_len = 16; | ||
328 | break; | ||
329 | case MMC_RSP_R3: | ||
330 | rsp_type = SD_RSP_TYPE_R3; | ||
331 | break; | ||
332 | default: | ||
333 | dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n"); | ||
334 | err = -EINVAL; | ||
335 | goto out; | 242 | goto out; |
336 | } | 243 | |
244 | stat_idx = sd_status_index(rsp_type); | ||
337 | 245 | ||
338 | if (rsp_type == SD_RSP_TYPE_R1b) | 246 | if (rsp_type == SD_RSP_TYPE_R1b) |
339 | timeout = 3000; | 247 | timeout = 3000; |
@@ -348,13 +256,7 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
348 | } | 256 | } |
349 | 257 | ||
350 | rtsx_pci_init_cmd(pcr); | 258 | rtsx_pci_init_cmd(pcr); |
351 | 259 | sd_cmd_set_sd_cmd(pcr, cmd); | |
352 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); | ||
353 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24)); | ||
354 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16)); | ||
355 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8)); | ||
356 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg); | ||
357 | |||
358 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); | 260 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); |
359 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, | 261 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
360 | 0x01, PINGPONG_BUFFER); | 262 | 0x01, PINGPONG_BUFFER); |
@@ -368,12 +270,10 @@ static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, | |||
368 | /* Read data from ping-pong buffer */ | 270 | /* Read data from ping-pong buffer */ |
369 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) | 271 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) |
370 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 272 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
371 | stat_idx = 16; | ||
372 | } else if (rsp_type != SD_RSP_TYPE_R0) { | 273 | } else if (rsp_type != SD_RSP_TYPE_R0) { |
373 | /* Read data from SD_CMDx registers */ | 274 | /* Read data from SD_CMDx registers */ |
374 | for (i = SD_CMD0; i <= SD_CMD4; i++) | 275 | for (i = SD_CMD0; i <= SD_CMD4; i++) |
375 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 276 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
376 | stat_idx = 5; | ||
377 | } | 277 | } |
378 | 278 | ||
379 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); | 279 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); |
@@ -438,71 +338,213 @@ out: | |||
438 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); | 338 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); |
439 | } | 339 | } |
440 | 340 | ||
441 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | 341 | static int sd_read_data(struct realtek_pci_sdmmc *host, struct mmc_command *cmd, |
342 | u16 byte_cnt, u8 *buf, int buf_len, int timeout) | ||
343 | { | ||
344 | struct rtsx_pcr *pcr = host->pcr; | ||
345 | int err; | ||
346 | u8 trans_mode; | ||
347 | |||
348 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
349 | __func__, cmd->opcode, cmd->arg); | ||
350 | |||
351 | if (!buf) | ||
352 | buf_len = 0; | ||
353 | |||
354 | if (cmd->opcode == MMC_SEND_TUNING_BLOCK) | ||
355 | trans_mode = SD_TM_AUTO_TUNING; | ||
356 | else | ||
357 | trans_mode = SD_TM_NORMAL_READ; | ||
358 | |||
359 | rtsx_pci_init_cmd(pcr); | ||
360 | sd_cmd_set_sd_cmd(pcr, cmd); | ||
361 | sd_cmd_set_data_len(pcr, 1, byte_cnt); | ||
362 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
363 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
364 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); | ||
365 | if (trans_mode != SD_TM_AUTO_TUNING) | ||
366 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
367 | CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); | ||
368 | |||
369 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, | ||
370 | 0xFF, trans_mode | SD_TRANSFER_START); | ||
371 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
372 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
373 | |||
374 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
375 | if (err < 0) { | ||
376 | sd_print_debug_regs(host); | ||
377 | dev_dbg(sdmmc_dev(host), | ||
378 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
379 | return err; | ||
380 | } | ||
381 | |||
382 | if (buf && buf_len) { | ||
383 | err = rtsx_pci_read_ppbuf(pcr, buf, buf_len); | ||
384 | if (err < 0) { | ||
385 | dev_dbg(sdmmc_dev(host), | ||
386 | "rtsx_pci_read_ppbuf fail (err = %d)\n", err); | ||
387 | return err; | ||
388 | } | ||
389 | } | ||
390 | |||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int sd_write_data(struct realtek_pci_sdmmc *host, | ||
395 | struct mmc_command *cmd, u16 byte_cnt, u8 *buf, int buf_len, | ||
396 | int timeout) | ||
397 | { | ||
398 | struct rtsx_pcr *pcr = host->pcr; | ||
399 | int err; | ||
400 | |||
401 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
402 | __func__, cmd->opcode, cmd->arg); | ||
403 | |||
404 | if (!buf) | ||
405 | buf_len = 0; | ||
406 | |||
407 | sd_send_cmd_get_rsp(host, cmd); | ||
408 | if (cmd->error) | ||
409 | return cmd->error; | ||
410 | |||
411 | if (buf && buf_len) { | ||
412 | err = rtsx_pci_write_ppbuf(pcr, buf, buf_len); | ||
413 | if (err < 0) { | ||
414 | dev_dbg(sdmmc_dev(host), | ||
415 | "rtsx_pci_write_ppbuf fail (err = %d)\n", err); | ||
416 | return err; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | rtsx_pci_init_cmd(pcr); | ||
421 | sd_cmd_set_data_len(pcr, 1, byte_cnt); | ||
422 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, | ||
423 | SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
424 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0); | ||
425 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | ||
426 | SD_TRANSFER_START | SD_TM_AUTO_WRITE_3); | ||
427 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
428 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
429 | |||
430 | err = rtsx_pci_send_cmd(pcr, timeout); | ||
431 | if (err < 0) { | ||
432 | sd_print_debug_regs(host); | ||
433 | dev_dbg(sdmmc_dev(host), | ||
434 | "rtsx_pci_send_cmd fail (err = %d)\n", err); | ||
435 | return err; | ||
436 | } | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int sd_read_long_data(struct realtek_pci_sdmmc *host, | ||
442 | struct mmc_request *mrq) | ||
442 | { | 443 | { |
443 | struct rtsx_pcr *pcr = host->pcr; | 444 | struct rtsx_pcr *pcr = host->pcr; |
444 | struct mmc_host *mmc = host->mmc; | 445 | struct mmc_host *mmc = host->mmc; |
445 | struct mmc_card *card = mmc->card; | 446 | struct mmc_card *card = mmc->card; |
447 | struct mmc_command *cmd = mrq->cmd; | ||
446 | struct mmc_data *data = mrq->data; | 448 | struct mmc_data *data = mrq->data; |
447 | int uhs = mmc_card_uhs(card); | 449 | int uhs = mmc_card_uhs(card); |
448 | int read = (data->flags & MMC_DATA_READ) ? 1 : 0; | 450 | u8 cfg2 = 0; |
449 | u8 cfg2, trans_mode; | ||
450 | int err; | 451 | int err; |
452 | int resp_type; | ||
451 | size_t data_len = data->blksz * data->blocks; | 453 | size_t data_len = data->blksz * data->blocks; |
452 | 454 | ||
453 | if (read) { | 455 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
454 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 456 | __func__, cmd->opcode, cmd->arg); |
455 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; | 457 | |
456 | trans_mode = SD_TM_AUTO_READ_3; | 458 | resp_type = sd_response_type(cmd); |
457 | } else { | 459 | if (resp_type < 0) |
458 | cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 460 | return resp_type; |
459 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; | ||
460 | trans_mode = SD_TM_AUTO_WRITE_3; | ||
461 | } | ||
462 | 461 | ||
463 | if (!uhs) | 462 | if (!uhs) |
464 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; | 463 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; |
465 | 464 | ||
466 | rtsx_pci_init_cmd(pcr); | 465 | rtsx_pci_init_cmd(pcr); |
467 | 466 | sd_cmd_set_sd_cmd(pcr, cmd); | |
468 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); | 467 | sd_cmd_set_data_len(pcr, data->blocks, data->blksz); |
469 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); | ||
470 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, | ||
471 | 0xFF, (u8)data->blocks); | ||
472 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, | ||
473 | 0xFF, (u8)(data->blocks >> 8)); | ||
474 | |||
475 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, | 468 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, |
476 | DMA_DONE_INT, DMA_DONE_INT); | 469 | DMA_DONE_INT, DMA_DONE_INT); |
477 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, | 470 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, |
478 | 0xFF, (u8)(data_len >> 24)); | 471 | 0xFF, (u8)(data_len >> 24)); |
479 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, | 472 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, |
480 | 0xFF, (u8)(data_len >> 16)); | 473 | 0xFF, (u8)(data_len >> 16)); |
481 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, | 474 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, |
482 | 0xFF, (u8)(data_len >> 8)); | 475 | 0xFF, (u8)(data_len >> 8)); |
483 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); | 476 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); |
484 | if (read) { | 477 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, |
485 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | 478 | 0x03 | DMA_PACK_SIZE_MASK, |
486 | 0x03 | DMA_PACK_SIZE_MASK, | 479 | DMA_DIR_FROM_CARD | DMA_EN | DMA_512); |
487 | DMA_DIR_FROM_CARD | DMA_EN | DMA_512); | 480 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
488 | } else { | 481 | 0x01, RING_BUFFER); |
489 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | 482 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2 | resp_type); |
490 | 0x03 | DMA_PACK_SIZE_MASK, | 483 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, |
491 | DMA_DIR_TO_CARD | DMA_EN | DMA_512); | 484 | SD_TRANSFER_START | SD_TM_AUTO_READ_2); |
485 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | ||
486 | SD_TRANSFER_END, SD_TRANSFER_END); | ||
487 | rtsx_pci_send_cmd_no_wait(pcr); | ||
488 | |||
489 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, 1, 10000); | ||
490 | if (err < 0) { | ||
491 | sd_print_debug_regs(host); | ||
492 | sd_clear_error(host); | ||
493 | return err; | ||
492 | } | 494 | } |
493 | 495 | ||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static int sd_write_long_data(struct realtek_pci_sdmmc *host, | ||
500 | struct mmc_request *mrq) | ||
501 | { | ||
502 | struct rtsx_pcr *pcr = host->pcr; | ||
503 | struct mmc_host *mmc = host->mmc; | ||
504 | struct mmc_card *card = mmc->card; | ||
505 | struct mmc_command *cmd = mrq->cmd; | ||
506 | struct mmc_data *data = mrq->data; | ||
507 | int uhs = mmc_card_uhs(card); | ||
508 | u8 cfg2; | ||
509 | int err; | ||
510 | size_t data_len = data->blksz * data->blocks; | ||
511 | |||
512 | sd_send_cmd_get_rsp(host, cmd); | ||
513 | if (cmd->error) | ||
514 | return cmd->error; | ||
515 | |||
516 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | ||
517 | __func__, cmd->opcode, cmd->arg); | ||
518 | |||
519 | cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | | ||
520 | SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; | ||
521 | |||
522 | if (!uhs) | ||
523 | cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; | ||
524 | |||
525 | rtsx_pci_init_cmd(pcr); | ||
526 | sd_cmd_set_data_len(pcr, data->blocks, data->blksz); | ||
527 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, | ||
528 | DMA_DONE_INT, DMA_DONE_INT); | ||
529 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, | ||
530 | 0xFF, (u8)(data_len >> 24)); | ||
531 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, | ||
532 | 0xFF, (u8)(data_len >> 16)); | ||
533 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, | ||
534 | 0xFF, (u8)(data_len >> 8)); | ||
535 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); | ||
536 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, | ||
537 | 0x03 | DMA_PACK_SIZE_MASK, | ||
538 | DMA_DIR_TO_CARD | DMA_EN | DMA_512); | ||
494 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, | 539 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, |
495 | 0x01, RING_BUFFER); | 540 | 0x01, RING_BUFFER); |
496 | |||
497 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2); | 541 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, cfg2); |
498 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, | 542 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, |
499 | trans_mode | SD_TRANSFER_START); | 543 | SD_TRANSFER_START | SD_TM_AUTO_WRITE_3); |
500 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | 544 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, |
501 | SD_TRANSFER_END, SD_TRANSFER_END); | 545 | SD_TRANSFER_END, SD_TRANSFER_END); |
502 | |||
503 | rtsx_pci_send_cmd_no_wait(pcr); | 546 | rtsx_pci_send_cmd_no_wait(pcr); |
504 | 547 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, 0, 10000); | |
505 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read, 10000); | ||
506 | if (err < 0) { | 548 | if (err < 0) { |
507 | sd_clear_error(host); | 549 | sd_clear_error(host); |
508 | return err; | 550 | return err; |
@@ -511,6 +553,23 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | |||
511 | return 0; | 553 | return 0; |
512 | } | 554 | } |
513 | 555 | ||
556 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | ||
557 | { | ||
558 | struct mmc_data *data = mrq->data; | ||
559 | |||
560 | if (host->sg_count < 0) { | ||
561 | data->error = host->sg_count; | ||
562 | dev_dbg(sdmmc_dev(host), "%s: sg_count = %d is invalid\n", | ||
563 | __func__, host->sg_count); | ||
564 | return data->error; | ||
565 | } | ||
566 | |||
567 | if (data->flags & MMC_DATA_READ) | ||
568 | return sd_read_long_data(host, mrq); | ||
569 | |||
570 | return sd_write_long_data(host, mrq); | ||
571 | } | ||
572 | |||
514 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) | 573 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) |
515 | { | 574 | { |
516 | rtsx_pci_write_register(host->pcr, SD_CFG1, | 575 | rtsx_pci_write_register(host->pcr, SD_CFG1, |
@@ -528,10 +587,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
528 | { | 587 | { |
529 | struct mmc_command *cmd = mrq->cmd; | 588 | struct mmc_command *cmd = mrq->cmd; |
530 | struct mmc_data *data = mrq->data; | 589 | struct mmc_data *data = mrq->data; |
531 | u8 _cmd[5], *buf; | 590 | u8 *buf; |
532 | |||
533 | _cmd[0] = 0x40 | (u8)cmd->opcode; | ||
534 | put_unaligned_be32(cmd->arg, (u32 *)(&_cmd[1])); | ||
535 | 591 | ||
536 | buf = kzalloc(data->blksz, GFP_NOIO); | 592 | buf = kzalloc(data->blksz, GFP_NOIO); |
537 | if (!buf) { | 593 | if (!buf) { |
@@ -543,7 +599,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
543 | if (host->initial_mode) | 599 | if (host->initial_mode) |
544 | sd_disable_initial_mode(host); | 600 | sd_disable_initial_mode(host); |
545 | 601 | ||
546 | cmd->error = sd_read_data(host, _cmd, (u16)data->blksz, buf, | 602 | cmd->error = sd_read_data(host, cmd, (u16)data->blksz, buf, |
547 | data->blksz, 200); | 603 | data->blksz, 200); |
548 | 604 | ||
549 | if (host->initial_mode) | 605 | if (host->initial_mode) |
@@ -553,7 +609,7 @@ static void sd_normal_rw(struct realtek_pci_sdmmc *host, | |||
553 | } else { | 609 | } else { |
554 | sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz); | 610 | sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz); |
555 | 611 | ||
556 | cmd->error = sd_write_data(host, _cmd, (u16)data->blksz, buf, | 612 | cmd->error = sd_write_data(host, cmd, (u16)data->blksz, buf, |
557 | data->blksz, 200); | 613 | data->blksz, 200); |
558 | } | 614 | } |
559 | 615 | ||
@@ -653,14 +709,14 @@ static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, | |||
653 | u8 opcode, u8 sample_point) | 709 | u8 opcode, u8 sample_point) |
654 | { | 710 | { |
655 | int err; | 711 | int err; |
656 | u8 cmd[5] = {0}; | 712 | struct mmc_command cmd = {0}; |
657 | 713 | ||
658 | err = sd_change_phase(host, sample_point, true); | 714 | err = sd_change_phase(host, sample_point, true); |
659 | if (err < 0) | 715 | if (err < 0) |
660 | return err; | 716 | return err; |
661 | 717 | ||
662 | cmd[0] = 0x40 | opcode; | 718 | cmd.opcode = opcode; |
663 | err = sd_read_data(host, cmd, 0x40, NULL, 0, 100); | 719 | err = sd_read_data(host, &cmd, 0x40, NULL, 0, 100); |
664 | if (err < 0) { | 720 | if (err < 0) { |
665 | /* Wait till SD DATA IDLE */ | 721 | /* Wait till SD DATA IDLE */ |
666 | sd_wait_data_idle(host); | 722 | sd_wait_data_idle(host); |
@@ -727,6 +783,12 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) | |||
727 | return 0; | 783 | return 0; |
728 | } | 784 | } |
729 | 785 | ||
786 | static inline int sdio_extblock_cmd(struct mmc_command *cmd, | ||
787 | struct mmc_data *data) | ||
788 | { | ||
789 | return (cmd->opcode == SD_IO_RW_EXTENDED) && (data->blksz == 512); | ||
790 | } | ||
791 | |||
730 | static inline int sd_rw_cmd(struct mmc_command *cmd) | 792 | static inline int sd_rw_cmd(struct mmc_command *cmd) |
731 | { | 793 | { |
732 | return mmc_op_multi(cmd->opcode) || | 794 | return mmc_op_multi(cmd->opcode) || |
@@ -748,7 +810,7 @@ static void sd_request(struct work_struct *work) | |||
748 | unsigned int data_size = 0; | 810 | unsigned int data_size = 0; |
749 | int err; | 811 | int err; |
750 | 812 | ||
751 | if (host->eject) { | 813 | if (host->eject || !sd_get_cd_int(host)) { |
752 | cmd->error = -ENOMEDIUM; | 814 | cmd->error = -ENOMEDIUM; |
753 | goto finish; | 815 | goto finish; |
754 | } | 816 | } |
@@ -776,17 +838,15 @@ static void sd_request(struct work_struct *work) | |||
776 | if (mrq->data) | 838 | if (mrq->data) |
777 | data_size = data->blocks * data->blksz; | 839 | data_size = data->blocks * data->blksz; |
778 | 840 | ||
779 | if (!data_size || sd_rw_cmd(cmd)) { | 841 | if (!data_size) { |
780 | sd_send_cmd_get_rsp(host, cmd); | 842 | sd_send_cmd_get_rsp(host, cmd); |
843 | } else if (sd_rw_cmd(cmd) || sdio_extblock_cmd(cmd, data)) { | ||
844 | cmd->error = sd_rw_multi(host, mrq); | ||
845 | if (!host->using_cookie) | ||
846 | sdmmc_post_req(host->mmc, host->mrq, 0); | ||
781 | 847 | ||
782 | if (!cmd->error && data_size) { | 848 | if (mmc_op_multi(cmd->opcode) && mrq->stop) |
783 | sd_rw_multi(host, mrq); | 849 | sd_send_cmd_get_rsp(host, mrq->stop); |
784 | if (!host->using_cookie) | ||
785 | sdmmc_post_req(host->mmc, host->mrq, 0); | ||
786 | |||
787 | if (mmc_op_multi(cmd->opcode) && mrq->stop) | ||
788 | sd_send_cmd_get_rsp(host, mrq->stop); | ||
789 | } | ||
790 | } else { | 850 | } else { |
791 | sd_normal_rw(host, mrq); | 851 | sd_normal_rw(host, mrq); |
792 | } | 852 | } |
@@ -801,8 +861,10 @@ static void sd_request(struct work_struct *work) | |||
801 | mutex_unlock(&pcr->pcr_mutex); | 861 | mutex_unlock(&pcr->pcr_mutex); |
802 | 862 | ||
803 | finish: | 863 | finish: |
804 | if (cmd->error) | 864 | if (cmd->error) { |
805 | dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); | 865 | dev_dbg(sdmmc_dev(host), "CMD %d 0x%08x error(%d)\n", |
866 | cmd->opcode, cmd->arg, cmd->error); | ||
867 | } | ||
806 | 868 | ||
807 | mutex_lock(&host->host_mutex); | 869 | mutex_lock(&host->host_mutex); |
808 | host->mrq = NULL; | 870 | host->mrq = NULL; |
@@ -820,7 +882,7 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
820 | host->mrq = mrq; | 882 | host->mrq = mrq; |
821 | mutex_unlock(&host->host_mutex); | 883 | mutex_unlock(&host->host_mutex); |
822 | 884 | ||
823 | if (sd_rw_cmd(mrq->cmd)) | 885 | if (sd_rw_cmd(mrq->cmd) || sdio_extblock_cmd(mrq->cmd, data)) |
824 | host->using_cookie = sd_pre_dma_transfer(host, data, false); | 886 | host->using_cookie = sd_pre_dma_transfer(host, data, false); |
825 | 887 | ||
826 | queue_work(host->workq, &host->work); | 888 | queue_work(host->workq, &host->work); |
@@ -1066,7 +1128,7 @@ static int sdmmc_get_cd(struct mmc_host *mmc) | |||
1066 | u32 val; | 1128 | u32 val; |
1067 | 1129 | ||
1068 | if (host->eject) | 1130 | if (host->eject) |
1069 | return -ENOMEDIUM; | 1131 | return cd; |
1070 | 1132 | ||
1071 | mutex_lock(&pcr->pcr_mutex); | 1133 | mutex_lock(&pcr->pcr_mutex); |
1072 | 1134 | ||
@@ -1317,6 +1379,7 @@ static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev) | |||
1317 | { | 1379 | { |
1318 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | 1380 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); |
1319 | 1381 | ||
1382 | host->cookie = -1; | ||
1320 | mmc_detect_change(host->mmc, 0); | 1383 | mmc_detect_change(host->mmc, 0); |
1321 | } | 1384 | } |
1322 | 1385 | ||
@@ -1349,6 +1412,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
1349 | host->pcr = pcr; | 1412 | host->pcr = pcr; |
1350 | host->mmc = mmc; | 1413 | host->mmc = mmc; |
1351 | host->pdev = pdev; | 1414 | host->pdev = pdev; |
1415 | host->cookie = -1; | ||
1352 | host->power_state = SDMMC_POWER_OFF; | 1416 | host->power_state = SDMMC_POWER_OFF; |
1353 | INIT_WORK(&host->work, sd_request); | 1417 | INIT_WORK(&host->work, sd_request); |
1354 | platform_set_drvdata(pdev, host); | 1418 | platform_set_drvdata(pdev, host); |
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 970314e0aac8..a45ed39d062c 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -158,7 +158,7 @@ static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev, | |||
158 | 158 | ||
159 | host = c->host; | 159 | host = c->host; |
160 | 160 | ||
161 | /* Platform specific code during emmc proble slot goes here */ | 161 | /* Platform specific code during emmc probe slot goes here */ |
162 | 162 | ||
163 | if (hid && uid && !strcmp(hid, "80860F14") && !strcmp(uid, "1") && | 163 | if (hid && uid && !strcmp(hid, "80860F14") && !strcmp(uid, "1") && |
164 | sdhci_readl(host, SDHCI_CAPABILITIES) == 0x446cc8b2 && | 164 | sdhci_readl(host, SDHCI_CAPABILITIES) == 0x446cc8b2 && |
@@ -179,7 +179,7 @@ static int sdhci_acpi_sdio_probe_slot(struct platform_device *pdev, | |||
179 | 179 | ||
180 | host = c->host; | 180 | host = c->host; |
181 | 181 | ||
182 | /* Platform specific code during emmc proble slot goes here */ | 182 | /* Platform specific code during sdio probe slot goes here */ |
183 | 183 | ||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
@@ -195,7 +195,7 @@ static int sdhci_acpi_sd_probe_slot(struct platform_device *pdev, | |||
195 | 195 | ||
196 | host = c->host; | 196 | host = c->host; |
197 | 197 | ||
198 | /* Platform specific code during emmc proble slot goes here */ | 198 | /* Platform specific code during sd probe slot goes here */ |
199 | 199 | ||
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
@@ -448,18 +448,13 @@ static int sdhci_acpi_runtime_resume(struct device *dev) | |||
448 | return sdhci_runtime_resume_host(c->host); | 448 | return sdhci_runtime_resume_host(c->host); |
449 | } | 449 | } |
450 | 450 | ||
451 | static int sdhci_acpi_runtime_idle(struct device *dev) | ||
452 | { | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | #endif | 451 | #endif |
457 | 452 | ||
458 | static const struct dev_pm_ops sdhci_acpi_pm_ops = { | 453 | static const struct dev_pm_ops sdhci_acpi_pm_ops = { |
459 | .suspend = sdhci_acpi_suspend, | 454 | .suspend = sdhci_acpi_suspend, |
460 | .resume = sdhci_acpi_resume, | 455 | .resume = sdhci_acpi_resume, |
461 | SET_RUNTIME_PM_OPS(sdhci_acpi_runtime_suspend, | 456 | SET_RUNTIME_PM_OPS(sdhci_acpi_runtime_suspend, |
462 | sdhci_acpi_runtime_resume, sdhci_acpi_runtime_idle) | 457 | sdhci_acpi_runtime_resume, NULL) |
463 | }; | 458 | }; |
464 | 459 | ||
465 | static struct platform_driver sdhci_acpi_driver = { | 460 | static struct platform_driver sdhci_acpi_driver = { |
diff --git a/drivers/mmc/host/sdhci-bcm-kona.c b/drivers/mmc/host/sdhci-bcm-kona.c index e7e4fbdcbfe0..34bb8f92586e 100644 --- a/drivers/mmc/host/sdhci-bcm-kona.c +++ b/drivers/mmc/host/sdhci-bcm-kona.c | |||
@@ -254,7 +254,9 @@ static int sdhci_bcm_kona_probe(struct platform_device *pdev) | |||
254 | kona_dev = sdhci_pltfm_priv(pltfm_priv); | 254 | kona_dev = sdhci_pltfm_priv(pltfm_priv); |
255 | mutex_init(&kona_dev->write_lock); | 255 | mutex_init(&kona_dev->write_lock); |
256 | 256 | ||
257 | mmc_of_parse(host->mmc); | 257 | ret = mmc_of_parse(host->mmc); |
258 | if (ret) | ||
259 | goto err_pltfm_free; | ||
258 | 260 | ||
259 | if (!host->mmc->f_max) { | 261 | if (!host->mmc->f_max) { |
260 | dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n"); | 262 | dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n"); |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index af1f7c0f9545..10ef8244a239 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -1080,10 +1080,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) | |||
1080 | goto disable_clk; | 1080 | goto disable_clk; |
1081 | 1081 | ||
1082 | pm_runtime_set_active(&pdev->dev); | 1082 | pm_runtime_set_active(&pdev->dev); |
1083 | pm_runtime_enable(&pdev->dev); | ||
1084 | pm_runtime_set_autosuspend_delay(&pdev->dev, 50); | 1083 | pm_runtime_set_autosuspend_delay(&pdev->dev, 50); |
1085 | pm_runtime_use_autosuspend(&pdev->dev); | 1084 | pm_runtime_use_autosuspend(&pdev->dev); |
1086 | pm_suspend_ignore_children(&pdev->dev, 1); | 1085 | pm_suspend_ignore_children(&pdev->dev, 1); |
1086 | pm_runtime_enable(&pdev->dev); | ||
1087 | 1087 | ||
1088 | return 0; | 1088 | return 0; |
1089 | 1089 | ||
@@ -1103,16 +1103,15 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev) | |||
1103 | struct pltfm_imx_data *imx_data = pltfm_host->priv; | 1103 | struct pltfm_imx_data *imx_data = pltfm_host->priv; |
1104 | int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); | 1104 | int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); |
1105 | 1105 | ||
1106 | sdhci_remove_host(host, dead); | 1106 | pm_runtime_get_sync(&pdev->dev); |
1107 | |||
1108 | pm_runtime_dont_use_autosuspend(&pdev->dev); | ||
1109 | pm_runtime_disable(&pdev->dev); | 1107 | pm_runtime_disable(&pdev->dev); |
1108 | pm_runtime_put_noidle(&pdev->dev); | ||
1110 | 1109 | ||
1111 | if (!IS_ENABLED(CONFIG_PM)) { | 1110 | sdhci_remove_host(host, dead); |
1112 | clk_disable_unprepare(imx_data->clk_per); | 1111 | |
1113 | clk_disable_unprepare(imx_data->clk_ipg); | 1112 | clk_disable_unprepare(imx_data->clk_per); |
1114 | clk_disable_unprepare(imx_data->clk_ahb); | 1113 | clk_disable_unprepare(imx_data->clk_ipg); |
1115 | } | 1114 | clk_disable_unprepare(imx_data->clk_ahb); |
1116 | 1115 | ||
1117 | sdhci_pltfm_free(pdev); | 1116 | sdhci_pltfm_free(pdev); |
1118 | 1117 | ||
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 8872c85c63d4..17fe02ed6672 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -276,6 +276,14 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) | |||
276 | ESDHC_CTRL_BUSWIDTH_MASK, ctrl); | 276 | ESDHC_CTRL_BUSWIDTH_MASK, ctrl); |
277 | } | 277 | } |
278 | 278 | ||
279 | static void esdhc_reset(struct sdhci_host *host, u8 mask) | ||
280 | { | ||
281 | sdhci_reset(host, mask); | ||
282 | |||
283 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); | ||
284 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | ||
285 | } | ||
286 | |||
279 | static const struct sdhci_ops sdhci_esdhc_ops = { | 287 | static const struct sdhci_ops sdhci_esdhc_ops = { |
280 | .read_l = esdhc_readl, | 288 | .read_l = esdhc_readl, |
281 | .read_w = esdhc_readw, | 289 | .read_w = esdhc_readw, |
@@ -290,7 +298,7 @@ static const struct sdhci_ops sdhci_esdhc_ops = { | |||
290 | .platform_init = esdhc_of_platform_init, | 298 | .platform_init = esdhc_of_platform_init, |
291 | .adma_workaround = esdhci_of_adma_workaround, | 299 | .adma_workaround = esdhci_of_adma_workaround, |
292 | .set_bus_width = esdhc_pltfm_set_bus_width, | 300 | .set_bus_width = esdhc_pltfm_set_bus_width, |
293 | .reset = sdhci_reset, | 301 | .reset = esdhc_reset, |
294 | .set_uhs_signaling = sdhci_set_uhs_signaling, | 302 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
295 | }; | 303 | }; |
296 | 304 | ||
@@ -362,13 +370,19 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) | |||
362 | } | 370 | } |
363 | 371 | ||
364 | /* call to generic mmc_of_parse to support additional capabilities */ | 372 | /* call to generic mmc_of_parse to support additional capabilities */ |
365 | mmc_of_parse(host->mmc); | 373 | ret = mmc_of_parse(host->mmc); |
374 | if (ret) | ||
375 | goto err; | ||
376 | |||
366 | mmc_of_parse_voltage(np, &host->ocr_mask); | 377 | mmc_of_parse_voltage(np, &host->ocr_mask); |
367 | 378 | ||
368 | ret = sdhci_add_host(host); | 379 | ret = sdhci_add_host(host); |
369 | if (ret) | 380 | if (ret) |
370 | sdhci_pltfm_free(pdev); | 381 | goto err; |
371 | 382 | ||
383 | return 0; | ||
384 | err: | ||
385 | sdhci_pltfm_free(pdev); | ||
372 | return ret; | 386 | return ret; |
373 | } | 387 | } |
374 | 388 | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 4f38554ce679..29eaff78238e 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -1367,11 +1367,6 @@ static int sdhci_pci_runtime_resume(struct device *dev) | |||
1367 | return 0; | 1367 | return 0; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | static int sdhci_pci_runtime_idle(struct device *dev) | ||
1371 | { | ||
1372 | return 0; | ||
1373 | } | ||
1374 | |||
1375 | #else /* CONFIG_PM */ | 1370 | #else /* CONFIG_PM */ |
1376 | 1371 | ||
1377 | #define sdhci_pci_suspend NULL | 1372 | #define sdhci_pci_suspend NULL |
@@ -1383,7 +1378,7 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = { | |||
1383 | .suspend = sdhci_pci_suspend, | 1378 | .suspend = sdhci_pci_suspend, |
1384 | .resume = sdhci_pci_resume, | 1379 | .resume = sdhci_pci_resume, |
1385 | SET_RUNTIME_PM_OPS(sdhci_pci_runtime_suspend, | 1380 | SET_RUNTIME_PM_OPS(sdhci_pci_runtime_suspend, |
1386 | sdhci_pci_runtime_resume, sdhci_pci_runtime_idle) | 1381 | sdhci_pci_runtime_resume, NULL) |
1387 | }; | 1382 | }; |
1388 | 1383 | ||
1389 | /*****************************************************************************\ | 1384 | /*****************************************************************************\ |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index ca3424e7ef71..b5103a247bc1 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -62,6 +62,7 @@ struct sdhci_pxa { | |||
62 | struct clk *clk_core; | 62 | struct clk *clk_core; |
63 | struct clk *clk_io; | 63 | struct clk *clk_io; |
64 | u8 power_mode; | 64 | u8 power_mode; |
65 | void __iomem *sdio3_conf_reg; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* | 68 | /* |
@@ -72,6 +73,14 @@ struct sdhci_pxa { | |||
72 | #define SDHCI_WINDOW_BASE(i) (0x84 + ((i) << 3)) | 73 | #define SDHCI_WINDOW_BASE(i) (0x84 + ((i) << 3)) |
73 | #define SDHCI_MAX_WIN_NUM 8 | 74 | #define SDHCI_MAX_WIN_NUM 8 |
74 | 75 | ||
76 | /* | ||
77 | * Fields below belong to SDIO3 Configuration Register (third register | ||
78 | * region for the Armada 38x flavor) | ||
79 | */ | ||
80 | |||
81 | #define SDIO3_CONF_CLK_INV BIT(0) | ||
82 | #define SDIO3_CONF_SD_FB_CLK BIT(2) | ||
83 | |||
75 | static int mv_conf_mbus_windows(struct platform_device *pdev, | 84 | static int mv_conf_mbus_windows(struct platform_device *pdev, |
76 | const struct mbus_dram_target_info *dram) | 85 | const struct mbus_dram_target_info *dram) |
77 | { | 86 | { |
@@ -118,6 +127,51 @@ static int mv_conf_mbus_windows(struct platform_device *pdev, | |||
118 | return 0; | 127 | return 0; |
119 | } | 128 | } |
120 | 129 | ||
130 | static int armada_38x_quirks(struct platform_device *pdev, | ||
131 | struct sdhci_host *host) | ||
132 | { | ||
133 | struct device_node *np = pdev->dev.of_node; | ||
134 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
135 | struct sdhci_pxa *pxa = pltfm_host->priv; | ||
136 | struct resource *res; | ||
137 | |||
138 | host->quirks |= SDHCI_QUIRK_MISSING_CAPS; | ||
139 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
140 | "conf-sdio3"); | ||
141 | if (res) { | ||
142 | pxa->sdio3_conf_reg = devm_ioremap_resource(&pdev->dev, res); | ||
143 | if (IS_ERR(pxa->sdio3_conf_reg)) | ||
144 | return PTR_ERR(pxa->sdio3_conf_reg); | ||
145 | } else { | ||
146 | /* | ||
147 | * According to erratum 'FE-2946959' both SDR50 and DDR50 | ||
148 | * modes require specific clock adjustments in SDIO3 | ||
149 | * Configuration register, if the adjustment is not done, | ||
150 | * remove them from the capabilities. | ||
151 | */ | ||
152 | host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); | ||
153 | host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50); | ||
154 | |||
155 | dev_warn(&pdev->dev, "conf-sdio3 register not found: disabling SDR50 and DDR50 modes.\nConsider updating your dtb\n"); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * According to erratum 'ERR-7878951' Armada 38x SDHCI | ||
160 | * controller has different capabilities than the ones shown | ||
161 | * in its registers | ||
162 | */ | ||
163 | host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); | ||
164 | if (of_property_read_bool(np, "no-1-8-v")) { | ||
165 | host->caps &= ~SDHCI_CAN_VDD_180; | ||
166 | host->mmc->caps &= ~MMC_CAP_1_8V_DDR; | ||
167 | } else { | ||
168 | host->caps &= ~SDHCI_CAN_VDD_330; | ||
169 | } | ||
170 | host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_USE_SDR50_TUNING); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
121 | static void pxav3_reset(struct sdhci_host *host, u8 mask) | 175 | static void pxav3_reset(struct sdhci_host *host, u8 mask) |
122 | { | 176 | { |
123 | struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc)); | 177 | struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc)); |
@@ -194,6 +248,8 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host *host, u8 power_mode) | |||
194 | 248 | ||
195 | static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) | 249 | static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) |
196 | { | 250 | { |
251 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
252 | struct sdhci_pxa *pxa = pltfm_host->priv; | ||
197 | u16 ctrl_2; | 253 | u16 ctrl_2; |
198 | 254 | ||
199 | /* | 255 | /* |
@@ -223,6 +279,24 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) | |||
223 | break; | 279 | break; |
224 | } | 280 | } |
225 | 281 | ||
282 | /* | ||
283 | * Update SDIO3 Configuration register according to erratum | ||
284 | * FE-2946959 | ||
285 | */ | ||
286 | if (pxa->sdio3_conf_reg) { | ||
287 | u8 reg_val = readb(pxa->sdio3_conf_reg); | ||
288 | |||
289 | if (uhs == MMC_TIMING_UHS_SDR50 || | ||
290 | uhs == MMC_TIMING_UHS_DDR50) { | ||
291 | reg_val &= ~SDIO3_CONF_CLK_INV; | ||
292 | reg_val |= SDIO3_CONF_SD_FB_CLK; | ||
293 | } else { | ||
294 | reg_val |= SDIO3_CONF_CLK_INV; | ||
295 | reg_val &= ~SDIO3_CONF_SD_FB_CLK; | ||
296 | } | ||
297 | writeb(reg_val, pxa->sdio3_conf_reg); | ||
298 | } | ||
299 | |||
226 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); | 300 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); |
227 | dev_dbg(mmc_dev(host->mmc), | 301 | dev_dbg(mmc_dev(host->mmc), |
228 | "%s uhs = %d, ctrl_2 = %04X\n", | 302 | "%s uhs = %d, ctrl_2 = %04X\n", |
@@ -268,8 +342,8 @@ static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev) | |||
268 | if (!pdata) | 342 | if (!pdata) |
269 | return NULL; | 343 | return NULL; |
270 | 344 | ||
271 | of_property_read_u32(np, "mrvl,clk-delay-cycles", &clk_delay_cycles); | 345 | if (!of_property_read_u32(np, "mrvl,clk-delay-cycles", |
272 | if (clk_delay_cycles > 0) | 346 | &clk_delay_cycles)) |
273 | pdata->clk_delay_cycles = clk_delay_cycles; | 347 | pdata->clk_delay_cycles = clk_delay_cycles; |
274 | 348 | ||
275 | return pdata; | 349 | return pdata; |
@@ -318,15 +392,18 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
318 | if (!IS_ERR(pxa->clk_core)) | 392 | if (!IS_ERR(pxa->clk_core)) |
319 | clk_prepare_enable(pxa->clk_core); | 393 | clk_prepare_enable(pxa->clk_core); |
320 | 394 | ||
395 | /* enable 1/8V DDR capable */ | ||
396 | host->mmc->caps |= MMC_CAP_1_8V_DDR; | ||
397 | |||
321 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | 398 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { |
399 | ret = armada_38x_quirks(pdev, host); | ||
400 | if (ret < 0) | ||
401 | goto err_clk_get; | ||
322 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | 402 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); |
323 | if (ret < 0) | 403 | if (ret < 0) |
324 | goto err_mbus_win; | 404 | goto err_mbus_win; |
325 | } | 405 | } |
326 | 406 | ||
327 | /* enable 1/8V DDR capable */ | ||
328 | host->mmc->caps |= MMC_CAP_1_8V_DDR; | ||
329 | |||
330 | match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev); | 407 | match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev); |
331 | if (match) { | 408 | if (match) { |
332 | ret = mmc_of_parse(host->mmc); | 409 | ret = mmc_of_parse(host->mmc); |
@@ -365,10 +442,11 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
365 | } | 442 | } |
366 | } | 443 | } |
367 | 444 | ||
368 | pm_runtime_enable(&pdev->dev); | 445 | pm_runtime_get_noresume(&pdev->dev); |
369 | pm_runtime_get_sync(&pdev->dev); | 446 | pm_runtime_set_active(&pdev->dev); |
370 | pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); | 447 | pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS); |
371 | pm_runtime_use_autosuspend(&pdev->dev); | 448 | pm_runtime_use_autosuspend(&pdev->dev); |
449 | pm_runtime_enable(&pdev->dev); | ||
372 | pm_suspend_ignore_children(&pdev->dev, 1); | 450 | pm_suspend_ignore_children(&pdev->dev, 1); |
373 | 451 | ||
374 | ret = sdhci_add_host(host); | 452 | ret = sdhci_add_host(host); |
@@ -391,14 +469,13 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
391 | return 0; | 469 | return 0; |
392 | 470 | ||
393 | err_add_host: | 471 | err_add_host: |
394 | pm_runtime_put_sync(&pdev->dev); | ||
395 | pm_runtime_disable(&pdev->dev); | 472 | pm_runtime_disable(&pdev->dev); |
473 | pm_runtime_put_noidle(&pdev->dev); | ||
396 | err_of_parse: | 474 | err_of_parse: |
397 | err_cd_req: | 475 | err_cd_req: |
398 | err_mbus_win: | 476 | err_mbus_win: |
399 | clk_disable_unprepare(pxa->clk_io); | 477 | clk_disable_unprepare(pxa->clk_io); |
400 | if (!IS_ERR(pxa->clk_core)) | 478 | clk_disable_unprepare(pxa->clk_core); |
401 | clk_disable_unprepare(pxa->clk_core); | ||
402 | err_clk_get: | 479 | err_clk_get: |
403 | sdhci_pltfm_free(pdev); | 480 | sdhci_pltfm_free(pdev); |
404 | return ret; | 481 | return ret; |
@@ -411,12 +488,13 @@ static int sdhci_pxav3_remove(struct platform_device *pdev) | |||
411 | struct sdhci_pxa *pxa = pltfm_host->priv; | 488 | struct sdhci_pxa *pxa = pltfm_host->priv; |
412 | 489 | ||
413 | pm_runtime_get_sync(&pdev->dev); | 490 | pm_runtime_get_sync(&pdev->dev); |
414 | sdhci_remove_host(host, 1); | ||
415 | pm_runtime_disable(&pdev->dev); | 491 | pm_runtime_disable(&pdev->dev); |
492 | pm_runtime_put_noidle(&pdev->dev); | ||
493 | |||
494 | sdhci_remove_host(host, 1); | ||
416 | 495 | ||
417 | clk_disable_unprepare(pxa->clk_io); | 496 | clk_disable_unprepare(pxa->clk_io); |
418 | if (!IS_ERR(pxa->clk_core)) | 497 | clk_disable_unprepare(pxa->clk_core); |
419 | clk_disable_unprepare(pxa->clk_core); | ||
420 | 498 | ||
421 | sdhci_pltfm_free(pdev); | 499 | sdhci_pltfm_free(pdev); |
422 | 500 | ||
@@ -457,11 +535,11 @@ static int sdhci_pxav3_runtime_suspend(struct device *dev) | |||
457 | struct sdhci_host *host = dev_get_drvdata(dev); | 535 | struct sdhci_host *host = dev_get_drvdata(dev); |
458 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 536 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
459 | struct sdhci_pxa *pxa = pltfm_host->priv; | 537 | struct sdhci_pxa *pxa = pltfm_host->priv; |
460 | unsigned long flags; | 538 | int ret; |
461 | 539 | ||
462 | spin_lock_irqsave(&host->lock, flags); | 540 | ret = sdhci_runtime_suspend_host(host); |
463 | host->runtime_suspended = true; | 541 | if (ret) |
464 | spin_unlock_irqrestore(&host->lock, flags); | 542 | return ret; |
465 | 543 | ||
466 | clk_disable_unprepare(pxa->clk_io); | 544 | clk_disable_unprepare(pxa->clk_io); |
467 | if (!IS_ERR(pxa->clk_core)) | 545 | if (!IS_ERR(pxa->clk_core)) |
@@ -475,17 +553,12 @@ static int sdhci_pxav3_runtime_resume(struct device *dev) | |||
475 | struct sdhci_host *host = dev_get_drvdata(dev); | 553 | struct sdhci_host *host = dev_get_drvdata(dev); |
476 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 554 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
477 | struct sdhci_pxa *pxa = pltfm_host->priv; | 555 | struct sdhci_pxa *pxa = pltfm_host->priv; |
478 | unsigned long flags; | ||
479 | 556 | ||
480 | clk_prepare_enable(pxa->clk_io); | 557 | clk_prepare_enable(pxa->clk_io); |
481 | if (!IS_ERR(pxa->clk_core)) | 558 | if (!IS_ERR(pxa->clk_core)) |
482 | clk_prepare_enable(pxa->clk_core); | 559 | clk_prepare_enable(pxa->clk_core); |
483 | 560 | ||
484 | spin_lock_irqsave(&host->lock, flags); | 561 | return sdhci_runtime_resume_host(host); |
485 | host->runtime_suspended = false; | ||
486 | spin_unlock_irqrestore(&host->lock, flags); | ||
487 | |||
488 | return 0; | ||
489 | } | 562 | } |
490 | #endif | 563 | #endif |
491 | 564 | ||
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index c45b8932d843..c6d2dd7317c1 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -12,6 +12,7 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/spinlock.h> | ||
15 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
16 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
17 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
@@ -312,7 +313,14 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) | |||
312 | 313 | ||
313 | sdhci_s3c_set_clock(host, clock); | 314 | sdhci_s3c_set_clock(host, clock); |
314 | 315 | ||
316 | /* Reset SD Clock Enable */ | ||
317 | clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); | ||
318 | clk &= ~SDHCI_CLOCK_CARD_EN; | ||
319 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | ||
320 | |||
321 | spin_unlock_irq(&host->lock); | ||
315 | ret = clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); | 322 | ret = clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); |
323 | spin_lock_irq(&host->lock); | ||
316 | if (ret != 0) { | 324 | if (ret != 0) { |
317 | dev_err(dev, "%s: failed to set clock rate %uHz\n", | 325 | dev_err(dev, "%s: failed to set clock rate %uHz\n", |
318 | mmc_hostname(host->mmc), clock); | 326 | mmc_hostname(host->mmc), clock); |
@@ -607,7 +615,9 @@ static int sdhci_s3c_probe(struct platform_device *pdev) | |||
607 | pm_runtime_use_autosuspend(&pdev->dev); | 615 | pm_runtime_use_autosuspend(&pdev->dev); |
608 | pm_suspend_ignore_children(&pdev->dev, 1); | 616 | pm_suspend_ignore_children(&pdev->dev, 1); |
609 | 617 | ||
610 | mmc_of_parse(host->mmc); | 618 | ret = mmc_of_parse(host->mmc); |
619 | if (ret) | ||
620 | goto err_req_regs; | ||
611 | 621 | ||
612 | ret = sdhci_add_host(host); | 622 | ret = sdhci_add_host(host); |
613 | if (ret) { | 623 | if (ret) { |
diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c index dd29d47c07aa..f6f82ec3618d 100644 --- a/drivers/mmc/host/sdhci-sirf.c +++ b/drivers/mmc/host/sdhci-sirf.c | |||
@@ -15,7 +15,9 @@ | |||
15 | #include <linux/mmc/slot-gpio.h> | 15 | #include <linux/mmc/slot-gpio.h> |
16 | #include "sdhci-pltfm.h" | 16 | #include "sdhci-pltfm.h" |
17 | 17 | ||
18 | #define SDHCI_CLK_DELAY_SETTING 0x4C | ||
18 | #define SDHCI_SIRF_8BITBUS BIT(3) | 19 | #define SDHCI_SIRF_8BITBUS BIT(3) |
20 | #define SIRF_TUNING_COUNT 128 | ||
19 | 21 | ||
20 | struct sdhci_sirf_priv { | 22 | struct sdhci_sirf_priv { |
21 | struct clk *clk; | 23 | struct clk *clk; |
@@ -49,7 +51,76 @@ static void sdhci_sirf_set_bus_width(struct sdhci_host *host, int width) | |||
49 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); | 51 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); |
50 | } | 52 | } |
51 | 53 | ||
54 | static int sdhci_sirf_execute_tuning(struct sdhci_host *host, u32 opcode) | ||
55 | { | ||
56 | int tuning_seq_cnt = 3; | ||
57 | u8 phase, tuned_phases[SIRF_TUNING_COUNT]; | ||
58 | u8 tuned_phase_cnt = 0; | ||
59 | int rc, longest_range = 0; | ||
60 | int start = -1, end = 0, tuning_value = -1, range = 0; | ||
61 | u16 clock_setting; | ||
62 | struct mmc_host *mmc = host->mmc; | ||
63 | |||
64 | clock_setting = sdhci_readw(host, SDHCI_CLK_DELAY_SETTING); | ||
65 | clock_setting &= ~0x3fff; | ||
66 | |||
67 | retry: | ||
68 | phase = 0; | ||
69 | do { | ||
70 | sdhci_writel(host, | ||
71 | clock_setting | phase | (phase << 7) | (phase << 16), | ||
72 | SDHCI_CLK_DELAY_SETTING); | ||
73 | |||
74 | if (!mmc_send_tuning(mmc)) { | ||
75 | /* Tuning is successful at this tuning point */ | ||
76 | tuned_phases[tuned_phase_cnt++] = phase; | ||
77 | dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n", | ||
78 | mmc_hostname(mmc), phase); | ||
79 | if (start == -1) | ||
80 | start = phase; | ||
81 | end = phase; | ||
82 | range++; | ||
83 | if (phase == (SIRF_TUNING_COUNT - 1) | ||
84 | && range > longest_range) | ||
85 | tuning_value = (start + end) / 2; | ||
86 | } else { | ||
87 | dev_dbg(mmc_dev(mmc), "%s: Found bad phase = %d\n", | ||
88 | mmc_hostname(mmc), phase); | ||
89 | if (range > longest_range) { | ||
90 | tuning_value = (start + end) / 2; | ||
91 | longest_range = range; | ||
92 | } | ||
93 | start = -1; | ||
94 | end = range = 0; | ||
95 | } | ||
96 | } while (++phase < ARRAY_SIZE(tuned_phases)); | ||
97 | |||
98 | if (tuned_phase_cnt && tuning_value > 0) { | ||
99 | /* | ||
100 | * Finally set the selected phase in delay | ||
101 | * line hw block. | ||
102 | */ | ||
103 | phase = tuning_value; | ||
104 | sdhci_writel(host, | ||
105 | clock_setting | phase | (phase << 7) | (phase << 16), | ||
106 | SDHCI_CLK_DELAY_SETTING); | ||
107 | |||
108 | dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", | ||
109 | mmc_hostname(mmc), phase); | ||
110 | } else { | ||
111 | if (--tuning_seq_cnt) | ||
112 | goto retry; | ||
113 | /* Tuning failed */ | ||
114 | dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n", | ||
115 | mmc_hostname(mmc)); | ||
116 | rc = -EIO; | ||
117 | } | ||
118 | |||
119 | return rc; | ||
120 | } | ||
121 | |||
52 | static struct sdhci_ops sdhci_sirf_ops = { | 122 | static struct sdhci_ops sdhci_sirf_ops = { |
123 | .platform_execute_tuning = sdhci_sirf_execute_tuning, | ||
53 | .set_clock = sdhci_set_clock, | 124 | .set_clock = sdhci_set_clock, |
54 | .get_max_clock = sdhci_sirf_get_max_clk, | 125 | .get_max_clock = sdhci_sirf_get_max_clk, |
55 | .set_bus_width = sdhci_sirf_set_bus_width, | 126 | .set_bus_width = sdhci_sirf_set_bus_width, |
@@ -138,9 +209,6 @@ static int sdhci_sirf_remove(struct platform_device *pdev) | |||
138 | 209 | ||
139 | sdhci_pltfm_unregister(pdev); | 210 | sdhci_pltfm_unregister(pdev); |
140 | 211 | ||
141 | if (gpio_is_valid(priv->gpio_cd)) | ||
142 | mmc_gpio_free_cd(host->mmc); | ||
143 | |||
144 | clk_disable_unprepare(priv->clk); | 212 | clk_disable_unprepare(priv->clk); |
145 | return 0; | 213 | return 0; |
146 | } | 214 | } |
diff --git a/drivers/mmc/host/sdhci-st.c b/drivers/mmc/host/sdhci-st.c index 328f348c7243..882b07e9667e 100644 --- a/drivers/mmc/host/sdhci-st.c +++ b/drivers/mmc/host/sdhci-st.c | |||
@@ -78,10 +78,9 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | ret = mmc_of_parse(host->mmc); | 80 | ret = mmc_of_parse(host->mmc); |
81 | |||
82 | if (ret) { | 81 | if (ret) { |
83 | dev_err(&pdev->dev, "Failed mmc_of_parse\n"); | 82 | dev_err(&pdev->dev, "Failed mmc_of_parse\n"); |
84 | return ret; | 83 | goto err_of; |
85 | } | 84 | } |
86 | 85 | ||
87 | clk_prepare_enable(clk); | 86 | clk_prepare_enable(clk); |
@@ -108,6 +107,7 @@ static int sdhci_st_probe(struct platform_device *pdev) | |||
108 | 107 | ||
109 | err_out: | 108 | err_out: |
110 | clk_disable_unprepare(clk); | 109 | clk_disable_unprepare(clk); |
110 | err_of: | ||
111 | sdhci_pltfm_free(pdev); | 111 | sdhci_pltfm_free(pdev); |
112 | 112 | ||
113 | return ret; | 113 | return ret; |
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 59797106af93..f3778d58d1cd 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #define NVQUIRK_DISABLE_SDR50 BIT(3) | 41 | #define NVQUIRK_DISABLE_SDR50 BIT(3) |
42 | #define NVQUIRK_DISABLE_SDR104 BIT(4) | 42 | #define NVQUIRK_DISABLE_SDR104 BIT(4) |
43 | #define NVQUIRK_DISABLE_DDR50 BIT(5) | 43 | #define NVQUIRK_DISABLE_DDR50 BIT(5) |
44 | #define NVQUIRK_SHADOW_XFER_MODE_REG BIT(6) | ||
44 | 45 | ||
45 | struct sdhci_tegra_soc_data { | 46 | struct sdhci_tegra_soc_data { |
46 | const struct sdhci_pltfm_data *pdata; | 47 | const struct sdhci_pltfm_data *pdata; |
@@ -67,6 +68,31 @@ static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg) | |||
67 | return readw(host->ioaddr + reg); | 68 | return readw(host->ioaddr + reg); |
68 | } | 69 | } |
69 | 70 | ||
71 | static void tegra_sdhci_writew(struct sdhci_host *host, u16 val, int reg) | ||
72 | { | ||
73 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | ||
74 | struct sdhci_tegra *tegra_host = pltfm_host->priv; | ||
75 | const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; | ||
76 | |||
77 | if (soc_data->nvquirks & NVQUIRK_SHADOW_XFER_MODE_REG) { | ||
78 | switch (reg) { | ||
79 | case SDHCI_TRANSFER_MODE: | ||
80 | /* | ||
81 | * Postpone this write, we must do it together with a | ||
82 | * command write that is down below. | ||
83 | */ | ||
84 | pltfm_host->xfer_mode_shadow = val; | ||
85 | return; | ||
86 | case SDHCI_COMMAND: | ||
87 | writel((val << 16) | pltfm_host->xfer_mode_shadow, | ||
88 | host->ioaddr + SDHCI_TRANSFER_MODE); | ||
89 | return; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | writew(val, host->ioaddr + reg); | ||
94 | } | ||
95 | |||
70 | static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg) | 96 | static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg) |
71 | { | 97 | { |
72 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 98 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
@@ -147,6 +173,7 @@ static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width) | |||
147 | static const struct sdhci_ops tegra_sdhci_ops = { | 173 | static const struct sdhci_ops tegra_sdhci_ops = { |
148 | .get_ro = tegra_sdhci_get_ro, | 174 | .get_ro = tegra_sdhci_get_ro, |
149 | .read_w = tegra_sdhci_readw, | 175 | .read_w = tegra_sdhci_readw, |
176 | .write_w = tegra_sdhci_writew, | ||
150 | .write_l = tegra_sdhci_writel, | 177 | .write_l = tegra_sdhci_writel, |
151 | .set_clock = sdhci_set_clock, | 178 | .set_clock = sdhci_set_clock, |
152 | .set_bus_width = tegra_sdhci_set_bus_width, | 179 | .set_bus_width = tegra_sdhci_set_bus_width, |
@@ -201,7 +228,8 @@ static struct sdhci_tegra_soc_data soc_data_tegra114 = { | |||
201 | .pdata = &sdhci_tegra114_pdata, | 228 | .pdata = &sdhci_tegra114_pdata, |
202 | .nvquirks = NVQUIRK_DISABLE_SDR50 | | 229 | .nvquirks = NVQUIRK_DISABLE_SDR50 | |
203 | NVQUIRK_DISABLE_DDR50 | | 230 | NVQUIRK_DISABLE_DDR50 | |
204 | NVQUIRK_DISABLE_SDR104, | 231 | NVQUIRK_DISABLE_SDR104 | |
232 | NVQUIRK_SHADOW_XFER_MODE_REG, | ||
205 | }; | 233 | }; |
206 | 234 | ||
207 | static const struct of_device_id sdhci_tegra_dt_match[] = { | 235 | static const struct of_device_id sdhci_tegra_dt_match[] = { |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f1a488ee432f..0ad412a4876f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -53,6 +53,9 @@ static void sdhci_finish_command(struct sdhci_host *); | |||
53 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); | 53 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); |
54 | static void sdhci_tuning_timer(unsigned long data); | 54 | static void sdhci_tuning_timer(unsigned long data); |
55 | static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); | 55 | static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); |
56 | static int sdhci_pre_dma_transfer(struct sdhci_host *host, | ||
57 | struct mmc_data *data, | ||
58 | struct sdhci_host_next *next); | ||
56 | 59 | ||
57 | #ifdef CONFIG_PM | 60 | #ifdef CONFIG_PM |
58 | static int sdhci_runtime_pm_get(struct sdhci_host *host); | 61 | static int sdhci_runtime_pm_get(struct sdhci_host *host); |
@@ -505,9 +508,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
505 | goto fail; | 508 | goto fail; |
506 | BUG_ON(host->align_addr & host->align_mask); | 509 | BUG_ON(host->align_addr & host->align_mask); |
507 | 510 | ||
508 | host->sg_count = dma_map_sg(mmc_dev(host->mmc), | 511 | host->sg_count = sdhci_pre_dma_transfer(host, data, NULL); |
509 | data->sg, data->sg_len, direction); | 512 | if (host->sg_count < 0) |
510 | if (host->sg_count == 0) | ||
511 | goto unmap_align; | 513 | goto unmap_align; |
512 | 514 | ||
513 | desc = host->adma_table; | 515 | desc = host->adma_table; |
@@ -531,8 +533,6 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
531 | if (offset) { | 533 | if (offset) { |
532 | if (data->flags & MMC_DATA_WRITE) { | 534 | if (data->flags & MMC_DATA_WRITE) { |
533 | buffer = sdhci_kmap_atomic(sg, &flags); | 535 | buffer = sdhci_kmap_atomic(sg, &flags); |
534 | WARN_ON(((long)buffer & (PAGE_SIZE - 1)) > | ||
535 | (PAGE_SIZE - offset)); | ||
536 | memcpy(align, buffer, offset); | 536 | memcpy(align, buffer, offset); |
537 | sdhci_kunmap_atomic(buffer, &flags); | 537 | sdhci_kunmap_atomic(buffer, &flags); |
538 | } | 538 | } |
@@ -639,8 +639,6 @@ static void sdhci_adma_table_post(struct sdhci_host *host, | |||
639 | (sg_dma_address(sg) & host->align_mask); | 639 | (sg_dma_address(sg) & host->align_mask); |
640 | 640 | ||
641 | buffer = sdhci_kmap_atomic(sg, &flags); | 641 | buffer = sdhci_kmap_atomic(sg, &flags); |
642 | WARN_ON(((long)buffer & (PAGE_SIZE - 1)) > | ||
643 | (PAGE_SIZE - size)); | ||
644 | memcpy(buffer, align, size); | 642 | memcpy(buffer, align, size); |
645 | sdhci_kunmap_atomic(buffer, &flags); | 643 | sdhci_kunmap_atomic(buffer, &flags); |
646 | 644 | ||
@@ -649,8 +647,9 @@ static void sdhci_adma_table_post(struct sdhci_host *host, | |||
649 | } | 647 | } |
650 | } | 648 | } |
651 | 649 | ||
652 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 650 | if (!data->host_cookie) |
653 | data->sg_len, direction); | 651 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
652 | data->sg_len, direction); | ||
654 | } | 653 | } |
655 | 654 | ||
656 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | 655 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) |
@@ -846,11 +845,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
846 | } else { | 845 | } else { |
847 | int sg_cnt; | 846 | int sg_cnt; |
848 | 847 | ||
849 | sg_cnt = dma_map_sg(mmc_dev(host->mmc), | 848 | sg_cnt = sdhci_pre_dma_transfer(host, data, NULL); |
850 | data->sg, data->sg_len, | ||
851 | (data->flags & MMC_DATA_READ) ? | ||
852 | DMA_FROM_DEVICE : | ||
853 | DMA_TO_DEVICE); | ||
854 | if (sg_cnt == 0) { | 849 | if (sg_cnt == 0) { |
855 | /* | 850 | /* |
856 | * This only happens when someone fed | 851 | * This only happens when someone fed |
@@ -909,7 +904,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
909 | static void sdhci_set_transfer_mode(struct sdhci_host *host, | 904 | static void sdhci_set_transfer_mode(struct sdhci_host *host, |
910 | struct mmc_command *cmd) | 905 | struct mmc_command *cmd) |
911 | { | 906 | { |
912 | u16 mode; | 907 | u16 mode = 0; |
913 | struct mmc_data *data = cmd->data; | 908 | struct mmc_data *data = cmd->data; |
914 | 909 | ||
915 | if (data == NULL) { | 910 | if (data == NULL) { |
@@ -927,9 +922,11 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, | |||
927 | 922 | ||
928 | WARN_ON(!host->data); | 923 | WARN_ON(!host->data); |
929 | 924 | ||
930 | mode = SDHCI_TRNS_BLK_CNT_EN; | 925 | if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) |
926 | mode = SDHCI_TRNS_BLK_CNT_EN; | ||
927 | |||
931 | if (mmc_op_multi(cmd->opcode) || data->blocks > 1) { | 928 | if (mmc_op_multi(cmd->opcode) || data->blocks > 1) { |
932 | mode |= SDHCI_TRNS_MULTI; | 929 | mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI; |
933 | /* | 930 | /* |
934 | * If we are sending CMD23, CMD12 never gets sent | 931 | * If we are sending CMD23, CMD12 never gets sent |
935 | * on successful completion (so no Auto-CMD12). | 932 | * on successful completion (so no Auto-CMD12). |
@@ -963,8 +960,10 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
963 | if (host->flags & SDHCI_USE_ADMA) | 960 | if (host->flags & SDHCI_USE_ADMA) |
964 | sdhci_adma_table_post(host, data); | 961 | sdhci_adma_table_post(host, data); |
965 | else { | 962 | else { |
966 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 963 | if (!data->host_cookie) |
967 | data->sg_len, (data->flags & MMC_DATA_READ) ? | 964 | dma_unmap_sg(mmc_dev(host->mmc), |
965 | data->sg, data->sg_len, | ||
966 | (data->flags & MMC_DATA_READ) ? | ||
968 | DMA_FROM_DEVICE : DMA_TO_DEVICE); | 967 | DMA_FROM_DEVICE : DMA_TO_DEVICE); |
969 | } | 968 | } |
970 | } | 969 | } |
@@ -1630,7 +1629,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
1630 | * signalling timeout and CRC errors even on CMD0. Resetting | 1629 | * signalling timeout and CRC errors even on CMD0. Resetting |
1631 | * it on each ios seems to solve the problem. | 1630 | * it on each ios seems to solve the problem. |
1632 | */ | 1631 | */ |
1633 | if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) | 1632 | if (host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) |
1634 | sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); | 1633 | sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); |
1635 | 1634 | ||
1636 | mmiowb(); | 1635 | mmiowb(); |
@@ -1832,6 +1831,10 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, | |||
1832 | ctrl |= SDHCI_CTRL_VDD_180; | 1831 | ctrl |= SDHCI_CTRL_VDD_180; |
1833 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); | 1832 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); |
1834 | 1833 | ||
1834 | /* Some controller need to do more when switching */ | ||
1835 | if (host->ops->voltage_switch) | ||
1836 | host->ops->voltage_switch(host); | ||
1837 | |||
1835 | /* 1.8V regulator output should be stable within 5 ms */ | 1838 | /* 1.8V regulator output should be stable within 5 ms */ |
1836 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1839 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
1837 | if (ctrl & SDHCI_CTRL_VDD_180) | 1840 | if (ctrl & SDHCI_CTRL_VDD_180) |
@@ -1960,6 +1963,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1960 | 1963 | ||
1961 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1964 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
1962 | ctrl |= SDHCI_CTRL_EXEC_TUNING; | 1965 | ctrl |= SDHCI_CTRL_EXEC_TUNING; |
1966 | if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND) | ||
1967 | ctrl |= SDHCI_CTRL_TUNED_CLK; | ||
1963 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); | 1968 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); |
1964 | 1969 | ||
1965 | /* | 1970 | /* |
@@ -2129,6 +2134,77 @@ static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) | |||
2129 | } | 2134 | } |
2130 | } | 2135 | } |
2131 | 2136 | ||
2137 | static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
2138 | int err) | ||
2139 | { | ||
2140 | struct sdhci_host *host = mmc_priv(mmc); | ||
2141 | struct mmc_data *data = mrq->data; | ||
2142 | |||
2143 | if (host->flags & SDHCI_REQ_USE_DMA) { | ||
2144 | if (data->host_cookie) | ||
2145 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
2146 | data->flags & MMC_DATA_WRITE ? | ||
2147 | DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
2148 | mrq->data->host_cookie = 0; | ||
2149 | } | ||
2150 | } | ||
2151 | |||
2152 | static int sdhci_pre_dma_transfer(struct sdhci_host *host, | ||
2153 | struct mmc_data *data, | ||
2154 | struct sdhci_host_next *next) | ||
2155 | { | ||
2156 | int sg_count; | ||
2157 | |||
2158 | if (!next && data->host_cookie && | ||
2159 | data->host_cookie != host->next_data.cookie) { | ||
2160 | pr_debug(DRIVER_NAME "[%s] invalid cookie: %d, next-cookie %d\n", | ||
2161 | __func__, data->host_cookie, host->next_data.cookie); | ||
2162 | data->host_cookie = 0; | ||
2163 | } | ||
2164 | |||
2165 | /* Check if next job is already prepared */ | ||
2166 | if (next || | ||
2167 | (!next && data->host_cookie != host->next_data.cookie)) { | ||
2168 | sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, | ||
2169 | data->sg_len, | ||
2170 | data->flags & MMC_DATA_WRITE ? | ||
2171 | DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
2172 | |||
2173 | } else { | ||
2174 | sg_count = host->next_data.sg_count; | ||
2175 | host->next_data.sg_count = 0; | ||
2176 | } | ||
2177 | |||
2178 | |||
2179 | if (sg_count == 0) | ||
2180 | return -EINVAL; | ||
2181 | |||
2182 | if (next) { | ||
2183 | next->sg_count = sg_count; | ||
2184 | data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie; | ||
2185 | } else | ||
2186 | host->sg_count = sg_count; | ||
2187 | |||
2188 | return sg_count; | ||
2189 | } | ||
2190 | |||
2191 | static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
2192 | bool is_first_req) | ||
2193 | { | ||
2194 | struct sdhci_host *host = mmc_priv(mmc); | ||
2195 | |||
2196 | if (mrq->data->host_cookie) { | ||
2197 | mrq->data->host_cookie = 0; | ||
2198 | return; | ||
2199 | } | ||
2200 | |||
2201 | if (host->flags & SDHCI_REQ_USE_DMA) | ||
2202 | if (sdhci_pre_dma_transfer(host, | ||
2203 | mrq->data, | ||
2204 | &host->next_data) < 0) | ||
2205 | mrq->data->host_cookie = 0; | ||
2206 | } | ||
2207 | |||
2132 | static void sdhci_card_event(struct mmc_host *mmc) | 2208 | static void sdhci_card_event(struct mmc_host *mmc) |
2133 | { | 2209 | { |
2134 | struct sdhci_host *host = mmc_priv(mmc); | 2210 | struct sdhci_host *host = mmc_priv(mmc); |
@@ -2162,6 +2238,8 @@ static void sdhci_card_event(struct mmc_host *mmc) | |||
2162 | 2238 | ||
2163 | static const struct mmc_host_ops sdhci_ops = { | 2239 | static const struct mmc_host_ops sdhci_ops = { |
2164 | .request = sdhci_request, | 2240 | .request = sdhci_request, |
2241 | .post_req = sdhci_post_req, | ||
2242 | .pre_req = sdhci_pre_req, | ||
2165 | .set_ios = sdhci_set_ios, | 2243 | .set_ios = sdhci_set_ios, |
2166 | .get_cd = sdhci_get_cd, | 2244 | .get_cd = sdhci_get_cd, |
2167 | .get_ro = sdhci_get_ro, | 2245 | .get_ro = sdhci_get_ro, |
@@ -2793,9 +2871,9 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) | |||
2793 | /* Force clock and power re-program */ | 2871 | /* Force clock and power re-program */ |
2794 | host->pwr = 0; | 2872 | host->pwr = 0; |
2795 | host->clock = 0; | 2873 | host->clock = 0; |
2874 | sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios); | ||
2796 | sdhci_do_set_ios(host, &host->mmc->ios); | 2875 | sdhci_do_set_ios(host, &host->mmc->ios); |
2797 | 2876 | ||
2798 | sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios); | ||
2799 | if ((host_flags & SDHCI_PV_ENABLED) && | 2877 | if ((host_flags & SDHCI_PV_ENABLED) && |
2800 | !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) { | 2878 | !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) { |
2801 | spin_lock_irqsave(&host->lock, flags); | 2879 | spin_lock_irqsave(&host->lock, flags); |
@@ -3019,6 +3097,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3019 | host->max_clk = host->ops->get_max_clock(host); | 3097 | host->max_clk = host->ops->get_max_clock(host); |
3020 | } | 3098 | } |
3021 | 3099 | ||
3100 | host->next_data.cookie = 1; | ||
3022 | /* | 3101 | /* |
3023 | * In case of Host Controller v3.00, find out whether clock | 3102 | * In case of Host Controller v3.00, find out whether clock |
3024 | * multiplier is supported. | 3103 | * multiplier is supported. |
@@ -3338,9 +3417,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3338 | 3417 | ||
3339 | setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); | 3418 | setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); |
3340 | 3419 | ||
3341 | if (host->version >= SDHCI_SPEC_300) { | 3420 | init_waitqueue_head(&host->buf_ready_int); |
3342 | init_waitqueue_head(&host->buf_ready_int); | ||
3343 | 3421 | ||
3422 | if (host->version >= SDHCI_SPEC_300) { | ||
3344 | /* Initialize re-tuning timer */ | 3423 | /* Initialize re-tuning timer */ |
3345 | init_timer(&host->tuning_timer); | 3424 | init_timer(&host->tuning_timer); |
3346 | host->tuning_timer.data = (unsigned long)host; | 3425 | host->tuning_timer.data = (unsigned long)host; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 41a2c34299ed..0315e1844330 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -339,6 +339,7 @@ struct sdhci_ops { | |||
339 | void (*adma_workaround)(struct sdhci_host *host, u32 intmask); | 339 | void (*adma_workaround)(struct sdhci_host *host, u32 intmask); |
340 | void (*platform_init)(struct sdhci_host *host); | 340 | void (*platform_init)(struct sdhci_host *host); |
341 | void (*card_event)(struct sdhci_host *host); | 341 | void (*card_event)(struct sdhci_host *host); |
342 | void (*voltage_switch)(struct sdhci_host *host); | ||
342 | }; | 343 | }; |
343 | 344 | ||
344 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS | 345 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |
diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c new file mode 100644 index 000000000000..2fe8b91481b3 --- /dev/null +++ b/drivers/mmc/host/sdhci_f_sdh30.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * linux/drivers/mmc/host/sdhci_f_sdh30.c | ||
3 | * | ||
4 | * Copyright (C) 2013 - 2015 Fujitsu Semiconductor, Ltd | ||
5 | * Vincent Yang <vincent.yang@tw.fujitsu.com> | ||
6 | * Copyright (C) 2015 Linaro Ltd Andy Green <andy.green@linaro.org> | ||
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, version 2 of the License. | ||
11 | */ | ||
12 | |||
13 | #include <linux/err.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/clk.h> | ||
17 | |||
18 | #include "sdhci-pltfm.h" | ||
19 | |||
20 | /* F_SDH30 extended Controller registers */ | ||
21 | #define F_SDH30_AHB_CONFIG 0x100 | ||
22 | #define F_SDH30_AHB_BIGED 0x00000040 | ||
23 | #define F_SDH30_BUSLOCK_DMA 0x00000020 | ||
24 | #define F_SDH30_BUSLOCK_EN 0x00000010 | ||
25 | #define F_SDH30_SIN 0x00000008 | ||
26 | #define F_SDH30_AHB_INCR_16 0x00000004 | ||
27 | #define F_SDH30_AHB_INCR_8 0x00000002 | ||
28 | #define F_SDH30_AHB_INCR_4 0x00000001 | ||
29 | |||
30 | #define F_SDH30_TUNING_SETTING 0x108 | ||
31 | #define F_SDH30_CMD_CHK_DIS 0x00010000 | ||
32 | |||
33 | #define F_SDH30_IO_CONTROL2 0x114 | ||
34 | #define F_SDH30_CRES_O_DN 0x00080000 | ||
35 | #define F_SDH30_MSEL_O_1_8 0x00040000 | ||
36 | |||
37 | #define F_SDH30_ESD_CONTROL 0x124 | ||
38 | #define F_SDH30_EMMC_RST 0x00000002 | ||
39 | #define F_SDH30_EMMC_HS200 0x01000000 | ||
40 | |||
41 | #define F_SDH30_CMD_DAT_DELAY 0x200 | ||
42 | |||
43 | #define F_SDH30_MIN_CLOCK 400000 | ||
44 | |||
45 | struct f_sdhost_priv { | ||
46 | struct clk *clk_iface; | ||
47 | struct clk *clk; | ||
48 | u32 vendor_hs200; | ||
49 | struct device *dev; | ||
50 | }; | ||
51 | |||
52 | void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host) | ||
53 | { | ||
54 | struct f_sdhost_priv *priv = sdhci_priv(host); | ||
55 | u32 ctrl = 0; | ||
56 | |||
57 | usleep_range(2500, 3000); | ||
58 | ctrl = sdhci_readl(host, F_SDH30_IO_CONTROL2); | ||
59 | ctrl |= F_SDH30_CRES_O_DN; | ||
60 | sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2); | ||
61 | ctrl |= F_SDH30_MSEL_O_1_8; | ||
62 | sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2); | ||
63 | |||
64 | ctrl &= ~F_SDH30_CRES_O_DN; | ||
65 | sdhci_writel(host, ctrl, F_SDH30_IO_CONTROL2); | ||
66 | usleep_range(2500, 3000); | ||
67 | |||
68 | if (priv->vendor_hs200) { | ||
69 | dev_info(priv->dev, "%s: setting hs200\n", __func__); | ||
70 | ctrl = sdhci_readl(host, F_SDH30_ESD_CONTROL); | ||
71 | ctrl |= priv->vendor_hs200; | ||
72 | sdhci_writel(host, ctrl, F_SDH30_ESD_CONTROL); | ||
73 | } | ||
74 | |||
75 | ctrl = sdhci_readl(host, F_SDH30_TUNING_SETTING); | ||
76 | ctrl |= F_SDH30_CMD_CHK_DIS; | ||
77 | sdhci_writel(host, ctrl, F_SDH30_TUNING_SETTING); | ||
78 | } | ||
79 | |||
80 | unsigned int sdhci_f_sdh30_get_min_clock(struct sdhci_host *host) | ||
81 | { | ||
82 | return F_SDH30_MIN_CLOCK; | ||
83 | } | ||
84 | |||
85 | void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask) | ||
86 | { | ||
87 | if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0) | ||
88 | sdhci_writew(host, 0xBC01, SDHCI_CLOCK_CONTROL); | ||
89 | |||
90 | sdhci_reset(host, mask); | ||
91 | } | ||
92 | |||
93 | static const struct sdhci_ops sdhci_f_sdh30_ops = { | ||
94 | .voltage_switch = sdhci_f_sdh30_soft_voltage_switch, | ||
95 | .get_min_clock = sdhci_f_sdh30_get_min_clock, | ||
96 | .reset = sdhci_f_sdh30_reset, | ||
97 | .set_clock = sdhci_set_clock, | ||
98 | .set_bus_width = sdhci_set_bus_width, | ||
99 | .set_uhs_signaling = sdhci_set_uhs_signaling, | ||
100 | }; | ||
101 | |||
102 | static int sdhci_f_sdh30_probe(struct platform_device *pdev) | ||
103 | { | ||
104 | struct sdhci_host *host; | ||
105 | struct device *dev = &pdev->dev; | ||
106 | struct resource *res; | ||
107 | int irq, ctrl = 0, ret = 0; | ||
108 | struct f_sdhost_priv *priv; | ||
109 | u32 reg = 0; | ||
110 | |||
111 | irq = platform_get_irq(pdev, 0); | ||
112 | if (irq < 0) { | ||
113 | dev_err(dev, "%s: no irq specified\n", __func__); | ||
114 | return irq; | ||
115 | } | ||
116 | |||
117 | host = sdhci_alloc_host(dev, sizeof(struct sdhci_host) + | ||
118 | sizeof(struct f_sdhost_priv)); | ||
119 | if (IS_ERR(host)) | ||
120 | return PTR_ERR(host); | ||
121 | |||
122 | priv = sdhci_priv(host); | ||
123 | priv->dev = dev; | ||
124 | |||
125 | host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | ||
126 | SDHCI_QUIRK_INVERTED_WRITE_PROTECT; | ||
127 | host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | | ||
128 | SDHCI_QUIRK2_TUNING_WORK_AROUND; | ||
129 | |||
130 | ret = mmc_of_parse(host->mmc); | ||
131 | if (ret) | ||
132 | goto err; | ||
133 | |||
134 | platform_set_drvdata(pdev, host); | ||
135 | |||
136 | sdhci_get_of_property(pdev); | ||
137 | host->hw_name = "f_sdh30"; | ||
138 | host->ops = &sdhci_f_sdh30_ops; | ||
139 | host->irq = irq; | ||
140 | |||
141 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
142 | host->ioaddr = devm_ioremap_resource(&pdev->dev, res); | ||
143 | if (IS_ERR(host->ioaddr)) { | ||
144 | ret = PTR_ERR(host->ioaddr); | ||
145 | goto err; | ||
146 | } | ||
147 | |||
148 | priv->clk_iface = devm_clk_get(&pdev->dev, "iface"); | ||
149 | if (IS_ERR(priv->clk_iface)) { | ||
150 | ret = PTR_ERR(priv->clk_iface); | ||
151 | goto err; | ||
152 | } | ||
153 | |||
154 | ret = clk_prepare_enable(priv->clk_iface); | ||
155 | if (ret) | ||
156 | goto err; | ||
157 | |||
158 | priv->clk = devm_clk_get(&pdev->dev, "core"); | ||
159 | if (IS_ERR(priv->clk)) { | ||
160 | ret = PTR_ERR(priv->clk); | ||
161 | goto err_clk; | ||
162 | } | ||
163 | |||
164 | ret = clk_prepare_enable(priv->clk); | ||
165 | if (ret) | ||
166 | goto err_clk; | ||
167 | |||
168 | /* init vendor specific regs */ | ||
169 | ctrl = sdhci_readw(host, F_SDH30_AHB_CONFIG); | ||
170 | ctrl |= F_SDH30_SIN | F_SDH30_AHB_INCR_16 | F_SDH30_AHB_INCR_8 | | ||
171 | F_SDH30_AHB_INCR_4; | ||
172 | ctrl &= ~(F_SDH30_AHB_BIGED | F_SDH30_BUSLOCK_EN); | ||
173 | sdhci_writew(host, ctrl, F_SDH30_AHB_CONFIG); | ||
174 | |||
175 | reg = sdhci_readl(host, F_SDH30_ESD_CONTROL); | ||
176 | sdhci_writel(host, reg & ~F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL); | ||
177 | msleep(20); | ||
178 | sdhci_writel(host, reg | F_SDH30_EMMC_RST, F_SDH30_ESD_CONTROL); | ||
179 | |||
180 | reg = sdhci_readl(host, SDHCI_CAPABILITIES); | ||
181 | if (reg & SDHCI_CAN_DO_8BIT) | ||
182 | priv->vendor_hs200 = F_SDH30_EMMC_HS200; | ||
183 | |||
184 | ret = sdhci_add_host(host); | ||
185 | if (ret) | ||
186 | goto err_add_host; | ||
187 | |||
188 | return 0; | ||
189 | |||
190 | err_add_host: | ||
191 | clk_disable_unprepare(priv->clk); | ||
192 | err_clk: | ||
193 | clk_disable_unprepare(priv->clk_iface); | ||
194 | err: | ||
195 | sdhci_free_host(host); | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | static int sdhci_f_sdh30_remove(struct platform_device *pdev) | ||
200 | { | ||
201 | struct sdhci_host *host = platform_get_drvdata(pdev); | ||
202 | struct f_sdhost_priv *priv = sdhci_priv(host); | ||
203 | |||
204 | sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) == | ||
205 | 0xffffffff); | ||
206 | |||
207 | clk_disable_unprepare(priv->clk_iface); | ||
208 | clk_disable_unprepare(priv->clk); | ||
209 | |||
210 | sdhci_free_host(host); | ||
211 | platform_set_drvdata(pdev, NULL); | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static const struct of_device_id f_sdh30_dt_ids[] = { | ||
217 | { .compatible = "fujitsu,mb86s70-sdhci-3.0" }, | ||
218 | { /* sentinel */ } | ||
219 | }; | ||
220 | MODULE_DEVICE_TABLE(of, f_sdh30_dt_ids); | ||
221 | |||
222 | static struct platform_driver sdhci_f_sdh30_driver = { | ||
223 | .driver = { | ||
224 | .name = "f_sdh30", | ||
225 | .of_match_table = f_sdh30_dt_ids, | ||
226 | .pm = SDHCI_PLTFM_PMOPS, | ||
227 | }, | ||
228 | .probe = sdhci_f_sdh30_probe, | ||
229 | .remove = sdhci_f_sdh30_remove, | ||
230 | }; | ||
231 | |||
232 | module_platform_driver(sdhci_f_sdh30_driver); | ||
233 | |||
234 | MODULE_DESCRIPTION("F_SDH30 SD Card Controller driver"); | ||
235 | MODULE_LICENSE("GPL v2"); | ||
236 | MODULE_AUTHOR("FUJITSU SEMICONDUCTOR LTD."); | ||
237 | MODULE_ALIAS("platform:f_sdh30"); | ||
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 00c8ebdf8ec7..6906a905cd54 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c | |||
@@ -35,10 +35,13 @@ | |||
35 | 35 | ||
36 | #define EXT_ACC 0xe4 | 36 | #define EXT_ACC 0xe4 |
37 | 37 | ||
38 | #define host_to_priv(host) container_of((host)->pdata, struct sh_mobile_sdhi, mmc_data) | ||
39 | |||
38 | struct sh_mobile_sdhi_of_data { | 40 | struct sh_mobile_sdhi_of_data { |
39 | unsigned long tmio_flags; | 41 | unsigned long tmio_flags; |
40 | unsigned long capabilities; | 42 | unsigned long capabilities; |
41 | unsigned long capabilities2; | 43 | unsigned long capabilities2; |
44 | enum dma_slave_buswidth dma_buswidth; | ||
42 | dma_addr_t dma_rx_offset; | 45 | dma_addr_t dma_rx_offset; |
43 | }; | 46 | }; |
44 | 47 | ||
@@ -58,6 +61,7 @@ static const struct sh_mobile_sdhi_of_data of_rcar_gen2_compatible = { | |||
58 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE | | 61 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE | |
59 | TMIO_MMC_CLK_ACTUAL, | 62 | TMIO_MMC_CLK_ACTUAL, |
60 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, | 63 | .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, |
64 | .dma_buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
61 | .dma_rx_offset = 0x2000, | 65 | .dma_rx_offset = 0x2000, |
62 | }; | 66 | }; |
63 | 67 | ||
@@ -84,16 +88,43 @@ struct sh_mobile_sdhi { | |||
84 | struct tmio_mmc_dma dma_priv; | 88 | struct tmio_mmc_dma dma_priv; |
85 | }; | 89 | }; |
86 | 90 | ||
91 | static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width) | ||
92 | { | ||
93 | u32 val; | ||
94 | |||
95 | /* | ||
96 | * see also | ||
97 | * sh_mobile_sdhi_of_data :: dma_buswidth | ||
98 | */ | ||
99 | switch (sd_ctrl_read16(host, CTL_VERSION)) { | ||
100 | case 0x490C: | ||
101 | val = (width == 32) ? 0x0001 : 0x0000; | ||
102 | break; | ||
103 | case 0xCB0D: | ||
104 | val = (width == 32) ? 0x0000 : 0x0001; | ||
105 | break; | ||
106 | default: | ||
107 | /* nothing to do */ | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | sd_ctrl_write16(host, EXT_ACC, val); | ||
112 | } | ||
113 | |||
87 | static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f) | 114 | static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f) |
88 | { | 115 | { |
89 | struct mmc_host *mmc = platform_get_drvdata(pdev); | 116 | struct mmc_host *mmc = platform_get_drvdata(pdev); |
90 | struct tmio_mmc_host *host = mmc_priv(mmc); | 117 | struct tmio_mmc_host *host = mmc_priv(mmc); |
91 | struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data); | 118 | struct sh_mobile_sdhi *priv = host_to_priv(host); |
92 | int ret = clk_prepare_enable(priv->clk); | 119 | int ret = clk_prepare_enable(priv->clk); |
93 | if (ret < 0) | 120 | if (ret < 0) |
94 | return ret; | 121 | return ret; |
95 | 122 | ||
96 | *f = clk_get_rate(priv->clk); | 123 | *f = clk_get_rate(priv->clk); |
124 | |||
125 | /* enable 16bit data access on SDBUF as default */ | ||
126 | sh_mobile_sdhi_sdbuf_width(host, 16); | ||
127 | |||
97 | return 0; | 128 | return 0; |
98 | } | 129 | } |
99 | 130 | ||
@@ -101,7 +132,7 @@ static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev) | |||
101 | { | 132 | { |
102 | struct mmc_host *mmc = platform_get_drvdata(pdev); | 133 | struct mmc_host *mmc = platform_get_drvdata(pdev); |
103 | struct tmio_mmc_host *host = mmc_priv(mmc); | 134 | struct tmio_mmc_host *host = mmc_priv(mmc); |
104 | struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data); | 135 | struct sh_mobile_sdhi *priv = host_to_priv(host); |
105 | clk_disable_unprepare(priv->clk); | 136 | clk_disable_unprepare(priv->clk); |
106 | } | 137 | } |
107 | 138 | ||
@@ -113,7 +144,7 @@ static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host) | |||
113 | udelay(1); | 144 | udelay(1); |
114 | 145 | ||
115 | if (!timeout) { | 146 | if (!timeout) { |
116 | dev_warn(host->pdata->dev, "timeout waiting for SD bus idle\n"); | 147 | dev_warn(&host->pdev->dev, "timeout waiting for SD bus idle\n"); |
117 | return -EBUSY; | 148 | return -EBUSY; |
118 | } | 149 | } |
119 | 150 | ||
@@ -156,14 +187,13 @@ static int sh_mobile_sdhi_multi_io_quirk(struct mmc_card *card, | |||
156 | return blk_size; | 187 | return blk_size; |
157 | } | 188 | } |
158 | 189 | ||
159 | static void sh_mobile_sdhi_cd_wakeup(const struct platform_device *pdev) | 190 | static void sh_mobile_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable) |
160 | { | 191 | { |
161 | mmc_detect_change(platform_get_drvdata(pdev), msecs_to_jiffies(100)); | 192 | sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? 2 : 0); |
162 | } | ||
163 | 193 | ||
164 | static const struct sh_mobile_sdhi_ops sdhi_ops = { | 194 | /* enable 32bit access if DMA mode if possibile */ |
165 | .cd_wakeup = sh_mobile_sdhi_cd_wakeup, | 195 | sh_mobile_sdhi_sdbuf_width(host, enable ? 32 : 16); |
166 | }; | 196 | } |
167 | 197 | ||
168 | static int sh_mobile_sdhi_probe(struct platform_device *pdev) | 198 | static int sh_mobile_sdhi_probe(struct platform_device *pdev) |
169 | { | 199 | { |
@@ -177,7 +207,6 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
177 | int irq, ret, i = 0; | 207 | int irq, ret, i = 0; |
178 | bool multiplexed_isr = true; | 208 | bool multiplexed_isr = true; |
179 | struct tmio_mmc_dma *dma_priv; | 209 | struct tmio_mmc_dma *dma_priv; |
180 | u16 ver; | ||
181 | 210 | ||
182 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 211 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
183 | if (!res) | 212 | if (!res) |
@@ -192,26 +221,31 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
192 | mmc_data = &priv->mmc_data; | 221 | mmc_data = &priv->mmc_data; |
193 | dma_priv = &priv->dma_priv; | 222 | dma_priv = &priv->dma_priv; |
194 | 223 | ||
195 | if (p) { | ||
196 | if (p->init) { | ||
197 | ret = p->init(pdev, &sdhi_ops); | ||
198 | if (ret) | ||
199 | return ret; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | priv->clk = devm_clk_get(&pdev->dev, NULL); | 224 | priv->clk = devm_clk_get(&pdev->dev, NULL); |
204 | if (IS_ERR(priv->clk)) { | 225 | if (IS_ERR(priv->clk)) { |
205 | ret = PTR_ERR(priv->clk); | 226 | ret = PTR_ERR(priv->clk); |
206 | dev_err(&pdev->dev, "cannot get clock: %d\n", ret); | 227 | dev_err(&pdev->dev, "cannot get clock: %d\n", ret); |
207 | goto eclkget; | 228 | goto eprobe; |
208 | } | 229 | } |
209 | 230 | ||
210 | mmc_data->clk_enable = sh_mobile_sdhi_clk_enable; | 231 | host = tmio_mmc_host_alloc(pdev); |
211 | mmc_data->clk_disable = sh_mobile_sdhi_clk_disable; | 232 | if (!host) { |
233 | ret = -ENOMEM; | ||
234 | goto eprobe; | ||
235 | } | ||
236 | |||
237 | host->dma = dma_priv; | ||
238 | host->write16_hook = sh_mobile_sdhi_write16_hook; | ||
239 | host->clk_enable = sh_mobile_sdhi_clk_enable; | ||
240 | host->clk_disable = sh_mobile_sdhi_clk_disable; | ||
241 | host->multi_io_quirk = sh_mobile_sdhi_multi_io_quirk; | ||
242 | /* SD control register space size is 0x100, 0x200 for bus_shift=1 */ | ||
243 | if (resource_size(res) > 0x100) | ||
244 | host->bus_shift = 1; | ||
245 | else | ||
246 | host->bus_shift = 0; | ||
247 | |||
212 | mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; | 248 | mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED; |
213 | mmc_data->write16_hook = sh_mobile_sdhi_write16_hook; | ||
214 | mmc_data->multi_io_quirk = sh_mobile_sdhi_multi_io_quirk; | ||
215 | if (p) { | 249 | if (p) { |
216 | mmc_data->flags = p->tmio_flags; | 250 | mmc_data->flags = p->tmio_flags; |
217 | mmc_data->ocr_mask = p->tmio_ocr_mask; | 251 | mmc_data->ocr_mask = p->tmio_ocr_mask; |
@@ -231,11 +265,10 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
231 | dma_priv->slave_id_rx = p->dma_slave_rx; | 265 | dma_priv->slave_id_rx = p->dma_slave_rx; |
232 | } | 266 | } |
233 | } | 267 | } |
234 | |||
235 | dma_priv->alignment_shift = 1; /* 2-byte alignment */ | ||
236 | dma_priv->filter = shdma_chan_filter; | 268 | dma_priv->filter = shdma_chan_filter; |
269 | dma_priv->enable = sh_mobile_sdhi_enable_dma; | ||
237 | 270 | ||
238 | mmc_data->dma = dma_priv; | 271 | mmc_data->alignment_shift = 1; /* 2-byte alignment */ |
239 | 272 | ||
240 | /* | 273 | /* |
241 | * All SDHI blocks support 2-byte and larger block sizes in 4-bit | 274 | * All SDHI blocks support 2-byte and larger block sizes in 4-bit |
@@ -258,33 +291,18 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
258 | */ | 291 | */ |
259 | mmc_data->flags |= TMIO_MMC_SDIO_STATUS_QUIRK; | 292 | mmc_data->flags |= TMIO_MMC_SDIO_STATUS_QUIRK; |
260 | 293 | ||
261 | /* | ||
262 | * All SDHI have DMA control register | ||
263 | */ | ||
264 | mmc_data->flags |= TMIO_MMC_HAVE_CTL_DMA_REG; | ||
265 | |||
266 | if (of_id && of_id->data) { | 294 | if (of_id && of_id->data) { |
267 | const struct sh_mobile_sdhi_of_data *of_data = of_id->data; | 295 | const struct sh_mobile_sdhi_of_data *of_data = of_id->data; |
268 | mmc_data->flags |= of_data->tmio_flags; | 296 | mmc_data->flags |= of_data->tmio_flags; |
269 | mmc_data->capabilities |= of_data->capabilities; | 297 | mmc_data->capabilities |= of_data->capabilities; |
270 | mmc_data->capabilities2 |= of_data->capabilities2; | 298 | mmc_data->capabilities2 |= of_data->capabilities2; |
271 | dma_priv->dma_rx_offset = of_data->dma_rx_offset; | 299 | mmc_data->dma_rx_offset = of_data->dma_rx_offset; |
300 | dma_priv->dma_buswidth = of_data->dma_buswidth; | ||
272 | } | 301 | } |
273 | 302 | ||
274 | /* SD control register space size is 0x100, 0x200 for bus_shift=1 */ | 303 | ret = tmio_mmc_host_probe(host, mmc_data); |
275 | mmc_data->bus_shift = resource_size(res) >> 9; | ||
276 | |||
277 | ret = tmio_mmc_host_probe(&host, pdev, mmc_data); | ||
278 | if (ret < 0) | 304 | if (ret < 0) |
279 | goto eprobe; | 305 | goto efree; |
280 | |||
281 | /* | ||
282 | * FIXME: | ||
283 | * this Workaround can be more clever method | ||
284 | */ | ||
285 | ver = sd_ctrl_read16(host, CTL_VERSION); | ||
286 | if (ver == 0xCB0D) | ||
287 | sd_ctrl_write16(host, EXT_ACC, 1); | ||
288 | 306 | ||
289 | /* | 307 | /* |
290 | * Allow one or more specific (named) ISRs or | 308 | * Allow one or more specific (named) ISRs or |
@@ -351,10 +369,9 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev) | |||
351 | 369 | ||
352 | eirq: | 370 | eirq: |
353 | tmio_mmc_host_remove(host); | 371 | tmio_mmc_host_remove(host); |
372 | efree: | ||
373 | tmio_mmc_host_free(host); | ||
354 | eprobe: | 374 | eprobe: |
355 | eclkget: | ||
356 | if (p && p->cleanup) | ||
357 | p->cleanup(pdev); | ||
358 | return ret; | 375 | return ret; |
359 | } | 376 | } |
360 | 377 | ||
@@ -362,13 +379,9 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev) | |||
362 | { | 379 | { |
363 | struct mmc_host *mmc = platform_get_drvdata(pdev); | 380 | struct mmc_host *mmc = platform_get_drvdata(pdev); |
364 | struct tmio_mmc_host *host = mmc_priv(mmc); | 381 | struct tmio_mmc_host *host = mmc_priv(mmc); |
365 | struct sh_mobile_sdhi_info *p = pdev->dev.platform_data; | ||
366 | 382 | ||
367 | tmio_mmc_host_remove(host); | 383 | tmio_mmc_host_remove(host); |
368 | 384 | ||
369 | if (p && p->cleanup) | ||
370 | p->cleanup(pdev); | ||
371 | |||
372 | return 0; | 385 | return 0; |
373 | } | 386 | } |
374 | 387 | ||
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 15cb8b7ffc34..6af0a28ba37d 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c | |||
@@ -252,7 +252,7 @@ static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host) | |||
252 | unsigned long expire = jiffies + msecs_to_jiffies(250); | 252 | unsigned long expire = jiffies + msecs_to_jiffies(250); |
253 | u32 rval; | 253 | u32 rval; |
254 | 254 | ||
255 | mmc_writel(host, REG_CMDR, SDXC_HARDWARE_RESET); | 255 | mmc_writel(host, REG_GCTRL, SDXC_HARDWARE_RESET); |
256 | do { | 256 | do { |
257 | rval = mmc_readl(host, REG_GCTRL); | 257 | rval = mmc_readl(host, REG_GCTRL); |
258 | } while (time_before(jiffies, expire) && (rval & SDXC_HARDWARE_RESET)); | 258 | } while (time_before(jiffies, expire) && (rval & SDXC_HARDWARE_RESET)); |
@@ -310,7 +310,9 @@ static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host, | |||
310 | } | 310 | } |
311 | 311 | ||
312 | pdes[0].config |= SDXC_IDMAC_DES0_FD; | 312 | pdes[0].config |= SDXC_IDMAC_DES0_FD; |
313 | pdes[i - 1].config = SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_LD; | 313 | pdes[i - 1].config |= SDXC_IDMAC_DES0_LD | SDXC_IDMAC_DES0_ER; |
314 | pdes[i - 1].config &= ~SDXC_IDMAC_DES0_DIC; | ||
315 | pdes[i - 1].buf_addr_ptr2 = 0; | ||
314 | 316 | ||
315 | /* | 317 | /* |
316 | * Avoid the io-store starting the idmac hitting io-mem before the | 318 | * Avoid the io-store starting the idmac hitting io-mem before the |
@@ -570,6 +572,15 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id) | |||
570 | } | 572 | } |
571 | 573 | ||
572 | dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); | 574 | dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); |
575 | |||
576 | /* | ||
577 | * We will never have more than one outstanding request, | ||
578 | * and we do not complete the request until after | ||
579 | * we've cleared host->manual_stop_mrq so we do not need to | ||
580 | * spin lock this function. | ||
581 | * Additionally we have wait states within this function | ||
582 | * so having it in a lock is a very bad idea. | ||
583 | */ | ||
573 | sunxi_mmc_send_manual_stop(host, mrq); | 584 | sunxi_mmc_send_manual_stop(host, mrq); |
574 | 585 | ||
575 | spin_lock_irqsave(&host->lock, iflags); | 586 | spin_lock_irqsave(&host->lock, iflags); |
@@ -616,7 +627,7 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) | |||
616 | static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | 627 | static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, |
617 | struct mmc_ios *ios) | 628 | struct mmc_ios *ios) |
618 | { | 629 | { |
619 | u32 rate, oclk_dly, rval, sclk_dly, src_clk; | 630 | u32 rate, oclk_dly, rval, sclk_dly; |
620 | int ret; | 631 | int ret; |
621 | 632 | ||
622 | rate = clk_round_rate(host->clk_mmc, ios->clock); | 633 | rate = clk_round_rate(host->clk_mmc, ios->clock); |
@@ -661,14 +672,6 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host, | |||
661 | sclk_dly = 4; | 672 | sclk_dly = 4; |
662 | } | 673 | } |
663 | 674 | ||
664 | src_clk = clk_get_rate(clk_get_parent(host->clk_mmc)); | ||
665 | if (src_clk >= 300000000 && src_clk <= 400000000) { | ||
666 | if (oclk_dly) | ||
667 | oclk_dly--; | ||
668 | if (sclk_dly) | ||
669 | sclk_dly--; | ||
670 | } | ||
671 | |||
672 | clk_sunxi_mmc_phase_control(host->clk_mmc, sclk_dly, oclk_dly); | 675 | clk_sunxi_mmc_phase_control(host->clk_mmc, sclk_dly, oclk_dly); |
673 | 676 | ||
674 | return sunxi_mmc_oclk_onoff(host, 1); | 677 | return sunxi_mmc_oclk_onoff(host, 1); |
@@ -766,6 +769,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
766 | unsigned long iflags; | 769 | unsigned long iflags; |
767 | u32 imask = SDXC_INTERRUPT_ERROR_BIT; | 770 | u32 imask = SDXC_INTERRUPT_ERROR_BIT; |
768 | u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); | 771 | u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); |
772 | bool wait_dma = host->wait_dma; | ||
769 | int ret; | 773 | int ret; |
770 | 774 | ||
771 | /* Check for set_ios errors (should never happen) */ | 775 | /* Check for set_ios errors (should never happen) */ |
@@ -816,7 +820,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
816 | if (cmd->data->flags & MMC_DATA_WRITE) | 820 | if (cmd->data->flags & MMC_DATA_WRITE) |
817 | cmd_val |= SDXC_WRITE; | 821 | cmd_val |= SDXC_WRITE; |
818 | else | 822 | else |
819 | host->wait_dma = true; | 823 | wait_dma = true; |
820 | } else { | 824 | } else { |
821 | imask |= SDXC_COMMAND_DONE; | 825 | imask |= SDXC_COMMAND_DONE; |
822 | } | 826 | } |
@@ -850,6 +854,7 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
850 | } | 854 | } |
851 | 855 | ||
852 | host->mrq = mrq; | 856 | host->mrq = mrq; |
857 | host->wait_dma = wait_dma; | ||
853 | mmc_writel(host, REG_IMASK, host->sdio_imask | imask); | 858 | mmc_writel(host, REG_IMASK, host->sdio_imask | imask); |
854 | mmc_writel(host, REG_CARG, cmd->arg); | 859 | mmc_writel(host, REG_CARG, cmd->arg); |
855 | mmc_writel(host, REG_CMDR, cmd_val); | 860 | mmc_writel(host, REG_CMDR, cmd_val); |
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 2ca0afaab792..f746df493892 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -88,14 +88,19 @@ static int tmio_mmc_probe(struct platform_device *pdev) | |||
88 | if (!res) | 88 | if (!res) |
89 | return -EINVAL; | 89 | return -EINVAL; |
90 | 90 | ||
91 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ | ||
92 | pdata->bus_shift = resource_size(res) >> 10; | ||
93 | pdata->flags |= TMIO_MMC_HAVE_HIGH_REG; | 91 | pdata->flags |= TMIO_MMC_HAVE_HIGH_REG; |
94 | 92 | ||
95 | ret = tmio_mmc_host_probe(&host, pdev, pdata); | 93 | host = tmio_mmc_host_alloc(pdev); |
96 | if (ret) | 94 | if (!host) |
97 | goto cell_disable; | 95 | goto cell_disable; |
98 | 96 | ||
97 | /* SD control register space size is 0x200, 0x400 for bus_shift=1 */ | ||
98 | host->bus_shift = resource_size(res) >> 10; | ||
99 | |||
100 | ret = tmio_mmc_host_probe(host, pdata); | ||
101 | if (ret) | ||
102 | goto host_free; | ||
103 | |||
99 | ret = request_irq(irq, tmio_mmc_irq, IRQF_TRIGGER_FALLING, | 104 | ret = request_irq(irq, tmio_mmc_irq, IRQF_TRIGGER_FALLING, |
100 | dev_name(&pdev->dev), host); | 105 | dev_name(&pdev->dev), host); |
101 | if (ret) | 106 | if (ret) |
@@ -108,6 +113,8 @@ static int tmio_mmc_probe(struct platform_device *pdev) | |||
108 | 113 | ||
109 | host_remove: | 114 | host_remove: |
110 | tmio_mmc_host_remove(host); | 115 | tmio_mmc_host_remove(host); |
116 | host_free: | ||
117 | tmio_mmc_host_free(host); | ||
111 | cell_disable: | 118 | cell_disable: |
112 | if (cell->disable) | 119 | if (cell->disable) |
113 | cell->disable(pdev); | 120 | cell->disable(pdev); |
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index a34ecbe1c1ad..fc3805ed69d1 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #ifndef TMIO_MMC_H | 16 | #ifndef TMIO_MMC_H |
17 | #define TMIO_MMC_H | 17 | #define TMIO_MMC_H |
18 | 18 | ||
19 | #include <linux/dmaengine.h> | ||
19 | #include <linux/highmem.h> | 20 | #include <linux/highmem.h> |
20 | #include <linux/mmc/tmio.h> | 21 | #include <linux/mmc/tmio.h> |
21 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
@@ -39,6 +40,17 @@ | |||
39 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) | 40 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) |
40 | 41 | ||
41 | struct tmio_mmc_data; | 42 | struct tmio_mmc_data; |
43 | struct tmio_mmc_host; | ||
44 | |||
45 | struct tmio_mmc_dma { | ||
46 | void *chan_priv_tx; | ||
47 | void *chan_priv_rx; | ||
48 | int slave_id_tx; | ||
49 | int slave_id_rx; | ||
50 | enum dma_slave_buswidth dma_buswidth; | ||
51 | bool (*filter)(struct dma_chan *chan, void *arg); | ||
52 | void (*enable)(struct tmio_mmc_host *host, bool enable); | ||
53 | }; | ||
42 | 54 | ||
43 | struct tmio_mmc_host { | 55 | struct tmio_mmc_host { |
44 | void __iomem *ctl; | 56 | void __iomem *ctl; |
@@ -56,9 +68,11 @@ struct tmio_mmc_host { | |||
56 | struct scatterlist *sg_orig; | 68 | struct scatterlist *sg_orig; |
57 | unsigned int sg_len; | 69 | unsigned int sg_len; |
58 | unsigned int sg_off; | 70 | unsigned int sg_off; |
71 | unsigned long bus_shift; | ||
59 | 72 | ||
60 | struct platform_device *pdev; | 73 | struct platform_device *pdev; |
61 | struct tmio_mmc_data *pdata; | 74 | struct tmio_mmc_data *pdata; |
75 | struct tmio_mmc_dma *dma; | ||
62 | 76 | ||
63 | /* DMA support */ | 77 | /* DMA support */ |
64 | bool force_pio; | 78 | bool force_pio; |
@@ -83,10 +97,17 @@ struct tmio_mmc_host { | |||
83 | struct mutex ios_lock; /* protect set_ios() context */ | 97 | struct mutex ios_lock; /* protect set_ios() context */ |
84 | bool native_hotplug; | 98 | bool native_hotplug; |
85 | bool sdio_irq_enabled; | 99 | bool sdio_irq_enabled; |
100 | |||
101 | int (*write16_hook)(struct tmio_mmc_host *host, int addr); | ||
102 | int (*clk_enable)(struct platform_device *pdev, unsigned int *f); | ||
103 | void (*clk_disable)(struct platform_device *pdev); | ||
104 | int (*multi_io_quirk)(struct mmc_card *card, | ||
105 | unsigned int direction, int blk_size); | ||
86 | }; | 106 | }; |
87 | 107 | ||
88 | int tmio_mmc_host_probe(struct tmio_mmc_host **host, | 108 | struct tmio_mmc_host *tmio_mmc_host_alloc(struct platform_device *pdev); |
89 | struct platform_device *pdev, | 109 | void tmio_mmc_host_free(struct tmio_mmc_host *host); |
110 | int tmio_mmc_host_probe(struct tmio_mmc_host *host, | ||
90 | struct tmio_mmc_data *pdata); | 111 | struct tmio_mmc_data *pdata); |
91 | void tmio_mmc_host_remove(struct tmio_mmc_host *host); | 112 | void tmio_mmc_host_remove(struct tmio_mmc_host *host); |
92 | void tmio_mmc_do_data_irq(struct tmio_mmc_host *host); | 113 | void tmio_mmc_do_data_irq(struct tmio_mmc_host *host); |
@@ -151,19 +172,19 @@ int tmio_mmc_host_runtime_resume(struct device *dev); | |||
151 | 172 | ||
152 | static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr) | 173 | static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr) |
153 | { | 174 | { |
154 | return readw(host->ctl + (addr << host->pdata->bus_shift)); | 175 | return readw(host->ctl + (addr << host->bus_shift)); |
155 | } | 176 | } |
156 | 177 | ||
157 | static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr, | 178 | static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr, |
158 | u16 *buf, int count) | 179 | u16 *buf, int count) |
159 | { | 180 | { |
160 | readsw(host->ctl + (addr << host->pdata->bus_shift), buf, count); | 181 | readsw(host->ctl + (addr << host->bus_shift), buf, count); |
161 | } | 182 | } |
162 | 183 | ||
163 | static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr) | 184 | static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr) |
164 | { | 185 | { |
165 | return readw(host->ctl + (addr << host->pdata->bus_shift)) | | 186 | return readw(host->ctl + (addr << host->bus_shift)) | |
166 | readw(host->ctl + ((addr + 2) << host->pdata->bus_shift)) << 16; | 187 | readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16; |
167 | } | 188 | } |
168 | 189 | ||
169 | static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val) | 190 | static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val) |
@@ -171,21 +192,21 @@ static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val | |||
171 | /* If there is a hook and it returns non-zero then there | 192 | /* If there is a hook and it returns non-zero then there |
172 | * is an error and the write should be skipped | 193 | * is an error and the write should be skipped |
173 | */ | 194 | */ |
174 | if (host->pdata->write16_hook && host->pdata->write16_hook(host, addr)) | 195 | if (host->write16_hook && host->write16_hook(host, addr)) |
175 | return; | 196 | return; |
176 | writew(val, host->ctl + (addr << host->pdata->bus_shift)); | 197 | writew(val, host->ctl + (addr << host->bus_shift)); |
177 | } | 198 | } |
178 | 199 | ||
179 | static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr, | 200 | static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr, |
180 | u16 *buf, int count) | 201 | u16 *buf, int count) |
181 | { | 202 | { |
182 | writesw(host->ctl + (addr << host->pdata->bus_shift), buf, count); | 203 | writesw(host->ctl + (addr << host->bus_shift), buf, count); |
183 | } | 204 | } |
184 | 205 | ||
185 | static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val) | 206 | static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val) |
186 | { | 207 | { |
187 | writew(val, host->ctl + (addr << host->pdata->bus_shift)); | 208 | writew(val, host->ctl + (addr << host->bus_shift)); |
188 | writew(val >> 16, host->ctl + ((addr + 2) << host->pdata->bus_shift)); | 209 | writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift)); |
189 | } | 210 | } |
190 | 211 | ||
191 | 212 | ||
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c index 7d077388b9eb..331bb618e398 100644 --- a/drivers/mmc/host/tmio_mmc_dma.c +++ b/drivers/mmc/host/tmio_mmc_dma.c | |||
@@ -28,8 +28,8 @@ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) | |||
28 | if (!host->chan_tx || !host->chan_rx) | 28 | if (!host->chan_tx || !host->chan_rx) |
29 | return; | 29 | return; |
30 | 30 | ||
31 | if (host->pdata->flags & TMIO_MMC_HAVE_CTL_DMA_REG) | 31 | if (host->dma->enable) |
32 | sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? 2 : 0); | 32 | host->dma->enable(host, enable); |
33 | } | 33 | } |
34 | 34 | ||
35 | void tmio_mmc_abort_dma(struct tmio_mmc_host *host) | 35 | void tmio_mmc_abort_dma(struct tmio_mmc_host *host) |
@@ -49,11 +49,10 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host) | |||
49 | struct scatterlist *sg = host->sg_ptr, *sg_tmp; | 49 | struct scatterlist *sg = host->sg_ptr, *sg_tmp; |
50 | struct dma_async_tx_descriptor *desc = NULL; | 50 | struct dma_async_tx_descriptor *desc = NULL; |
51 | struct dma_chan *chan = host->chan_rx; | 51 | struct dma_chan *chan = host->chan_rx; |
52 | struct tmio_mmc_data *pdata = host->pdata; | ||
53 | dma_cookie_t cookie; | 52 | dma_cookie_t cookie; |
54 | int ret, i; | 53 | int ret, i; |
55 | bool aligned = true, multiple = true; | 54 | bool aligned = true, multiple = true; |
56 | unsigned int align = (1 << pdata->dma->alignment_shift) - 1; | 55 | unsigned int align = (1 << host->pdata->alignment_shift) - 1; |
57 | 56 | ||
58 | for_each_sg(sg, sg_tmp, host->sg_len, i) { | 57 | for_each_sg(sg, sg_tmp, host->sg_len, i) { |
59 | if (sg_tmp->offset & align) | 58 | if (sg_tmp->offset & align) |
@@ -126,11 +125,10 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host) | |||
126 | struct scatterlist *sg = host->sg_ptr, *sg_tmp; | 125 | struct scatterlist *sg = host->sg_ptr, *sg_tmp; |
127 | struct dma_async_tx_descriptor *desc = NULL; | 126 | struct dma_async_tx_descriptor *desc = NULL; |
128 | struct dma_chan *chan = host->chan_tx; | 127 | struct dma_chan *chan = host->chan_tx; |
129 | struct tmio_mmc_data *pdata = host->pdata; | ||
130 | dma_cookie_t cookie; | 128 | dma_cookie_t cookie; |
131 | int ret, i; | 129 | int ret, i; |
132 | bool aligned = true, multiple = true; | 130 | bool aligned = true, multiple = true; |
133 | unsigned int align = (1 << pdata->dma->alignment_shift) - 1; | 131 | unsigned int align = (1 << host->pdata->alignment_shift) - 1; |
134 | 132 | ||
135 | for_each_sg(sg, sg_tmp, host->sg_len, i) { | 133 | for_each_sg(sg, sg_tmp, host->sg_len, i) { |
136 | if (sg_tmp->offset & align) | 134 | if (sg_tmp->offset & align) |
@@ -262,8 +260,8 @@ out: | |||
262 | void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata) | 260 | void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata) |
263 | { | 261 | { |
264 | /* We can only either use DMA for both Tx and Rx or not use it at all */ | 262 | /* We can only either use DMA for both Tx and Rx or not use it at all */ |
265 | if (!pdata->dma || (!host->pdev->dev.of_node && | 263 | if (!host->dma || (!host->pdev->dev.of_node && |
266 | (!pdata->dma->chan_priv_tx || !pdata->dma->chan_priv_rx))) | 264 | (!host->dma->chan_priv_tx || !host->dma->chan_priv_rx))) |
267 | return; | 265 | return; |
268 | 266 | ||
269 | if (!host->chan_tx && !host->chan_rx) { | 267 | if (!host->chan_tx && !host->chan_rx) { |
@@ -280,7 +278,7 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat | |||
280 | dma_cap_set(DMA_SLAVE, mask); | 278 | dma_cap_set(DMA_SLAVE, mask); |
281 | 279 | ||
282 | host->chan_tx = dma_request_slave_channel_compat(mask, | 280 | host->chan_tx = dma_request_slave_channel_compat(mask, |
283 | pdata->dma->filter, pdata->dma->chan_priv_tx, | 281 | host->dma->filter, host->dma->chan_priv_tx, |
284 | &host->pdev->dev, "tx"); | 282 | &host->pdev->dev, "tx"); |
285 | dev_dbg(&host->pdev->dev, "%s: TX: got channel %p\n", __func__, | 283 | dev_dbg(&host->pdev->dev, "%s: TX: got channel %p\n", __func__, |
286 | host->chan_tx); | 284 | host->chan_tx); |
@@ -288,18 +286,20 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat | |||
288 | if (!host->chan_tx) | 286 | if (!host->chan_tx) |
289 | return; | 287 | return; |
290 | 288 | ||
291 | if (pdata->dma->chan_priv_tx) | 289 | if (host->dma->chan_priv_tx) |
292 | cfg.slave_id = pdata->dma->slave_id_tx; | 290 | cfg.slave_id = host->dma->slave_id_tx; |
293 | cfg.direction = DMA_MEM_TO_DEV; | 291 | cfg.direction = DMA_MEM_TO_DEV; |
294 | cfg.dst_addr = res->start + (CTL_SD_DATA_PORT << host->pdata->bus_shift); | 292 | cfg.dst_addr = res->start + (CTL_SD_DATA_PORT << host->bus_shift); |
295 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 293 | cfg.dst_addr_width = host->dma->dma_buswidth; |
294 | if (!cfg.dst_addr_width) | ||
295 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
296 | cfg.src_addr = 0; | 296 | cfg.src_addr = 0; |
297 | ret = dmaengine_slave_config(host->chan_tx, &cfg); | 297 | ret = dmaengine_slave_config(host->chan_tx, &cfg); |
298 | if (ret < 0) | 298 | if (ret < 0) |
299 | goto ecfgtx; | 299 | goto ecfgtx; |
300 | 300 | ||
301 | host->chan_rx = dma_request_slave_channel_compat(mask, | 301 | host->chan_rx = dma_request_slave_channel_compat(mask, |
302 | pdata->dma->filter, pdata->dma->chan_priv_rx, | 302 | host->dma->filter, host->dma->chan_priv_rx, |
303 | &host->pdev->dev, "rx"); | 303 | &host->pdev->dev, "rx"); |
304 | dev_dbg(&host->pdev->dev, "%s: RX: got channel %p\n", __func__, | 304 | dev_dbg(&host->pdev->dev, "%s: RX: got channel %p\n", __func__, |
305 | host->chan_rx); | 305 | host->chan_rx); |
@@ -307,11 +307,13 @@ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdat | |||
307 | if (!host->chan_rx) | 307 | if (!host->chan_rx) |
308 | goto ereqrx; | 308 | goto ereqrx; |
309 | 309 | ||
310 | if (pdata->dma->chan_priv_rx) | 310 | if (host->dma->chan_priv_rx) |
311 | cfg.slave_id = pdata->dma->slave_id_rx; | 311 | cfg.slave_id = host->dma->slave_id_rx; |
312 | cfg.direction = DMA_DEV_TO_MEM; | 312 | cfg.direction = DMA_DEV_TO_MEM; |
313 | cfg.src_addr = cfg.dst_addr + pdata->dma->dma_rx_offset; | 313 | cfg.src_addr = cfg.dst_addr + host->pdata->dma_rx_offset; |
314 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 314 | cfg.src_addr_width = host->dma->dma_buswidth; |
315 | if (!cfg.src_addr_width) | ||
316 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
315 | cfg.dst_addr = 0; | 317 | cfg.dst_addr = 0; |
316 | ret = dmaengine_slave_config(host->chan_rx, &cfg); | 318 | ret = dmaengine_slave_config(host->chan_rx, &cfg); |
317 | if (ret < 0) | 319 | if (ret < 0) |
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 250bf8c9f998..a31c3573d386 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -835,13 +835,12 @@ fail: | |||
835 | static int tmio_mmc_clk_update(struct tmio_mmc_host *host) | 835 | static int tmio_mmc_clk_update(struct tmio_mmc_host *host) |
836 | { | 836 | { |
837 | struct mmc_host *mmc = host->mmc; | 837 | struct mmc_host *mmc = host->mmc; |
838 | struct tmio_mmc_data *pdata = host->pdata; | ||
839 | int ret; | 838 | int ret; |
840 | 839 | ||
841 | if (!pdata->clk_enable) | 840 | if (!host->clk_enable) |
842 | return -ENOTSUPP; | 841 | return -ENOTSUPP; |
843 | 842 | ||
844 | ret = pdata->clk_enable(host->pdev, &mmc->f_max); | 843 | ret = host->clk_enable(host->pdev, &mmc->f_max); |
845 | if (!ret) | 844 | if (!ret) |
846 | mmc->f_min = mmc->f_max / 512; | 845 | mmc->f_min = mmc->f_max / 512; |
847 | 846 | ||
@@ -1005,10 +1004,9 @@ static int tmio_multi_io_quirk(struct mmc_card *card, | |||
1005 | unsigned int direction, int blk_size) | 1004 | unsigned int direction, int blk_size) |
1006 | { | 1005 | { |
1007 | struct tmio_mmc_host *host = mmc_priv(card->host); | 1006 | struct tmio_mmc_host *host = mmc_priv(card->host); |
1008 | struct tmio_mmc_data *pdata = host->pdata; | ||
1009 | 1007 | ||
1010 | if (pdata->multi_io_quirk) | 1008 | if (host->multi_io_quirk) |
1011 | return pdata->multi_io_quirk(card, direction, blk_size); | 1009 | return host->multi_io_quirk(card, direction, blk_size); |
1012 | 1010 | ||
1013 | return blk_size; | 1011 | return blk_size; |
1014 | } | 1012 | } |
@@ -1054,12 +1052,37 @@ static void tmio_mmc_of_parse(struct platform_device *pdev, | |||
1054 | pdata->flags |= TMIO_MMC_WRPROTECT_DISABLE; | 1052 | pdata->flags |= TMIO_MMC_WRPROTECT_DISABLE; |
1055 | } | 1053 | } |
1056 | 1054 | ||
1057 | int tmio_mmc_host_probe(struct tmio_mmc_host **host, | 1055 | struct tmio_mmc_host* |
1058 | struct platform_device *pdev, | 1056 | tmio_mmc_host_alloc(struct platform_device *pdev) |
1059 | struct tmio_mmc_data *pdata) | ||
1060 | { | 1057 | { |
1061 | struct tmio_mmc_host *_host; | 1058 | struct tmio_mmc_host *host; |
1062 | struct mmc_host *mmc; | 1059 | struct mmc_host *mmc; |
1060 | |||
1061 | mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &pdev->dev); | ||
1062 | if (!mmc) | ||
1063 | return NULL; | ||
1064 | |||
1065 | host = mmc_priv(mmc); | ||
1066 | host->mmc = mmc; | ||
1067 | host->pdev = pdev; | ||
1068 | |||
1069 | return host; | ||
1070 | } | ||
1071 | EXPORT_SYMBOL(tmio_mmc_host_alloc); | ||
1072 | |||
1073 | void tmio_mmc_host_free(struct tmio_mmc_host *host) | ||
1074 | { | ||
1075 | mmc_free_host(host->mmc); | ||
1076 | |||
1077 | host->mmc = NULL; | ||
1078 | } | ||
1079 | EXPORT_SYMBOL(tmio_mmc_host_free); | ||
1080 | |||
1081 | int tmio_mmc_host_probe(struct tmio_mmc_host *_host, | ||
1082 | struct tmio_mmc_data *pdata) | ||
1083 | { | ||
1084 | struct platform_device *pdev = _host->pdev; | ||
1085 | struct mmc_host *mmc = _host->mmc; | ||
1063 | struct resource *res_ctl; | 1086 | struct resource *res_ctl; |
1064 | int ret; | 1087 | int ret; |
1065 | u32 irq_mask = TMIO_MASK_CMD; | 1088 | u32 irq_mask = TMIO_MASK_CMD; |
@@ -1067,25 +1090,17 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
1067 | tmio_mmc_of_parse(pdev, pdata); | 1090 | tmio_mmc_of_parse(pdev, pdata); |
1068 | 1091 | ||
1069 | if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT)) | 1092 | if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT)) |
1070 | pdata->write16_hook = NULL; | 1093 | _host->write16_hook = NULL; |
1071 | 1094 | ||
1072 | res_ctl = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1095 | res_ctl = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1073 | if (!res_ctl) | 1096 | if (!res_ctl) |
1074 | return -EINVAL; | 1097 | return -EINVAL; |
1075 | 1098 | ||
1076 | mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &pdev->dev); | ||
1077 | if (!mmc) | ||
1078 | return -ENOMEM; | ||
1079 | |||
1080 | ret = mmc_of_parse(mmc); | 1099 | ret = mmc_of_parse(mmc); |
1081 | if (ret < 0) | 1100 | if (ret < 0) |
1082 | goto host_free; | 1101 | goto host_free; |
1083 | 1102 | ||
1084 | pdata->dev = &pdev->dev; | ||
1085 | _host = mmc_priv(mmc); | ||
1086 | _host->pdata = pdata; | 1103 | _host->pdata = pdata; |
1087 | _host->mmc = mmc; | ||
1088 | _host->pdev = pdev; | ||
1089 | platform_set_drvdata(pdev, mmc); | 1104 | platform_set_drvdata(pdev, mmc); |
1090 | 1105 | ||
1091 | _host->set_pwr = pdata->set_pwr; | 1106 | _host->set_pwr = pdata->set_pwr; |
@@ -1192,12 +1207,9 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
1192 | mmc_gpiod_request_cd_irq(mmc); | 1207 | mmc_gpiod_request_cd_irq(mmc); |
1193 | } | 1208 | } |
1194 | 1209 | ||
1195 | *host = _host; | ||
1196 | |||
1197 | return 0; | 1210 | return 0; |
1198 | 1211 | ||
1199 | host_free: | 1212 | host_free: |
1200 | mmc_free_host(mmc); | ||
1201 | 1213 | ||
1202 | return ret; | 1214 | return ret; |
1203 | } | 1215 | } |
@@ -1222,7 +1234,6 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) | |||
1222 | pm_runtime_disable(&pdev->dev); | 1234 | pm_runtime_disable(&pdev->dev); |
1223 | 1235 | ||
1224 | iounmap(host->ctl); | 1236 | iounmap(host->ctl); |
1225 | mmc_free_host(mmc); | ||
1226 | } | 1237 | } |
1227 | EXPORT_SYMBOL(tmio_mmc_host_remove); | 1238 | EXPORT_SYMBOL(tmio_mmc_host_remove); |
1228 | 1239 | ||
@@ -1237,8 +1248,8 @@ int tmio_mmc_host_runtime_suspend(struct device *dev) | |||
1237 | if (host->clk_cache) | 1248 | if (host->clk_cache) |
1238 | tmio_mmc_clk_stop(host); | 1249 | tmio_mmc_clk_stop(host); |
1239 | 1250 | ||
1240 | if (host->pdata->clk_disable) | 1251 | if (host->clk_disable) |
1241 | host->pdata->clk_disable(host->pdev); | 1252 | host->clk_disable(host->pdev); |
1242 | 1253 | ||
1243 | return 0; | 1254 | return 0; |
1244 | } | 1255 | } |
diff --git a/drivers/mmc/host/toshsd.c b/drivers/mmc/host/toshsd.c index 4666262edaca..e2cdd5fb1423 100644 --- a/drivers/mmc/host/toshsd.c +++ b/drivers/mmc/host/toshsd.c | |||
@@ -176,7 +176,8 @@ static irqreturn_t toshsd_thread_irq(int irq, void *dev_id) | |||
176 | spin_lock_irqsave(&host->lock, flags); | 176 | spin_lock_irqsave(&host->lock, flags); |
177 | 177 | ||
178 | if (!sg_miter_next(sg_miter)) | 178 | if (!sg_miter_next(sg_miter)) |
179 | return IRQ_HANDLED; | 179 | goto done; |
180 | |||
180 | buf = sg_miter->addr; | 181 | buf = sg_miter->addr; |
181 | 182 | ||
182 | /* Ensure we dont read more than one block. The chip will interrupt us | 183 | /* Ensure we dont read more than one block. The chip will interrupt us |
@@ -198,6 +199,7 @@ static irqreturn_t toshsd_thread_irq(int irq, void *dev_id) | |||
198 | sg_miter->consumed = count; | 199 | sg_miter->consumed = count; |
199 | sg_miter_stop(sg_miter); | 200 | sg_miter_stop(sg_miter); |
200 | 201 | ||
202 | done: | ||
201 | spin_unlock_irqrestore(&host->lock, flags); | 203 | spin_unlock_irqrestore(&host->lock, flags); |
202 | 204 | ||
203 | return IRQ_HANDLED; | 205 | return IRQ_HANDLED; |
@@ -699,18 +701,7 @@ static struct pci_driver toshsd_driver = { | |||
699 | .driver.pm = &toshsd_pm_ops, | 701 | .driver.pm = &toshsd_pm_ops, |
700 | }; | 702 | }; |
701 | 703 | ||
702 | static int __init toshsd_drv_init(void) | 704 | module_pci_driver(toshsd_driver); |
703 | { | ||
704 | return pci_register_driver(&toshsd_driver); | ||
705 | } | ||
706 | |||
707 | static void __exit toshsd_drv_exit(void) | ||
708 | { | ||
709 | pci_unregister_driver(&toshsd_driver); | ||
710 | } | ||
711 | |||
712 | module_init(toshsd_drv_init); | ||
713 | module_exit(toshsd_drv_exit); | ||
714 | 705 | ||
715 | MODULE_AUTHOR("Ondrej Zary, Richard Betts"); | 706 | MODULE_AUTHOR("Ondrej Zary, Richard Betts"); |
716 | MODULE_DESCRIPTION("Toshiba PCI Secure Digital Host Controller Interface driver"); | 707 | MODULE_DESCRIPTION("Toshiba PCI Secure Digital Host Controller Interface driver"); |
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index 4262296c12fa..fbabbb82b354 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c | |||
@@ -659,7 +659,7 @@ static void __vub300_irqpoll_response(struct vub300_mmc_host *vub300) | |||
659 | static void __do_poll(struct vub300_mmc_host *vub300) | 659 | static void __do_poll(struct vub300_mmc_host *vub300) |
660 | { | 660 | { |
661 | /* cmd_mutex is held by vub300_pollwork_thread */ | 661 | /* cmd_mutex is held by vub300_pollwork_thread */ |
662 | long commretval; | 662 | unsigned long commretval; |
663 | mod_timer(&vub300->inactivity_timer, jiffies + HZ); | 663 | mod_timer(&vub300->inactivity_timer, jiffies + HZ); |
664 | init_completion(&vub300->irqpoll_complete); | 664 | init_completion(&vub300->irqpoll_complete); |
665 | send_irqpoll(vub300); | 665 | send_irqpoll(vub300); |
@@ -671,8 +671,6 @@ static void __do_poll(struct vub300_mmc_host *vub300) | |||
671 | vub300->usb_timed_out = 1; | 671 | vub300->usb_timed_out = 1; |
672 | usb_kill_urb(vub300->command_out_urb); | 672 | usb_kill_urb(vub300->command_out_urb); |
673 | usb_kill_urb(vub300->command_res_urb); | 673 | usb_kill_urb(vub300->command_res_urb); |
674 | } else if (commretval < 0) { | ||
675 | vub300_queue_poll_work(vub300, 1); | ||
676 | } else { /* commretval > 0 */ | 674 | } else { /* commretval > 0 */ |
677 | __vub300_irqpoll_response(vub300); | 675 | __vub300_irqpoll_response(vub300); |
678 | } | 676 | } |
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 57388171610d..605812820e48 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h | |||
@@ -96,11 +96,6 @@ | |||
96 | #define TMIO_MMC_SDIO_STATUS_QUIRK (1 << 8) | 96 | #define TMIO_MMC_SDIO_STATUS_QUIRK (1 << 8) |
97 | 97 | ||
98 | /* | 98 | /* |
99 | * Some controllers have DMA enable/disable register | ||
100 | */ | ||
101 | #define TMIO_MMC_HAVE_CTL_DMA_REG (1 << 9) | ||
102 | |||
103 | /* | ||
104 | * Some controllers allows to set SDx actual clock | 99 | * Some controllers allows to set SDx actual clock |
105 | */ | 100 | */ |
106 | #define TMIO_MMC_CLK_ACTUAL (1 << 10) | 101 | #define TMIO_MMC_CLK_ACTUAL (1 << 10) |
@@ -112,18 +107,6 @@ void tmio_core_mmc_clk_div(void __iomem *cnf, int shift, int state); | |||
112 | 107 | ||
113 | struct dma_chan; | 108 | struct dma_chan; |
114 | 109 | ||
115 | struct tmio_mmc_dma { | ||
116 | void *chan_priv_tx; | ||
117 | void *chan_priv_rx; | ||
118 | int slave_id_tx; | ||
119 | int slave_id_rx; | ||
120 | int alignment_shift; | ||
121 | dma_addr_t dma_rx_offset; | ||
122 | bool (*filter)(struct dma_chan *chan, void *arg); | ||
123 | }; | ||
124 | |||
125 | struct tmio_mmc_host; | ||
126 | |||
127 | /* | 110 | /* |
128 | * data for the MMC controller | 111 | * data for the MMC controller |
129 | */ | 112 | */ |
@@ -132,19 +115,12 @@ struct tmio_mmc_data { | |||
132 | unsigned long capabilities; | 115 | unsigned long capabilities; |
133 | unsigned long capabilities2; | 116 | unsigned long capabilities2; |
134 | unsigned long flags; | 117 | unsigned long flags; |
135 | unsigned long bus_shift; | ||
136 | u32 ocr_mask; /* available voltages */ | 118 | u32 ocr_mask; /* available voltages */ |
137 | struct tmio_mmc_dma *dma; | ||
138 | struct device *dev; | ||
139 | unsigned int cd_gpio; | 119 | unsigned int cd_gpio; |
120 | int alignment_shift; | ||
121 | dma_addr_t dma_rx_offset; | ||
140 | void (*set_pwr)(struct platform_device *host, int state); | 122 | void (*set_pwr)(struct platform_device *host, int state); |
141 | void (*set_clk_div)(struct platform_device *host, int state); | 123 | void (*set_clk_div)(struct platform_device *host, int state); |
142 | int (*write16_hook)(struct tmio_mmc_host *host, int addr); | ||
143 | /* clock management callbacks */ | ||
144 | int (*clk_enable)(struct platform_device *pdev, unsigned int *f); | ||
145 | void (*clk_disable)(struct platform_device *pdev); | ||
146 | int (*multi_io_quirk)(struct mmc_card *card, | ||
147 | unsigned int direction, int blk_size); | ||
148 | }; | 124 | }; |
149 | 125 | ||
150 | /* | 126 | /* |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4d69c00497bd..a6cf4c063e4e 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -83,7 +83,7 @@ struct mmc_ext_csd { | |||
83 | bool hpi; /* HPI support bit */ | 83 | bool hpi; /* HPI support bit */ |
84 | unsigned int hpi_cmd; /* cmd used as HPI */ | 84 | unsigned int hpi_cmd; /* cmd used as HPI */ |
85 | bool bkops; /* background support bit */ | 85 | bool bkops; /* background support bit */ |
86 | bool bkops_en; /* background enable bit */ | 86 | bool man_bkops_en; /* manual 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 */ |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index cb2b0400d284..160448f920ac 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -182,7 +182,6 @@ extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); | |||
182 | extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, | 182 | extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, |
183 | bool is_rel_write); | 183 | bool is_rel_write); |
184 | extern int mmc_hw_reset(struct mmc_host *host); | 184 | extern int mmc_hw_reset(struct mmc_host *host); |
185 | extern int mmc_hw_reset_check(struct mmc_host *host); | ||
186 | extern int mmc_can_reset(struct mmc_card *card); | 185 | extern int mmc_can_reset(struct mmc_card *card); |
187 | 186 | ||
188 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); | 187 | extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); |
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 42b724e8d503..471fb3116dbe 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h | |||
@@ -106,6 +106,11 @@ struct mmc_data; | |||
106 | * @cur_slot, @mrq and @state. These must always be updated | 106 | * @cur_slot, @mrq and @state. These must always be updated |
107 | * at the same time while holding @lock. | 107 | * at the same time while holding @lock. |
108 | * | 108 | * |
109 | * @irq_lock is an irq-safe spinlock protecting the INTMASK register | ||
110 | * to allow the interrupt handler to modify it directly. Held for only long | ||
111 | * enough to read-modify-write INTMASK and no other locks are grabbed when | ||
112 | * holding this one. | ||
113 | * | ||
109 | * The @mrq field of struct dw_mci_slot is also protected by @lock, | 114 | * The @mrq field of struct dw_mci_slot is also protected by @lock, |
110 | * and must always be written at the same time as the slot is added to | 115 | * and must always be written at the same time as the slot is added to |
111 | * @queue. | 116 | * @queue. |
@@ -125,6 +130,7 @@ struct mmc_data; | |||
125 | */ | 130 | */ |
126 | struct dw_mci { | 131 | struct dw_mci { |
127 | spinlock_t lock; | 132 | spinlock_t lock; |
133 | spinlock_t irq_lock; | ||
128 | void __iomem *regs; | 134 | void __iomem *regs; |
129 | 135 | ||
130 | struct scatterlist *sg; | 136 | struct scatterlist *sg; |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 9f322706f7cb..0c8cbe5d1550 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -166,7 +166,6 @@ struct mmc_async_req { | |||
166 | * struct mmc_slot - MMC slot functions | 166 | * struct mmc_slot - MMC slot functions |
167 | * | 167 | * |
168 | * @cd_irq: MMC/SD-card slot hotplug detection IRQ or -EINVAL | 168 | * @cd_irq: MMC/SD-card slot hotplug detection IRQ or -EINVAL |
169 | * @lock: protect the @handler_priv pointer | ||
170 | * @handler_priv: MMC/SD-card slot context | 169 | * @handler_priv: MMC/SD-card slot context |
171 | * | 170 | * |
172 | * Some MMC/SD host controllers implement slot-functions like card and | 171 | * Some MMC/SD host controllers implement slot-functions like card and |
@@ -176,7 +175,6 @@ struct mmc_async_req { | |||
176 | */ | 175 | */ |
177 | struct mmc_slot { | 176 | struct mmc_slot { |
178 | int cd_irq; | 177 | int cd_irq; |
179 | struct mutex lock; | ||
180 | void *handler_priv; | 178 | void *handler_priv; |
181 | }; | 179 | }; |
182 | 180 | ||
@@ -197,6 +195,7 @@ struct mmc_context_info { | |||
197 | }; | 195 | }; |
198 | 196 | ||
199 | struct regulator; | 197 | struct regulator; |
198 | struct mmc_pwrseq; | ||
200 | 199 | ||
201 | struct mmc_supply { | 200 | struct mmc_supply { |
202 | struct regulator *vmmc; /* Card power supply */ | 201 | struct regulator *vmmc; /* Card power supply */ |
@@ -208,6 +207,7 @@ struct mmc_host { | |||
208 | struct device class_dev; | 207 | struct device class_dev; |
209 | int index; | 208 | int index; |
210 | const struct mmc_host_ops *ops; | 209 | const struct mmc_host_ops *ops; |
210 | struct mmc_pwrseq *pwrseq; | ||
211 | unsigned int f_min; | 211 | unsigned int f_min; |
212 | unsigned int f_max; | 212 | unsigned int f_max; |
213 | unsigned int f_init; | 213 | unsigned int f_init; |
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 49ad7a943638..124f562118b8 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
@@ -53,11 +53,6 @@ | |||
53 | #define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */ | 53 | #define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */ |
54 | #define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */ | 54 | #define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */ |
55 | 55 | ||
56 | #define MMC_TUNING_BLK_PATTERN_4BIT_SIZE 64 | ||
57 | #define MMC_TUNING_BLK_PATTERN_8BIT_SIZE 128 | ||
58 | extern const u8 tuning_blk_pattern_4bit[MMC_TUNING_BLK_PATTERN_4BIT_SIZE]; | ||
59 | extern const u8 tuning_blk_pattern_8bit[MMC_TUNING_BLK_PATTERN_8BIT_SIZE]; | ||
60 | |||
61 | /* class 3 */ | 56 | /* class 3 */ |
62 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ | 57 | #define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */ |
63 | 58 | ||
@@ -433,6 +428,11 @@ struct _mmc_csd { | |||
433 | #define EXT_CSD_BKOPS_LEVEL_2 0x2 | 428 | #define EXT_CSD_BKOPS_LEVEL_2 0x2 |
434 | 429 | ||
435 | /* | 430 | /* |
431 | * BKOPS modes | ||
432 | */ | ||
433 | #define EXT_CSD_MANUAL_BKOPS_MASK 0x01 | ||
434 | |||
435 | /* | ||
436 | * MMC_SWITCH access modes | 436 | * MMC_SWITCH access modes |
437 | */ | 437 | */ |
438 | 438 | ||
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index f767a0de611f..c3e3db196738 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h | |||
@@ -17,6 +17,11 @@ | |||
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/mmc/host.h> | 18 | #include <linux/mmc/host.h> |
19 | 19 | ||
20 | struct sdhci_host_next { | ||
21 | unsigned int sg_count; | ||
22 | s32 cookie; | ||
23 | }; | ||
24 | |||
20 | struct sdhci_host { | 25 | struct sdhci_host { |
21 | /* Data set by hardware interface driver */ | 26 | /* Data set by hardware interface driver */ |
22 | const char *hw_name; /* Hardware bus name */ | 27 | const char *hw_name; /* Hardware bus name */ |
@@ -106,6 +111,10 @@ struct sdhci_host { | |||
106 | #define SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD (1<<10) | 111 | #define SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD (1<<10) |
107 | /* Capability register bit-63 indicates HS400 support */ | 112 | /* Capability register bit-63 indicates HS400 support */ |
108 | #define SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 (1<<11) | 113 | #define SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 (1<<11) |
114 | /* forced tuned clock */ | ||
115 | #define SDHCI_QUIRK2_TUNING_WORK_AROUND (1<<12) | ||
116 | /* disable the block count for single block transactions */ | ||
117 | #define SDHCI_QUIRK2_SUPPORT_SINGLE (1<<13) | ||
109 | 118 | ||
110 | int irq; /* Device IRQ */ | 119 | int irq; /* Device IRQ */ |
111 | void __iomem *ioaddr; /* Mapped address */ | 120 | void __iomem *ioaddr; /* Mapped address */ |
@@ -203,6 +212,7 @@ struct sdhci_host { | |||
203 | #define SDHCI_TUNING_MODE_1 0 | 212 | #define SDHCI_TUNING_MODE_1 0 |
204 | struct timer_list tuning_timer; /* Timer for tuning */ | 213 | struct timer_list tuning_timer; /* Timer for tuning */ |
205 | 214 | ||
215 | struct sdhci_host_next next_data; | ||
206 | unsigned long private[0] ____cacheline_aligned; | 216 | unsigned long private[0] ____cacheline_aligned; |
207 | }; | 217 | }; |
208 | #endif /* LINUX_MMC_SDHCI_H */ | 218 | #endif /* LINUX_MMC_SDHCI_H */ |
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h index 68927ae50845..da77e5e2041d 100644 --- a/include/linux/mmc/sh_mobile_sdhi.h +++ b/include/linux/mmc/sh_mobile_sdhi.h | |||
@@ -3,20 +3,10 @@ | |||
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | struct platform_device; | ||
7 | |||
8 | #define SH_MOBILE_SDHI_IRQ_CARD_DETECT "card_detect" | 6 | #define SH_MOBILE_SDHI_IRQ_CARD_DETECT "card_detect" |
9 | #define SH_MOBILE_SDHI_IRQ_SDCARD "sdcard" | 7 | #define SH_MOBILE_SDHI_IRQ_SDCARD "sdcard" |
10 | #define SH_MOBILE_SDHI_IRQ_SDIO "sdio" | 8 | #define SH_MOBILE_SDHI_IRQ_SDIO "sdio" |
11 | 9 | ||
12 | /** | ||
13 | * struct sh_mobile_sdhi_ops - SDHI driver callbacks | ||
14 | * @cd_wakeup: trigger a card-detection run | ||
15 | */ | ||
16 | struct sh_mobile_sdhi_ops { | ||
17 | void (*cd_wakeup)(const struct platform_device *pdev); | ||
18 | }; | ||
19 | |||
20 | struct sh_mobile_sdhi_info { | 10 | struct sh_mobile_sdhi_info { |
21 | int dma_slave_tx; | 11 | int dma_slave_tx; |
22 | int dma_slave_rx; | 12 | int dma_slave_rx; |
@@ -25,11 +15,6 @@ struct sh_mobile_sdhi_info { | |||
25 | unsigned long tmio_caps2; | 15 | unsigned long tmio_caps2; |
26 | u32 tmio_ocr_mask; /* available MMC voltages */ | 16 | u32 tmio_ocr_mask; /* available MMC voltages */ |
27 | unsigned int cd_gpio; | 17 | unsigned int cd_gpio; |
28 | |||
29 | /* callbacks for board specific setup code */ | ||
30 | int (*init)(struct platform_device *pdev, | ||
31 | const struct sh_mobile_sdhi_ops *ops); | ||
32 | void (*cleanup)(struct platform_device *pdev); | ||
33 | }; | 18 | }; |
34 | 19 | ||
35 | #endif /* LINUX_MMC_SH_MOBILE_SDHI_H */ | 20 | #endif /* LINUX_MMC_SH_MOBILE_SDHI_H */ |
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h index e56fa24c9322..3945a8c9d3cb 100644 --- a/include/linux/mmc/slot-gpio.h +++ b/include/linux/mmc/slot-gpio.h | |||
@@ -15,12 +15,10 @@ struct mmc_host; | |||
15 | 15 | ||
16 | int mmc_gpio_get_ro(struct mmc_host *host); | 16 | int mmc_gpio_get_ro(struct mmc_host *host); |
17 | int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio); | 17 | int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio); |
18 | void mmc_gpio_free_ro(struct mmc_host *host); | ||
19 | 18 | ||
20 | int mmc_gpio_get_cd(struct mmc_host *host); | 19 | int mmc_gpio_get_cd(struct mmc_host *host); |
21 | int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, | 20 | int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, |
22 | unsigned int debounce); | 21 | unsigned int debounce); |
23 | void mmc_gpio_free_cd(struct mmc_host *host); | ||
24 | 22 | ||
25 | int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | 23 | int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, |
26 | unsigned int idx, bool override_active_level, | 24 | unsigned int idx, bool override_active_level, |
@@ -28,7 +26,8 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, | |||
28 | int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, | 26 | int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, |
29 | unsigned int idx, bool override_active_level, | 27 | unsigned int idx, bool override_active_level, |
30 | unsigned int debounce, bool *gpio_invert); | 28 | unsigned int debounce, bool *gpio_invert); |
31 | void mmc_gpiod_free_cd(struct mmc_host *host); | 29 | void mmc_gpio_set_cd_isr(struct mmc_host *host, |
30 | irqreturn_t (*isr)(int irq, void *dev_id)); | ||
32 | void mmc_gpiod_request_cd_irq(struct mmc_host *host); | 31 | void mmc_gpiod_request_cd_irq(struct mmc_host *host); |
33 | 32 | ||
34 | #endif | 33 | #endif |
diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h index 5c188f4e9bec..929469291406 100644 --- a/include/linux/platform_data/mmc-omap.h +++ b/include/linux/platform_data/mmc-omap.h | |||
@@ -31,10 +31,6 @@ struct omap_mmc_platform_data { | |||
31 | void (*cleanup)(struct device *dev); | 31 | void (*cleanup)(struct device *dev); |
32 | void (*shutdown)(struct device *dev); | 32 | void (*shutdown)(struct device *dev); |
33 | 33 | ||
34 | /* To handle board related suspend/resume functionality for MMC */ | ||
35 | int (*suspend)(struct device *dev, int slot); | ||
36 | int (*resume)(struct device *dev, int slot); | ||
37 | |||
38 | /* Return context loss count due to PM states changing */ | 34 | /* Return context loss count due to PM states changing */ |
39 | int (*get_context_loss_count)(struct device *dev); | 35 | int (*get_context_loss_count)(struct device *dev); |
40 | 36 | ||