Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: mxcmmc: use dmaengine API

This switches the mxcmmc driver to use the dmaengine API. Unlike
the old one this one is always present in the tree, even if no DMA
is implemented, hence we can remove all the #ifdefs in from the driver.
The driver automatically switches to PIO mode if no DMA support or no
suitable channel is available.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by

Sascha Hauer and committed by
Chris Ball
f53fbde4 c9b2a06f

+104 -77
+104 -77
drivers/mmc/host/mxcmmc.c
··· 32 32 #include <linux/io.h> 33 33 #include <linux/gpio.h> 34 34 #include <linux/regulator/consumer.h> 35 + #include <linux/dmaengine.h> 35 36 36 37 #include <asm/dma.h> 37 38 #include <asm/irq.h> 38 39 #include <asm/sizes.h> 39 40 #include <mach/mmc.h> 40 41 41 - #ifdef CONFIG_ARCH_MX2 42 - #include <mach/dma-mx1-mx2.h> 43 - #define HAS_DMA 44 - #endif 42 + #include <mach/dma.h> 45 43 46 44 #define DRIVER_NAME "mxc-mmc" 47 45 ··· 116 118 void __iomem *base; 117 119 int irq; 118 120 int detect_irq; 119 - int dma; 121 + struct dma_chan *dma; 122 + struct dma_async_tx_descriptor *desc; 120 123 int do_dma; 121 124 int default_irq_mask; 122 125 int use_sdio; ··· 128 129 struct mmc_command *cmd; 129 130 struct mmc_data *data; 130 131 131 - unsigned int dma_nents; 132 132 unsigned int datasize; 133 133 unsigned int dma_dir; 134 134 ··· 142 144 spinlock_t lock; 143 145 144 146 struct regulator *vcc; 147 + 148 + int burstlen; 149 + int dmareq; 150 + struct dma_slave_config dma_slave_config; 151 + struct imx_dma_data dma_data; 145 152 }; 146 153 147 154 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); ··· 209 206 210 207 writew(0xff, host->base + MMC_REG_RES_TO); 211 208 } 209 + static int mxcmci_setup_dma(struct mmc_host *mmc); 212 210 213 211 static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) 214 212 { 215 213 unsigned int nob = data->blocks; 216 214 unsigned int blksz = data->blksz; 217 215 unsigned int datasize = nob * blksz; 218 - #ifdef HAS_DMA 219 216 struct scatterlist *sg; 220 - int i; 221 - int ret; 222 - #endif 217 + int i, nents; 218 + 223 219 if (data->flags & MMC_DATA_STREAM) 224 220 nob = 0xffff; 225 221 ··· 229 227 writew(blksz, host->base + MMC_REG_BLK_LEN); 230 228 host->datasize = datasize; 231 229 232 - #ifdef HAS_DMA 230 + if (!mxcmci_use_dma(host)) 231 + return 0; 232 + 233 233 for_each_sg(data->sg, sg, data->sg_len, i) { 234 234 if (sg->offset & 3 || sg->length & 3) { 235 235 host->do_dma = 0; ··· 239 235 } 240 236 } 241 237 242 - if (data->flags & MMC_DATA_READ) { 238 + if (data->flags & MMC_DATA_READ) 243 239 host->dma_dir = DMA_FROM_DEVICE; 244 - host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, 245 - data->sg_len, host->dma_dir); 246 - 247 - ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, 248 - datasize, 249 - host->res->start + MMC_REG_BUFFER_ACCESS, 250 - DMA_MODE_READ); 251 - } else { 240 + else 252 241 host->dma_dir = DMA_TO_DEVICE; 253 - host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, 254 - data->sg_len, host->dma_dir); 255 242 256 - ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, 257 - datasize, 258 - host->res->start + MMC_REG_BUFFER_ACCESS, 259 - DMA_MODE_WRITE); 260 - } 243 + nents = dma_map_sg(host->dma->device->dev, data->sg, 244 + data->sg_len, host->dma_dir); 245 + if (nents != data->sg_len) 246 + return -EINVAL; 261 247 262 - if (ret) { 263 - dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret); 264 - return ret; 248 + host->desc = host->dma->device->device_prep_slave_sg(host->dma, 249 + data->sg, data->sg_len, host->dma_dir, 250 + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 251 + 252 + if (!host->desc) { 253 + dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len, 254 + host->dma_dir); 255 + host->do_dma = 0; 256 + return 0; /* Fall back to PIO */ 265 257 } 266 258 wmb(); 267 259 268 - imx_dma_enable(host->dma); 269 - #endif /* HAS_DMA */ 260 + dmaengine_submit(host->desc); 261 + 270 262 return 0; 271 263 } 272 264 ··· 337 337 struct mmc_data *data = host->data; 338 338 int data_error; 339 339 340 - #ifdef HAS_DMA 341 340 if (mxcmci_use_dma(host)) { 342 - imx_dma_disable(host->dma); 343 - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_nents, 341 + dmaengine_terminate_all(host->dma); 342 + dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len, 344 343 host->dma_dir); 345 344 } 346 - #endif 347 345 348 346 if (stat & STATUS_ERR_MASK) { 349 347 dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", ··· 543 545 } 544 546 } 545 547 546 - #ifdef HAS_DMA 547 548 static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat) 548 549 { 549 550 struct mmc_data *data = host->data; ··· 565 568 mxcmci_finish_request(host, host->req); 566 569 } 567 570 } 568 - #endif /* HAS_DMA */ 569 571 570 572 static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) 571 573 { ··· 602 606 sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio; 603 607 spin_unlock_irqrestore(&host->lock, flags); 604 608 605 - #ifdef HAS_DMA 606 609 if (mxcmci_use_dma(host) && 607 610 (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE))) 608 611 writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE, 609 612 host->base + MMC_REG_STATUS); 610 - #endif 611 613 612 614 if (sdio_irq) { 613 615 writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS); ··· 615 621 if (stat & STATUS_END_CMD_RESP) 616 622 mxcmci_cmd_done(host, stat); 617 623 618 - #ifdef HAS_DMA 619 624 if (mxcmci_use_dma(host) && 620 625 (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) 621 626 mxcmci_data_done(host, stat); 622 - #endif 627 + 623 628 if (host->default_irq_mask && 624 629 (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL))) 625 630 mmc_detect_change(host->mmc, msecs_to_jiffies(200)); 631 + 626 632 return IRQ_HANDLED; 627 633 } 628 634 ··· 636 642 637 643 host->req = req; 638 644 host->cmdat &= ~CMD_DAT_CONT_INIT; 639 - #ifdef HAS_DMA 640 - host->do_dma = 1; 641 - #endif 645 + 646 + if (host->dma) 647 + host->do_dma = 1; 648 + 642 649 if (req->data) { 643 650 error = mxcmci_setup_data(host, req->data); 644 651 if (error) { ··· 655 660 } 656 661 657 662 error = mxcmci_start_cmd(host, req->cmd, cmdat); 663 + 658 664 out: 659 665 if (error) 660 666 mxcmci_finish_request(host, req); ··· 694 698 prescaler, divider, clk_in, clk_ios); 695 699 } 696 700 701 + static int mxcmci_setup_dma(struct mmc_host *mmc) 702 + { 703 + struct mxcmci_host *host = mmc_priv(mmc); 704 + struct dma_slave_config *config = &host->dma_slave_config; 705 + 706 + config->dst_addr = host->res->start + MMC_REG_BUFFER_ACCESS; 707 + config->src_addr = host->res->start + MMC_REG_BUFFER_ACCESS; 708 + config->dst_addr_width = 4; 709 + config->src_addr_width = 4; 710 + config->dst_maxburst = host->burstlen; 711 + config->src_maxburst = host->burstlen; 712 + 713 + return dmaengine_slave_config(host->dma, config); 714 + } 715 + 697 716 static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 698 717 { 699 718 struct mxcmci_host *host = mmc_priv(mmc); 700 - #ifdef HAS_DMA 701 - unsigned int blen; 719 + int burstlen, ret; 720 + 702 721 /* 703 722 * use burstlen of 64 in 4 bit mode (--> reg value 0) 704 723 * use burstlen of 16 in 1 bit mode (--> reg value 16) 705 724 */ 706 725 if (ios->bus_width == MMC_BUS_WIDTH_4) 707 - blen = 0; 726 + burstlen = 64; 708 727 else 709 - blen = 16; 728 + burstlen = 16; 710 729 711 - imx_dma_config_burstlen(host->dma, blen); 712 - #endif 730 + if (mxcmci_use_dma(host) && burstlen != host->burstlen) { 731 + host->burstlen = burstlen; 732 + ret = mxcmci_setup_dma(mmc); 733 + if (ret) { 734 + dev_err(mmc_dev(host->mmc), 735 + "failed to config DMA channel. Falling back to PIO\n"); 736 + dma_release_channel(host->dma); 737 + host->do_dma = 0; 738 + } 739 + } 740 + 713 741 if (ios->bus_width == MMC_BUS_WIDTH_4) 714 742 host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4; 715 743 else ··· 814 794 host->caps |= MMC_CAP_4_BIT_DATA; 815 795 } 816 796 797 + static bool filter(struct dma_chan *chan, void *param) 798 + { 799 + struct mxcmci_host *host = param; 800 + 801 + if (!imx_dma_is_general_purpose(chan)) 802 + return false; 803 + 804 + chan->private = &host->dma_data; 805 + 806 + return true; 807 + } 808 + 817 809 static const struct mmc_host_ops mxcmci_ops = { 818 810 .request = mxcmci_request, 819 811 .set_ios = mxcmci_set_ios, ··· 840 808 struct mxcmci_host *host = NULL; 841 809 struct resource *iores, *r; 842 810 int ret = 0, irq; 811 + dma_cap_mask_t mask; 843 812 844 813 printk(KERN_INFO "i.MX SDHC driver\n"); 845 814 ··· 916 883 917 884 writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR); 918 885 919 - #ifdef HAS_DMA 920 - host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW); 921 - if (host->dma < 0) { 922 - dev_err(mmc_dev(host->mmc), "imx_dma_request_by_prio failed\n"); 923 - ret = -EBUSY; 924 - goto out_clk_put; 925 - } 926 - 927 886 r = platform_get_resource(pdev, IORESOURCE_DMA, 0); 928 - if (!r) { 929 - ret = -EINVAL; 930 - goto out_free_dma; 887 + if (r) { 888 + host->dmareq = r->start; 889 + host->dma_data.peripheral_type = IMX_DMATYPE_SDHC; 890 + host->dma_data.priority = DMA_PRIO_LOW; 891 + host->dma_data.dma_request = host->dmareq; 892 + dma_cap_zero(mask); 893 + dma_cap_set(DMA_SLAVE, mask); 894 + host->dma = dma_request_channel(mask, filter, host); 895 + if (host->dma) 896 + mmc->max_seg_size = dma_get_max_seg_size( 897 + host->dma->device->dev); 931 898 } 932 899 933 - ret = imx_dma_config_channel(host->dma, 934 - IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_FIFO, 935 - IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, 936 - r->start, 0); 937 - if (ret) { 938 - dev_err(mmc_dev(host->mmc), "failed to config DMA channel\n"); 939 - goto out_free_dma; 940 - } 941 - #endif 900 + if (!host->dma) 901 + dev_info(mmc_dev(host->mmc), "dma not available. Using PIO\n"); 902 + 942 903 INIT_WORK(&host->datawork, mxcmci_datawork); 943 904 944 905 ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host); ··· 955 928 out_free_irq: 956 929 free_irq(host->irq, host); 957 930 out_free_dma: 958 - #ifdef HAS_DMA 959 - imx_dma_free(host->dma); 960 - #endif 931 + if (host->dma) 932 + dma_release_channel(host->dma); 961 933 out_clk_put: 962 934 clk_disable(host->clk); 963 935 clk_put(host->clk); ··· 986 960 987 961 free_irq(host->irq, host); 988 962 iounmap(host->base); 989 - #ifdef HAS_DMA 990 - imx_dma_free(host->dma); 991 - #endif 963 + 964 + if (host->dma) 965 + dma_release_channel(host->dma); 966 + 992 967 clk_disable(host->clk); 993 968 clk_put(host->clk); 994 969