diff mbox series

[v1] dmaengine: dw: Enable runtime PM

Message ID 20201103183938.64752-1-andriy.shevchenko@linux.intel.com (mailing list archive)
State Accepted
Headers show
Series [v1] dmaengine: dw: Enable runtime PM | expand

Commit Message

Andy Shevchenko Nov. 3, 2020, 6:39 p.m. UTC
When consumer requests channel power on the DMA controller device
and otherwise on the freeing channel resources.

Note, in some cases consumer acquires channel at the ->probe() stage and
releases it at the ->remove() stage. It will mean that DMA controller device
will be powered during all this time if there is no assist from hardware
to idle it. The above mentioned cases should be investigated separately
and individually.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/dma/dw/core.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Viresh Kumar Nov. 4, 2020, 3:05 a.m. UTC | #1
On 03-11-20, 20:39, Andy Shevchenko wrote:
> When consumer requests channel power on the DMA controller device
> and otherwise on the freeing channel resources.
> 
> Note, in some cases consumer acquires channel at the ->probe() stage and
> releases it at the ->remove() stage. It will mean that DMA controller device
> will be powered during all this time if there is no assist from hardware
> to idle it. The above mentioned cases should be investigated separately
> and individually.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/dma/dw/core.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
> index 7ab83fe601ed..19a23767533a 100644
> --- a/drivers/dma/dw/core.c
> +++ b/drivers/dma/dw/core.c
> @@ -982,8 +982,11 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
>  
>  	dev_vdbg(chan2dev(chan), "%s\n", __func__);
>  
> +	pm_runtime_get_sync(dw->dma.dev);
> +
>  	/* ASSERT:  channel is idle */
>  	if (dma_readl(dw, CH_EN) & dwc->mask) {
> +		pm_runtime_put_sync_suspend(dw->dma.dev);
>  		dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
>  		return -EIO;
>  	}
> @@ -1000,6 +1003,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
>  	 * We need controller-specific data to set up slave transfers.
>  	 */
>  	if (chan->private && !dw_dma_filter(chan, chan->private)) {
> +		pm_runtime_put_sync_suspend(dw->dma.dev);
>  		dev_warn(chan2dev(chan), "Wrong controller-specific data\n");
>  		return -EINVAL;
>  	}
> @@ -1043,6 +1047,8 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
>  	if (!dw->in_use)
>  		do_dw_dma_off(dw);
>  
> +	pm_runtime_put_sync_suspend(dw->dma.dev);
> +
>  	dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
>  }

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Vinod Koul Nov. 9, 2020, 11:49 a.m. UTC | #2
On 03-11-20, 20:39, Andy Shevchenko wrote:
> When consumer requests channel power on the DMA controller device
> and otherwise on the freeing channel resources.
> 
> Note, in some cases consumer acquires channel at the ->probe() stage and
> releases it at the ->remove() stage. It will mean that DMA controller device
> will be powered during all this time if there is no assist from hardware
> to idle it. The above mentioned cases should be investigated separately
> and individually.

Applied, thanks
diff mbox series

Patch

diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 7ab83fe601ed..19a23767533a 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -982,8 +982,11 @@  static int dwc_alloc_chan_resources(struct dma_chan *chan)
 
 	dev_vdbg(chan2dev(chan), "%s\n", __func__);
 
+	pm_runtime_get_sync(dw->dma.dev);
+
 	/* ASSERT:  channel is idle */
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
+		pm_runtime_put_sync_suspend(dw->dma.dev);
 		dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
 		return -EIO;
 	}
@@ -1000,6 +1003,7 @@  static int dwc_alloc_chan_resources(struct dma_chan *chan)
 	 * We need controller-specific data to set up slave transfers.
 	 */
 	if (chan->private && !dw_dma_filter(chan, chan->private)) {
+		pm_runtime_put_sync_suspend(dw->dma.dev);
 		dev_warn(chan2dev(chan), "Wrong controller-specific data\n");
 		return -EINVAL;
 	}
@@ -1043,6 +1047,8 @@  static void dwc_free_chan_resources(struct dma_chan *chan)
 	if (!dw->in_use)
 		do_dw_dma_off(dw);
 
+	pm_runtime_put_sync_suspend(dw->dma.dev);
+
 	dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
 }