All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND v3 0/2] dmaengine: axi-dmac: move to device managed probe
@ 2024-03-28 13:58 ` Nuno Sa
  0 siblings, 0 replies; 8+ messages in thread
From: Nuno Sa via B4 Relay @ 2024-03-28 13:58 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Lars-Peter Clausen, stable, Nuno Sa

Added a new patch so we can easily backport a possible race in the
unbind path.

Vinod, I'm just resending these patches again (as merge window is now
over. I applied and compiled them on top of the next branch. Tip in:

8b7149803af17 ("MAINTAINERS: Drop Gustavo Pimentel as EDMA Reviewer")

---
Changes in v3:
- Patch 1
  * New patch.
- Patch 2
  * Updated commit message (request_irq() is no longer moved).
- Link to v2: https://lore.kernel.org/r/20240219-axi-dmac-devm-probe-v2-1-1a6737294f69@analog.com

---
Nuno Sa (2):
      dmaengine: axi-dmac: fix possible race in remove()
      dmaengine: axi-dmac: move to device managed probe

 drivers/dma/dma-axi-dmac.c | 78 ++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 44 deletions(-)
---
base-commit: 8b7149803af174f3184d97c779faa1c7608da5af
change-id: 20240328-axi-dmac-devm-probe-b443e9de9cf1
--

Thanks!
- Nuno Sá



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

* [PATCH RESEND v3 0/2] dmaengine: axi-dmac: move to device managed probe
@ 2024-03-28 13:58 ` Nuno Sa
  0 siblings, 0 replies; 8+ messages in thread
From: Nuno Sa @ 2024-03-28 13:58 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Lars-Peter Clausen, stable, Nuno Sa

Added a new patch so we can easily backport a possible race in the
unbind path.

Vinod, I'm just resending these patches again (as merge window is now
over. I applied and compiled them on top of the next branch. Tip in:

8b7149803af17 ("MAINTAINERS: Drop Gustavo Pimentel as EDMA Reviewer")

---
Changes in v3:
- Patch 1
  * New patch.
- Patch 2
  * Updated commit message (request_irq() is no longer moved).
- Link to v2: https://lore.kernel.org/r/20240219-axi-dmac-devm-probe-v2-1-1a6737294f69@analog.com

---
Nuno Sa (2):
      dmaengine: axi-dmac: fix possible race in remove()
      dmaengine: axi-dmac: move to device managed probe

 drivers/dma/dma-axi-dmac.c | 78 ++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 44 deletions(-)
---
base-commit: 8b7149803af174f3184d97c779faa1c7608da5af
change-id: 20240328-axi-dmac-devm-probe-b443e9de9cf1
--

Thanks!
- Nuno Sá


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

* [PATCH RESEND v3 1/2] dmaengine: axi-dmac: fix possible race in remove()
  2024-03-28 13:58 ` Nuno Sa
@ 2024-03-28 13:58   ` Nuno Sa
  -1 siblings, 0 replies; 8+ messages in thread
From: Nuno Sa via B4 Relay @ 2024-03-28 13:58 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Lars-Peter Clausen, stable, Nuno Sa

From: Nuno Sa <nuno.sa@analog.com>

We need to first free the IRQ before calling of_dma_controller_free().
Otherwise we could get an interrupt and schedule a tasklet while
removing the DMA controller.

Fixes: 0e3b67b348b8 ("dmaengine: Add support for the Analog Devices AXI-DMAC DMA controller")
Cc: stable@kernel.org
Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 4e339c04fc1e..d5a33e4a91b1 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -1134,8 +1134,8 @@ static void axi_dmac_remove(struct platform_device *pdev)
 {
 	struct axi_dmac *dmac = platform_get_drvdata(pdev);
 
-	of_dma_controller_free(pdev->dev.of_node);
 	free_irq(dmac->irq, dmac);
+	of_dma_controller_free(pdev->dev.of_node);
 	tasklet_kill(&dmac->chan.vchan.task);
 	dma_async_device_unregister(&dmac->dma_dev);
 	clk_disable_unprepare(dmac->clk);

-- 
2.44.0



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

* [PATCH RESEND v3 1/2] dmaengine: axi-dmac: fix possible race in remove()
@ 2024-03-28 13:58   ` Nuno Sa
  0 siblings, 0 replies; 8+ messages in thread
From: Nuno Sa @ 2024-03-28 13:58 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Lars-Peter Clausen, stable, Nuno Sa

We need to first free the IRQ before calling of_dma_controller_free().
Otherwise we could get an interrupt and schedule a tasklet while
removing the DMA controller.

Fixes: 0e3b67b348b8 ("dmaengine: Add support for the Analog Devices AXI-DMAC DMA controller")
Cc: stable@kernel.org
Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 4e339c04fc1e..d5a33e4a91b1 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -1134,8 +1134,8 @@ static void axi_dmac_remove(struct platform_device *pdev)
 {
 	struct axi_dmac *dmac = platform_get_drvdata(pdev);
 
-	of_dma_controller_free(pdev->dev.of_node);
 	free_irq(dmac->irq, dmac);
+	of_dma_controller_free(pdev->dev.of_node);
 	tasklet_kill(&dmac->chan.vchan.task);
 	dma_async_device_unregister(&dmac->dma_dev);
 	clk_disable_unprepare(dmac->clk);

-- 
2.44.0


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

* [PATCH RESEND v3 2/2] dmaengine: axi-dmac: move to device managed probe
  2024-03-28 13:58 ` Nuno Sa
@ 2024-03-28 13:58   ` Nuno Sa
  -1 siblings, 0 replies; 8+ messages in thread
From: Nuno Sa via B4 Relay @ 2024-03-28 13:58 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Lars-Peter Clausen, Nuno Sa

From: Nuno Sa <nuno.sa@analog.com>

In axi_dmac_probe(), there's a mix in using device managed APIs and
explicitly cleaning things in the driver .remove() hook. Move to use
device managed APIs and thus drop the .remove() hook.

Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 78 ++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 44 deletions(-)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index d5a33e4a91b1..bdb752f11869 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -1002,6 +1002,16 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
 	return 0;
 }
 
+static void axi_dmac_tasklet_kill(void *task)
+{
+	tasklet_kill(task);
+}
+
+static void axi_dmac_free_dma_controller(void *of_node)
+{
+	of_dma_controller_free(of_node);
+}
+
 static int axi_dmac_probe(struct platform_device *pdev)
 {
 	struct dma_device *dma_dev;
@@ -1025,14 +1035,10 @@ static int axi_dmac_probe(struct platform_device *pdev)
 	if (IS_ERR(dmac->base))
 		return PTR_ERR(dmac->base);
 
-	dmac->clk = devm_clk_get(&pdev->dev, NULL);
+	dmac->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(dmac->clk))
 		return PTR_ERR(dmac->clk);
 
-	ret = clk_prepare_enable(dmac->clk);
-	if (ret < 0)
-		return ret;
-
 	version = axi_dmac_read(dmac, ADI_AXI_REG_VERSION);
 
 	if (version >= ADI_AXI_PCORE_VER(4, 3, 'a'))
@@ -1041,7 +1047,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
 		ret = axi_dmac_parse_dt(&pdev->dev, dmac);
 
 	if (ret < 0)
-		goto err_clk_disable;
+		return ret;
 
 	INIT_LIST_HEAD(&dmac->chan.active_descs);
 
@@ -1072,7 +1078,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
 
 	ret = axi_dmac_detect_caps(dmac, version);
 	if (ret)
-		goto err_clk_disable;
+		return ret;
 
 	dma_dev->copy_align = (dmac->chan.address_align_mask + 1);
 
@@ -1088,57 +1094,42 @@ static int axi_dmac_probe(struct platform_device *pdev)
 		    !AXI_DMAC_DST_COHERENT_GET(ret)) {
 			dev_err(dmac->dma_dev.dev,
 				"Coherent DMA not supported in hardware");
-			ret = -EINVAL;
-			goto err_clk_disable;
+			return -EINVAL;
 		}
 	}
 
-	ret = dma_async_device_register(dma_dev);
+	ret = dmaenginem_async_device_register(dma_dev);
 	if (ret)
-		goto err_clk_disable;
+		return ret;
+
+	/*
+	 * Put the action in here so it get's done before unregistering the DMA
+	 * device.
+	 */
+	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_tasklet_kill,
+				       &dmac->chan.vchan.task);
+	if (ret)
+		return ret;
 
 	ret = of_dma_controller_register(pdev->dev.of_node,
 		of_dma_xlate_by_chan_id, dma_dev);
 	if (ret)
-		goto err_unregister_device;
+		return ret;
 
-	ret = request_irq(dmac->irq, axi_dmac_interrupt_handler, IRQF_SHARED,
-		dev_name(&pdev->dev), dmac);
+	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_free_dma_controller,
+				       pdev->dev.of_node);
 	if (ret)
-		goto err_unregister_of;
+		return ret;
 
-	platform_set_drvdata(pdev, dmac);
+	ret = devm_request_irq(&pdev->dev, dmac->irq, axi_dmac_interrupt_handler,
+			       IRQF_SHARED, dev_name(&pdev->dev), dmac);
+	if (ret)
+		return ret;
 
 	regmap = devm_regmap_init_mmio(&pdev->dev, dmac->base,
 		 &axi_dmac_regmap_config);
-	if (IS_ERR(regmap)) {
-		ret = PTR_ERR(regmap);
-		goto err_free_irq;
-	}
 
-	return 0;
-
-err_free_irq:
-	free_irq(dmac->irq, dmac);
-err_unregister_of:
-	of_dma_controller_free(pdev->dev.of_node);
-err_unregister_device:
-	dma_async_device_unregister(&dmac->dma_dev);
-err_clk_disable:
-	clk_disable_unprepare(dmac->clk);
-
-	return ret;
-}
-
-static void axi_dmac_remove(struct platform_device *pdev)
-{
-	struct axi_dmac *dmac = platform_get_drvdata(pdev);
-
-	free_irq(dmac->irq, dmac);
-	of_dma_controller_free(pdev->dev.of_node);
-	tasklet_kill(&dmac->chan.vchan.task);
-	dma_async_device_unregister(&dmac->dma_dev);
-	clk_disable_unprepare(dmac->clk);
+	return PTR_ERR_OR_ZERO(regmap);
 }
 
 static const struct of_device_id axi_dmac_of_match_table[] = {
@@ -1153,7 +1144,6 @@ static struct platform_driver axi_dmac_driver = {
 		.of_match_table = axi_dmac_of_match_table,
 	},
 	.probe = axi_dmac_probe,
-	.remove_new = axi_dmac_remove,
 };
 module_platform_driver(axi_dmac_driver);
 

-- 
2.44.0



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

* [PATCH RESEND v3 2/2] dmaengine: axi-dmac: move to device managed probe
@ 2024-03-28 13:58   ` Nuno Sa
  0 siblings, 0 replies; 8+ messages in thread
From: Nuno Sa @ 2024-03-28 13:58 UTC (permalink / raw)
  To: dmaengine; +Cc: Vinod Koul, Lars-Peter Clausen, Nuno Sa

In axi_dmac_probe(), there's a mix in using device managed APIs and
explicitly cleaning things in the driver .remove() hook. Move to use
device managed APIs and thus drop the .remove() hook.

Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 78 ++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 44 deletions(-)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index d5a33e4a91b1..bdb752f11869 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -1002,6 +1002,16 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
 	return 0;
 }
 
+static void axi_dmac_tasklet_kill(void *task)
+{
+	tasklet_kill(task);
+}
+
+static void axi_dmac_free_dma_controller(void *of_node)
+{
+	of_dma_controller_free(of_node);
+}
+
 static int axi_dmac_probe(struct platform_device *pdev)
 {
 	struct dma_device *dma_dev;
@@ -1025,14 +1035,10 @@ static int axi_dmac_probe(struct platform_device *pdev)
 	if (IS_ERR(dmac->base))
 		return PTR_ERR(dmac->base);
 
-	dmac->clk = devm_clk_get(&pdev->dev, NULL);
+	dmac->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(dmac->clk))
 		return PTR_ERR(dmac->clk);
 
-	ret = clk_prepare_enable(dmac->clk);
-	if (ret < 0)
-		return ret;
-
 	version = axi_dmac_read(dmac, ADI_AXI_REG_VERSION);
 
 	if (version >= ADI_AXI_PCORE_VER(4, 3, 'a'))
@@ -1041,7 +1047,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
 		ret = axi_dmac_parse_dt(&pdev->dev, dmac);
 
 	if (ret < 0)
-		goto err_clk_disable;
+		return ret;
 
 	INIT_LIST_HEAD(&dmac->chan.active_descs);
 
@@ -1072,7 +1078,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
 
 	ret = axi_dmac_detect_caps(dmac, version);
 	if (ret)
-		goto err_clk_disable;
+		return ret;
 
 	dma_dev->copy_align = (dmac->chan.address_align_mask + 1);
 
@@ -1088,57 +1094,42 @@ static int axi_dmac_probe(struct platform_device *pdev)
 		    !AXI_DMAC_DST_COHERENT_GET(ret)) {
 			dev_err(dmac->dma_dev.dev,
 				"Coherent DMA not supported in hardware");
-			ret = -EINVAL;
-			goto err_clk_disable;
+			return -EINVAL;
 		}
 	}
 
-	ret = dma_async_device_register(dma_dev);
+	ret = dmaenginem_async_device_register(dma_dev);
 	if (ret)
-		goto err_clk_disable;
+		return ret;
+
+	/*
+	 * Put the action in here so it get's done before unregistering the DMA
+	 * device.
+	 */
+	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_tasklet_kill,
+				       &dmac->chan.vchan.task);
+	if (ret)
+		return ret;
 
 	ret = of_dma_controller_register(pdev->dev.of_node,
 		of_dma_xlate_by_chan_id, dma_dev);
 	if (ret)
-		goto err_unregister_device;
+		return ret;
 
-	ret = request_irq(dmac->irq, axi_dmac_interrupt_handler, IRQF_SHARED,
-		dev_name(&pdev->dev), dmac);
+	ret = devm_add_action_or_reset(&pdev->dev, axi_dmac_free_dma_controller,
+				       pdev->dev.of_node);
 	if (ret)
-		goto err_unregister_of;
+		return ret;
 
-	platform_set_drvdata(pdev, dmac);
+	ret = devm_request_irq(&pdev->dev, dmac->irq, axi_dmac_interrupt_handler,
+			       IRQF_SHARED, dev_name(&pdev->dev), dmac);
+	if (ret)
+		return ret;
 
 	regmap = devm_regmap_init_mmio(&pdev->dev, dmac->base,
 		 &axi_dmac_regmap_config);
-	if (IS_ERR(regmap)) {
-		ret = PTR_ERR(regmap);
-		goto err_free_irq;
-	}
 
-	return 0;
-
-err_free_irq:
-	free_irq(dmac->irq, dmac);
-err_unregister_of:
-	of_dma_controller_free(pdev->dev.of_node);
-err_unregister_device:
-	dma_async_device_unregister(&dmac->dma_dev);
-err_clk_disable:
-	clk_disable_unprepare(dmac->clk);
-
-	return ret;
-}
-
-static void axi_dmac_remove(struct platform_device *pdev)
-{
-	struct axi_dmac *dmac = platform_get_drvdata(pdev);
-
-	free_irq(dmac->irq, dmac);
-	of_dma_controller_free(pdev->dev.of_node);
-	tasklet_kill(&dmac->chan.vchan.task);
-	dma_async_device_unregister(&dmac->dma_dev);
-	clk_disable_unprepare(dmac->clk);
+	return PTR_ERR_OR_ZERO(regmap);
 }
 
 static const struct of_device_id axi_dmac_of_match_table[] = {
@@ -1153,7 +1144,6 @@ static struct platform_driver axi_dmac_driver = {
 		.of_match_table = axi_dmac_of_match_table,
 	},
 	.probe = axi_dmac_probe,
-	.remove_new = axi_dmac_remove,
 };
 module_platform_driver(axi_dmac_driver);
 

-- 
2.44.0


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

* Re: [PATCH RESEND v3 0/2] dmaengine: axi-dmac: move to device managed probe
  2024-03-28 13:58 ` Nuno Sa
                   ` (2 preceding siblings ...)
  (?)
@ 2024-04-07 16:39 ` Vinod Koul
  -1 siblings, 0 replies; 8+ messages in thread
From: Vinod Koul @ 2024-04-07 16:39 UTC (permalink / raw)
  To: dmaengine, Nuno Sa; +Cc: Lars-Peter Clausen, stable


On Thu, 28 Mar 2024 14:58:49 +0100, Nuno Sa wrote:
> Added a new patch so we can easily backport a possible race in the
> unbind path.
> 
> Vinod, I'm just resending these patches again (as merge window is now
> over. I applied and compiled them on top of the next branch. Tip in:
> 
> 8b7149803af17 ("MAINTAINERS: Drop Gustavo Pimentel as EDMA Reviewer")
> 
> [...]

Applied, thanks!

[1/2] dmaengine: axi-dmac: fix possible race in remove()
      commit: 1bc31444209c8efae98cb78818131950d9a6f4d6
[2/2] dmaengine: axi-dmac: move to device managed probe
      commit: 779a44831a4f64616a2fb18256fc9c299e1c033a

Best regards,
-- 
~Vinod



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

* [PATCH RESEND v3 1/2] dmaengine: axi-dmac: fix possible race in remove()
  2024-02-29 16:23 Nuno Sa
@ 2024-02-29 16:23 ` Nuno Sa
  0 siblings, 0 replies; 8+ messages in thread
From: Nuno Sa @ 2024-02-29 16:23 UTC (permalink / raw)
  To: dmaengine; +Cc: Lars-Peter Clausen, Vinod Koul, stable

We need to first free the IRQ before calling of_dma_controller_free().
Otherwise we could get an interrupt and schedule a tasklet while
removing the DMA controller.

Fixes: 0e3b67b348b8 ("dmaengine: Add support for the Analog Devices AXI-DMAC DMA controller")
Cc: <stable@kernel.org>
Signed-off-by: Nuno Sa <nuno.sa@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 4e339c04fc1e..d5a33e4a91b1 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -1134,8 +1134,8 @@ static void axi_dmac_remove(struct platform_device *pdev)
 {
 	struct axi_dmac *dmac = platform_get_drvdata(pdev);
 
-	of_dma_controller_free(pdev->dev.of_node);
 	free_irq(dmac->irq, dmac);
+	of_dma_controller_free(pdev->dev.of_node);
 	tasklet_kill(&dmac->chan.vchan.task);
 	dma_async_device_unregister(&dmac->dma_dev);
 	clk_disable_unprepare(dmac->clk);

-- 
2.44.0


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

end of thread, other threads:[~2024-04-07 16:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-28 13:58 [PATCH RESEND v3 0/2] dmaengine: axi-dmac: move to device managed probe Nuno Sa via B4 Relay
2024-03-28 13:58 ` Nuno Sa
2024-03-28 13:58 ` [PATCH RESEND v3 1/2] dmaengine: axi-dmac: fix possible race in remove() Nuno Sa via B4 Relay
2024-03-28 13:58   ` Nuno Sa
2024-03-28 13:58 ` [PATCH RESEND v3 2/2] dmaengine: axi-dmac: move to device managed probe Nuno Sa via B4 Relay
2024-03-28 13:58   ` Nuno Sa
2024-04-07 16:39 ` [PATCH RESEND v3 0/2] " Vinod Koul
  -- strict thread matches above, loose matches on Subject: below --
2024-02-29 16:23 Nuno Sa
2024-02-29 16:23 ` [PATCH RESEND v3 1/2] dmaengine: axi-dmac: fix possible race in remove() Nuno Sa

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.