From patchwork Thu Nov 8 08:35:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jaehoon Chung X-Patchwork-Id: 1714471 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 2997D3FCDF for ; Thu, 8 Nov 2012 08:35:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752787Ab2KHIfs (ORCPT ); Thu, 8 Nov 2012 03:35:48 -0500 Received: from mailout3.samsung.com ([203.254.224.33]:56570 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751419Ab2KHIfr (ORCPT ); Thu, 8 Nov 2012 03:35:47 -0500 Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MD500II1UJGAMI0@mailout3.samsung.com> for linux-mmc@vger.kernel.org; Thu, 08 Nov 2012 17:35:46 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [203.254.230.46]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 44.84.01231.2EE6B905; Thu, 08 Nov 2012 17:35:46 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-ab-509b6ee24008 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id D3.84.01231.2EE6B905; Thu, 08 Nov 2012 17:35:46 +0900 (KST) Received: from [10.90.51.55] by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MD500LVVUJMWZ20@mmp1.samsung.com> for linux-mmc@vger.kernel.org; Thu, 08 Nov 2012 17:35:46 +0900 (KST) Message-id: <509B6ED4.703@samsung.com> Date: Thu, 08 Nov 2012 17:35:32 +0900 From: Jaehoon Chung User-Agent: Mozilla/5.0 (X11; Linux i686; rv:16.0) Gecko/20121011 Thunderbird/16.0.1 MIME-version: 1.0 To: linux-mmc Cc: Chris Ball , Kyungmin Park , Will Newton , James Hogan , Seungwon Jeon Subject: [PATCH v3 3/4] mmc: dw-mmc: check whether card is busy or not, before disabling clock Content-type: text/plain; charset=ISO-8859-1 Content-transfer-encoding: 7bit DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuphkeLIzCtJLcpLzFFi42I5/e+Znu6jvNkBBnvOaVgc+d/P6MDo8XmT XABjFJdNSmpOZllqkb5dAlfGpVUf2QqeSVb8u7qbrYHxiUgXIyeHhICJRN+GDcwQtpjEhXvr 2boYuTiEBJYxSrxs+MoOU7Tq5yN2iMQiRom7TduZIZx2Jon2tglsIFW8AmoSH2ZvYwKxWQRU JVacXQ0WZxPQkdj+7ThQnINDVCBMYufmdIhyQYkfk++xgNgiApoSndtXgm1mFjjAKLH3I8Rm YYEEie2NE8FmMgPN2d86jQ3ClpfYvOYtM8QuAYlvkw+xgMyXEJCV2HQA7DYJgddsEpPXLIH6 QFLi4IobLBMYRWYh2T0LydhZSMYuYGRexSiaWpBcUJyUnmuoV5yYW1yal66XnJ+7iRES5FI7 GFc2WBxiFOBgVOLh1ZCcHSDEmlhWXJl7iFGCg1lJhHeZM1CINyWxsiq1KD++qDQntfgQow/Q tROZpUST84ERmFcSb2hsYGxoaGloZmppaoBDWEmct9kjJUBIID2xJDU7NbUgtQhmHBMHp1QD 4/6+Nf76+uwOEbGahwWElsa5VnwsSi04L/y16/XMgj/hTYdOTtt/IetwH9/TX8pZ6xaJCFzu qrmzcyV73+vLXYLNZ1zkuELkTsbeKJ34NFnypIV12xz39AszZUTvrFauvhfzU74hv/Xnmn3F kiWzhG5O/96VdUGF6c7K40/0rS6rBtcfj9vwU4mlOCPRUIu5qDgRABxIZm6fAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrNIsWRmVeSWpSXmKPExsVy+t9jAd1HebMDDJ6fVrE48r+f0YHR4/Mm uQDGqAZGm4zUxJTUIoXUvOT8lMy8dFsl7+B453hTMwNDXUNLC3MlhbzE3FRbJRefAF23zByg qUoKZYk5pUChgMTiYiV9O0wTQkPcdC1gGiN0fUOC4HqMDNBAwjrGjEurPrIVPJOs+Hd1N1sD 4xORLkZODgkBE4lVPx+xQ9hiEhfurWfrYuTiEBJYxChxt2k7M4TTziTR3jaBDaSKV0BN4sPs bUwgNouAqsSKs6vB4mwCOhLbvx0HinNwiAqESezcnA5RLijxY/I9FhBbREBTonP7SrAFzAIH GCX2fvwKtllYIEFie+NEsJnMQHP2t05jg7DlJTavecs8gZFvFpJZs5CUzUJStoCReRWjaGpB ckFxUnquoV5xYm5xaV66XnJ+7iZGcAw9k9rBuLLB4hCjAAejEg+vhuTsACHWxLLiytxDjBIc zEoivMucgUK8KYmVValF+fFFpTmpxYcYfYA+ncgsJZqcD4zvvJJ4Q2MTMyNLIzNjE3NjYxzC SuK8zR4pAUIC6YklqdmpqQWpRTDjmDg4pRoYI9/mzIx8+/ZLZIPzptWTp9dby7y63bPtodwl KQ33Tcv/RcUYzrgzV2tq7ulKmxWyLCU79qucavCpfKZ552Fi55f6r/1RGrJiDx78uD93T90R jzcF1caPfkcUnV/xS2DepN23zvumzZMITnwbvtyYLecJk7PyjEWsz46WRSWK5r3JNvkQz95u ocRSnJFoqMVcVJwIAJhS837OAgAA X-CFilter-Loop: Reflected Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Before disabling clock, need to check whether card is busy on not. Signed-off-by: Jaehoon Chung --- drivers/mmc/host/dw_mmc.c | 53 +++++++++++++++++++++++++++----------------- drivers/mmc/host/dw_mmc.h | 1 + 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 0a80b5c..9704b09 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -228,6 +228,27 @@ static void dw_mci_set_timeout(struct dw_mci *host) mci_writel(host, TMOUT, 0xffffffff); } +static bool mci_wait_reset(struct device *dev, struct dw_mci *host) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(500); + unsigned int ctrl; + + mci_writel(host, CTRL, (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | + SDMMC_CTRL_DMA_RESET)); + + /* wait till resets clear */ + do { + ctrl = mci_readl(host, CTRL); + if (!(ctrl & (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | + SDMMC_CTRL_DMA_RESET))) + return true; + } while (time_before(jiffies, timeout)); + + dev_err(dev, "Timeout resetting block (ctrl %#x)\n", ctrl); + + return false; +} + static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) { struct mmc_data *data; @@ -622,6 +643,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) struct dw_mci *host = slot->host; u32 div; u32 clk_en_a; + int timeout = 1000; if (slot->clock != host->current_speed) { div = host->bus_hz / slot->clock; @@ -638,6 +660,16 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" " div = %d)\n", slot->id, host->bus_hz, slot->clock, div ? ((host->bus_hz / div) >> 1) : host->bus_hz, div); + do { + if (!(mci_readl(host, STATUS) & SDMMC_DATA_BUSY)) + break; + if (timeout-- < 0) { + dev_err(host->dev, "Can't disable clock" + "because Card is busy!!\n"); + return; + } + mci_wait_reset(host->dev, host); + } while (1); /* disable clock */ mci_writel(host, CLKENA, 0); @@ -1995,27 +2027,6 @@ no_dma: return; } -static bool mci_wait_reset(struct device *dev, struct dw_mci *host) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(500); - unsigned int ctrl; - - mci_writel(host, CTRL, (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | - SDMMC_CTRL_DMA_RESET)); - - /* wait till resets clear */ - do { - ctrl = mci_readl(host, CTRL); - if (!(ctrl & (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | - SDMMC_CTRL_DMA_RESET))) - return true; - } while (time_before(jiffies, timeout)); - - dev_err(dev, "Timeout resetting block (ctrl %#x)\n", ctrl); - - return false; -} - #ifdef CONFIG_OF static struct dw_mci_of_quirks { char *quirk; diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 53b8fd9..4f27357 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -127,6 +127,7 @@ #define SDMMC_CMD_INDX(n) ((n) & 0x1F) /* Status register defines */ #define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FFF) +#define SDMMC_DATA_BUSY BIT(9) /* Internal DMAC interrupt defines */ #define SDMMC_IDMAC_INT_AI BIT(9) #define SDMMC_IDMAC_INT_NI BIT(8)