From patchwork Mon Mar 9 23:18:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 5972391 Return-Path: X-Original-To: patchwork-linux-rockchip@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 94BF19F2A9 for ; Mon, 9 Mar 2015 23:19:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C0E2F20437 for ; Mon, 9 Mar 2015 23:19:18 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E063520431 for ; Mon, 9 Mar 2015 23:19:17 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YV6xA-0007xi-5M; Mon, 09 Mar 2015 23:19:16 +0000 Received: from mail-ig0-x22a.google.com ([2607:f8b0:4001:c05::22a]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YV6ww-0007pj-0K for linux-rockchip@lists.infradead.org; Mon, 09 Mar 2015 23:19:03 +0000 Received: by igbhn18 with SMTP id hn18so25669834igb.2 for ; Mon, 09 Mar 2015 16:18:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=WcsF8kBM1bN19CGiEL62x4rROicwjXTIZttWJair6CE=; b=RxzMGxzqmOG1hb9sqUbimgGOjBQbL4hhygpTHUunTGdFe7Fq7/ZeIfwdO5m7BN8bkz GGiDkd48uRaOjOzuZ4v25DUZH26pcdnx//SwyxPQs14bo1r0Uv2nFf7x7xFmqQDhJNMw js/bWmj5zg/N659TGLZM26SjjZgIwbp1gK9zQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=WcsF8kBM1bN19CGiEL62x4rROicwjXTIZttWJair6CE=; b=Qe6Xruohwg32/ARqMAtCj+2q5Pt6yCKwQb9qkYEIG6kbLm+3KMq20MMNjbf07oaw+t TKWGyL/LRmZkQDrSTQJsP2CxmrXlaEVWAidUcM3PfUDOsetlox8IST0Rlvl0s3ZMcQTV +tZhtxzAcUVn60SBxdbL4BwBPb1NMYC0hVttLUaynPUWmvO3jb3anstKvbb3N5i5t178 yVgOfdHCCh5PIJOBgR11LKkdgThmpHQ+6ezvG3ZJbCzWbhRALivzTi7Ra+V8Y+fjOwH5 244bDsGqb/qEJefeM1wNxXuhTZLdKMZB5C21cQqapA8y2Ty5AzBdD131K6CVVAIz1ZVu O63g== X-Gm-Message-State: ALoCoQnZgiMjL1phbcxmbiV4nkcSAfIJnhhCBkMhP2hQmIbPV5tMgcD+DYxjKtVEsK/G7rkXPVNb X-Received: by 10.42.148.197 with SMTP id s5mr29991007icv.13.1425943118761; Mon, 09 Mar 2015 16:18:38 -0700 (PDT) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by mx.google.com with ESMTPSA id o8sm6971647igp.11.2015.03.09.16.18.37 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Mar 2015 16:18:38 -0700 (PDT) From: Doug Anderson To: Jaehoon Chung , Seungwon Jeon , Ulf Hansson Subject: [PATCH] mmc: dw_mmc: Add a timeout for sending CMD11 Date: Mon, 9 Mar 2015 16:18:21 -0700 Message-Id: <1425943101-11976-1-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.2.0.rc0.207.ga3a616c X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150309_161902_082854_FC48818B X-CRM114-Status: GOOD ( 13.07 ) X-Spam-Score: -0.8 (/) Cc: Addy Ke , Heiko Stuebner , Andrew Bresticker , linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org, Doug Anderson , chris@printf.net, linux-rockchip@lists.infradead.org, Alim Akhtar , Sonny Rao , javier.martinez@collabora.co.uk, linux-arm-kernel@lists.infradead.org, Alexandru Stan X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In the Designware databook's description of the "Voltage Switch Normal Scenario" it instructs us to set a timer and fail the voltage change if we don't see the voltage change interrupt within 2ms. Let's implement that. Without implementing this I have often been able to reproduce a hang while trying to send CMD11 on an rk3288-based board while constantly ejecting and inserting UHS cards. Signed-off-by: Doug Anderson --- drivers/mmc/host/dw_mmc.c | 26 ++++++++++++++++++++++++++ include/linux/mmc/dw_mmc.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 47dfd0e..d259662 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1020,6 +1020,15 @@ static void __dw_mci_start_request(struct dw_mci *host, dw_mci_start_command(host, cmd, cmdflags); + if (cmd->opcode == SD_SWITCH_VOLTAGE) { + /* + * Databook says to fail after 2ms w/ no response; give an + * extra jiffy just in case we're about to roll over. + */ + mod_timer(&host->cmd11_timer, + jiffies + msecs_to_jiffies(2) + 1); + } + if (mrq->stop) host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); else @@ -2158,6 +2167,8 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) /* Check volt switch first, since it can look like an error */ if ((host->state == STATE_SENDING_CMD11) && (pending & SDMMC_INT_VOLT_SWITCH)) { + del_timer(&host->cmd11_timer); + mci_writel(host, RINTSTS, SDMMC_INT_VOLT_SWITCH); pending &= ~SDMMC_INT_VOLT_SWITCH; dw_mci_cmd_interrupt(host, pending); @@ -2571,6 +2582,18 @@ ciu_out: return ret; } +static void dw_mci_cmd11_timer(unsigned long arg) +{ + struct dw_mci *host = (struct dw_mci *)arg; + + if (host->state != STATE_SENDING_CMD11) + dev_info(host->dev, "Unexpected CMD11 timeout\n"); + + host->cmd_status = SDMMC_INT_RTO; + set_bit(EVENT_CMD_COMPLETE, &host->pending_events); + tasklet_schedule(&host->tasklet); +} + #ifdef CONFIG_OF static struct dw_mci_of_quirks { char *quirk; @@ -2745,6 +2768,9 @@ int dw_mci_probe(struct dw_mci *host) } } + setup_timer(&host->cmd11_timer, + dw_mci_cmd11_timer, (unsigned long)host); + host->quirks = host->pdata->quirks; spin_lock_init(&host->lock); diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 471fb31..9efc567 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -202,6 +202,8 @@ struct dw_mci { int irq; int sdio_id0; + + struct timer_list cmd11_timer; }; /* DMA ops for Internal/External DMAC interface */