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: 5972421 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 49DBFBF440 for ; Mon, 9 Mar 2015 23:21:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5EC2520431 for ; Mon, 9 Mar 2015 23:21:51 +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 6E7ED20411 for ; Mon, 9 Mar 2015 23:21:50 +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 1YV6wz-0007tg-Fa; Mon, 09 Mar 2015 23:19:05 +0000 Received: from mail-ie0-x22e.google.com ([2607:f8b0:4001:c03::22e]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YV6wv-0007ph-Qc for linux-arm-kernel@lists.infradead.org; Mon, 09 Mar 2015 23:19:02 +0000 Received: by iecrp18 with SMTP id rp18so39935866iec.7 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=SFoVBALW04Y9WmEoOgmHchFg2pyi8+RV7w5yNlnwruJVK4zucEko+J+r4p0bff/G7u sMrjVB6IsL1Y8yyu2Of5h2F5rn4tYuDPI6OnTDnm/xpbosOq/z3kP5GwYR/mwKdETiYi hh8VPqG7GMMdLN6a0Ilw5574BacChlEkQpwukNp8yUBidY2ECg3LtSSAXyG1WdKUnCNs Hzy0THtQvOFF+QugcLSL6oTlLAwHBKc7jQ3HDFC1PkeuPWJYMvG30KUvOzE2WM+/zFp8 FFwugqD5v8ILEG1FJBA+E6/08x+6h+VvgFPMdGqsDRyxl14ErYtQ7bnnOwLhZJSg/fdx eLWg== X-Gm-Message-State: ALoCoQmCwUTo7YfGi64hDX6+BhLYRfcBbc5s6gEiuHQTcv58FTV5zEfWdcyCExsNqO29yKigX1tT 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_161901_912442_DFDDC55E X-CRM114-Status: GOOD ( 14.53 ) 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-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=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 */