diff options
author | Stefan Brüns <stefan.bruens@rwth-aachen.de> | 2017-09-27 21:49:22 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2017-10-16 03:01:24 -0400 |
commit | 500fa9e76bbc40c7dbb65c7daccdc8bc49684429 (patch) | |
tree | be2d07339f44bf9a7ed88ff5dab705f8475e5951 | |
parent | d5f6d8cf31a89045fe5d8fe283ae428763e243a7 (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.c | 26 |
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 | ||
193 | static struct device *chan2dev(struct dma_chan *chan) | 196 | static struct device *chan2dev(struct dma_chan *chan) |
@@ -434,7 +437,6 @@ static int sun6i_dma_start_desc(struct sun6i_vchan *vchan) | |||
434 | static void sun6i_dma_tasklet(unsigned long data) | 437 | static 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); |