From patchwork Tue Jun 12 13:14:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic BARRE X-Patchwork-Id: 10460373 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6265F60348 for ; Tue, 12 Jun 2018 13:47:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C09425F31 for ; Tue, 12 Jun 2018 13:47:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2FDB02879C; Tue, 12 Jun 2018 13:47:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id AC94C25F31 for ; Tue, 12 Jun 2018 13:47:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=LSO7nf8TSYiHrYzVJX900E10iC4ydipAF3S1ITHTGCY=; b=u8oD3jZ09gXpep WE6t2SdwXwS233fNWotqyRPq+/NtWXZNPeaOk+7C5cpBc1ogXQFryzMLQP3Uw9ZPLcqGcfxxoZWNF gLxSPxtV5jkHj5IKhhdZcAiYx7kH7iWjsTbqqP7nK5hzr/Tyw6N2egA73ftbIUMfdZUA0vsOcOrze VfdRxY3rj6F4i9FYzAvepJZqbb4xHY/h3pg5H2Tx0Rbzh52GtBarf4BYILUqRtmYbhNTtYILG3bXU Sjtm7ayiL5lmpHYG7mykXqeNe5b45TAd3URrZZqJjbcELR/qd/y2GdxLaeYG93fnOtqno0dYWKrw3 jXgvPrMoENwdeDAhRvvg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fSjdc-0003sz-1z; Tue, 12 Jun 2018 13:47:08 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fSj9o-0006SB-0Z for linux-arm-kernel@lists.infradead.org; Tue, 12 Jun 2018 13:16:48 +0000 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w5CDDbPY008981; Tue, 12 Jun 2018 15:16:08 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2jj63btf2m-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 12 Jun 2018 15:16:08 +0200 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 89AD234; Tue, 12 Jun 2018 13:16:04 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas22.st.com [10.75.90.92]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id DA88AA54A; Tue, 12 Jun 2018 13:16:03 +0000 (GMT) Received: from SAFEX1HUBCAS21.st.com (10.75.90.44) by Safex1hubcas22.st.com (10.75.90.92) with Microsoft SMTP Server (TLS) id 14.3.361.1; Tue, 12 Jun 2018 15:16:03 +0200 Received: from lmecxl0923.lme.st.com (10.48.0.237) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.361.1; Tue, 12 Jun 2018 15:16:03 +0200 From: Ludovic Barre To: Ulf Hansson , Rob Herring Subject: [PATCH 13/19] mmc: mmci: send stop cmd if a data command fail Date: Tue, 12 Jun 2018 15:14:34 +0200 Message-ID: <1528809280-31116-14-git-send-email-ludovic.Barre@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1528809280-31116-1-git-send-email-ludovic.Barre@st.com> References: <1528809280-31116-1-git-send-email-ludovic.Barre@st.com> MIME-Version: 1.0 X-Originating-IP: [10.48.0.237] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-06-12_01:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180612_061620_367409_E6D15716 X-CRM114-Status: GOOD ( 17.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Torgue , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, Ludovic Barre , Maxime Coquelin , Gerald Baeza , linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ludovic Barre The mmc framework follows the requirement of SD_Specification: the STOP_TRANSMISSION is sent on multiple write/read commands and the stop command (alone), not needed on other ADTC commands. But, some variants require a stop command "STOP_TRANSMISION" to clear the DPSM "Data Path State Machine" if an error happens on command or data step. If it's not done the next data command will freeze hardware block. Needed to support the STM32 sdmmc variant. Signed-off-by: Ludovic Barre --- drivers/mmc/host/mmci.c | 36 +++++++++++++++++++++++++++++++----- drivers/mmc/host/mmci.h | 3 +++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 87724e1..9af7db8 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -522,11 +523,28 @@ static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) host->mask1_reg = mask; } -static void mmci_stop_data(struct mmci_host *host) +static int mmci_stop_data(struct mmci_host *host) { + struct mmc_command *stop = &host->stop_abort; + struct mmc_data *data = host->data; + unsigned int cmd = 0; + mmci_write_datactrlreg(host, 0); mmci_set_mask1(host, 0); host->data = NULL; + + if (host->variant->cmdreg_stop) { + cmd |= host->variant->cmdreg_stop; + if (!data->stop) { + memset(stop, 0, sizeof(struct mmc_command)); + stop->opcode = MMC_STOP_TRANSMISSION; + stop->arg = 0; + stop->flags = MMC_RSP_R1B | MMC_CMD_AC; + data->stop = stop; + } + } + + return cmd; } static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data) @@ -703,6 +721,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, unsigned int status) { unsigned int status_err; + unsigned int cmd_reg = 0; /* Make sure we have data to handle */ if (!data) @@ -761,7 +780,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, if (status & MCI_DATAEND || data->error) { mmci_dma_finalize(host, data); - mmci_stop_data(host); + cmd_reg = mmci_stop_data(host); if (!data->error) /* The error clause is handled above, success! */ @@ -770,7 +789,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, if (!data->stop || host->mrq->sbc) { mmci_request_end(host, data->mrq); } else { - mmci_start_command(host, data->stop, 0); + mmci_start_command(host, data->stop, cmd_reg); } } } @@ -780,6 +799,8 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, unsigned int status) { void __iomem *base = host->base; + struct mmc_data *data = host->data; + unsigned int cmd_reg = 0; bool sbc; if (!cmd) @@ -865,11 +886,16 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } if ((!sbc && !cmd->data) || cmd->error) { - if (host->data) { + if (data) { /* Terminate the DMA transfer */ mmci_dma_error(host); - mmci_stop_data(host); + cmd_reg = mmci_stop_data(host); + + if (data->stop) { + mmci_start_command(host, data->stop, cmd_reg); + return; + } } mmci_request_end(host, host->mrq); } else if (sbc) { diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 2d7e901..4b4cd1d 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -243,6 +243,7 @@ struct mmci_host; * @cmdreg_lrsp_crc: enable value for long response with crc * @cmdreg_srsp_crc: enable value for short response with crc * @cmdreg_srsp: enable value for short response without crc + * @cmdreg_stop: enable value for stop and abort transmission * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -298,6 +299,7 @@ struct variant_data { unsigned int cmdreg_lrsp_crc; unsigned int cmdreg_srsp_crc; unsigned int cmdreg_srsp; + unsigned int cmdreg_stop; unsigned int datalength_bits; unsigned int fifosize; unsigned int fifohalfsize; @@ -343,6 +345,7 @@ struct mmci_host { struct mmc_request *mrq; struct mmc_command *cmd; struct mmc_data *data; + struct mmc_command stop_abort; struct mmc_host *mmc; struct clk *clk; bool singleirq;