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

s3cmci: Kconfig selection for PIO/DMA/Both

Add a selection for the data transfer mode of the s3cmci driver, allowing
for either a configuration or rumtime selection of the use of the DMA or
PIO transfer code.

The PIO only mode is 476 bytes smaller than the driver with both methods
compiled in.

Signed-off-by: Ben Dooks <ben@simtec.co.uk>
Cc: <linux-mmc@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ben Dooks and committed by
Linus Torvalds
26f14947 c2258893

+66 -8
+1
arch/arm/plat-s3c24xx/include/plat/mci.h
··· 4 4 struct s3c24xx_mci_pdata { 5 5 unsigned int wprotect_invert : 1; 6 6 unsigned int detect_invert : 1; /* set => detect active high. */ 7 + unsigned int use_dma : 1; 7 8 8 9 unsigned int gpio_detect; 9 10 unsigned int gpio_wprotect;
+34
drivers/mmc/host/Kconfig
··· 276 276 277 277 If unsure, say N. 278 278 279 + choice 280 + prompt "Samsung S3C SD/MMC transfer code" 281 + depends on MMC_S3C 282 + 283 + config MMC_S3C_PIO 284 + bool "Use PIO transfers only" 285 + help 286 + Use PIO to transfer data between memory and the hardware. 287 + 288 + PIO is slower than DMA as it requires CPU instructions to 289 + move the data. This has been the traditional default for 290 + the S3C MCI driver. 291 + 292 + config MMC_S3C_DMA 293 + bool "Use DMA transfers only (EXPERIMENTAL)" 294 + depends on EXPERIMENTAL 295 + help 296 + Use DMA to transfer data between memory and the hardare. 297 + 298 + Currently, the DMA support in this driver seems to not be 299 + working properly and needs to be debugged before this 300 + option is useful. 301 + 302 + config MMC_S3C_PIODMA 303 + bool "Support for both PIO and DMA (EXPERIMENTAL)" 304 + help 305 + Compile both the PIO and DMA transfer routines into the 306 + driver and let the platform select at run-time which one 307 + is best. 308 + 309 + See notes for the DMA option. 310 + 311 + endchoice 312 + 279 313 config MMC_SDRICOH_CS 280 314 tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)" 281 315 depends on EXPERIMENTAL && PCI && PCMCIA
+31 -8
drivers/mmc/host/s3cmci.c
··· 164 164 165 165 #endif /* CONFIG_MMC_DEBUG */ 166 166 167 + /** 168 + * s3cmci_host_usedma - return whether the host is using dma or pio 169 + * @host: The host state 170 + * 171 + * Return true if the host is using DMA to transfer data, else false 172 + * to use PIO mode. Will return static data depending on the driver 173 + * configuration. 174 + */ 175 + static inline bool s3cmci_host_usedma(struct s3cmci_host *host) 176 + { 177 + #ifdef CONFIG_MMC_S3C_PIO 178 + return false; 179 + #elif defined(CONFIG_MMC_S3C_DMA) 180 + return true; 181 + #else 182 + return host->dodma; 183 + #endif 184 + } 185 + 167 186 static inline u32 enable_imask(struct s3cmci_host *host, u32 imask) 168 187 { 169 188 u32 newmask; ··· 579 560 goto irq_out; 580 561 } 581 562 582 - if (!host->dodma) { 563 + if (!s3cmci_host_usedma(host)) { 583 564 if ((host->pio_active == XFER_WRITE) && 584 565 (mci_fsta & S3C2410_SDIFSTA_TFDET)) { 585 566 ··· 815 796 816 797 if (cmd->data && (cmd->error == 0) && 817 798 (cmd->data->error == 0)) { 818 - if (host->dodma && (!host->dma_complete)) { 799 + if (s3cmci_host_usedma(host) && (!host->dma_complete)) { 819 800 dbg(host, dbg_dma, "DMA Missing!\n"); 820 801 return; 821 802 } ··· 867 848 /* If we had an error while transfering data we flush the 868 849 * DMA channel and the fifo to clear out any garbage. */ 869 850 if (mrq->data->error != 0) { 870 - if (host->dodma) 851 + if (s3cmci_host_usedma(host)) 871 852 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); 872 853 873 854 if (host->is2440) { ··· 987 968 988 969 dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK; 989 970 990 - if (host->dodma) 971 + if (s3cmci_host_usedma(host)) 991 972 dcon |= S3C2410_SDIDCON_DMAEN; 992 973 993 974 if (host->bus_width == MMC_BUS_WIDTH_4) ··· 1133 1114 return; 1134 1115 } 1135 1116 1136 - if (host->dodma) 1117 + if (s3cmci_host_usedma(host)) 1137 1118 res = s3cmci_prepare_dma(host, cmd->data); 1138 1119 else 1139 1120 res = s3cmci_prepare_pio(host, cmd->data); ··· 1417 1398 seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled); 1418 1399 seq_printf(seq, "IRQ state = %d\n", host->irq_state); 1419 1400 seq_printf(seq, "CD IRQ = %d\n", host->irq_cd); 1420 - seq_printf(seq, "Do DMA = %d\n", host->dodma); 1401 + seq_printf(seq, "Do DMA = %d\n", s3cmci_host_usedma(host)); 1421 1402 seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk); 1422 1403 seq_printf(seq, "SDIDATA at %d\n", host->sdidata); 1423 1404 ··· 1578 1559 host->clk_div = 2; 1579 1560 } 1580 1561 1581 - host->dodma = 0; 1582 1562 host->complete_what = COMPLETION_NONE; 1583 1563 host->pio_active = XFER_NONE; 1584 1564 1585 1565 host->dma = S3CMCI_DMA; 1566 + 1567 + #ifdef CONFIG_MMC_S3C_PIODMA 1568 + host->dodma = host->pdata->dma; 1569 + #endif 1586 1570 1587 1571 host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1588 1572 if (!host->mem) { ··· 1724 1702 s3cmci_debugfs_attach(host); 1725 1703 1726 1704 platform_set_drvdata(pdev, mmc); 1727 - dev_info(&pdev->dev, "initialisation done.\n"); 1705 + dev_info(&pdev->dev, "%s - using %s\n", mmc_hostname(mmc), 1706 + s3cmci_host_usedma(host) ? "dma" : "pio"); 1728 1707 1729 1708 return 0; 1730 1709