From patchwork Mon Feb 9 07:25:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: addy ke X-Patchwork-Id: 5798611 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 22C069F336 for ; Mon, 9 Feb 2015 07:28:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5067B20121 for ; Mon, 9 Feb 2015 07:28:42 +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 7569A2011E for ; Mon, 9 Feb 2015 07:28:41 +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 1YKils-0005nU-II; Mon, 09 Feb 2015 07:28:40 +0000 Received: from regular1.263xmail.com ([211.150.99.133]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YKilU-0005Ww-9C; Mon, 09 Feb 2015 07:28:18 +0000 Received: from addy.ke?rock-chips.com (unknown [192.168.167.12]) by regular1.263xmail.com (Postfix) with SMTP id BB67C7EA6; Mon, 9 Feb 2015 15:27:46 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.263.net (Postfix) with ESMTP id F244837E; Mon, 9 Feb 2015 15:27:37 +0800 (CST) X-RL-SENDER: addy.ke@rock-chips.com X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: addy.ke@rock-chips.com X-UNIQUE-TAG: X-ATTACHMENT-NUM: 0 X-SENDER: kfx@rock-chips.com X-DNS-TYPE: 0 Received: from unknown (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith SMTP id 16080306BZS; Mon, 09 Feb 2015 15:27:44 +0800 (CST) From: Addy Ke To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, ijc+devicetree@hellion.org.uk, galak@codeaurora.org, rdunlap@infradead.org, tgih.jun@samsung.com, jh80.chung@samsung.com, chris@printf.net, ulf.hansson@linaro.org, dinguyen@altera.com, heiko@sntech.de, olof@lixom.net, dianders@chromium.org, sonnyrao@chromium.org, amstan@chromium.org, djkurtz@chromium.org Subject: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Date: Mon, 9 Feb 2015 15:25:25 +0800 Message-Id: <1423466726-20833-2-git-send-email-addy.ke@rock-chips.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1423466726-20833-1-git-send-email-addy.ke@rock-chips.com> References: <1423134801-23219-1-git-send-email-addy.ke@rock-chips.com> <1423466726-20833-1-git-send-email-addy.ke@rock-chips.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150208_232817_797782_17BB2911 X-CRM114-Status: UNSURE ( 9.43 ) X-CRM114-Notice: Please train this message. X-Spam-Score: 1.7 (+) Cc: huangtao@rock-chips.com, devicetree@vger.kernel.org, Addy Ke , hl@rock-chips.com, linux-doc@vger.kernel.org, yzq@rock-chips.com, zyw@rock-chips.com, zhangqing@rock-chips.com, linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, kever.yang@rock-chips.com, lintao@rock-chips.com, linux-rockchip@lists.infradead.org, xjq@rock-chips.com, zhenfu.fang@rock-chips.com, chenfen@rock-chips.com, cf@rock-chips.com, hj@rock-chips.com, linux-arm-kernel@lists.infradead.org, zyf@rock-chips.com 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=-2.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY, URIBL_BLACK 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 Because of some uncertain factors, such as worse card or worse hardware, DAT[3:0](the data lines) may be pulled down by card, and mmc controller will be in busy state. This should not happend when mmc controller send command to update card clocks. If this happends, mci_send_cmd will be failed and we will get 'Timeout sending command', and then system will be blocked. To avoid this, we need reset mmc controller. Signed-off-by: Addy Ke --- drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4d2e3c2..b0b57e3 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -100,6 +100,7 @@ struct idmac_desc { }; #endif /* CONFIG_MMC_DW_IDMAC */ +static int dw_mci_card_busy(struct mmc_host *mmc); static bool dw_mci_reset(struct dw_mci *host); static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset); @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg) cmd, arg, cmd_status); } +static void dw_mci_wait_busy(struct dw_mci_slot *slot) +{ + struct dw_mci *host = slot->host; + unsigned long timeout = jiffies + msecs_to_jiffies(500); + + do { + if (!dw_mci_card_busy(slot->mmc)) + return; + cpu_relax(); + } while (time_before(jiffies, timeout)); + + dev_err(host->dev, "Data busy (status %#x)\n", + mci_readl(slot->host, STATUS)); + + /* + * Data busy, this should not happend when mmc controller send command + * to update card clocks in non-volt-switch state. If it happends, we + * should reset controller to avoid getting "Timeout sending command". + */ + dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS); + + /* Fail to reset controller or still data busy, WARN_ON! */ + WARN_ON(dw_mci_card_busy(slot->mmc)); +} + static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) { struct dw_mci *host = slot->host; @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) /* We must continue to set bit 28 in CMD until the change is complete */ if (host->state == STATE_WAITING_CMD11_DONE) sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH; + else + dw_mci_wait_busy(slot); if (!clock) { mci_writel(host, CLKENA, 0);