aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2018-07-02 09:08:10 -0400
committerVinod Koul <vkoul@kernel.org>2018-07-09 13:29:04 -0400
commitd8095f94e19581057bcad35b8a725aa739e77595 (patch)
tree5926a5a47750d50d9498b8126ccd5db0735856f5
parentce397d215ccd07b8ae3f71db689aedb85d56ab40 (diff)
dmaengine: add support for reporting pause and resume separately
'cmd_pause' DMA channel capability means that respective DMA engine supports both pausing and resuming given DMA channel. However, in some cases it is important to know if DMA channel can be paused without the need to resume it. This is a typical requirement for proper residue reading on transfer timeout in UART drivers. There are also some DMA engines with limited hardware, which doesn't really support resuming. Reporting pause and resume capabilities separately allows UART drivers to properly check for the really required capabilities and operate in DMA mode also in systems with limited DMA hardware. On the other hand drivers, which rely on full channel suspend/resume support, should now check for both 'pause' and 'resume' features. Existing clients of dma_get_slave_caps() have been checked and the only driver which rely on proper channel resuming is soc-generic-dmaengine-pcm driver, which has been updated to check the newly added capability. Existing 'cmd_pause' now only indicates that DMA engine support pausing given DMA channel. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Mark Brown <broonie@kernel.org> Signed-off-by: Vinod Koul <vkoul@kernel.org>
-rw-r--r--drivers/dma/dmaengine.c8
-rw-r--r--include/linux/dmaengine.h5
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c2
3 files changed, 7 insertions, 8 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 08ba8473a284..84ac38dbdb65 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -500,12 +500,8 @@ int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps)
500 caps->max_burst = device->max_burst; 500 caps->max_burst = device->max_burst;
501 caps->residue_granularity = device->residue_granularity; 501 caps->residue_granularity = device->residue_granularity;
502 caps->descriptor_reuse = device->descriptor_reuse; 502 caps->descriptor_reuse = device->descriptor_reuse;
503 503 caps->cmd_pause = !!device->device_pause;
504 /* 504 caps->cmd_resume = !!device->device_resume;
505 * Some devices implement only pause (e.g. to get residuum) but no
506 * resume. However cmd_pause is advertised as pause AND resume.
507 */
508 caps->cmd_pause = !!(device->device_pause && device->device_resume);
509 caps->cmd_terminate = !!device->device_terminate_all; 505 caps->cmd_terminate = !!device->device_terminate_all;
510 506
511 return 0; 507 return 0;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 861be5cab1df..c8c3a7a93802 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -415,7 +415,9 @@ enum dma_residue_granularity {
415 * each type, the dma controller should set BIT(<TYPE>) and same 415 * each type, the dma controller should set BIT(<TYPE>) and same
416 * should be checked by controller as well 416 * should be checked by controller as well
417 * @max_burst: max burst capability per-transfer 417 * @max_burst: max burst capability per-transfer
418 * @cmd_pause: true, if pause and thereby resume is supported 418 * @cmd_pause: true, if pause is supported (i.e. for reading residue or
419 * for resume later)
420 * @cmd_resume: true, if resume is supported
419 * @cmd_terminate: true, if terminate cmd is supported 421 * @cmd_terminate: true, if terminate cmd is supported
420 * @residue_granularity: granularity of the reported transfer residue 422 * @residue_granularity: granularity of the reported transfer residue
421 * @descriptor_reuse: if a descriptor can be reused by client and 423 * @descriptor_reuse: if a descriptor can be reused by client and
@@ -427,6 +429,7 @@ struct dma_slave_caps {
427 u32 directions; 429 u32 directions;
428 u32 max_burst; 430 u32 max_burst;
429 bool cmd_pause; 431 bool cmd_pause;
432 bool cmd_resume;
430 bool cmd_terminate; 433 bool cmd_terminate;
431 enum dma_residue_granularity residue_granularity; 434 enum dma_residue_granularity residue_granularity;
432 bool descriptor_reuse; 435 bool descriptor_reuse;
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 56a541b9ff9e..76c46d793843 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -156,7 +156,7 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea
156 156
157 ret = dma_get_slave_caps(chan, &dma_caps); 157 ret = dma_get_slave_caps(chan, &dma_caps);
158 if (ret == 0) { 158 if (ret == 0) {
159 if (dma_caps.cmd_pause) 159 if (dma_caps.cmd_pause && dma_caps.cmd_resume)
160 hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; 160 hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME;
161 if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) 161 if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT)
162 hw.info |= SNDRV_PCM_INFO_BATCH; 162 hw.info |= SNDRV_PCM_INFO_BATCH;