diff options
author | Marek Vasut <marex@denx.de> | 2012-08-03 11:26:12 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-17 17:54:15 -0400 |
commit | 65defb9b3ba67c1d6f88ac62c24644eb23a7b676 (patch) | |
tree | 68b68b0eb966f6691353363deea65de0d1ea06d1 | |
parent | 646781d3325cdcc648b8eeb3b7cda393bcb78659 (diff) |
mmc: spi: Pull out common DMA parts from MXS MMC
These parts will be used by the MXS SPI driver too.
Signed-off-by: Marek Vasut <marex@denx.de>
Acked-by: Chris Ball <cjb@laptop.org>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 88 | ||||
-rw-r--r-- | drivers/spi/spi-mxs.c | 1 | ||||
-rw-r--r-- | include/linux/spi/mxs-spi.h | 9 |
3 files changed, 51 insertions, 47 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 0813340fa29c..4da996654772 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/gpio.h> | 41 | #include <linux/gpio.h> |
42 | #include <linux/regulator/consumer.h> | 42 | #include <linux/regulator/consumer.h> |
43 | #include <linux/module.h> | 43 | #include <linux/module.h> |
44 | #include <linux/fsl/mxs-dma.h> | ||
45 | #include <linux/pinctrl/consumer.h> | 44 | #include <linux/pinctrl/consumer.h> |
46 | #include <linux/stmp_device.h> | 45 | #include <linux/stmp_device.h> |
47 | #include <linux/mmc/mxs-mmc.h> | 46 | #include <linux/mmc/mxs-mmc.h> |
@@ -69,13 +68,6 @@ struct mxs_mmc_host { | |||
69 | struct mmc_command *cmd; | 68 | struct mmc_command *cmd; |
70 | struct mmc_data *data; | 69 | struct mmc_data *data; |
71 | 70 | ||
72 | int dma_channel; | ||
73 | struct dma_chan *dmach; | ||
74 | struct mxs_dma_data dma_data; | ||
75 | unsigned int dma_dir; | ||
76 | enum dma_transfer_direction slave_dirn; | ||
77 | u32 ssp_pio_words[SSP_PIO_NUM]; | ||
78 | |||
79 | unsigned char bus_width; | 71 | unsigned char bus_width; |
80 | spinlock_t lock; | 72 | spinlock_t lock; |
81 | int sdio_irq_en; | 73 | int sdio_irq_en; |
@@ -163,7 +155,7 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host) | |||
163 | 155 | ||
164 | if (data) { | 156 | if (data) { |
165 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 157 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
166 | data->sg_len, host->dma_dir); | 158 | data->sg_len, ssp->dma_dir); |
167 | /* | 159 | /* |
168 | * If there was an error on any block, we mark all | 160 | * If there was an error on any block, we mark all |
169 | * data blocks as being in error. | 161 | * data blocks as being in error. |
@@ -232,6 +224,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) | |||
232 | static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( | 224 | static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( |
233 | struct mxs_mmc_host *host, unsigned long flags) | 225 | struct mxs_mmc_host *host, unsigned long flags) |
234 | { | 226 | { |
227 | struct mxs_ssp *ssp = &host->ssp; | ||
235 | struct dma_async_tx_descriptor *desc; | 228 | struct dma_async_tx_descriptor *desc; |
236 | struct mmc_data *data = host->data; | 229 | struct mmc_data *data = host->data; |
237 | struct scatterlist * sgl; | 230 | struct scatterlist * sgl; |
@@ -240,24 +233,24 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( | |||
240 | if (data) { | 233 | if (data) { |
241 | /* data */ | 234 | /* data */ |
242 | dma_map_sg(mmc_dev(host->mmc), data->sg, | 235 | dma_map_sg(mmc_dev(host->mmc), data->sg, |
243 | data->sg_len, host->dma_dir); | 236 | data->sg_len, ssp->dma_dir); |
244 | sgl = data->sg; | 237 | sgl = data->sg; |
245 | sg_len = data->sg_len; | 238 | sg_len = data->sg_len; |
246 | } else { | 239 | } else { |
247 | /* pio */ | 240 | /* pio */ |
248 | sgl = (struct scatterlist *) host->ssp_pio_words; | 241 | sgl = (struct scatterlist *) ssp->ssp_pio_words; |
249 | sg_len = SSP_PIO_NUM; | 242 | sg_len = SSP_PIO_NUM; |
250 | } | 243 | } |
251 | 244 | ||
252 | desc = dmaengine_prep_slave_sg(host->dmach, | 245 | desc = dmaengine_prep_slave_sg(ssp->dmach, |
253 | sgl, sg_len, host->slave_dirn, flags); | 246 | sgl, sg_len, ssp->slave_dirn, flags); |
254 | if (desc) { | 247 | if (desc) { |
255 | desc->callback = mxs_mmc_dma_irq_callback; | 248 | desc->callback = mxs_mmc_dma_irq_callback; |
256 | desc->callback_param = host; | 249 | desc->callback_param = host; |
257 | } else { | 250 | } else { |
258 | if (data) | 251 | if (data) |
259 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 252 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
260 | data->sg_len, host->dma_dir); | 253 | data->sg_len, ssp->dma_dir); |
261 | } | 254 | } |
262 | 255 | ||
263 | return desc; | 256 | return desc; |
@@ -265,6 +258,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( | |||
265 | 258 | ||
266 | static void mxs_mmc_bc(struct mxs_mmc_host *host) | 259 | static void mxs_mmc_bc(struct mxs_mmc_host *host) |
267 | { | 260 | { |
261 | struct mxs_ssp *ssp = &host->ssp; | ||
268 | struct mmc_command *cmd = host->cmd; | 262 | struct mmc_command *cmd = host->cmd; |
269 | struct dma_async_tx_descriptor *desc; | 263 | struct dma_async_tx_descriptor *desc; |
270 | u32 ctrl0, cmd0, cmd1; | 264 | u32 ctrl0, cmd0, cmd1; |
@@ -278,17 +272,17 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) | |||
278 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; | 272 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; |
279 | } | 273 | } |
280 | 274 | ||
281 | host->ssp_pio_words[0] = ctrl0; | 275 | ssp->ssp_pio_words[0] = ctrl0; |
282 | host->ssp_pio_words[1] = cmd0; | 276 | ssp->ssp_pio_words[1] = cmd0; |
283 | host->ssp_pio_words[2] = cmd1; | 277 | ssp->ssp_pio_words[2] = cmd1; |
284 | host->dma_dir = DMA_NONE; | 278 | ssp->dma_dir = DMA_NONE; |
285 | host->slave_dirn = DMA_TRANS_NONE; | 279 | ssp->slave_dirn = DMA_TRANS_NONE; |
286 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); | 280 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); |
287 | if (!desc) | 281 | if (!desc) |
288 | goto out; | 282 | goto out; |
289 | 283 | ||
290 | dmaengine_submit(desc); | 284 | dmaengine_submit(desc); |
291 | dma_async_issue_pending(host->dmach); | 285 | dma_async_issue_pending(ssp->dmach); |
292 | return; | 286 | return; |
293 | 287 | ||
294 | out: | 288 | out: |
@@ -298,6 +292,7 @@ out: | |||
298 | 292 | ||
299 | static void mxs_mmc_ac(struct mxs_mmc_host *host) | 293 | static void mxs_mmc_ac(struct mxs_mmc_host *host) |
300 | { | 294 | { |
295 | struct mxs_ssp *ssp = &host->ssp; | ||
301 | struct mmc_command *cmd = host->cmd; | 296 | struct mmc_command *cmd = host->cmd; |
302 | struct dma_async_tx_descriptor *desc; | 297 | struct dma_async_tx_descriptor *desc; |
303 | u32 ignore_crc, get_resp, long_resp; | 298 | u32 ignore_crc, get_resp, long_resp; |
@@ -319,17 +314,17 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) | |||
319 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; | 314 | cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; |
320 | } | 315 | } |
321 | 316 | ||
322 | host->ssp_pio_words[0] = ctrl0; | 317 | ssp->ssp_pio_words[0] = ctrl0; |
323 | host->ssp_pio_words[1] = cmd0; | 318 | ssp->ssp_pio_words[1] = cmd0; |
324 | host->ssp_pio_words[2] = cmd1; | 319 | ssp->ssp_pio_words[2] = cmd1; |
325 | host->dma_dir = DMA_NONE; | 320 | ssp->dma_dir = DMA_NONE; |
326 | host->slave_dirn = DMA_TRANS_NONE; | 321 | ssp->slave_dirn = DMA_TRANS_NONE; |
327 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); | 322 | desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); |
328 | if (!desc) | 323 | if (!desc) |
329 | goto out; | 324 | goto out; |
330 | 325 | ||
331 | dmaengine_submit(desc); | 326 | dmaengine_submit(desc); |
332 | dma_async_issue_pending(host->dmach); | 327 | dma_async_issue_pending(ssp->dmach); |
333 | return; | 328 | return; |
334 | 329 | ||
335 | out: | 330 | out: |
@@ -441,11 +436,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
441 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); | 436 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); |
442 | 437 | ||
443 | /* pio */ | 438 | /* pio */ |
444 | host->ssp_pio_words[0] = ctrl0; | 439 | ssp->ssp_pio_words[0] = ctrl0; |
445 | host->ssp_pio_words[1] = cmd0; | 440 | ssp->ssp_pio_words[1] = cmd0; |
446 | host->ssp_pio_words[2] = cmd1; | 441 | ssp->ssp_pio_words[2] = cmd1; |
447 | host->dma_dir = DMA_NONE; | 442 | ssp->dma_dir = DMA_NONE; |
448 | host->slave_dirn = DMA_TRANS_NONE; | 443 | ssp->slave_dirn = DMA_TRANS_NONE; |
449 | desc = mxs_mmc_prep_dma(host, 0); | 444 | desc = mxs_mmc_prep_dma(host, 0); |
450 | if (!desc) | 445 | if (!desc) |
451 | goto out; | 446 | goto out; |
@@ -453,14 +448,14 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) | |||
453 | /* append data sg */ | 448 | /* append data sg */ |
454 | WARN_ON(host->data != NULL); | 449 | WARN_ON(host->data != NULL); |
455 | host->data = data; | 450 | host->data = data; |
456 | host->dma_dir = dma_data_dir; | 451 | ssp->dma_dir = dma_data_dir; |
457 | host->slave_dirn = slave_dirn; | 452 | ssp->slave_dirn = slave_dirn; |
458 | desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 453 | desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
459 | if (!desc) | 454 | if (!desc) |
460 | goto out; | 455 | goto out; |
461 | 456 | ||
462 | dmaengine_submit(desc); | 457 | dmaengine_submit(desc); |
463 | dma_async_issue_pending(host->dmach); | 458 | dma_async_issue_pending(ssp->dmach); |
464 | return; | 459 | return; |
465 | out: | 460 | out: |
466 | dev_warn(mmc_dev(host->mmc), | 461 | dev_warn(mmc_dev(host->mmc), |
@@ -557,14 +552,15 @@ static const struct mmc_host_ops mxs_mmc_ops = { | |||
557 | static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param) | 552 | static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param) |
558 | { | 553 | { |
559 | struct mxs_mmc_host *host = param; | 554 | struct mxs_mmc_host *host = param; |
555 | struct mxs_ssp *ssp = &host->ssp; | ||
560 | 556 | ||
561 | if (!mxs_dma_is_apbh(chan)) | 557 | if (!mxs_dma_is_apbh(chan)) |
562 | return false; | 558 | return false; |
563 | 559 | ||
564 | if (chan->chan_id != host->dma_channel) | 560 | if (chan->chan_id != ssp->dma_channel) |
565 | return false; | 561 | return false; |
566 | 562 | ||
567 | chan->private = &host->dma_data; | 563 | chan->private = &ssp->dma_data; |
568 | 564 | ||
569 | return true; | 565 | return true; |
570 | } | 566 | } |
@@ -632,7 +628,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
632 | * to use generic DMA binding later when the helpers get in. | 628 | * to use generic DMA binding later when the helpers get in. |
633 | */ | 629 | */ |
634 | ret = of_property_read_u32(np, "fsl,ssp-dma-channel", | 630 | ret = of_property_read_u32(np, "fsl,ssp-dma-channel", |
635 | &host->dma_channel); | 631 | &ssp->dma_channel); |
636 | if (ret) { | 632 | if (ret) { |
637 | dev_err(mmc_dev(host->mmc), | 633 | dev_err(mmc_dev(host->mmc), |
638 | "failed to get dma channel\n"); | 634 | "failed to get dma channel\n"); |
@@ -640,7 +636,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
640 | } | 636 | } |
641 | } else { | 637 | } else { |
642 | ssp->devid = pdev->id_entry->driver_data; | 638 | ssp->devid = pdev->id_entry->driver_data; |
643 | host->dma_channel = dmares->start; | 639 | ssp->dma_channel = dmares->start; |
644 | } | 640 | } |
645 | 641 | ||
646 | host->mmc = mmc; | 642 | host->mmc = mmc; |
@@ -673,9 +669,9 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
673 | 669 | ||
674 | dma_cap_zero(mask); | 670 | dma_cap_zero(mask); |
675 | dma_cap_set(DMA_SLAVE, mask); | 671 | dma_cap_set(DMA_SLAVE, mask); |
676 | host->dma_data.chan_irq = irq_dma; | 672 | ssp->dma_data.chan_irq = irq_dma; |
677 | host->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host); | 673 | ssp->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host); |
678 | if (!host->dmach) { | 674 | if (!ssp->dmach) { |
679 | dev_err(mmc_dev(host->mmc), | 675 | dev_err(mmc_dev(host->mmc), |
680 | "%s: failed to request dma\n", __func__); | 676 | "%s: failed to request dma\n", __func__); |
681 | goto out_clk_put; | 677 | goto out_clk_put; |
@@ -714,7 +710,7 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
714 | mmc->max_blk_size = 1 << 0xf; | 710 | mmc->max_blk_size = 1 << 0xf; |
715 | mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff; | 711 | mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff; |
716 | mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff; | 712 | mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff; |
717 | mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); | 713 | mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev); |
718 | 714 | ||
719 | platform_set_drvdata(pdev, mmc); | 715 | platform_set_drvdata(pdev, mmc); |
720 | 716 | ||
@@ -734,8 +730,8 @@ static int mxs_mmc_probe(struct platform_device *pdev) | |||
734 | return 0; | 730 | return 0; |
735 | 731 | ||
736 | out_free_dma: | 732 | out_free_dma: |
737 | if (host->dmach) | 733 | if (ssp->dmach) |
738 | dma_release_channel(host->dmach); | 734 | dma_release_channel(ssp->dmach); |
739 | out_clk_put: | 735 | out_clk_put: |
740 | clk_disable_unprepare(ssp->clk); | 736 | clk_disable_unprepare(ssp->clk); |
741 | clk_put(ssp->clk); | 737 | clk_put(ssp->clk); |
@@ -754,8 +750,8 @@ static int mxs_mmc_remove(struct platform_device *pdev) | |||
754 | 750 | ||
755 | platform_set_drvdata(pdev, NULL); | 751 | platform_set_drvdata(pdev, NULL); |
756 | 752 | ||
757 | if (host->dmach) | 753 | if (ssp->dmach) |
758 | dma_release_channel(host->dmach); | 754 | dma_release_channel(ssp->dmach); |
759 | 755 | ||
760 | clk_disable_unprepare(ssp->clk); | 756 | clk_disable_unprepare(ssp->clk); |
761 | clk_put(ssp->clk); | 757 | clk_put(ssp->clk); |
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 7bf826f5af59..0f28afb80310 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/gpio.h> | 46 | #include <linux/gpio.h> |
47 | #include <linux/regulator/consumer.h> | 47 | #include <linux/regulator/consumer.h> |
48 | #include <linux/module.h> | 48 | #include <linux/module.h> |
49 | #include <linux/fsl/mxs-dma.h> | ||
50 | #include <linux/pinctrl/consumer.h> | 49 | #include <linux/pinctrl/consumer.h> |
51 | #include <linux/stmp_device.h> | 50 | #include <linux/stmp_device.h> |
52 | #include <linux/spi/spi.h> | 51 | #include <linux/spi/spi.h> |
diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h index d07f8dc7fdd9..61ae1306db23 100644 --- a/include/linux/spi/mxs-spi.h +++ b/include/linux/spi/mxs-spi.h | |||
@@ -24,6 +24,8 @@ | |||
24 | #ifndef __LINUX_SPI_MXS_SPI_H__ | 24 | #ifndef __LINUX_SPI_MXS_SPI_H__ |
25 | #define __LINUX_SPI_MXS_SPI_H__ | 25 | #define __LINUX_SPI_MXS_SPI_H__ |
26 | 26 | ||
27 | #include <linux/fsl/mxs-dma.h> | ||
28 | |||
27 | #define ssp_is_old(host) ((host)->devid == IMX23_SSP) | 29 | #define ssp_is_old(host) ((host)->devid == IMX23_SSP) |
28 | 30 | ||
29 | /* SSP registers */ | 31 | /* SSP registers */ |
@@ -134,6 +136,13 @@ struct mxs_ssp { | |||
134 | struct clk *clk; | 136 | struct clk *clk; |
135 | unsigned int clk_rate; | 137 | unsigned int clk_rate; |
136 | enum mxs_ssp_id devid; | 138 | enum mxs_ssp_id devid; |
139 | |||
140 | int dma_channel; | ||
141 | struct dma_chan *dmach; | ||
142 | struct mxs_dma_data dma_data; | ||
143 | unsigned int dma_dir; | ||
144 | enum dma_transfer_direction slave_dirn; | ||
145 | u32 ssp_pio_words[SSP_PIO_NUM]; | ||
137 | }; | 146 | }; |
138 | 147 | ||
139 | void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate); | 148 | void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate); |