aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Brüns <stefan.bruens@rwth-aachen.de>2017-09-27 21:49:22 -0400
committerVinod Koul <vinod.koul@intel.com>2017-10-16 03:01:24 -0400
commit500fa9e76bbc40c7dbb65c7daccdc8bc49684429 (patch)
treebe2d07339f44bf9a7ed88ff5dab705f8475e5951
parentd5f6d8cf31a89045fe5d8fe283ae428763e243a7 (diff)
dmaengine: sun6i: Move number of pchans/vchans/request to device struct
Preparatory patch: If the same compatible is used for different SoCs which have a common register layout, but different number of channels, the channel count can no longer be stored in the config. Store it in the device structure instead. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/sun6i-dma.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 55c915f490e0..f27b126dd6cd 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -188,6 +188,9 @@ struct sun6i_dma_dev {
188 struct sun6i_pchan *pchans; 188 struct sun6i_pchan *pchans;
189 struct sun6i_vchan *vchans; 189 struct sun6i_vchan *vchans;
190 const struct sun6i_dma_config *cfg; 190 const struct sun6i_dma_config *cfg;
191 u32 num_pchans;
192 u32 num_vchans;
193 u32 max_request;
191}; 194};
192 195
193static struct device *chan2dev(struct dma_chan *chan) 196static struct device *chan2dev(struct dma_chan *chan)
@@ -434,7 +437,6 @@ static int sun6i_dma_start_desc(struct sun6i_vchan *vchan)
434static void sun6i_dma_tasklet(unsigned long data) 437static void sun6i_dma_tasklet(unsigned long data)
435{ 438{
436 struct sun6i_dma_dev *sdev = (struct sun6i_dma_dev *)data; 439 struct sun6i_dma_dev *sdev = (struct sun6i_dma_dev *)data;
437 const struct sun6i_dma_config *cfg = sdev->cfg;
438 struct sun6i_vchan *vchan; 440 struct sun6i_vchan *vchan;
439 struct sun6i_pchan *pchan; 441 struct sun6i_pchan *pchan;
440 unsigned int pchan_alloc = 0; 442 unsigned int pchan_alloc = 0;
@@ -462,7 +464,7 @@ static void sun6i_dma_tasklet(unsigned long data)
462 } 464 }
463 465
464 spin_lock_irq(&sdev->lock); 466 spin_lock_irq(&sdev->lock);
465 for (pchan_idx = 0; pchan_idx < cfg->nr_max_channels; pchan_idx++) { 467 for (pchan_idx = 0; pchan_idx < sdev->num_pchans; pchan_idx++) {
466 pchan = &sdev->pchans[pchan_idx]; 468 pchan = &sdev->pchans[pchan_idx];
467 469
468 if (pchan->vchan || list_empty(&sdev->pending)) 470 if (pchan->vchan || list_empty(&sdev->pending))
@@ -483,7 +485,7 @@ static void sun6i_dma_tasklet(unsigned long data)
483 } 485 }
484 spin_unlock_irq(&sdev->lock); 486 spin_unlock_irq(&sdev->lock);
485 487
486 for (pchan_idx = 0; pchan_idx < cfg->nr_max_channels; pchan_idx++) { 488 for (pchan_idx = 0; pchan_idx < sdev->num_pchans; pchan_idx++) {
487 if (!(pchan_alloc & BIT(pchan_idx))) 489 if (!(pchan_alloc & BIT(pchan_idx)))
488 continue; 490 continue;
489 491
@@ -505,7 +507,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id)
505 int i, j, ret = IRQ_NONE; 507 int i, j, ret = IRQ_NONE;
506 u32 status; 508 u32 status;
507 509
508 for (i = 0; i < sdev->cfg->nr_max_channels / DMA_IRQ_CHAN_NR; i++) { 510 for (i = 0; i < sdev->num_pchans / DMA_IRQ_CHAN_NR; i++) {
509 status = readl(sdev->base + DMA_IRQ_STAT(i)); 511 status = readl(sdev->base + DMA_IRQ_STAT(i));
510 if (!status) 512 if (!status)
511 continue; 513 continue;
@@ -985,7 +987,7 @@ static struct dma_chan *sun6i_dma_of_xlate(struct of_phandle_args *dma_spec,
985 struct dma_chan *chan; 987 struct dma_chan *chan;
986 u8 port = dma_spec->args[0]; 988 u8 port = dma_spec->args[0];
987 989
988 if (port > sdev->cfg->nr_max_requests) 990 if (port > sdev->max_request)
989 return NULL; 991 return NULL;
990 992
991 chan = dma_get_any_slave_channel(&sdev->slave); 993 chan = dma_get_any_slave_channel(&sdev->slave);
@@ -1018,7 +1020,7 @@ static inline void sun6i_dma_free(struct sun6i_dma_dev *sdev)
1018{ 1020{
1019 int i; 1021 int i;
1020 1022
1021 for (i = 0; i < sdev->cfg->nr_max_vchans; i++) { 1023 for (i = 0; i < sdev->num_vchans; i++) {
1022 struct sun6i_vchan *vchan = &sdev->vchans[i]; 1024 struct sun6i_vchan *vchan = &sdev->vchans[i];
1023 1025
1024 list_del(&vchan->vc.chan.device_node); 1026 list_del(&vchan->vc.chan.device_node);
@@ -1222,26 +1224,30 @@ static int sun6i_dma_probe(struct platform_device *pdev)
1222 sdc->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; 1224 sdc->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
1223 sdc->slave.dev = &pdev->dev; 1225 sdc->slave.dev = &pdev->dev;
1224 1226
1225 sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels, 1227 sdc->num_pchans = sdc->cfg->nr_max_channels;
1228 sdc->num_vchans = sdc->cfg->nr_max_vchans;
1229 sdc->max_request = sdc->cfg->nr_max_requests;
1230
1231 sdc->pchans = devm_kcalloc(&pdev->dev, sdc->num_pchans,
1226 sizeof(struct sun6i_pchan), GFP_KERNEL); 1232 sizeof(struct sun6i_pchan), GFP_KERNEL);
1227 if (!sdc->pchans) 1233 if (!sdc->pchans)
1228 return -ENOMEM; 1234 return -ENOMEM;
1229 1235
1230 sdc->vchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_vchans, 1236 sdc->vchans = devm_kcalloc(&pdev->dev, sdc->num_vchans,
1231 sizeof(struct sun6i_vchan), GFP_KERNEL); 1237 sizeof(struct sun6i_vchan), GFP_KERNEL);
1232 if (!sdc->vchans) 1238 if (!sdc->vchans)
1233 return -ENOMEM; 1239 return -ENOMEM;
1234 1240
1235 tasklet_init(&sdc->task, sun6i_dma_tasklet, (unsigned long)sdc); 1241 tasklet_init(&sdc->task, sun6i_dma_tasklet, (unsigned long)sdc);
1236 1242
1237 for (i = 0; i < sdc->cfg->nr_max_channels; i++) { 1243 for (i = 0; i < sdc->num_pchans; i++) {
1238 struct sun6i_pchan *pchan = &sdc->pchans[i]; 1244 struct sun6i_pchan *pchan = &sdc->pchans[i];
1239 1245
1240 pchan->idx = i; 1246 pchan->idx = i;
1241 pchan->base = sdc->base + 0x100 + i * 0x40; 1247 pchan->base = sdc->base + 0x100 + i * 0x40;
1242 } 1248 }
1243 1249
1244 for (i = 0; i < sdc->cfg->nr_max_vchans; i++) { 1250 for (i = 0; i < sdc->num_vchans; i++) {
1245 struct sun6i_vchan *vchan = &sdc->vchans[i]; 1251 struct sun6i_vchan *vchan = &sdc->vchans[i];
1246 1252
1247 INIT_LIST_HEAD(&vchan->node); 1253 INIT_LIST_HEAD(&vchan->node);