aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-03-16 17:13:50 -0400
committerPierre Ossman <drzeus@drzeus.cx>2009-03-24 16:30:08 -0400
commit6aa943ab8994fe6e4ccba22c5bc8150a84268bdd (patch)
treeef277e4d6012c0cf10c220360a031bd5bc2f9b1c /drivers/mmc/host/sdhci.c
parent7260cf5e12393536ce61d184c3fc750fb2ba635a (diff)
sdhci: Enable only relevant (DMA/PIO) interrupts during transfers
Some hosts (that is, FSL eSDHC) throw PIO interrupts during DMA transfers, this causes tons of unneeded interrupts, and thus highly degraded speed. This patch modifies the driver so that now we only enable relevant (DMA or PIO) interrupts during transfers. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index bd5acfb0c1b8..6fbbc005dd7f 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -167,9 +167,7 @@ static void sdhci_init(struct sdhci_host *host)
167 SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | 167 SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
168 SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | 168 SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
169 SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | 169 SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
170 SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | 170 SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
171 SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
172 SDHCI_INT_ADMA_ERROR);
173} 171}
174 172
175static void sdhci_reinit(struct sdhci_host *host) 173static void sdhci_reinit(struct sdhci_host *host)
@@ -603,6 +601,17 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
603 return count; 601 return count;
604} 602}
605 603
604static void sdhci_set_transfer_irqs(struct sdhci_host *host)
605{
606 u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
607 u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
608
609 if (host->flags & SDHCI_REQ_USE_DMA)
610 sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
611 else
612 sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
613}
614
606static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) 615static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
607{ 616{
608 u8 count; 617 u8 count;
@@ -751,6 +760,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
751 host->blocks = data->blocks; 760 host->blocks = data->blocks;
752 } 761 }
753 762
763 sdhci_set_transfer_irqs(host);
764
754 /* We do not handle DMA boundaries, so set it to max (512 KiB) */ 765 /* We do not handle DMA boundaries, so set it to max (512 KiB) */
755 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE); 766 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
756 sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT); 767 sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);