lkml.org 
[lkml]   [2016]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.8 18/92] mmc: sdhci: Fix CMD line reset interfering with ongoing data transfer
    Date
    4.8-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Adrian Hunter <adrian.hunter@intel.com>

    commit 6ebebeab5185f50d55c6a24d0abe47e5dac1b191 upstream.

    CMD line reset during an ongoing data transfer can cause the data transfer
    to hang. Fix by delaying the reset until the data transfer is finished.

    Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
    Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/mmc/host/sdhci.c | 23 ++++++++++++++++-------
    1 file changed, 16 insertions(+), 7 deletions(-)

    --- a/drivers/mmc/host/sdhci.c
    +++ b/drivers/mmc/host/sdhci.c
    @@ -2269,10 +2269,8 @@ static bool sdhci_request_done(struct sd

    for (i = 0; i < SDHCI_MAX_MRQS; i++) {
    mrq = host->mrqs_done[i];
    - if (mrq) {
    - host->mrqs_done[i] = NULL;
    + if (mrq)
    break;
    - }
    }

    if (!mrq) {
    @@ -2303,6 +2301,17 @@ static bool sdhci_request_done(struct sd
    * upon error conditions.
    */
    if (sdhci_needs_reset(host, mrq)) {
    + /*
    + * Do not finish until command and data lines are available for
    + * reset. Note there can only be one other mrq, so it cannot
    + * also be in mrqs_done, otherwise host->cmd and host->data_cmd
    + * would both be null.
    + */
    + if (host->cmd || host->data_cmd) {
    + spin_unlock_irqrestore(&host->lock, flags);
    + return true;
    + }
    +
    /* Some controllers need this kick or reset won't work here */
    if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
    /* This is to force an update */
    @@ -2310,10 +2319,8 @@ static bool sdhci_request_done(struct sd

    /* Spec says we should do both at the same time, but Ricoh
    controllers do not like that. */
    - if (!host->cmd)
    - sdhci_do_reset(host, SDHCI_RESET_CMD);
    - if (!host->data_cmd)
    - sdhci_do_reset(host, SDHCI_RESET_DATA);
    + sdhci_do_reset(host, SDHCI_RESET_CMD);
    + sdhci_do_reset(host, SDHCI_RESET_DATA);

    host->pending_reset = false;
    }
    @@ -2321,6 +2328,8 @@ static bool sdhci_request_done(struct sd
    if (!sdhci_has_requests(host))
    sdhci_led_deactivate(host);

    + host->mrqs_done[i] = NULL;
    +
    mmiowb();
    spin_unlock_irqrestore(&host->lock, flags);


    \
     
     \ /
      Last update: 2016-11-17 12:05    [W:4.789 / U:0.136 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site