diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-11 19:23:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-11 19:23:14 -0500 |
commit | b8b73df3450c9dc953e2bfb4d1f03a4cdd7d8dc6 (patch) | |
tree | 5b62bf95e7cc2324b1ec77a719d88388f8bc498f | |
parent | 5c03b53cb7386a5a9ee16b50de4d77d5cd06a438 (diff) | |
parent | f91346e8b5f46aaf12f1df26e87140584ffd1b3f (diff) |
Merge tag 'mmc-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC fixes from Ulf Hansson:
"MMC core:
- Fix mmc card initialization for hosts not supporting HW busy
detection
- Fix mmc_test for sending commands during non-blocking write
MMC host:
- mxs: Avoid using an uninitialized
- sdhci: Restore enhanced strobe setting during runtime resume
- sdhci: Fix a couple of reset related issues
- dw_mmc: Fix a reset controller issue"
* tag 'mmc-v4.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
mmc: mxs: Initialize the spinlock prior to using it
mmc: mmc: Use 500ms as the default generic CMD6 timeout
mmc: mmc_test: Fix "Commands during non-blocking write" tests
mmc: sdhci: Fix missing enhanced strobe setting during runtime resume
mmc: sdhci: Reset cmd and data circuits after tuning failure
mmc: sdhci: Fix unexpected data interrupt handling
mmc: sdhci: Fix CMD line reset interfering with ongoing data transfer
mmc: dw_mmc: add the "reset" as name of reset controller
Documentation: synopsys-dw-mshc: add binding for reset-names
-rw-r--r-- | Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt | 5 | ||||
-rw-r--r-- | drivers/mmc/card/mmc_test.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 3 | ||||
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 4 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 36 |
6 files changed, 41 insertions, 17 deletions
diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt index 4e00e859e885..bfa461aaac99 100644 --- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt | |||
@@ -43,6 +43,9 @@ Optional properties: | |||
43 | reset signal present internally in some host controller IC designs. | 43 | reset signal present internally in some host controller IC designs. |
44 | See Documentation/devicetree/bindings/reset/reset.txt for details. | 44 | See Documentation/devicetree/bindings/reset/reset.txt for details. |
45 | 45 | ||
46 | * reset-names: request name for using "resets" property. Must be "reset". | ||
47 | (It will be used together with "resets" property.) | ||
48 | |||
46 | * clocks: from common clock binding: handle to biu and ciu clocks for the | 49 | * clocks: from common clock binding: handle to biu and ciu clocks for the |
47 | bus interface unit clock and the card interface unit clock. | 50 | bus interface unit clock and the card interface unit clock. |
48 | 51 | ||
@@ -103,6 +106,8 @@ board specific portions as listed below. | |||
103 | interrupts = <0 75 0>; | 106 | interrupts = <0 75 0>; |
104 | #address-cells = <1>; | 107 | #address-cells = <1>; |
105 | #size-cells = <0>; | 108 | #size-cells = <0>; |
109 | resets = <&rst 20>; | ||
110 | reset-names = "reset"; | ||
106 | }; | 111 | }; |
107 | 112 | ||
108 | [board specific internal DMA resources] | 113 | [board specific internal DMA resources] |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index 5a8dc5a76e0d..3678220964fe 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -2347,7 +2347,7 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, | |||
2347 | struct mmc_test_req *rq = mmc_test_req_alloc(); | 2347 | struct mmc_test_req *rq = mmc_test_req_alloc(); |
2348 | struct mmc_host *host = test->card->host; | 2348 | struct mmc_host *host = test->card->host; |
2349 | struct mmc_test_area *t = &test->area; | 2349 | struct mmc_test_area *t = &test->area; |
2350 | struct mmc_async_req areq; | 2350 | struct mmc_test_async_req test_areq = { .test = test }; |
2351 | struct mmc_request *mrq; | 2351 | struct mmc_request *mrq; |
2352 | unsigned long timeout; | 2352 | unsigned long timeout; |
2353 | bool expired = false; | 2353 | bool expired = false; |
@@ -2363,8 +2363,8 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, | |||
2363 | mrq->sbc = &rq->sbc; | 2363 | mrq->sbc = &rq->sbc; |
2364 | mrq->cap_cmd_during_tfr = true; | 2364 | mrq->cap_cmd_during_tfr = true; |
2365 | 2365 | ||
2366 | areq.mrq = mrq; | 2366 | test_areq.areq.mrq = mrq; |
2367 | areq.err_check = mmc_test_check_result_async; | 2367 | test_areq.areq.err_check = mmc_test_check_result_async; |
2368 | 2368 | ||
2369 | mmc_test_prepare_mrq(test, mrq, t->sg, t->sg_len, dev_addr, t->blocks, | 2369 | mmc_test_prepare_mrq(test, mrq, t->sg, t->sg_len, dev_addr, t->blocks, |
2370 | 512, write); | 2370 | 512, write); |
@@ -2378,7 +2378,7 @@ static int mmc_test_ongoing_transfer(struct mmc_test_card *test, | |||
2378 | 2378 | ||
2379 | /* Start ongoing data request */ | 2379 | /* Start ongoing data request */ |
2380 | if (use_areq) { | 2380 | if (use_areq) { |
2381 | mmc_start_req(host, &areq, &ret); | 2381 | mmc_start_req(host, &test_areq.areq, &ret); |
2382 | if (ret) | 2382 | if (ret) |
2383 | goto out_free; | 2383 | goto out_free; |
2384 | } else { | 2384 | } else { |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 39fc5b2b96c5..df19777068a6 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "mmc_ops.h" | 26 | #include "mmc_ops.h" |
27 | #include "sd_ops.h" | 27 | #include "sd_ops.h" |
28 | 28 | ||
29 | #define DEFAULT_CMD6_TIMEOUT_MS 500 | ||
30 | |||
29 | static const unsigned int tran_exp[] = { | 31 | static const unsigned int tran_exp[] = { |
30 | 10000, 100000, 1000000, 10000000, | 32 | 10000, 100000, 1000000, 10000000, |
31 | 0, 0, 0, 0 | 33 | 0, 0, 0, 0 |
@@ -571,6 +573,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
571 | card->erased_byte = 0x0; | 573 | card->erased_byte = 0x0; |
572 | 574 | ||
573 | /* eMMC v4.5 or later */ | 575 | /* eMMC v4.5 or later */ |
576 | card->ext_csd.generic_cmd6_time = DEFAULT_CMD6_TIMEOUT_MS; | ||
574 | if (card->ext_csd.rev >= 6) { | 577 | if (card->ext_csd.rev >= 6) { |
575 | card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; | 578 | card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; |
576 | 579 | ||
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4fcbc4012ed0..50a674be6655 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -2940,7 +2940,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
2940 | return ERR_PTR(-ENOMEM); | 2940 | return ERR_PTR(-ENOMEM); |
2941 | 2941 | ||
2942 | /* find reset controller when exist */ | 2942 | /* find reset controller when exist */ |
2943 | pdata->rstc = devm_reset_control_get_optional(dev, NULL); | 2943 | pdata->rstc = devm_reset_control_get_optional(dev, "reset"); |
2944 | if (IS_ERR(pdata->rstc)) { | 2944 | if (IS_ERR(pdata->rstc)) { |
2945 | if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER) | 2945 | if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER) |
2946 | return ERR_PTR(-EPROBE_DEFER); | 2946 | return ERR_PTR(-EPROBE_DEFER); |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index d839147e591d..44ecebd1ea8c 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -661,13 +661,13 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
661 | 661 | ||
662 | platform_set_drvdata(pdev, mmc); | 662 | platform_set_drvdata(pdev, mmc); |
663 | 663 | ||
664 | spin_lock_init(&host->lock); | ||
665 | |||
664 | ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0, | 666 | ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0, |
665 | dev_name(&pdev->dev), host); | 667 | dev_name(&pdev->dev), host); |
666 | if (ret) | 668 | if (ret) |
667 | goto out_free_dma; | 669 | goto out_free_dma; |
668 | 670 | ||
669 | spin_lock_init(&host->lock); | ||
670 | |||
671 | ret = mmc_add_host(mmc); | 671 | ret = mmc_add_host(mmc); |
672 | if (ret) | 672 | if (ret) |
673 | goto out_free_dma; | 673 | goto out_free_dma; |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 71654b90227f..42ef3ebb1d8c 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -2086,6 +2086,10 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
2086 | 2086 | ||
2087 | if (!host->tuning_done) { | 2087 | if (!host->tuning_done) { |
2088 | pr_info(DRIVER_NAME ": Timeout waiting for Buffer Read Ready interrupt during tuning procedure, falling back to fixed sampling clock\n"); | 2088 | pr_info(DRIVER_NAME ": Timeout waiting for Buffer Read Ready interrupt during tuning procedure, falling back to fixed sampling clock\n"); |
2089 | |||
2090 | sdhci_do_reset(host, SDHCI_RESET_CMD); | ||
2091 | sdhci_do_reset(host, SDHCI_RESET_DATA); | ||
2092 | |||
2089 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 2093 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
2090 | ctrl &= ~SDHCI_CTRL_TUNED_CLK; | 2094 | ctrl &= ~SDHCI_CTRL_TUNED_CLK; |
2091 | ctrl &= ~SDHCI_CTRL_EXEC_TUNING; | 2095 | ctrl &= ~SDHCI_CTRL_EXEC_TUNING; |
@@ -2286,10 +2290,8 @@ static bool sdhci_request_done(struct sdhci_host *host) | |||
2286 | 2290 | ||
2287 | for (i = 0; i < SDHCI_MAX_MRQS; i++) { | 2291 | for (i = 0; i < SDHCI_MAX_MRQS; i++) { |
2288 | mrq = host->mrqs_done[i]; | 2292 | mrq = host->mrqs_done[i]; |
2289 | if (mrq) { | 2293 | if (mrq) |
2290 | host->mrqs_done[i] = NULL; | ||
2291 | break; | 2294 | break; |
2292 | } | ||
2293 | } | 2295 | } |
2294 | 2296 | ||
2295 | if (!mrq) { | 2297 | if (!mrq) { |
@@ -2320,6 +2322,17 @@ static bool sdhci_request_done(struct sdhci_host *host) | |||
2320 | * upon error conditions. | 2322 | * upon error conditions. |
2321 | */ | 2323 | */ |
2322 | if (sdhci_needs_reset(host, mrq)) { | 2324 | if (sdhci_needs_reset(host, mrq)) { |
2325 | /* | ||
2326 | * Do not finish until command and data lines are available for | ||
2327 | * reset. Note there can only be one other mrq, so it cannot | ||
2328 | * also be in mrqs_done, otherwise host->cmd and host->data_cmd | ||
2329 | * would both be null. | ||
2330 | */ | ||
2331 | if (host->cmd || host->data_cmd) { | ||
2332 | spin_unlock_irqrestore(&host->lock, flags); | ||
2333 | return true; | ||
2334 | } | ||
2335 | |||
2323 | /* Some controllers need this kick or reset won't work here */ | 2336 | /* Some controllers need this kick or reset won't work here */ |
2324 | if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) | 2337 | if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) |
2325 | /* This is to force an update */ | 2338 | /* This is to force an update */ |
@@ -2327,10 +2340,8 @@ static bool sdhci_request_done(struct sdhci_host *host) | |||
2327 | 2340 | ||
2328 | /* Spec says we should do both at the same time, but Ricoh | 2341 | /* Spec says we should do both at the same time, but Ricoh |
2329 | controllers do not like that. */ | 2342 | controllers do not like that. */ |
2330 | if (!host->cmd) | 2343 | sdhci_do_reset(host, SDHCI_RESET_CMD); |
2331 | sdhci_do_reset(host, SDHCI_RESET_CMD); | 2344 | sdhci_do_reset(host, SDHCI_RESET_DATA); |
2332 | if (!host->data_cmd) | ||
2333 | sdhci_do_reset(host, SDHCI_RESET_DATA); | ||
2334 | 2345 | ||
2335 | host->pending_reset = false; | 2346 | host->pending_reset = false; |
2336 | } | 2347 | } |
@@ -2338,6 +2349,8 @@ static bool sdhci_request_done(struct sdhci_host *host) | |||
2338 | if (!sdhci_has_requests(host)) | 2349 | if (!sdhci_has_requests(host)) |
2339 | sdhci_led_deactivate(host); | 2350 | sdhci_led_deactivate(host); |
2340 | 2351 | ||
2352 | host->mrqs_done[i] = NULL; | ||
2353 | |||
2341 | mmiowb(); | 2354 | mmiowb(); |
2342 | spin_unlock_irqrestore(&host->lock, flags); | 2355 | spin_unlock_irqrestore(&host->lock, flags); |
2343 | 2356 | ||
@@ -2512,9 +2525,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
2512 | if (!host->data) { | 2525 | if (!host->data) { |
2513 | struct mmc_command *data_cmd = host->data_cmd; | 2526 | struct mmc_command *data_cmd = host->data_cmd; |
2514 | 2527 | ||
2515 | if (data_cmd) | ||
2516 | host->data_cmd = NULL; | ||
2517 | |||
2518 | /* | 2528 | /* |
2519 | * The "data complete" interrupt is also used to | 2529 | * The "data complete" interrupt is also used to |
2520 | * indicate that a busy state has ended. See comment | 2530 | * indicate that a busy state has ended. See comment |
@@ -2522,11 +2532,13 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
2522 | */ | 2532 | */ |
2523 | if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) { | 2533 | if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) { |
2524 | if (intmask & SDHCI_INT_DATA_TIMEOUT) { | 2534 | if (intmask & SDHCI_INT_DATA_TIMEOUT) { |
2535 | host->data_cmd = NULL; | ||
2525 | data_cmd->error = -ETIMEDOUT; | 2536 | data_cmd->error = -ETIMEDOUT; |
2526 | sdhci_finish_mrq(host, data_cmd->mrq); | 2537 | sdhci_finish_mrq(host, data_cmd->mrq); |
2527 | return; | 2538 | return; |
2528 | } | 2539 | } |
2529 | if (intmask & SDHCI_INT_DATA_END) { | 2540 | if (intmask & SDHCI_INT_DATA_END) { |
2541 | host->data_cmd = NULL; | ||
2530 | /* | 2542 | /* |
2531 | * Some cards handle busy-end interrupt | 2543 | * Some cards handle busy-end interrupt |
2532 | * before the command completed, so make | 2544 | * before the command completed, so make |
@@ -2912,6 +2924,10 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) | |||
2912 | spin_unlock_irqrestore(&host->lock, flags); | 2924 | spin_unlock_irqrestore(&host->lock, flags); |
2913 | } | 2925 | } |
2914 | 2926 | ||
2927 | if ((mmc->caps2 & MMC_CAP2_HS400_ES) && | ||
2928 | mmc->ops->hs400_enhanced_strobe) | ||
2929 | mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios); | ||
2930 | |||
2915 | spin_lock_irqsave(&host->lock, flags); | 2931 | spin_lock_irqsave(&host->lock, flags); |
2916 | 2932 | ||
2917 | host->runtime_suspended = false; | 2933 | host->runtime_suspended = false; |