dmaengine.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume
@ 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
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

Hi,

Series adds fixes identified on suspend/resume of at_xdmac driver
(patches 1/7-5/7).

Patch 6/7 just adds a warning message that could be used for debugging
purposes.
Patch 7/7 is a minor cleanup.

Thank you,
Claudiu Beznea

Claudiu Beznea (7):
  dmaengine: at_xdmac: disable/enable clock directly on suspend/resume
  dmaengine: at_xdmac: fix imbalanced runtime PM reference counter
  dmaengine: at_xdmac: do not resume channels paused by consumers
  dmaengine: at_xdmac: restore the content of grws register
  dmaengine: at_xdmac: do not enable all cyclic channels
  dmaengine: at_xdmac: add a warning message regarding for unpaused
    channels
  dmaengine: at_xdmac: align declaration of ret with the rest of
    variables

 drivers/dma/at_xdmac.c | 107 +++++++++++++++++++++++++++++++----------
 1 file changed, 82 insertions(+), 25 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] dmaengine: at_xdmac: disable/enable clock directly on suspend/resume
  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 2/7] dmaengine: at_xdmac: fix imbalanced runtime PM reference counter Claudiu Beznea
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

Runtime PM APIs for at_xdmac just plays with clk_enable()/clk_disable()
letting aside the clk_prepare()/clk_unprepare() that needs to be
executed as the clock is also prepared on probe. Thus instead of using
runtime PM force suspend/resume APIs use
clk_disable_unprepare() + pm_runtime_put_noidle() on suspend and
clk_prepare_enable() + pm_runtime_get_noresume() on resume. This
approach as been chosen instead of using runtime PM force suspend/resume
with clk_unprepare()/clk_prepare() as it looks simpler and the final
code is better.

While at it added the missing pm_runtime_mark_last_busy() on suspend before
decrementing the reference counter.

Fixes: 650b0e990cbd ("dmaengine: at_xdmac: add runtime pm support")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/dma/at_xdmac.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 1f0fab180f8f..f654ecaafb90 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -2130,7 +2130,11 @@ static int __maybe_unused atmel_xdmac_suspend(struct device *dev)
 	atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM);
 
 	at_xdmac_off(atxdmac);
-	return pm_runtime_force_suspend(atxdmac->dev);
+	pm_runtime_mark_last_busy(atxdmac->dev);
+	pm_runtime_put_noidle(atxdmac->dev);
+	clk_disable_unprepare(atxdmac->clk);
+
+	return 0;
 }
 
 static int __maybe_unused atmel_xdmac_resume(struct device *dev)
@@ -2142,10 +2146,12 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev)
 	int			i;
 	int ret;
 
-	ret = pm_runtime_force_resume(atxdmac->dev);
-	if (ret < 0)
+	ret = clk_prepare_enable(atxdmac->clk);
+	if (ret)
 		return ret;
 
+	pm_runtime_get_noresume(atxdmac->dev);
+
 	at_xdmac_axi_config(pdev);
 
 	/* Clear pending interrupts. */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/7] dmaengine: at_xdmac: fix imbalanced runtime PM reference counter
  2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume 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 ` [PATCH 3/7] dmaengine: at_xdmac: do not resume channels paused by consumers Claudiu Beznea
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

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


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/7] dmaengine: at_xdmac: do not resume channels paused by consumers
  2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume 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 ` [PATCH 2/7] dmaengine: at_xdmac: fix imbalanced runtime PM reference counter 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
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

In case there are DMA channels not paused by consumers in suspend
process (valid on AT91 SoCs for serial driver when no_console_suspend) the
driver pauses them (using at_xdmac_device_pause() which is also the same
function called by dmaengine_pause()) and then in the resume process the
driver resumes them calling at_xdmac_device_resume() which is the same
function called by dmaengine_resume()). This is good for DMA channels
not paused by consumers but for drivers that calls
dmaengine_pause()/dmaegine_resume() on suspend/resume path this may lead to
DMA channel being enabled before the IP is enabled. For IPs that needs
strict ordering with regards to DMA channel enablement this will lead to
wrong behavior. To fix this add a new set of functions
at_xdmac_device_pause_internal()/at_xdmac_device_resume_internal() to be
called only on suspend/resume.

Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/dma/at_xdmac.c | 52 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index af3b494f9ba9..fa1e2e0da02f 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -187,6 +187,7 @@
 enum atc_status {
 	AT_XDMAC_CHAN_IS_CYCLIC = 0,
 	AT_XDMAC_CHAN_IS_PAUSED,
+	AT_XDMAC_CHAN_IS_PAUSED_INTERNAL,
 };
 
 struct at_xdmac_layout {
@@ -347,6 +348,11 @@ static inline int at_xdmac_chan_is_paused(struct at_xdmac_chan *atchan)
 	return test_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
 }
 
+static inline int at_xdmac_chan_is_paused_internal(struct at_xdmac_chan *atchan)
+{
+	return test_bit(AT_XDMAC_CHAN_IS_PAUSED_INTERNAL, &atchan->status);
+}
+
 static inline bool at_xdmac_chan_is_peripheral_xfer(u32 cfg)
 {
 	return cfg & AT_XDMAC_CC_TYPE_PER_TRAN;
@@ -1898,6 +1904,26 @@ static int at_xdmac_device_config(struct dma_chan *chan,
 	return ret;
 }
 
+static void at_xdmac_device_pause_set(struct at_xdmac *atxdmac,
+				      struct at_xdmac_chan *atchan)
+{
+	at_xdmac_write(atxdmac, atxdmac->layout->grws, atchan->mask);
+	while (at_xdmac_chan_read(atchan, AT_XDMAC_CC) &
+	       (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP))
+		cpu_relax();
+}
+
+static void at_xdmac_device_pause_internal(struct at_xdmac_chan *atchan)
+{
+	struct at_xdmac		*atxdmac = to_at_xdmac(atchan->chan.device);
+	unsigned long		flags;
+
+	spin_lock_irqsave(&atchan->lock, flags);
+	set_bit(AT_XDMAC_CHAN_IS_PAUSED_INTERNAL, &atchan->status);
+	at_xdmac_device_pause_set(atxdmac, atchan);
+	spin_unlock_irqrestore(&atchan->lock, flags);
+}
+
 static int at_xdmac_device_pause(struct dma_chan *chan)
 {
 	struct at_xdmac_chan	*atchan = to_at_xdmac_chan(chan);
@@ -1915,11 +1941,8 @@ static int at_xdmac_device_pause(struct dma_chan *chan)
 		return ret;
 
 	spin_lock_irqsave(&atchan->lock, flags);
-	at_xdmac_write(atxdmac, atxdmac->layout->grws, atchan->mask);
-	while (at_xdmac_chan_read(atchan, AT_XDMAC_CC)
-	       & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP))
-		cpu_relax();
 
+	at_xdmac_device_pause_set(atxdmac, atchan);
 	/* Decrement runtime PM ref counter for each active descriptor. */
 	at_xdmac_runtime_suspend_descriptors(atchan);
 
@@ -1931,6 +1954,17 @@ static int at_xdmac_device_pause(struct dma_chan *chan)
 	return 0;
 }
 
+static void at_xdmac_device_resume_internal(struct at_xdmac_chan *atchan)
+{
+	struct at_xdmac		*atxdmac = to_at_xdmac(atchan->chan.device);
+	unsigned long		flags;
+
+	spin_lock_irqsave(&atchan->lock, flags);
+	at_xdmac_write(atxdmac, atxdmac->layout->grwr, atchan->mask);
+	clear_bit(AT_XDMAC_CHAN_IS_PAUSED_INTERNAL, &atchan->status);
+	spin_unlock_irqrestore(&atchan->lock, flags);
+}
+
 static int at_xdmac_device_resume(struct dma_chan *chan)
 {
 	struct at_xdmac_chan	*atchan = to_at_xdmac_chan(chan);
@@ -2119,7 +2153,7 @@ 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)) {
-				at_xdmac_device_pause(chan);
+				at_xdmac_device_pause_internal(atchan);
 				at_xdmac_runtime_suspend_descriptors(atchan);
 			}
 			atchan->save_cim = at_xdmac_chan_read(atchan, AT_XDMAC_CIM);
@@ -2167,11 +2201,15 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev)
 
 		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)) {
+			/*
+			 * Resume only channels not explicitly paused by
+			 * consumers.
+			 */
+			if (at_xdmac_chan_is_paused_internal(atchan)) {
 				ret = at_xdmac_runtime_resume_descriptors(atchan);
 				if (ret < 0)
 					return ret;
-				at_xdmac_device_resume(chan);
+				at_xdmac_device_resume_internal(atchan);
 			}
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda);
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/7] dmaengine: at_xdmac: restore the content of grws register
  2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Claudiu Beznea
                   ` (2 preceding siblings ...)
  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 5/7] dmaengine: at_xdmac: do not enable all cyclic channels Claudiu Beznea
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

In case the system suspends to a deep sleep state where power to DMA
controller is cut-off we need to restore the content of GRWS register.
This is a write only register and writing bit X tells the controller
to suspend read and write requests for channel X. Thus set GRWS before
restoring the content of GE (Global Enable) regiter.

Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/dma/at_xdmac.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index fa1e2e0da02f..34c004a4b23c 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -2211,6 +2211,15 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev)
 					return ret;
 				at_xdmac_device_resume_internal(atchan);
 			}
+
+			/*
+			 * We may resume from a deep sleep state where power
+			 * to DMA controller is cut-off. Thus, restore the
+			 * suspend state of channels set though dmaengine API.
+			 */
+			else if (at_xdmac_chan_is_paused(atchan))
+				at_xdmac_device_pause_set(atxdmac, atchan);
+
 			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);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/7] dmaengine: at_xdmac: do not enable all cyclic channels
  2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Claudiu Beznea
                   ` (3 preceding siblings ...)
  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 6/7] dmaengine: at_xdmac: add a warning message regarding for unpaused channels Claudiu Beznea
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

Do not global enable all the cyclic channels in at_xdmac_resume(). Instead
save the global status in at_xdmac_suspend() and re-enable the cyclic
channel only if it was active before suspend.

Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/dma/at_xdmac.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 34c004a4b23c..96f1b69f8a75 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -246,6 +246,7 @@ struct at_xdmac {
 	int			irq;
 	struct clk		*clk;
 	u32			save_gim;
+	u32			save_gs;
 	struct dma_pool		*at_xdmac_desc_pool;
 	const struct at_xdmac_layout	*layout;
 	struct at_xdmac_chan	chan[];
@@ -2162,6 +2163,7 @@ static int __maybe_unused atmel_xdmac_suspend(struct device *dev)
 		}
 	}
 	atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM);
+	atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS);
 
 	at_xdmac_off(atxdmac, false);
 	pm_runtime_mark_last_busy(atxdmac->dev);
@@ -2224,7 +2226,8 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev)
 			at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
 			at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim);
 			wmb();
-			at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask);
+			if (atxdmac->save_gs & atchan->mask)
+				at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask);
 		}
 	}
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/7] dmaengine: at_xdmac: add a warning message regarding for unpaused channels
  2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Claudiu Beznea
                   ` (4 preceding siblings ...)
  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 7/7] dmaengine: at_xdmac: align declaration of ret with the rest of variables Claudiu Beznea
  2023-04-12 17:47 ` [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Vinod Koul
  7 siblings, 0 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

Add a warning message on suspend to let the user that there are channels
not paused by their consumers.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/dma/at_xdmac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 96f1b69f8a75..7ff6ca01e0b5 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -2154,6 +2154,8 @@ 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)) {
+				dev_warn(chan2dev(chan), "%s: channel %d not paused\n",
+					 __func__, chan->chan_id);
 				at_xdmac_device_pause_internal(atchan);
 				at_xdmac_runtime_suspend_descriptors(atchan);
 			}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/7] dmaengine: at_xdmac: align declaration of ret with the rest of variables
  2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Claudiu Beznea
                   ` (5 preceding siblings ...)
  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-04-12 17:47 ` [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Vinod Koul
  7 siblings, 0 replies; 9+ messages in thread
From: Claudiu Beznea @ 2023-02-14 15:18 UTC (permalink / raw)
  To: ludovic.desroches, tudor.ambarus, vkoul, nicolas.ferre
  Cc: linux-arm-kernel, dmaengine, linux-kernel, Claudiu Beznea

Align the declaration of ret in atmel_xdmac_resume() with the rest of
variables. Do this by adding ret to the line with declaration for i
variable.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/dma/at_xdmac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index 7ff6ca01e0b5..7da6d9b6098e 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -2181,8 +2181,7 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev)
 	struct at_xdmac_chan	*atchan;
 	struct dma_chan		*chan, *_chan;
 	struct platform_device	*pdev = container_of(dev, struct platform_device, dev);
-	int			i;
-	int ret;
+	int			i, ret;
 
 	ret = clk_prepare_enable(atxdmac->clk);
 	if (ret)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume
  2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Claudiu Beznea
                   ` (6 preceding siblings ...)
  2023-02-14 15:18 ` [PATCH 7/7] dmaengine: at_xdmac: align declaration of ret with the rest of variables Claudiu Beznea
@ 2023-04-12 17:47 ` Vinod Koul
  7 siblings, 0 replies; 9+ messages in thread
From: Vinod Koul @ 2023-04-12 17:47 UTC (permalink / raw)
  To: Claudiu Beznea
  Cc: ludovic.desroches, tudor.ambarus, nicolas.ferre, linux-arm-kernel,
	dmaengine, linux-kernel

On 14-02-23, 17:18, Claudiu Beznea wrote:
> Hi,
> 
> Series adds fixes identified on suspend/resume of at_xdmac driver
> (patches 1/7-5/7).

Applied, thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-04-12 17:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-14 15:18 [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume 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 ` [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 ` [PATCH 4/7] dmaengine: at_xdmac: restore the content of grws register 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 ` [PATCH 6/7] dmaengine: at_xdmac: add a warning message regarding for unpaused channels 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-04-12 17:47 ` [PATCH 0/7] dmaengine: at_xdmac: fixes for suspend/resume Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).