diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/davinci_mmc.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 3bd0ba294e9d..547d29c31b40 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c | |||
@@ -137,15 +137,15 @@ | |||
137 | 137 | ||
138 | /* | 138 | /* |
139 | * One scatterlist dma "segment" is at most MAX_CCNT rw_threshold units, | 139 | * One scatterlist dma "segment" is at most MAX_CCNT rw_threshold units, |
140 | * and we handle up to NR_SG segments. MMC_BLOCK_BOUNCE kicks in only | 140 | * and we handle up to MAX_NR_SG segments. MMC_BLOCK_BOUNCE kicks in only |
141 | * for drivers with max_hw_segs == 1, making the segments bigger (64KB) | 141 | * for drivers with max_hw_segs == 1, making the segments bigger (64KB) |
142 | * than the page or two that's otherwise typical. NR_SG == 16 gives at | 142 | * than the page or two that's otherwise typical. nr_sg (passed from |
143 | * least the same throughput boost, using EDMA transfer linkage instead | 143 | * platform data) == 16 gives at least the same throughput boost, using |
144 | * of spending CPU time copying pages. | 144 | * EDMA transfer linkage instead of spending CPU time copying pages. |
145 | */ | 145 | */ |
146 | #define MAX_CCNT ((1 << 16) - 1) | 146 | #define MAX_CCNT ((1 << 16) - 1) |
147 | 147 | ||
148 | #define NR_SG 16 | 148 | #define MAX_NR_SG 16 |
149 | 149 | ||
150 | static unsigned rw_threshold = 32; | 150 | static unsigned rw_threshold = 32; |
151 | module_param(rw_threshold, uint, S_IRUGO); | 151 | module_param(rw_threshold, uint, S_IRUGO); |
@@ -192,7 +192,7 @@ struct mmc_davinci_host { | |||
192 | struct edmacc_param tx_template; | 192 | struct edmacc_param tx_template; |
193 | struct edmacc_param rx_template; | 193 | struct edmacc_param rx_template; |
194 | unsigned n_link; | 194 | unsigned n_link; |
195 | u32 links[NR_SG - 1]; | 195 | u32 links[MAX_NR_SG - 1]; |
196 | 196 | ||
197 | /* For PIO we walk scatterlists one segment at a time. */ | 197 | /* For PIO we walk scatterlists one segment at a time. */ |
198 | unsigned int sg_len; | 198 | unsigned int sg_len; |
@@ -202,6 +202,8 @@ struct mmc_davinci_host { | |||
202 | u8 version; | 202 | u8 version; |
203 | /* for ns in one cycle calculation */ | 203 | /* for ns in one cycle calculation */ |
204 | unsigned ns_in_one_cycle; | 204 | unsigned ns_in_one_cycle; |
205 | /* Number of sg segments */ | ||
206 | u8 nr_sg; | ||
205 | #ifdef CONFIG_CPU_FREQ | 207 | #ifdef CONFIG_CPU_FREQ |
206 | struct notifier_block freq_transition; | 208 | struct notifier_block freq_transition; |
207 | #endif | 209 | #endif |
@@ -568,6 +570,7 @@ davinci_release_dma_channels(struct mmc_davinci_host *host) | |||
568 | 570 | ||
569 | static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) | 571 | static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) |
570 | { | 572 | { |
573 | u32 link_size; | ||
571 | int r, i; | 574 | int r, i; |
572 | 575 | ||
573 | /* Acquire master DMA write channel */ | 576 | /* Acquire master DMA write channel */ |
@@ -593,7 +596,8 @@ static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) | |||
593 | /* Allocate parameter RAM slots, which will later be bound to a | 596 | /* Allocate parameter RAM slots, which will later be bound to a |
594 | * channel as needed to handle a scatterlist. | 597 | * channel as needed to handle a scatterlist. |
595 | */ | 598 | */ |
596 | for (i = 0; i < ARRAY_SIZE(host->links); i++) { | 599 | link_size = min_t(unsigned, host->nr_sg, ARRAY_SIZE(host->links)); |
600 | for (i = 0; i < link_size; i++) { | ||
597 | r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY); | 601 | r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY); |
598 | if (r < 0) { | 602 | if (r < 0) { |
599 | dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n", | 603 | dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n", |
@@ -1202,6 +1206,12 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) | |||
1202 | 1206 | ||
1203 | init_mmcsd_host(host); | 1207 | init_mmcsd_host(host); |
1204 | 1208 | ||
1209 | if (pdata->nr_sg) | ||
1210 | host->nr_sg = pdata->nr_sg - 1; | ||
1211 | |||
1212 | if (host->nr_sg > MAX_NR_SG || !host->nr_sg) | ||
1213 | host->nr_sg = MAX_NR_SG; | ||
1214 | |||
1205 | host->use_dma = use_dma; | 1215 | host->use_dma = use_dma; |
1206 | host->irq = irq; | 1216 | host->irq = irq; |
1207 | 1217 | ||