aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2009-10-01 18:44:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-10-01 19:11:15 -0400
commit26f14947dbf31d60d1a67eee837a6d28c1e8830d (patch)
treee54c009f30d9df49bb2c421eeafec266d67be720
parentc225889375fea2a542f1c9dedffec4c7b8ebc9ab (diff)
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>
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/mci.h1
-rw-r--r--drivers/mmc/host/Kconfig34
-rw-r--r--drivers/mmc/host/s3cmci.c39
3 files changed, 66 insertions, 8 deletions
diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-s3c24xx/include/plat/mci.h
index 2d0852ac3b27..f1bd6d4198d4 100644
--- a/arch/arm/plat-s3c24xx/include/plat/mci.h
+++ b/arch/arm/plat-s3c24xx/include/plat/mci.h
@@ -4,6 +4,7 @@
4struct s3c24xx_mci_pdata { 4struct s3c24xx_mci_pdata {
5 unsigned int wprotect_invert : 1; 5 unsigned int wprotect_invert : 1;
6 unsigned int detect_invert : 1; /* set => detect active high. */ 6 unsigned int detect_invert : 1; /* set => detect active high. */
7 unsigned int use_dma : 1;
7 8
8 unsigned int gpio_detect; 9 unsigned int gpio_detect;
9 unsigned int gpio_wprotect; 10 unsigned int gpio_wprotect;
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7cb057f3f883..cf6a6545240b 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -276,6 +276,40 @@ config MMC_S3C
276 276
277 If unsure, say N. 277 If unsure, say N.
278 278
279choice
280 prompt "Samsung S3C SD/MMC transfer code"
281 depends on MMC_S3C
282
283config 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
292config 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
302config 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
311endchoice
312
279config MMC_SDRICOH_CS 313config MMC_SDRICOH_CS
280 tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)" 314 tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)"
281 depends on EXPERIMENTAL && PCI && PCMCIA 315 depends on EXPERIMENTAL && PCI && PCMCIA
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 7660ac4572e5..0adf31895f2a 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -164,6 +164,25 @@ static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { }
164 164
165#endif /* CONFIG_MMC_DEBUG */ 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 */
175static 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
167static inline u32 enable_imask(struct s3cmci_host *host, u32 imask) 186static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
168{ 187{
169 u32 newmask; 188 u32 newmask;
@@ -560,7 +579,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
560 goto irq_out; 579 goto irq_out;
561 } 580 }
562 581
563 if (!host->dodma) { 582 if (!s3cmci_host_usedma(host)) {
564 if ((host->pio_active == XFER_WRITE) && 583 if ((host->pio_active == XFER_WRITE) &&
565 (mci_fsta & S3C2410_SDIFSTA_TFDET)) { 584 (mci_fsta & S3C2410_SDIFSTA_TFDET)) {
566 585
@@ -796,7 +815,7 @@ static void finalize_request(struct s3cmci_host *host)
796 815
797 if (cmd->data && (cmd->error == 0) && 816 if (cmd->data && (cmd->error == 0) &&
798 (cmd->data->error == 0)) { 817 (cmd->data->error == 0)) {
799 if (host->dodma && (!host->dma_complete)) { 818 if (s3cmci_host_usedma(host) && (!host->dma_complete)) {
800 dbg(host, dbg_dma, "DMA Missing!\n"); 819 dbg(host, dbg_dma, "DMA Missing!\n");
801 return; 820 return;
802 } 821 }
@@ -848,7 +867,7 @@ static void finalize_request(struct s3cmci_host *host)
848 /* If we had an error while transfering data we flush the 867 /* If we had an error while transfering data we flush the
849 * DMA channel and the fifo to clear out any garbage. */ 868 * DMA channel and the fifo to clear out any garbage. */
850 if (mrq->data->error != 0) { 869 if (mrq->data->error != 0) {
851 if (host->dodma) 870 if (s3cmci_host_usedma(host))
852 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); 871 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
853 872
854 if (host->is2440) { 873 if (host->is2440) {
@@ -968,7 +987,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
968 987
969 dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK; 988 dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
970 989
971 if (host->dodma) 990 if (s3cmci_host_usedma(host))
972 dcon |= S3C2410_SDIDCON_DMAEN; 991 dcon |= S3C2410_SDIDCON_DMAEN;
973 992
974 if (host->bus_width == MMC_BUS_WIDTH_4) 993 if (host->bus_width == MMC_BUS_WIDTH_4)
@@ -1114,7 +1133,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
1114 return; 1133 return;
1115 } 1134 }
1116 1135
1117 if (host->dodma) 1136 if (s3cmci_host_usedma(host))
1118 res = s3cmci_prepare_dma(host, cmd->data); 1137 res = s3cmci_prepare_dma(host, cmd->data);
1119 else 1138 else
1120 res = s3cmci_prepare_pio(host, cmd->data); 1139 res = s3cmci_prepare_pio(host, cmd->data);
@@ -1398,7 +1417,7 @@ static int s3cmci_state_show(struct seq_file *seq, void *v)
1398 seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled); 1417 seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
1399 seq_printf(seq, "IRQ state = %d\n", host->irq_state); 1418 seq_printf(seq, "IRQ state = %d\n", host->irq_state);
1400 seq_printf(seq, "CD IRQ = %d\n", host->irq_cd); 1419 seq_printf(seq, "CD IRQ = %d\n", host->irq_cd);
1401 seq_printf(seq, "Do DMA = %d\n", host->dodma); 1420 seq_printf(seq, "Do DMA = %d\n", s3cmci_host_usedma(host));
1402 seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk); 1421 seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk);
1403 seq_printf(seq, "SDIDATA at %d\n", host->sdidata); 1422 seq_printf(seq, "SDIDATA at %d\n", host->sdidata);
1404 1423
@@ -1559,12 +1578,15 @@ static int __devinit s3cmci_probe(struct platform_device *pdev)
1559 host->clk_div = 2; 1578 host->clk_div = 2;
1560 } 1579 }
1561 1580
1562 host->dodma = 0;
1563 host->complete_what = COMPLETION_NONE; 1581 host->complete_what = COMPLETION_NONE;
1564 host->pio_active = XFER_NONE; 1582 host->pio_active = XFER_NONE;
1565 1583
1566 host->dma = S3CMCI_DMA; 1584 host->dma = S3CMCI_DMA;
1567 1585
1586#ifdef CONFIG_MMC_S3C_PIODMA
1587 host->dodma = host->pdata->dma;
1588#endif
1589
1568 host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1590 host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1569 if (!host->mem) { 1591 if (!host->mem) {
1570 dev_err(&pdev->dev, 1592 dev_err(&pdev->dev,
@@ -1702,7 +1724,8 @@ static int __devinit s3cmci_probe(struct platform_device *pdev)
1702 s3cmci_debugfs_attach(host); 1724 s3cmci_debugfs_attach(host);
1703 1725
1704 platform_set_drvdata(pdev, mmc); 1726 platform_set_drvdata(pdev, mmc);
1705 dev_info(&pdev->dev, "initialisation done.\n"); 1727 dev_info(&pdev->dev, "%s - using %s\n", mmc_hostname(mmc),
1728 s3cmci_host_usedma(host) ? "dma" : "pio");
1706 1729
1707 return 0; 1730 return 0;
1708 1731