All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
To: Claudiu Beznea <claudiu.beznea@kernel.org>
Cc: vkoul@kernel.org, Frank.Li@kernel.org, lgirdwood@gmail.com,
	broonie@kernel.org, perex@perex.cz, tiwai@suse.com,
	biju.das.jz@bp.renesas.com,
	prabhakar.mahadev-lad.rj@bp.renesas.com, p.zabel@pengutronix.de,
	geert+renesas@glider.be, kuninori.morimoto.gx@renesas.com,
	long.luu.ur@renesas.com, claudiu.beznea@tuxon.dev,
	dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-sound@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>,
	John Madieu <john.madieu.xa@bp.renesas.com>
Subject: Re: [PATCH v6 14/18] dmaengine: sh: rz-dmac: Add runtime PM support
Date: Thu, 28 May 2026 15:52:22 +0200	[thread overview]
Message-ID: <ahhIlt8PSF6_DoRU@tom-desktop> (raw)
In-Reply-To: <20260526084710.3491480-15-claudiu.beznea@kernel.org>

On Tue, May 26, 2026 at 11:47:06AM +0300, Claudiu Beznea wrote:
> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> 
> Protect the driver exposed APIs with runtime PM suspend/resume calls
> before accessing HW registers. As the current driver leaves runtime PM
> enabled in probe, the purpose of the changes in this patch is to avoid
> accessing HW registers after a failed system suspend leaves the runtime
> PM state of the device improperly reinitialized.
> 
> In that case, the driver remains bound to the device, the APIs are still
> exposed, and any access to HW registers without runtime resuming the
> device may lead to synchronous aborts.
> 
> To avoid leaking resources in case of runtime PM failures, save the error
> code returned by PM_RUNTIME_ACQUIRE_ERR() in rz_dmac_terminate_all() and
> return it only at the end of the function to allow the cleanup code to
> run. A similar approach is used in rz_dmac_free_chan_resources().
> 
> Because some exposed APIs (e.g. ->device_terminate_all()) may be called
> from atomic context according to the documentation, mark the DMA device as
> pm_runtime_irq_safe().
> 
> This patch prepares the driver for suspend-to-RAM support.
>

Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>

> Tested-by: John Madieu <john.madieu.xa@bp.renesas.com>
> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> ---
> 
> Changes in v6:
> - updated patch description
> - collected tags
> - in rz_dmac_free_chan_resources() and rz_dmac_terminate_all() don't touch
>   the HW registers if runtime resume failed but allow freeing resources
>   as suggested by sashiko; along with it added debug messages in case the
>   RPM resume failed
> - dropped the runtime resume from rz_dmac_xfer_desc() and move it instead
>   in rz_dmac_issue_pending() only to avoid calling rpm resume code in
>   interrupt path as, if we are in the interrupt path the device is sanely
>   in runtime resume state
> - moved the RPM resume code in from rz_dmac_tx_status to
>   rz_dmac_chan_get_residue(), as close as possible to the HW registers read
>   to avoid RPM resume in case the residue could be returned w/o interracting
>   with the HW
> - updated patch description
> 
> Changes in v5:
> - none, this patch is new
> 
>  drivers/dma/sh/rz-dmac.c | 60 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 57 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
> index 93394b9934c8..bd4ca8e939f1 100644
> --- a/drivers/dma/sh/rz-dmac.c
> +++ b/drivers/dma/sh/rz-dmac.c
> @@ -549,12 +549,22 @@ static void rz_dmac_free_chan_resources(struct dma_chan *chan)
>  	struct rz_dmac *dmac = to_rz_dmac(chan->device);
>  	struct rz_dmac_desc *desc, *_desc;
>  	unsigned long flags;
> +	int ret;
> +
> +	PM_RUNTIME_ACQUIRE_IF_ENABLED(dmac->dev, pm);
> +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> +	if (ret) {
> +		dev_err(dmac->dev, "RPM resume failed for channel %s, ret=%d\n!",
> +			dma_chan_name(chan), ret);
> +	}
>  
>  	spin_lock_irqsave(&channel->vc.lock, flags);
>  
>  	rz_lmdesc_setup(channel, channel->lmdesc.base);
>  
> -	rz_dmac_disable_hw(channel);
> +	/*  Skip touching HW if RPM resume failed. Let the cleanup do its jobs. */
> +	if (!ret)
> +		rz_dmac_disable_hw(channel);
>  
>  	if (channel->mid_rid >= 0) {
>  		clear_bit(channel->mid_rid, dmac->modules);
> @@ -697,11 +707,22 @@ rz_dmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr,
>  static int rz_dmac_terminate_all(struct dma_chan *chan)
>  {
>  	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
> +	struct rz_dmac *dmac = to_rz_dmac(chan->device);
>  	unsigned long flags;
>  	LIST_HEAD(head);
> +	int ret;
> +
> +	PM_RUNTIME_ACQUIRE_IF_ENABLED(dmac->dev, pm);
> +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> +	if (ret) {
> +		dev_err(dmac->dev, "RPM resume failed for channel %s, ret=%d\n!",
> +			dma_chan_name(chan), ret);
> +	}
>  
>  	spin_lock_irqsave(&channel->vc.lock, flags);
> -	rz_dmac_disable_hw(channel);
> +	/* Don't return if RPM failed. Let the cleanup do its jobs. */
> +	if (!ret)
> +		rz_dmac_disable_hw(channel);
>  	rz_lmdesc_setup(channel, channel->lmdesc.base);
>  
>  	if (channel->desc) {
> @@ -716,13 +737,20 @@ static int rz_dmac_terminate_all(struct dma_chan *chan)
>  	spin_unlock_irqrestore(&channel->vc.lock, flags);
>  	vchan_dma_desc_free_list(&channel->vc, &head);
>  
> -	return 0;
> +	return ret;
>  }
>  
>  static void rz_dmac_issue_pending(struct dma_chan *chan)
>  {
>  	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
> +	struct rz_dmac *dmac = to_rz_dmac(chan->device);
>  	unsigned long flags;
> +	int ret;
> +
> +	PM_RUNTIME_ACQUIRE_IF_ENABLED(dmac->dev, pm);
> +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> +	if (ret)
> +		return;
>  
>  	spin_lock_irqsave(&channel->vc.lock, flags);
>  
> @@ -807,6 +835,11 @@ static void rz_dmac_device_synchronize(struct dma_chan *chan)
>  
>  	vchan_synchronize(&channel->vc);
>  
> +	PM_RUNTIME_ACQUIRE_IF_ENABLED(dmac->dev, pm);
> +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> +	if (ret)
> +		return;
> +
>  	ret = read_poll_timeout(rz_dmac_ch_readl, chstat, !(chstat & CHSTAT_EN),
>  				100, 100000, false, channel, CHSTAT, 1);
>  	if (ret < 0)
> @@ -866,6 +899,7 @@ static int rz_dmac_chan_get_residue(struct device *dev, struct rz_dmac_chan *cha
>  	struct rz_dmac_desc *desc = NULL;
>  	struct virt_dma_desc *vd;
>  	u32 crla, crtb, i;
> +	int ret;
>  
>  	vd = vchan_find_desc(&channel->vc, cookie);
>  	if (vd) {
> @@ -884,6 +918,11 @@ static int rz_dmac_chan_get_residue(struct device *dev, struct rz_dmac_chan *cha
>  		return 0;
>  	}
>  
> +	PM_RUNTIME_ACQUIRE_IF_ENABLED(dev, pm);
> +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> +	if (ret)
> +		return ret;
> +
>  	/*
>  	 * We need to read two registers. Make sure the hardware does not move
>  	 * to next lmdesc while reading the current lmdesc. Trying it 3 times
> @@ -965,6 +1004,13 @@ static int rz_dmac_device_pause_set(struct rz_dmac_chan *channel,
>  static int rz_dmac_device_pause(struct dma_chan *chan)
>  {
>  	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
> +	struct rz_dmac *dmac = to_rz_dmac(chan->device);
> +	int ret;
> +
> +	PM_RUNTIME_ACQUIRE_IF_ENABLED(dmac->dev, pm);
> +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> +	if (ret)
> +		return ret;
>  
>  	guard(spinlock_irqsave)(&channel->vc.lock);
>  
> @@ -994,6 +1040,13 @@ static int rz_dmac_device_resume_set(struct rz_dmac_chan *channel,
>  static int rz_dmac_device_resume(struct dma_chan *chan)
>  {
>  	struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
> +	struct rz_dmac *dmac = to_rz_dmac(chan->device);
> +	int ret;
> +
> +	PM_RUNTIME_ACQUIRE_IF_ENABLED(dmac->dev, pm);
> +	ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> +	if (ret)
> +		return ret;
>  
>  	guard(spinlock_irqsave)(&channel->vc.lock);
>  
> @@ -1274,6 +1327,7 @@ static int rz_dmac_probe(struct platform_device *pdev)
>  		return dev_err_probe(&pdev->dev, PTR_ERR(dmac->rstc),
>  				     "failed to get resets\n");
>  
> +	pm_runtime_irq_safe(&pdev->dev);
>  	pm_runtime_enable(&pdev->dev);
>  	ret = pm_runtime_resume_and_get(&pdev->dev);
>  	if (ret < 0) {
> -- 
> 2.43.0
> 

  parent reply	other threads:[~2026-05-28 13:52 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-26  8:46 [PATCH v6 00/18] Renesas: dmaengine and ASoC fixes Claudiu Beznea
2026-05-26  8:46 ` [PATCH v6 01/18] dmaengine: sh: rz-dmac: Move interrupt request after everything is set up Claudiu Beznea
2026-05-26  8:54   ` Biju Das
2026-05-26  9:45     ` Claudiu Beznea
2026-05-26  9:51       ` Biju Das
2026-05-26 10:25         ` Claudiu Beznea
2026-05-26 10:39           ` Biju Das
2026-05-26  9:20   ` sashiko-bot
2026-05-28 13:44   ` Tommaso Merciai
2026-05-26  8:46 ` [PATCH v6 02/18] dmaengine: sh: rz-dmac: Fix incorrect NULL check for list_first_entry() Claudiu Beznea
2026-05-26  9:03   ` sashiko-bot
2026-05-28 13:45   ` Tommaso Merciai
2026-05-26  8:46 ` [PATCH v6 03/18] dmaengine: sh: rz-dmac: Use list_first_entry_or_null() Claudiu Beznea
2026-05-28 13:45   ` Tommaso Merciai
2026-05-26  8:46 ` [PATCH v6 04/18] dmaengine: sh: rz-dmac: Use rz_dmac_disable_hw() Claudiu Beznea
2026-05-26  9:15   ` sashiko-bot
2026-05-28 13:46   ` Tommaso Merciai
2026-05-26  8:46 ` [PATCH v6 05/18] dmaengine: sh: rz-dmac: Add helper to compute the lmdesc address Claudiu Beznea
2026-05-28 13:47   ` Tommaso Merciai
2026-05-26  8:46 ` [PATCH v6 06/18] dmaengine: sh: rz-dmac: Save the start LM descriptor Claudiu Beznea
2026-05-26  9:41   ` sashiko-bot
2026-05-28 13:47   ` Tommaso Merciai
2026-05-26  8:46 ` [PATCH v6 07/18] dmaengine: sh: rz-dmac: Add helper to check if the channel is enabled Claudiu Beznea
2026-05-28 13:48   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 08/18] dmaengine: sh: rz-dmac: Add helper to check if the channel is paused Claudiu Beznea
2026-05-28 13:48   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 09/18] dmaengine: sh: rz-dmac: Use virt-dma APIs for channel descriptor processing Claudiu Beznea
2026-05-26  9:28   ` sashiko-bot
2026-05-28 13:49   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 10/18] dmaengine: sh: rz-dmac: Refactor pause/resume code Claudiu Beznea
2026-05-26  9:28   ` sashiko-bot
2026-05-28 13:50   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 11/18] dmaengine: sh: rz-dmac: Drop the update of channel->chctrl with CHCTRL_SETEN Claudiu Beznea
2026-05-26  9:11   ` sashiko-bot
2026-05-28 13:50   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 12/18] dmaengine: sh: rz-dmac: Add cyclic DMA support Claudiu Beznea
2026-05-26  9:31   ` sashiko-bot
2026-05-28 13:51   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 13/18] dmaengine: sh: rz-dmac: Adjust rz_dmac_chan_get_residue() to return error codes Claudiu Beznea
2026-05-28 13:51   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 14/18] dmaengine: sh: rz-dmac: Add runtime PM support Claudiu Beznea
2026-05-26  9:57   ` sashiko-bot
2026-05-28 13:52   ` Tommaso Merciai [this message]
2026-05-26  8:47 ` [PATCH v6 15/18] dmaengine: sh: rz-dmac: Add suspend to RAM support Claudiu Beznea
2026-05-26  9:43   ` sashiko-bot
2026-05-28 14:38   ` Tommaso Merciai
2026-05-26  8:47 ` [PATCH v6 16/18] ASoC: renesas: rz-ssi: Add pause support Claudiu Beznea
2026-05-26  9:46   ` sashiko-bot
2026-05-26  8:47 ` [PATCH v6 17/18] ASoC: renesas: rz-ssi: Use generic PCM dmaengine APIs Claudiu Beznea
2026-05-26 10:00   ` sashiko-bot
2026-05-26  8:47 ` [PATCH v6 18/18] dmaengine: sh: rz-dmac: Set the Link End (LE) bit on the last descriptor Claudiu Beznea
2026-05-26  9:43   ` sashiko-bot
2026-05-28 14:39   ` Tommaso Merciai
2026-06-02 13:30 ` [PATCH v6 00/18] Renesas: dmaengine and ASoC fixes Claudiu Beznea

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ahhIlt8PSF6_DoRU@tom-desktop \
    --to=tommaso.merciai.xr@bp.renesas.com \
    --cc=Frank.Li@kernel.org \
    --cc=biju.das.jz@bp.renesas.com \
    --cc=broonie@kernel.org \
    --cc=claudiu.beznea.uj@bp.renesas.com \
    --cc=claudiu.beznea@kernel.org \
    --cc=claudiu.beznea@tuxon.dev \
    --cc=dmaengine@vger.kernel.org \
    --cc=geert+renesas@glider.be \
    --cc=john.madieu.xa@bp.renesas.com \
    --cc=kuninori.morimoto.gx@renesas.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=long.luu.ur@renesas.com \
    --cc=p.zabel@pengutronix.de \
    --cc=perex@perex.cz \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --cc=tiwai@suse.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.