From: Claudiu Beznea <claudiu.beznea@microchip.com> To: <ludovic.desroches@microchip.com>, <tudor.ambarus@linaro.org>, <vkoul@kernel.org>, <nicolas.ferre@microchip.com> Cc: <linux-arm-kernel@lists.infradead.org>, <dmaengine@vger.kernel.org>, <linux-kernel@vger.kernel.org>, Claudiu Beznea <claudiu.beznea@microchip.com> Subject: [PATCH 2/7] dmaengine: at_xdmac: fix imbalanced runtime PM reference counter Date: Tue, 14 Feb 2023 17:18:22 +0200 [thread overview] Message-ID: <20230214151827.1050280-3-claudiu.beznea@microchip.com> (raw) In-Reply-To: <20230214151827.1050280-1-claudiu.beznea@microchip.com> In case there are channels not paused during suspend (which on AT91 case is valid for serial driver when no_console_suspend boot argument is used) the at_xdmac_runtime_suspend_descriptors() was called more than one time due to at_xdmac_off(). To fix this add a new argument to at_xdmac_off() to specify if runtime PM reference counter needs to be decremented for queued active descriptors. Along with it moved the at_xdmac_runtime_suspend_descriptors() call under at_xdmac_chan_is_paused() check on suspend path as for the rest of channels the suspend is delayed by atmel_xdmac_prepare() in case channel is enabled. Same approach has been applied on resume path. Fixes: 650b0e990cbd ("dmaengine: at_xdmac: add runtime pm support") Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> --- drivers/dma/at_xdmac.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index f654ecaafb90..af3b494f9ba9 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -412,7 +412,7 @@ static bool at_xdmac_chan_is_enabled(struct at_xdmac_chan *atchan) return ret; } -static void at_xdmac_off(struct at_xdmac *atxdmac) +static void at_xdmac_off(struct at_xdmac *atxdmac, bool suspend_descriptors) { struct dma_chan *chan, *_chan; struct at_xdmac_chan *atchan; @@ -431,7 +431,7 @@ static void at_xdmac_off(struct at_xdmac *atxdmac) at_xdmac_write(atxdmac, AT_XDMAC_GID, -1L); /* Decrement runtime PM ref counter for each active descriptor. */ - if (!list_empty(&atxdmac->dma.channels)) { + if (!list_empty(&atxdmac->dma.channels) && suspend_descriptors) { list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { atchan = to_at_xdmac_chan(chan); @@ -2118,18 +2118,18 @@ static int __maybe_unused atmel_xdmac_suspend(struct device *dev) atchan->save_cc = at_xdmac_chan_read(atchan, AT_XDMAC_CC); if (at_xdmac_chan_is_cyclic(atchan)) { - if (!at_xdmac_chan_is_paused(atchan)) + if (!at_xdmac_chan_is_paused(atchan)) { at_xdmac_device_pause(chan); + at_xdmac_runtime_suspend_descriptors(atchan); + } atchan->save_cim = at_xdmac_chan_read(atchan, AT_XDMAC_CIM); atchan->save_cnda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA); atchan->save_cndc = at_xdmac_chan_read(atchan, AT_XDMAC_CNDC); } - - at_xdmac_runtime_suspend_descriptors(atchan); } atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); - at_xdmac_off(atxdmac); + at_xdmac_off(atxdmac, false); pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_noidle(atxdmac->dev); clk_disable_unprepare(atxdmac->clk); @@ -2165,14 +2165,14 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev) list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { atchan = to_at_xdmac_chan(chan); - ret = at_xdmac_runtime_resume_descriptors(atchan); - if (ret < 0) - return ret; - at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc); if (at_xdmac_chan_is_cyclic(atchan)) { - if (at_xdmac_chan_is_paused(atchan)) + if (at_xdmac_chan_is_paused(atchan)) { + ret = at_xdmac_runtime_resume_descriptors(atchan); + if (ret < 0) + return ret; at_xdmac_device_resume(chan); + } at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda); at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); @@ -2318,7 +2318,7 @@ static int at_xdmac_probe(struct platform_device *pdev) INIT_LIST_HEAD(&atxdmac->dma.channels); /* Disable all chans and interrupts. */ - at_xdmac_off(atxdmac); + at_xdmac_off(atxdmac, true); for (i = 0; i < nr_channels; i++) { struct at_xdmac_chan *atchan = &atxdmac->chan[i]; @@ -2382,7 +2382,7 @@ static int at_xdmac_remove(struct platform_device *pdev) struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); int i; - at_xdmac_off(atxdmac); + at_xdmac_off(atxdmac, true); of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&atxdmac->dma); pm_runtime_disable(atxdmac->dev); -- 2.34.1
WARNING: multiple messages have this Message-ID (diff)
From: Claudiu Beznea <claudiu.beznea@microchip.com> To: <ludovic.desroches@microchip.com>, <tudor.ambarus@linaro.org>, <vkoul@kernel.org>, <nicolas.ferre@microchip.com> Cc: <linux-arm-kernel@lists.infradead.org>, <dmaengine@vger.kernel.org>, <linux-kernel@vger.kernel.org>, Claudiu Beznea <claudiu.beznea@microchip.com> Subject: [PATCH 2/7] dmaengine: at_xdmac: fix imbalanced runtime PM reference counter Date: Tue, 14 Feb 2023 17:18:22 +0200 [thread overview] Message-ID: <20230214151827.1050280-3-claudiu.beznea@microchip.com> (raw) In-Reply-To: <20230214151827.1050280-1-claudiu.beznea@microchip.com> In case there are channels not paused during suspend (which on AT91 case is valid for serial driver when no_console_suspend boot argument is used) the at_xdmac_runtime_suspend_descriptors() was called more than one time due to at_xdmac_off(). To fix this add a new argument to at_xdmac_off() to specify if runtime PM reference counter needs to be decremented for queued active descriptors. Along with it moved the at_xdmac_runtime_suspend_descriptors() call under at_xdmac_chan_is_paused() check on suspend path as for the rest of channels the suspend is delayed by atmel_xdmac_prepare() in case channel is enabled. Same approach has been applied on resume path. Fixes: 650b0e990cbd ("dmaengine: at_xdmac: add runtime pm support") Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> --- drivers/dma/at_xdmac.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index f654ecaafb90..af3b494f9ba9 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -412,7 +412,7 @@ static bool at_xdmac_chan_is_enabled(struct at_xdmac_chan *atchan) return ret; } -static void at_xdmac_off(struct at_xdmac *atxdmac) +static void at_xdmac_off(struct at_xdmac *atxdmac, bool suspend_descriptors) { struct dma_chan *chan, *_chan; struct at_xdmac_chan *atchan; @@ -431,7 +431,7 @@ static void at_xdmac_off(struct at_xdmac *atxdmac) at_xdmac_write(atxdmac, AT_XDMAC_GID, -1L); /* Decrement runtime PM ref counter for each active descriptor. */ - if (!list_empty(&atxdmac->dma.channels)) { + if (!list_empty(&atxdmac->dma.channels) && suspend_descriptors) { list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { atchan = to_at_xdmac_chan(chan); @@ -2118,18 +2118,18 @@ static int __maybe_unused atmel_xdmac_suspend(struct device *dev) atchan->save_cc = at_xdmac_chan_read(atchan, AT_XDMAC_CC); if (at_xdmac_chan_is_cyclic(atchan)) { - if (!at_xdmac_chan_is_paused(atchan)) + if (!at_xdmac_chan_is_paused(atchan)) { at_xdmac_device_pause(chan); + at_xdmac_runtime_suspend_descriptors(atchan); + } atchan->save_cim = at_xdmac_chan_read(atchan, AT_XDMAC_CIM); atchan->save_cnda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA); atchan->save_cndc = at_xdmac_chan_read(atchan, AT_XDMAC_CNDC); } - - at_xdmac_runtime_suspend_descriptors(atchan); } atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); - at_xdmac_off(atxdmac); + at_xdmac_off(atxdmac, false); pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_noidle(atxdmac->dev); clk_disable_unprepare(atxdmac->clk); @@ -2165,14 +2165,14 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev) list_for_each_entry_safe(chan, _chan, &atxdmac->dma.channels, device_node) { atchan = to_at_xdmac_chan(chan); - ret = at_xdmac_runtime_resume_descriptors(atchan); - if (ret < 0) - return ret; - at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc); if (at_xdmac_chan_is_cyclic(atchan)) { - if (at_xdmac_chan_is_paused(atchan)) + if (at_xdmac_chan_is_paused(atchan)) { + ret = at_xdmac_runtime_resume_descriptors(atchan); + if (ret < 0) + return ret; at_xdmac_device_resume(chan); + } at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda); at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); @@ -2318,7 +2318,7 @@ static int at_xdmac_probe(struct platform_device *pdev) INIT_LIST_HEAD(&atxdmac->dma.channels); /* Disable all chans and interrupts. */ - at_xdmac_off(atxdmac); + at_xdmac_off(atxdmac, true); for (i = 0; i < nr_channels; i++) { struct at_xdmac_chan *atchan = &atxdmac->chan[i]; @@ -2382,7 +2382,7 @@ static int at_xdmac_remove(struct platform_device *pdev) struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); int i; - at_xdmac_off(atxdmac); + at_xdmac_off(atxdmac, true); of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&atxdmac->dma); pm_runtime_disable(atxdmac->dev); -- 2.34.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-02-14 15:20 UTC|newest] Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea 2023-02-14 15:18 ` [PATCH 1/7] dmaengine: at_xdmac: disable/enable clock directly on suspend/resume Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea [this message] 2023-02-14 15:18 ` [PATCH 2/7] dmaengine: at_xdmac: fix imbalanced runtime PM reference counter Claudiu Beznea 2023-02-14 15:18 ` [PATCH 3/7] dmaengine: at_xdmac: do not resume channels paused by consumers Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea 2023-02-14 15:18 ` [PATCH 4/7] dmaengine: at_xdmac: restore the content of grws register Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea 2023-02-14 15:18 ` [PATCH 5/7] dmaengine: at_xdmac: do not enable all cyclic channels Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea 2023-02-14 15:18 ` [PATCH 6/7] dmaengine: at_xdmac: add a warning message regarding for unpaused channels Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea 2023-02-14 15:18 ` [PATCH 7/7] dmaengine: at_xdmac: align declaration of ret with the rest of variables Claudiu Beznea 2023-02-14 15:18 ` Claudiu Beznea 2023-04-12 17:47 ` [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Vinod Koul 2023-04-12 17:47 ` Vinod Koul
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=20230214151827.1050280-3-claudiu.beznea@microchip.com \ --to=claudiu.beznea@microchip.com \ --cc=dmaengine@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=ludovic.desroches@microchip.com \ --cc=nicolas.ferre@microchip.com \ --cc=tudor.ambarus@linaro.org \ --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: linkBe 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.