mmc: mmci: add dma_start callback
authorLudovic Barre <ludovic.barre@st.com>
Mon, 8 Oct 2018 12:08:38 +0000 (14:08 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 9 Oct 2018 07:13:03 +0000 (09:13 +0200)
This patch adds dma_start callback to mmci_host_ops.
Create a generic mmci_dma_start function which regroup
common action between variant.

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h
drivers/mmc/host/mmci_qcom_dml.c

index 8d483dd..72584f4 100644 (file)
@@ -425,6 +425,41 @@ void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
                host->ops->get_next_data(host, data);
 }
 
+int mmci_dma_start(struct mmci_host *host, unsigned int datactrl)
+{
+       struct mmc_data *data = host->data;
+       int ret;
+
+       if (!host->use_dma)
+               return -EINVAL;
+
+       ret = mmci_prep_data(host, data, false);
+       if (ret)
+               return ret;
+
+       if (!host->ops || !host->ops->dma_start)
+               return -EINVAL;
+
+       /* Okay, go for it. */
+       dev_vdbg(mmc_dev(host->mmc),
+                "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n",
+                data->sg_len, data->blksz, data->blocks, data->flags);
+
+       host->ops->dma_start(host, &datactrl);
+
+       /* Trigger the DMA transfer */
+       mmci_write_datactrlreg(host, datactrl);
+
+       /*
+        * Let the MMCI say when the data is ended and it's time
+        * to fire next DMA request. When that happens, MMCI will
+        * call mmci_data_end()
+        */
+       writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK,
+              host->base + MMCIMASK0);
+       return 0;
+}
+
 static void
 mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
@@ -736,23 +771,11 @@ int mmci_dmae_prep_data(struct mmci_host *host,
                                    &dmae->desc_current);
 }
 
-static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
+int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl)
 {
-       int ret;
        struct mmci_dmae_priv *dmae = host->dma_priv;
        struct mmc_data *data = host->data;
 
-       if (!host->use_dma)
-               return -EINVAL;
-
-       ret = mmci_dmae_prep_data(host, host->data, false);
-       if (ret)
-               return ret;
-
-       /* Okay, go for it. */
-       dev_vdbg(mmc_dev(host->mmc),
-                "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n",
-                data->sg_len, data->blksz, data->blocks, data->flags);
        host->dma_in_progress = true;
        dmaengine_submit(dmae->desc_current);
        dma_async_issue_pending(dmae->cur);
@@ -760,18 +783,8 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
        if (host->variant->qcom_dml)
                dml_start_xfer(host, data);
 
-       datactrl |= MCI_DPSM_DMAENABLE;
+       *datactrl |= MCI_DPSM_DMAENABLE;
 
-       /* Trigger the DMA transfer */
-       mmci_write_datactrlreg(host, datactrl);
-
-       /*
-        * Let the MMCI say when the data is ended and it's time
-        * to fire next DMA request. When that happens, MMCI will
-        * call mmci_data_end()
-        */
-       writel(readl(host->base + MMCIMASK0) | MCI_DATAENDMASK,
-              host->base + MMCIMASK0);
        return 0;
 }
 
@@ -830,6 +843,7 @@ static struct mmci_host_ops mmci_variant_ops = {
        .get_next_data = mmci_dmae_get_next_data,
        .dma_setup = mmci_dmae_setup,
        .dma_release = mmci_dmae_release,
+       .dma_start = mmci_dmae_start,
 };
 
 void mmci_variant_init(struct mmci_host *host)
@@ -847,11 +861,6 @@ static inline void mmci_dma_data_error(struct mmci_host *host)
 {
 }
 
-static inline int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl)
-{
-       return -ENOSYS;
-}
-
 #endif
 
 static void mmci_pre_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -948,7 +957,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
         * Attempt to use DMA operation mode, if this
         * should fail, fall back to PIO mode
         */
-       if (!mmci_dma_start_data(host, datactrl))
+       if (!mmci_dma_start(host, datactrl))
                return;
 
        /* IRQ mode, map the SG list for CPU reading/writing */
index a6a85aa..7bca597 100644 (file)
@@ -280,6 +280,7 @@ struct mmci_host_ops {
        void (*get_next_data)(struct mmci_host *host, struct mmc_data *data);
        int (*dma_setup)(struct mmci_host *host);
        void (*dma_release)(struct mmci_host *host);
+       int (*dma_start)(struct mmci_host *host, unsigned int *datactrl);
 };
 
 struct mmci_host {
@@ -339,4 +340,5 @@ void mmci_dmae_unprep_data(struct mmci_host *host, struct mmc_data *data,
 void mmci_dmae_get_next_data(struct mmci_host *host, struct mmc_data *data);
 int mmci_dmae_setup(struct mmci_host *host);
 void mmci_dmae_release(struct mmci_host *host);
+int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl);
 
index da4c43a..66af406 100644 (file)
@@ -189,6 +189,7 @@ static struct mmci_host_ops qcom_variant_ops = {
        .get_next_data = mmci_dmae_get_next_data,
        .dma_setup = qcom_dma_setup,
        .dma_release = mmci_dmae_release,
+       .dma_start = mmci_dmae_start,
 };
 
 void qcom_variant_init(struct mmci_host *host)