From patchwork Wed Aug 1 09:36:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic BARRE X-Patchwork-Id: 10551971 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B706015E2 for ; Wed, 1 Aug 2018 09:39:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A54942A4D2 for ; Wed, 1 Aug 2018 09:39:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9989C2A7EE; Wed, 1 Aug 2018 09:39:01 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB66C2A4D2 for ; Wed, 1 Aug 2018 09:39:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389029AbeHALWh (ORCPT ); Wed, 1 Aug 2018 07:22:37 -0400 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:64186 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388842AbeHALWg (ORCPT ); Wed, 1 Aug 2018 07:22:36 -0400 Received: from pps.filterd (m0046037.ppops.net [127.0.0.1]) by mx07-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w719TftR009433; Wed, 1 Aug 2018 11:37:31 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 2kjnaddbd6-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 01 Aug 2018 11:37:31 +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 652F231; Wed, 1 Aug 2018 09:37:30 +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 11E0D28FD; Wed, 1 Aug 2018 09:37:30 +0000 (GMT) Received: from SAFEX1HUBCAS24.st.com (10.75.90.95) by Safex1hubcas22.st.com (10.75.90.92) with Microsoft SMTP Server (TLS) id 14.3.361.1; Wed, 1 Aug 2018 11:37:29 +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; Wed, 1 Aug 2018 11:37:29 +0200 From: Ludovic Barre To: Ulf Hansson , Rob Herring CC: Maxime Coquelin , Alexandre Torgue , Gerald Baeza , , , , , Ludovic Barre Subject: [PATCH 07/14] mmc: mmci: add prepare/unprepare_data callbacks Date: Wed, 1 Aug 2018 11:36:54 +0200 Message-ID: <1533116221-380-8-git-send-email-ludovic.Barre@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1533116221-380-1-git-send-email-ludovic.Barre@st.com> References: <1533116221-380-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-08-01_03:,, signatures=0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ludovic Barre This patch adds prepare/unprepare callbacks to mmci_host_ops. Like this mmci_pre/post_request can be generic, mmci_prepare_data and mmci_unprepare_data provide common next_cookie management. Signed-off-by: Ludovic Barre --- drivers/mmc/host/mmci.c | 118 +++++++++++++++++++++++++++------------ drivers/mmc/host/mmci.h | 10 ++++ drivers/mmc/host/mmci_qcom_dml.c | 2 + 3 files changed, 93 insertions(+), 37 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index e4d80f1..345aa2e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -58,6 +58,7 @@ static struct variant_data variant_arm = { .mmcimask1 = true, .start_err = MCI_STARTBITERR, .opendrain = MCI_ROD, + .init = mmci_variant_init, }; static struct variant_data variant_arm_extended_fifo = { @@ -69,6 +70,7 @@ static struct variant_data variant_arm_extended_fifo = { .mmcimask1 = true, .start_err = MCI_STARTBITERR, .opendrain = MCI_ROD, + .init = mmci_variant_init, }; static struct variant_data variant_arm_extended_fifo_hwfc = { @@ -81,6 +83,7 @@ static struct variant_data variant_arm_extended_fifo_hwfc = { .mmcimask1 = true, .start_err = MCI_STARTBITERR, .opendrain = MCI_ROD, + .init = mmci_variant_init, }; static struct variant_data variant_u300 = { @@ -99,6 +102,7 @@ static struct variant_data variant_u300 = { .mmcimask1 = true, .start_err = MCI_STARTBITERR, .opendrain = MCI_OD, + .init = mmci_variant_init, }; static struct variant_data variant_nomadik = { @@ -118,6 +122,7 @@ static struct variant_data variant_nomadik = { .mmcimask1 = true, .start_err = MCI_STARTBITERR, .opendrain = MCI_OD, + .init = mmci_variant_init, }; static struct variant_data variant_ux500 = { @@ -143,6 +148,7 @@ static struct variant_data variant_ux500 = { .mmcimask1 = true, .start_err = MCI_STARTBITERR, .opendrain = MCI_OD, + .init = mmci_variant_init, }; static struct variant_data variant_ux500v2 = { @@ -170,6 +176,7 @@ static struct variant_data variant_ux500v2 = { .mmcimask1 = true, .start_err = MCI_STARTBITERR, .opendrain = MCI_OD, + .init = mmci_variant_init, }; static struct variant_data variant_stm32 = { @@ -187,6 +194,7 @@ static struct variant_data variant_stm32 = { .f_max = 48000000, .pwrreg_clkgate = true, .pwrreg_nopower = true, + .init = mmci_variant_init, }; static struct variant_data variant_qcom = { @@ -357,6 +365,31 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) mmci_write_clkreg(host, clk); } +int mmci_prepare_data(struct mmci_host *host, struct mmc_data *data, bool next) +{ + int err; + + if (!host->ops || !host->ops->prepare_data) + return 0; + + err = host->ops->prepare_data(host, data, next); + + if (next && !err) + data->host_cookie = ++host->next_cookie < 0 ? + 1 : host->next_cookie; + + return err; +} + +void mmci_unprepare_data(struct mmci_host *host, struct mmc_data *data, + int err) +{ + if (host->ops && host->ops->unprepare_data) + host->ops->unprepare_data(host, data, err); + + data->host_cookie = 0; +} + static void mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) { @@ -588,9 +621,9 @@ static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) } /* prepares DMA channel and DMA descriptor, returns non-zero on failure */ -static int __mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, - struct dma_chan **dma_chan, - struct dma_async_tx_descriptor **dma_desc) +static int __mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, + struct dma_chan **dma_chan, + struct dma_async_tx_descriptor **dma_desc) { struct dmaengine_priv *dmae = host->dma_priv; struct variant_data *variant = host->variant; @@ -651,22 +684,21 @@ static int __mmci_dma_prep_data(struct mmci_host *host, struct mmc_data *data, return -ENOMEM; } -static inline int mmci_dma_prepare_data(struct mmci_host *host, - struct mmc_data *data, - bool next) +int mmci_dmae_prepare_data(struct mmci_host *host, + struct mmc_data *data, bool next) { struct dmaengine_priv *dmae = host->dma_priv; struct dmaengine_next *nd = &dmae->next_data; if (next) - return __mmci_dma_prep_data(host, data, &nd->dma_chan, + return __mmci_dmae_prep_data(host, data, &nd->dma_chan, &nd->dma_desc); /* Check if next job is already prepared. */ if (dmae->dma_current && dmae->dma_desc_current) return 0; /* No job were prepared thus do it now. */ - return __mmci_dma_prep_data(host, data, &dmae->dma_current, + return __mmci_dmae_prep_data(host, data, &dmae->dma_current, &dmae->dma_desc_current); } @@ -676,7 +708,7 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) struct mmc_data *data = host->data; int ret; - ret = mmci_dma_prepare_data(host, host->data, false); + ret = mmci_prepare_data(host, host->data, false); if (ret) return ret; @@ -720,33 +752,11 @@ static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) next->dma_chan = NULL; } -static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) -{ - struct mmci_host *host = mmc_priv(mmc); - struct mmc_data *data = mrq->data; - - if (!data) - return; - - BUG_ON(data->host_cookie); - - if (mmci_validate_data(host, data)) - return; +void mmci_dmae_unprepare_data(struct mmci_host *host, + struct mmc_data *data, int err) - if (!mmci_dma_prepare_data(host, data, true)) - data->host_cookie = ++host->next_cookie < 0 ? - 1 : host->next_cookie; -} - -static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, - int err) { - struct mmci_host *host = mmc_priv(mmc); struct dmaengine_priv *dmae = host->dma_priv; - struct mmc_data *data = mrq->data; - - if (!data || !data->host_cookie) - return; __mmci_dmae_unmap(host, data); @@ -769,10 +779,13 @@ static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, next->dma_desc = NULL; next->dma_chan = NULL; - data->host_cookie = 0; } } +static struct mmci_host_ops mmci_variant_ops = { + .prepare_data = mmci_dmae_prepare_data, + .unprepare_data = mmci_dmae_unprepare_data, +}; #else /* Blank functions if the DMA engine is not available */ static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data) @@ -802,11 +815,42 @@ static inline int mmci_dma_start_data(struct mmci_host *host, unsigned int datac return -ENOSYS; } -#define mmci_pre_request NULL -#define mmci_post_request NULL - +static struct mmci_host_ops mmci_variant_ops = {}; #endif +void mmci_variant_init(struct mmci_host *host) +{ + host->ops = &mmci_variant_ops; +} + +static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct mmci_host *host = mmc_priv(mmc); + struct mmc_data *data = mrq->data; + + if (!data) + return; + + WARN_ON(data->host_cookie); + + if (mmci_validate_data(host, data)) + return; + + mmci_prepare_data(host, data, true); +} + +static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq, + int err) +{ + struct mmci_host *host = mmc_priv(mmc); + struct mmc_data *data = mrq->data; + + if (!data || !data->host_cookie) + return; + + mmci_unprepare_data(host, data, err); +} + static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) { struct variant_data *variant = host->variant; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index d2ec4fd..fa2702b 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -273,6 +273,10 @@ struct variant_data { /* mmci variant callbacks */ struct mmci_host_ops { + int (*prepare_data)(struct mmci_host *host, struct mmc_data *data, + bool next); + void (*unprepare_data)(struct mmci_host *host, struct mmc_data *data, + int err); int (*dma_setup)(struct mmci_host *host); }; @@ -323,3 +327,9 @@ struct mmci_host { }; void qcom_variant_init(struct mmci_host *host); +void mmci_variant_init(struct mmci_host *host); + +int mmci_dmae_prepare_data(struct mmci_host *host, struct mmc_data *data, + bool next); +void mmci_dmae_unprepare_data(struct mmci_host *host, + struct mmc_data *data, int err); diff --git a/drivers/mmc/host/mmci_qcom_dml.c b/drivers/mmc/host/mmci_qcom_dml.c index 1bb59cf..d534fa1 100644 --- a/drivers/mmc/host/mmci_qcom_dml.c +++ b/drivers/mmc/host/mmci_qcom_dml.c @@ -180,6 +180,8 @@ static int qcom_dma_setup(struct mmci_host *host) } static struct mmci_host_ops qcom_variant_ops = { + .prepare_data = mmci_dmae_prepare_data, + .unprepare_data = mmci_dmae_unprepare_data, .dma_setup = qcom_dma_setup, };