From patchwork Wed Jul 6 09:40:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hogan X-Patchwork-Id: 949152 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p669eTlS008687 for ; Wed, 6 Jul 2011 09:40:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751924Ab1GFJk3 (ORCPT ); Wed, 6 Jul 2011 05:40:29 -0400 Received: from multi.imgtec.com ([194.200.65.239]:65213 "EHLO multi.imgtec.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752204Ab1GFJk2 (ORCPT ); Wed, 6 Jul 2011 05:40:28 -0400 Message-ID: <4E142D89.2070704@imgtec.com> Date: Wed, 06 Jul 2011 10:40:25 +0100 From: James Hogan User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Thunderbird/3.0.10 MIME-Version: 1.0 To: James Hogan CC: Chris Ball , Will , Jaehoon Chung , Kyungmin Park , linux-mmc , linux-kernel Subject: [PATCH v2 4/4] mmc: dw_mmc: reset FIFO after an error References: <4E142C10.3050508@imgtec.com> In-Reply-To: <4E142C10.3050508@imgtec.com> X-OriginalArrivalTime: 06 Jul 2011 09:40:25.0378 (UTC) FILETIME=[BB953820:01CC3BC0] X-SEF-Processed: 7_3_0_01158__2011_07_06_10_40_26 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Wed, 06 Jul 2011 09:40:30 +0000 (UTC) If an error occurs mid way through a transaction (such as a missing CRC status response after the 2nd block written out of 3), then the FIFO may still contain data which will interfere with the next transaction. Therefore after an error has been detected, reset the fifo using the CTRL register. Signed-off-by: James Hogan Acked-by: Will Newton Tested-by: Jaehoon Chung --- drivers/mmc/host/dw_mmc.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 0dac397..0c839d3 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -849,7 +849,7 @@ static void dw_mci_tasklet_func(unsigned long priv) struct mmc_command *cmd; enum dw_mci_state state; enum dw_mci_state prev_state; - u32 status; + u32 status, ctrl; spin_lock(&host->lock); @@ -929,6 +929,16 @@ static void dw_mci_tasklet_func(unsigned long priv) status); data->error = -EIO; } + /* + * After an error, there may be data lingering + * in the FIFO, so reset it - doing so + * generates a block interrupt, hence setting + * the scatter-gather pointer to NULL. + */ + host->sg = NULL; + ctrl = mci_readl(host, CTRL); + ctrl |= SDMMC_CTRL_FIFO_RESET; + mci_writel(host, CTRL, ctrl); } else { data->bytes_xfered = data->blocks * data->blksz; data->error = 0;