Commit 65defb9b authored by Marek Vasut's avatar Marek Vasut Committed by Mark Brown

mmc: spi: Pull out common DMA parts from MXS MMC

These parts will be used by the MXS SPI driver too.
Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Acked-by: default avatarChris Ball <cjb@laptop.org>
Acked-by: default avatarShawn Guo <shawn.guo@linaro.org>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 646781d3
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/fsl/mxs-dma.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/stmp_device.h> #include <linux/stmp_device.h>
#include <linux/mmc/mxs-mmc.h> #include <linux/mmc/mxs-mmc.h>
...@@ -69,13 +68,6 @@ struct mxs_mmc_host { ...@@ -69,13 +68,6 @@ struct mxs_mmc_host {
struct mmc_command *cmd; struct mmc_command *cmd;
struct mmc_data *data; struct mmc_data *data;
int dma_channel;
struct dma_chan *dmach;
struct mxs_dma_data dma_data;
unsigned int dma_dir;
enum dma_transfer_direction slave_dirn;
u32 ssp_pio_words[SSP_PIO_NUM];
unsigned char bus_width; unsigned char bus_width;
spinlock_t lock; spinlock_t lock;
int sdio_irq_en; int sdio_irq_en;
...@@ -163,7 +155,7 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host) ...@@ -163,7 +155,7 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
if (data) { if (data) {
dma_unmap_sg(mmc_dev(host->mmc), data->sg, dma_unmap_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, host->dma_dir); data->sg_len, ssp->dma_dir);
/* /*
* If there was an error on any block, we mark all * If there was an error on any block, we mark all
* data blocks as being in error. * data blocks as being in error.
...@@ -232,6 +224,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) ...@@ -232,6 +224,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
struct mxs_mmc_host *host, unsigned long flags) struct mxs_mmc_host *host, unsigned long flags)
{ {
struct mxs_ssp *ssp = &host->ssp;
struct dma_async_tx_descriptor *desc; struct dma_async_tx_descriptor *desc;
struct mmc_data *data = host->data; struct mmc_data *data = host->data;
struct scatterlist * sgl; struct scatterlist * sgl;
...@@ -240,24 +233,24 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( ...@@ -240,24 +233,24 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
if (data) { if (data) {
/* data */ /* data */
dma_map_sg(mmc_dev(host->mmc), data->sg, dma_map_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, host->dma_dir); data->sg_len, ssp->dma_dir);
sgl = data->sg; sgl = data->sg;
sg_len = data->sg_len; sg_len = data->sg_len;
} else { } else {
/* pio */ /* pio */
sgl = (struct scatterlist *) host->ssp_pio_words; sgl = (struct scatterlist *) ssp->ssp_pio_words;
sg_len = SSP_PIO_NUM; sg_len = SSP_PIO_NUM;
} }
desc = dmaengine_prep_slave_sg(host->dmach, desc = dmaengine_prep_slave_sg(ssp->dmach,
sgl, sg_len, host->slave_dirn, flags); sgl, sg_len, ssp->slave_dirn, flags);
if (desc) { if (desc) {
desc->callback = mxs_mmc_dma_irq_callback; desc->callback = mxs_mmc_dma_irq_callback;
desc->callback_param = host; desc->callback_param = host;
} else { } else {
if (data) if (data)
dma_unmap_sg(mmc_dev(host->mmc), data->sg, dma_unmap_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, host->dma_dir); data->sg_len, ssp->dma_dir);
} }
return desc; return desc;
...@@ -265,6 +258,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( ...@@ -265,6 +258,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
static void mxs_mmc_bc(struct mxs_mmc_host *host) static void mxs_mmc_bc(struct mxs_mmc_host *host)
{ {
struct mxs_ssp *ssp = &host->ssp;
struct mmc_command *cmd = host->cmd; struct mmc_command *cmd = host->cmd;
struct dma_async_tx_descriptor *desc; struct dma_async_tx_descriptor *desc;
u32 ctrl0, cmd0, cmd1; u32 ctrl0, cmd0, cmd1;
...@@ -278,17 +272,17 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) ...@@ -278,17 +272,17 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
} }
host->ssp_pio_words[0] = ctrl0; ssp->ssp_pio_words[0] = ctrl0;
host->ssp_pio_words[1] = cmd0; ssp->ssp_pio_words[1] = cmd0;
host->ssp_pio_words[2] = cmd1; ssp->ssp_pio_words[2] = cmd1;
host->dma_dir = DMA_NONE; ssp->dma_dir = DMA_NONE;
host->slave_dirn = DMA_TRANS_NONE; ssp->slave_dirn = DMA_TRANS_NONE;
desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
if (!desc) if (!desc)
goto out; goto out;
dmaengine_submit(desc); dmaengine_submit(desc);
dma_async_issue_pending(host->dmach); dma_async_issue_pending(ssp->dmach);
return; return;
out: out:
...@@ -298,6 +292,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) ...@@ -298,6 +292,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
static void mxs_mmc_ac(struct mxs_mmc_host *host) static void mxs_mmc_ac(struct mxs_mmc_host *host)
{ {
struct mxs_ssp *ssp = &host->ssp;
struct mmc_command *cmd = host->cmd; struct mmc_command *cmd = host->cmd;
struct dma_async_tx_descriptor *desc; struct dma_async_tx_descriptor *desc;
u32 ignore_crc, get_resp, long_resp; u32 ignore_crc, get_resp, long_resp;
...@@ -319,17 +314,17 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) ...@@ -319,17 +314,17 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
} }
host->ssp_pio_words[0] = ctrl0; ssp->ssp_pio_words[0] = ctrl0;
host->ssp_pio_words[1] = cmd0; ssp->ssp_pio_words[1] = cmd0;
host->ssp_pio_words[2] = cmd1; ssp->ssp_pio_words[2] = cmd1;
host->dma_dir = DMA_NONE; ssp->dma_dir = DMA_NONE;
host->slave_dirn = DMA_TRANS_NONE; ssp->slave_dirn = DMA_TRANS_NONE;
desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
if (!desc) if (!desc)
goto out; goto out;
dmaengine_submit(desc); dmaengine_submit(desc);
dma_async_issue_pending(host->dmach); dma_async_issue_pending(ssp->dmach);
return; return;
out: out:
...@@ -441,11 +436,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) ...@@ -441,11 +436,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
writel(val, ssp->base + HW_SSP_TIMING(ssp)); writel(val, ssp->base + HW_SSP_TIMING(ssp));
/* pio */ /* pio */
host->ssp_pio_words[0] = ctrl0; ssp->ssp_pio_words[0] = ctrl0;
host->ssp_pio_words[1] = cmd0; ssp->ssp_pio_words[1] = cmd0;
host->ssp_pio_words[2] = cmd1; ssp->ssp_pio_words[2] = cmd1;
host->dma_dir = DMA_NONE; ssp->dma_dir = DMA_NONE;
host->slave_dirn = DMA_TRANS_NONE; ssp->slave_dirn = DMA_TRANS_NONE;
desc = mxs_mmc_prep_dma(host, 0); desc = mxs_mmc_prep_dma(host, 0);
if (!desc) if (!desc)
goto out; goto out;
...@@ -453,14 +448,14 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) ...@@ -453,14 +448,14 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
/* append data sg */ /* append data sg */
WARN_ON(host->data != NULL); WARN_ON(host->data != NULL);
host->data = data; host->data = data;
host->dma_dir = dma_data_dir; ssp->dma_dir = dma_data_dir;
host->slave_dirn = slave_dirn; ssp->slave_dirn = slave_dirn;
desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) if (!desc)
goto out; goto out;
dmaengine_submit(desc); dmaengine_submit(desc);
dma_async_issue_pending(host->dmach); dma_async_issue_pending(ssp->dmach);
return; return;
out: out:
dev_warn(mmc_dev(host->mmc), dev_warn(mmc_dev(host->mmc),
...@@ -557,14 +552,15 @@ static const struct mmc_host_ops mxs_mmc_ops = { ...@@ -557,14 +552,15 @@ static const struct mmc_host_ops mxs_mmc_ops = {
static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param) static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
{ {
struct mxs_mmc_host *host = param; struct mxs_mmc_host *host = param;
struct mxs_ssp *ssp = &host->ssp;
if (!mxs_dma_is_apbh(chan)) if (!mxs_dma_is_apbh(chan))
return false; return false;
if (chan->chan_id != host->dma_channel) if (chan->chan_id != ssp->dma_channel)
return false; return false;
chan->private = &host->dma_data; chan->private = &ssp->dma_data;
return true; return true;
} }
...@@ -632,7 +628,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) ...@@ -632,7 +628,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
* to use generic DMA binding later when the helpers get in. * to use generic DMA binding later when the helpers get in.
*/ */
ret = of_property_read_u32(np, "fsl,ssp-dma-channel", ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
&host->dma_channel); &ssp->dma_channel);
if (ret) { if (ret) {
dev_err(mmc_dev(host->mmc), dev_err(mmc_dev(host->mmc),
"failed to get dma channel\n"); "failed to get dma channel\n");
...@@ -640,7 +636,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) ...@@ -640,7 +636,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
} }
} else { } else {
ssp->devid = pdev->id_entry->driver_data; ssp->devid = pdev->id_entry->driver_data;
host->dma_channel = dmares->start; ssp->dma_channel = dmares->start;
} }
host->mmc = mmc; host->mmc = mmc;
...@@ -673,9 +669,9 @@ static int mxs_mmc_probe(struct platform_device *pdev) ...@@ -673,9 +669,9 @@ static int mxs_mmc_probe(struct platform_device *pdev)
dma_cap_zero(mask); dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask); dma_cap_set(DMA_SLAVE, mask);
host->dma_data.chan_irq = irq_dma; ssp->dma_data.chan_irq = irq_dma;
host->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host); ssp->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host);
if (!host->dmach) { if (!ssp->dmach) {
dev_err(mmc_dev(host->mmc), dev_err(mmc_dev(host->mmc),
"%s: failed to request dma\n", __func__); "%s: failed to request dma\n", __func__);
goto out_clk_put; goto out_clk_put;
...@@ -714,7 +710,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) ...@@ -714,7 +710,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
mmc->max_blk_size = 1 << 0xf; mmc->max_blk_size = 1 << 0xf;
mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff; mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff;
mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff; mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff;
mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev);
platform_set_drvdata(pdev, mmc); platform_set_drvdata(pdev, mmc);
...@@ -734,8 +730,8 @@ static int mxs_mmc_probe(struct platform_device *pdev) ...@@ -734,8 +730,8 @@ static int mxs_mmc_probe(struct platform_device *pdev)
return 0; return 0;
out_free_dma: out_free_dma:
if (host->dmach) if (ssp->dmach)
dma_release_channel(host->dmach); dma_release_channel(ssp->dmach);
out_clk_put: out_clk_put:
clk_disable_unprepare(ssp->clk); clk_disable_unprepare(ssp->clk);
clk_put(ssp->clk); clk_put(ssp->clk);
...@@ -754,8 +750,8 @@ static int mxs_mmc_remove(struct platform_device *pdev) ...@@ -754,8 +750,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
if (host->dmach) if (ssp->dmach)
dma_release_channel(host->dmach); dma_release_channel(ssp->dmach);
clk_disable_unprepare(ssp->clk); clk_disable_unprepare(ssp->clk);
clk_put(ssp->clk); clk_put(ssp->clk);
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/fsl/mxs-dma.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/stmp_device.h> #include <linux/stmp_device.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#ifndef __LINUX_SPI_MXS_SPI_H__ #ifndef __LINUX_SPI_MXS_SPI_H__
#define __LINUX_SPI_MXS_SPI_H__ #define __LINUX_SPI_MXS_SPI_H__
#include <linux/fsl/mxs-dma.h>
#define ssp_is_old(host) ((host)->devid == IMX23_SSP) #define ssp_is_old(host) ((host)->devid == IMX23_SSP)
/* SSP registers */ /* SSP registers */
...@@ -134,6 +136,13 @@ struct mxs_ssp { ...@@ -134,6 +136,13 @@ struct mxs_ssp {
struct clk *clk; struct clk *clk;
unsigned int clk_rate; unsigned int clk_rate;
enum mxs_ssp_id devid; enum mxs_ssp_id devid;
int dma_channel;
struct dma_chan *dmach;
struct mxs_dma_data dma_data;
unsigned int dma_dir;
enum dma_transfer_direction slave_dirn;
u32 ssp_pio_words[SSP_PIO_NUM];
}; };
void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate); void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment