diff options
Diffstat (limited to 'drivers/mmc/host/mxcmmc.c')
-rw-r--r-- | drivers/mmc/host/mxcmmc.c | 237 |
1 files changed, 151 insertions, 86 deletions
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 350f78e86245..cc20e0259325 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -31,16 +31,15 @@ | |||
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
34 | #include <linux/regulator/consumer.h> | ||
35 | #include <linux/dmaengine.h> | ||
34 | 36 | ||
35 | #include <asm/dma.h> | 37 | #include <asm/dma.h> |
36 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
37 | #include <asm/sizes.h> | 39 | #include <asm/sizes.h> |
38 | #include <mach/mmc.h> | 40 | #include <mach/mmc.h> |
39 | 41 | ||
40 | #ifdef CONFIG_ARCH_MX2 | 42 | #include <mach/dma.h> |
41 | #include <mach/dma-mx1-mx2.h> | ||
42 | #define HAS_DMA | ||
43 | #endif | ||
44 | 43 | ||
45 | #define DRIVER_NAME "mxc-mmc" | 44 | #define DRIVER_NAME "mxc-mmc" |
46 | 45 | ||
@@ -117,7 +116,8 @@ struct mxcmci_host { | |||
117 | void __iomem *base; | 116 | void __iomem *base; |
118 | int irq; | 117 | int irq; |
119 | int detect_irq; | 118 | int detect_irq; |
120 | int dma; | 119 | struct dma_chan *dma; |
120 | struct dma_async_tx_descriptor *desc; | ||
121 | int do_dma; | 121 | int do_dma; |
122 | int default_irq_mask; | 122 | int default_irq_mask; |
123 | int use_sdio; | 123 | int use_sdio; |
@@ -128,7 +128,6 @@ struct mxcmci_host { | |||
128 | struct mmc_command *cmd; | 128 | struct mmc_command *cmd; |
129 | struct mmc_data *data; | 129 | struct mmc_data *data; |
130 | 130 | ||
131 | unsigned int dma_nents; | ||
132 | unsigned int datasize; | 131 | unsigned int datasize; |
133 | unsigned int dma_dir; | 132 | unsigned int dma_dir; |
134 | 133 | ||
@@ -141,10 +140,54 @@ struct mxcmci_host { | |||
141 | 140 | ||
142 | struct work_struct datawork; | 141 | struct work_struct datawork; |
143 | spinlock_t lock; | 142 | spinlock_t lock; |
143 | |||
144 | struct regulator *vcc; | ||
145 | |||
146 | int burstlen; | ||
147 | int dmareq; | ||
148 | struct dma_slave_config dma_slave_config; | ||
149 | struct imx_dma_data dma_data; | ||
144 | }; | 150 | }; |
145 | 151 | ||
146 | static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); | 152 | static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); |
147 | 153 | ||
154 | static inline void mxcmci_init_ocr(struct mxcmci_host *host) | ||
155 | { | ||
156 | host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); | ||
157 | |||
158 | if (IS_ERR(host->vcc)) { | ||
159 | host->vcc = NULL; | ||
160 | } else { | ||
161 | host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); | ||
162 | if (host->pdata && host->pdata->ocr_avail) | ||
163 | dev_warn(mmc_dev(host->mmc), | ||
164 | "pdata->ocr_avail will not be used\n"); | ||
165 | } | ||
166 | |||
167 | if (host->vcc == NULL) { | ||
168 | /* fall-back to platform data */ | ||
169 | if (host->pdata && host->pdata->ocr_avail) | ||
170 | host->mmc->ocr_avail = host->pdata->ocr_avail; | ||
171 | else | ||
172 | host->mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | static inline void mxcmci_set_power(struct mxcmci_host *host, | ||
177 | unsigned char power_mode, | ||
178 | unsigned int vdd) | ||
179 | { | ||
180 | if (host->vcc) { | ||
181 | if (power_mode == MMC_POWER_UP) | ||
182 | mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); | ||
183 | else if (power_mode == MMC_POWER_OFF) | ||
184 | mmc_regulator_set_ocr(host->mmc, host->vcc, 0); | ||
185 | } | ||
186 | |||
187 | if (host->pdata && host->pdata->setpower) | ||
188 | host->pdata->setpower(mmc_dev(host->mmc), vdd); | ||
189 | } | ||
190 | |||
148 | static inline int mxcmci_use_dma(struct mxcmci_host *host) | 191 | static inline int mxcmci_use_dma(struct mxcmci_host *host) |
149 | { | 192 | { |
150 | return host->do_dma; | 193 | return host->do_dma; |
@@ -166,17 +209,16 @@ static void mxcmci_softreset(struct mxcmci_host *host) | |||
166 | 209 | ||
167 | writew(0xff, host->base + MMC_REG_RES_TO); | 210 | writew(0xff, host->base + MMC_REG_RES_TO); |
168 | } | 211 | } |
212 | static int mxcmci_setup_dma(struct mmc_host *mmc); | ||
169 | 213 | ||
170 | static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) | 214 | static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) |
171 | { | 215 | { |
172 | unsigned int nob = data->blocks; | 216 | unsigned int nob = data->blocks; |
173 | unsigned int blksz = data->blksz; | 217 | unsigned int blksz = data->blksz; |
174 | unsigned int datasize = nob * blksz; | 218 | unsigned int datasize = nob * blksz; |
175 | #ifdef HAS_DMA | ||
176 | struct scatterlist *sg; | 219 | struct scatterlist *sg; |
177 | int i; | 220 | int i, nents; |
178 | int ret; | 221 | |
179 | #endif | ||
180 | if (data->flags & MMC_DATA_STREAM) | 222 | if (data->flags & MMC_DATA_STREAM) |
181 | nob = 0xffff; | 223 | nob = 0xffff; |
182 | 224 | ||
@@ -187,7 +229,9 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) | |||
187 | writew(blksz, host->base + MMC_REG_BLK_LEN); | 229 | writew(blksz, host->base + MMC_REG_BLK_LEN); |
188 | host->datasize = datasize; | 230 | host->datasize = datasize; |
189 | 231 | ||
190 | #ifdef HAS_DMA | 232 | if (!mxcmci_use_dma(host)) |
233 | return 0; | ||
234 | |||
191 | for_each_sg(data->sg, sg, data->sg_len, i) { | 235 | for_each_sg(data->sg, sg, data->sg_len, i) { |
192 | if (sg->offset & 3 || sg->length & 3) { | 236 | if (sg->offset & 3 || sg->length & 3) { |
193 | host->do_dma = 0; | 237 | host->do_dma = 0; |
@@ -195,34 +239,30 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) | |||
195 | } | 239 | } |
196 | } | 240 | } |
197 | 241 | ||
198 | if (data->flags & MMC_DATA_READ) { | 242 | if (data->flags & MMC_DATA_READ) |
199 | host->dma_dir = DMA_FROM_DEVICE; | 243 | host->dma_dir = DMA_FROM_DEVICE; |
200 | host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, | 244 | else |
201 | data->sg_len, host->dma_dir); | ||
202 | |||
203 | ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, | ||
204 | datasize, | ||
205 | host->res->start + MMC_REG_BUFFER_ACCESS, | ||
206 | DMA_MODE_READ); | ||
207 | } else { | ||
208 | host->dma_dir = DMA_TO_DEVICE; | 245 | host->dma_dir = DMA_TO_DEVICE; |
209 | host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, | ||
210 | data->sg_len, host->dma_dir); | ||
211 | 246 | ||
212 | ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, | 247 | nents = dma_map_sg(host->dma->device->dev, data->sg, |
213 | datasize, | 248 | data->sg_len, host->dma_dir); |
214 | host->res->start + MMC_REG_BUFFER_ACCESS, | 249 | if (nents != data->sg_len) |
215 | DMA_MODE_WRITE); | 250 | return -EINVAL; |
216 | } | 251 | |
252 | host->desc = host->dma->device->device_prep_slave_sg(host->dma, | ||
253 | data->sg, data->sg_len, host->dma_dir, | ||
254 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
217 | 255 | ||
218 | if (ret) { | 256 | if (!host->desc) { |
219 | dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret); | 257 | dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len, |
220 | return ret; | 258 | host->dma_dir); |
259 | host->do_dma = 0; | ||
260 | return 0; /* Fall back to PIO */ | ||
221 | } | 261 | } |
222 | wmb(); | 262 | wmb(); |
223 | 263 | ||
224 | imx_dma_enable(host->dma); | 264 | dmaengine_submit(host->desc); |
225 | #endif /* HAS_DMA */ | 265 | |
226 | return 0; | 266 | return 0; |
227 | } | 267 | } |
228 | 268 | ||
@@ -297,13 +337,11 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) | |||
297 | struct mmc_data *data = host->data; | 337 | struct mmc_data *data = host->data; |
298 | int data_error; | 338 | int data_error; |
299 | 339 | ||
300 | #ifdef HAS_DMA | ||
301 | if (mxcmci_use_dma(host)) { | 340 | if (mxcmci_use_dma(host)) { |
302 | imx_dma_disable(host->dma); | 341 | dmaengine_terminate_all(host->dma); |
303 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents, | 342 | dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len, |
304 | host->dma_dir); | 343 | host->dma_dir); |
305 | } | 344 | } |
306 | #endif | ||
307 | 345 | ||
308 | if (stat & STATUS_ERR_MASK) { | 346 | if (stat & STATUS_ERR_MASK) { |
309 | dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", | 347 | dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", |
@@ -505,7 +543,6 @@ static void mxcmci_datawork(struct work_struct *work) | |||
505 | } | 543 | } |
506 | } | 544 | } |
507 | 545 | ||
508 | #ifdef HAS_DMA | ||
509 | static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat) | 546 | static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat) |
510 | { | 547 | { |
511 | struct mmc_data *data = host->data; | 548 | struct mmc_data *data = host->data; |
@@ -528,7 +565,6 @@ static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat) | |||
528 | mxcmci_finish_request(host, host->req); | 565 | mxcmci_finish_request(host, host->req); |
529 | } | 566 | } |
530 | } | 567 | } |
531 | #endif /* HAS_DMA */ | ||
532 | 568 | ||
533 | static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) | 569 | static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) |
534 | { | 570 | { |
@@ -566,12 +602,10 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) | |||
566 | sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; | 602 | sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; |
567 | spin_unlock_irqrestore(&host->lock, flags); | 603 | spin_unlock_irqrestore(&host->lock, flags); |
568 | 604 | ||
569 | #ifdef HAS_DMA | ||
570 | if (mxcmci_use_dma(host) && | 605 | if (mxcmci_use_dma(host) && |
571 | (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE))) | 606 | (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE))) |
572 | writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE, | 607 | writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE, |
573 | host->base + MMC_REG_STATUS); | 608 | host->base + MMC_REG_STATUS); |
574 | #endif | ||
575 | 609 | ||
576 | if (sdio_irq) { | 610 | if (sdio_irq) { |
577 | writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); | 611 | writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); |
@@ -581,14 +615,14 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) | |||
581 | if (stat & STATUS_END_CMD_RESP) | 615 | if (stat & STATUS_END_CMD_RESP) |
582 | mxcmci_cmd_done(host, stat); | 616 | mxcmci_cmd_done(host, stat); |
583 | 617 | ||
584 | #ifdef HAS_DMA | ||
585 | if (mxcmci_use_dma(host) && | 618 | if (mxcmci_use_dma(host) && |
586 | (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) | 619 | (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) |
587 | mxcmci_data_done(host, stat); | 620 | mxcmci_data_done(host, stat); |
588 | #endif | 621 | |
589 | if (host->default_irq_mask && | 622 | if (host->default_irq_mask && |
590 | (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL))) | 623 | (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL))) |
591 | mmc_detect_change(host->mmc, msecs_to_jiffies(200)); | 624 | mmc_detect_change(host->mmc, msecs_to_jiffies(200)); |
625 | |||
592 | return IRQ_HANDLED; | 626 | return IRQ_HANDLED; |
593 | } | 627 | } |
594 | 628 | ||
@@ -602,9 +636,10 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) | |||
602 | 636 | ||
603 | host->req = req; | 637 | host->req = req; |
604 | host->cmdat &= ~CMD_DAT_CONT_INIT; | 638 | host->cmdat &= ~CMD_DAT_CONT_INIT; |
605 | #ifdef HAS_DMA | 639 | |
606 | host->do_dma = 1; | 640 | if (host->dma) |
607 | #endif | 641 | host->do_dma = 1; |
642 | |||
608 | if (req->data) { | 643 | if (req->data) { |
609 | error = mxcmci_setup_data(host, req->data); | 644 | error = mxcmci_setup_data(host, req->data); |
610 | if (error) { | 645 | if (error) { |
@@ -620,6 +655,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) | |||
620 | } | 655 | } |
621 | 656 | ||
622 | error = mxcmci_start_cmd(host, req->cmd, cmdat); | 657 | error = mxcmci_start_cmd(host, req->cmd, cmdat); |
658 | |||
623 | out: | 659 | out: |
624 | if (error) | 660 | if (error) |
625 | mxcmci_finish_request(host, req); | 661 | mxcmci_finish_request(host, req); |
@@ -658,31 +694,55 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios) | |||
658 | prescaler, divider, clk_in, clk_ios); | 694 | prescaler, divider, clk_in, clk_ios); |
659 | } | 695 | } |
660 | 696 | ||
697 | static int mxcmci_setup_dma(struct mmc_host *mmc) | ||
698 | { | ||
699 | struct mxcmci_host *host = mmc_priv(mmc); | ||
700 | struct dma_slave_config *config = &host->dma_slave_config; | ||
701 | |||
702 | config->dst_addr = host->res->start + MMC_REG_BUFFER_ACCESS; | ||
703 | config->src_addr = host->res->start + MMC_REG_BUFFER_ACCESS; | ||
704 | config->dst_addr_width = 4; | ||
705 | config->src_addr_width = 4; | ||
706 | config->dst_maxburst = host->burstlen; | ||
707 | config->src_maxburst = host->burstlen; | ||
708 | |||
709 | return dmaengine_slave_config(host->dma, config); | ||
710 | } | ||
711 | |||
661 | static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 712 | static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
662 | { | 713 | { |
663 | struct mxcmci_host *host = mmc_priv(mmc); | 714 | struct mxcmci_host *host = mmc_priv(mmc); |
664 | #ifdef HAS_DMA | 715 | int burstlen, ret; |
665 | unsigned int blen; | 716 | |
666 | /* | 717 | /* |
667 | * use burstlen of 64 in 4 bit mode (--> reg value 0) | 718 | * use burstlen of 64 in 4 bit mode (--> reg value 0) |
668 | * use burstlen of 16 in 1 bit mode (--> reg value 16) | 719 | * use burstlen of 16 in 1 bit mode (--> reg value 16) |
669 | */ | 720 | */ |
670 | if (ios->bus_width == MMC_BUS_WIDTH_4) | 721 | if (ios->bus_width == MMC_BUS_WIDTH_4) |
671 | blen = 0; | 722 | burstlen = 64; |
672 | else | 723 | else |
673 | blen = 16; | 724 | burstlen = 16; |
725 | |||
726 | if (mxcmci_use_dma(host) && burstlen != host->burstlen) { | ||
727 | host->burstlen = burstlen; | ||
728 | ret = mxcmci_setup_dma(mmc); | ||
729 | if (ret) { | ||
730 | dev_err(mmc_dev(host->mmc), | ||
731 | "failed to config DMA channel. Falling back to PIO\n"); | ||
732 | dma_release_channel(host->dma); | ||
733 | host->do_dma = 0; | ||
734 | } | ||
735 | } | ||
674 | 736 | ||
675 | imx_dma_config_burstlen(host->dma, blen); | ||
676 | #endif | ||
677 | if (ios->bus_width == MMC_BUS_WIDTH_4) | 737 | if (ios->bus_width == MMC_BUS_WIDTH_4) |
678 | host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; | 738 | host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; |
679 | else | 739 | else |
680 | host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4; | 740 | host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4; |
681 | 741 | ||
682 | if (host->power_mode != ios->power_mode) { | 742 | if (host->power_mode != ios->power_mode) { |
683 | if (host->pdata && host->pdata->setpower) | 743 | mxcmci_set_power(host, ios->power_mode, ios->vdd); |
684 | host->pdata->setpower(mmc_dev(mmc), ios->vdd); | ||
685 | host->power_mode = ios->power_mode; | 744 | host->power_mode = ios->power_mode; |
745 | |||
686 | if (ios->power_mode == MMC_POWER_ON) | 746 | if (ios->power_mode == MMC_POWER_ON) |
687 | host->cmdat |= CMD_DAT_CONT_INIT; | 747 | host->cmdat |= CMD_DAT_CONT_INIT; |
688 | } | 748 | } |
@@ -754,6 +814,18 @@ static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card) | |||
754 | host->caps |= MMC_CAP_4_BIT_DATA; | 814 | host->caps |= MMC_CAP_4_BIT_DATA; |
755 | } | 815 | } |
756 | 816 | ||
817 | static bool filter(struct dma_chan *chan, void *param) | ||
818 | { | ||
819 | struct mxcmci_host *host = param; | ||
820 | |||
821 | if (!imx_dma_is_general_purpose(chan)) | ||
822 | return false; | ||
823 | |||
824 | chan->private = &host->dma_data; | ||
825 | |||
826 | return true; | ||
827 | } | ||
828 | |||
757 | static const struct mmc_host_ops mxcmci_ops = { | 829 | static const struct mmc_host_ops mxcmci_ops = { |
758 | .request = mxcmci_request, | 830 | .request = mxcmci_request, |
759 | .set_ios = mxcmci_set_ios, | 831 | .set_ios = mxcmci_set_ios, |
@@ -768,6 +840,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
768 | struct mxcmci_host *host = NULL; | 840 | struct mxcmci_host *host = NULL; |
769 | struct resource *iores, *r; | 841 | struct resource *iores, *r; |
770 | int ret = 0, irq; | 842 | int ret = 0, irq; |
843 | dma_cap_mask_t mask; | ||
771 | 844 | ||
772 | printk(KERN_INFO "i.MX SDHC driver\n"); | 845 | printk(KERN_INFO "i.MX SDHC driver\n"); |
773 | 846 | ||
@@ -790,8 +863,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
790 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 863 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; |
791 | 864 | ||
792 | /* MMC core transfer sizes tunable parameters */ | 865 | /* MMC core transfer sizes tunable parameters */ |
793 | mmc->max_hw_segs = 64; | 866 | mmc->max_segs = 64; |
794 | mmc->max_phys_segs = 64; | ||
795 | mmc->max_blk_size = 2048; | 867 | mmc->max_blk_size = 2048; |
796 | mmc->max_blk_count = 65535; | 868 | mmc->max_blk_count = 65535; |
797 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 869 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
@@ -808,10 +880,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
808 | host->pdata = pdev->dev.platform_data; | 880 | host->pdata = pdev->dev.platform_data; |
809 | spin_lock_init(&host->lock); | 881 | spin_lock_init(&host->lock); |
810 | 882 | ||
811 | if (host->pdata && host->pdata->ocr_avail) | 883 | mxcmci_init_ocr(host); |
812 | mmc->ocr_avail = host->pdata->ocr_avail; | ||
813 | else | ||
814 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | ||
815 | 884 | ||
816 | if (host->pdata && host->pdata->dat3_card_detect) | 885 | if (host->pdata && host->pdata->dat3_card_detect) |
817 | host->default_irq_mask = | 886 | host->default_irq_mask = |
@@ -847,29 +916,23 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
847 | 916 | ||
848 | writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR); | 917 | writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR); |
849 | 918 | ||
850 | #ifdef HAS_DMA | ||
851 | host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); | ||
852 | if (host->dma < 0) { | ||
853 | dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n"); | ||
854 | ret = -EBUSY; | ||
855 | goto out_clk_put; | ||
856 | } | ||
857 | |||
858 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 919 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
859 | if (!r) { | 920 | if (r) { |
860 | ret = -EINVAL; | 921 | host->dmareq = r->start; |
861 | goto out_free_dma; | 922 | host->dma_data.peripheral_type = IMX_DMATYPE_SDHC; |
923 | host->dma_data.priority = DMA_PRIO_LOW; | ||
924 | host->dma_data.dma_request = host->dmareq; | ||
925 | dma_cap_zero(mask); | ||
926 | dma_cap_set(DMA_SLAVE, mask); | ||
927 | host->dma = dma_request_channel(mask, filter, host); | ||
928 | if (host->dma) | ||
929 | mmc->max_seg_size = dma_get_max_seg_size( | ||
930 | host->dma->device->dev); | ||
862 | } | 931 | } |
863 | 932 | ||
864 | ret = imx_dma_config_channel(host->dma, | 933 | if (!host->dma) |
865 | IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO, | 934 | dev_info(mmc_dev(host->mmc), "dma not available. Using PIO\n"); |
866 | IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, | 935 | |
867 | r->start, 0); | ||
868 | if (ret) { | ||
869 | dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n"); | ||
870 | goto out_free_dma; | ||
871 | } | ||
872 | #endif | ||
873 | INIT_WORK(&host->datawork, mxcmci_datawork); | 936 | INIT_WORK(&host->datawork, mxcmci_datawork); |
874 | 937 | ||
875 | ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host); | 938 | ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host); |
@@ -892,9 +955,8 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
892 | out_free_irq: | 955 | out_free_irq: |
893 | free_irq(host->irq, host); | 956 | free_irq(host->irq, host); |
894 | out_free_dma: | 957 | out_free_dma: |
895 | #ifdef HAS_DMA | 958 | if (host->dma) |
896 | imx_dma_free(host->dma); | 959 | dma_release_channel(host->dma); |
897 | #endif | ||
898 | out_clk_put: | 960 | out_clk_put: |
899 | clk_disable(host->clk); | 961 | clk_disable(host->clk); |
900 | clk_put(host->clk); | 962 | clk_put(host->clk); |
@@ -916,19 +978,22 @@ static int mxcmci_remove(struct platform_device *pdev) | |||
916 | 978 | ||
917 | mmc_remove_host(mmc); | 979 | mmc_remove_host(mmc); |
918 | 980 | ||
981 | if (host->vcc) | ||
982 | regulator_put(host->vcc); | ||
983 | |||
919 | if (host->pdata && host->pdata->exit) | 984 | if (host->pdata && host->pdata->exit) |
920 | host->pdata->exit(&pdev->dev, mmc); | 985 | host->pdata->exit(&pdev->dev, mmc); |
921 | 986 | ||
922 | free_irq(host->irq, host); | 987 | free_irq(host->irq, host); |
923 | iounmap(host->base); | 988 | iounmap(host->base); |
924 | #ifdef HAS_DMA | 989 | |
925 | imx_dma_free(host->dma); | 990 | if (host->dma) |
926 | #endif | 991 | dma_release_channel(host->dma); |
992 | |||
927 | clk_disable(host->clk); | 993 | clk_disable(host->clk); |
928 | clk_put(host->clk); | 994 | clk_put(host->clk); |
929 | 995 | ||
930 | release_mem_region(host->res->start, resource_size(host->res)); | 996 | release_mem_region(host->res->start, resource_size(host->res)); |
931 | release_resource(host->res); | ||
932 | 997 | ||
933 | mmc_free_host(mmc); | 998 | mmc_free_host(mmc); |
934 | 999 | ||