dmaengine.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features
@ 2023-03-13 17:04 Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended Jisheng Zhang
                   ` (10 more replies)
  0 siblings, 11 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

This series first fix a bug related with runtime pm. Then do three clean
up. After that, we add three new features: per channel irq support,
dma-channel-mask support and polled mode support.

Jisheng Zhang (11):
  dmaengine: dw-axi-dmac: fix reading register hen runtime suspended
  dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling
  dmaengine: dw-axi-dmac: remove unnecessary axi_dma_enable() calling
  dmaengine: dw-axi-dmac: remove redudant axi_dma_disable() calling
  dmaengine: dw-axi-dmac: delay irq getting until request_irq
  dmaengine: dw-axi-dmac: move ch irq handling into common routine
  dmaengine: dw-axi-dmac: support per channel irq
  dmaengine: dw-axi-dmac: support dma-channel-mask
  dmaengine: dw-axi-dmac: try best to get residue when tx is running
  dmaengine: dw-axi-dmac: move dma_chan_tx_status()
  dmaengine: dw-axi-dmac: support polled mode

 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 207 ++++++++++++------
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h         |   4 +
 2 files changed, 147 insertions(+), 64 deletions(-)

-- 
2.39.2


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

* [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-04-12 17:33   ` Vinod Koul
  2023-03-13 17:04 ` [PATCH 02/11] dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling Jisheng Zhang
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

We should runtime resume the device before calling
axi_chan_is_hw_enable().

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 7f3a60e28e38..23a10dbdecb7 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -462,13 +462,17 @@ static void dw_axi_dma_synchronize(struct dma_chan *dchan)
 
 static int dma_chan_alloc_chan_resources(struct dma_chan *dchan)
 {
+	int ret;
 	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
 
+	pm_runtime_get(chan->chip->dev);
+
 	/* ASSERT: channel is idle */
 	if (axi_chan_is_hw_enable(chan)) {
 		dev_err(chan2dev(chan), "%s is non-idle!\n",
 			axi_chan_name(chan));
-		return -EBUSY;
+		ret = -EBUSY;
+		goto err_busy;
 	}
 
 	/* LLI address must be aligned to a 64-byte boundary */
@@ -478,13 +482,16 @@ static int dma_chan_alloc_chan_resources(struct dma_chan *dchan)
 					  64, 0);
 	if (!chan->desc_pool) {
 		dev_err(chan2dev(chan), "No memory for descriptors\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto err_busy;
 	}
 	dev_vdbg(dchan2dev(dchan), "%s: allocating\n", axi_chan_name(chan));
 
-	pm_runtime_get(chan->chip->dev);
-
 	return 0;
+
+err_busy:
+	pm_runtime_put(chan->chip->dev);
+	return ret;
 }
 
 static void dma_chan_free_chan_resources(struct dma_chan *dchan)
-- 
2.39.2


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

* [PATCH 02/11] dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-04-12 17:38   ` Vinod Koul
  2023-03-13 17:04 ` [PATCH 03/11] dmaengine: dw-axi-dmac: remove unnecessary axi_dma_enable() calling Jisheng Zhang
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

In dw_remove(), We have disabled the irq from the dw-axi-dma side, so
we are safe against the case "The irq is still ON when devices remove
is executed and irq should be quiesced before remove is completed."

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 23a10dbdecb7..56f12dfa410d 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1542,8 +1542,6 @@ static int dw_remove(struct platform_device *pdev)
 	pm_runtime_disable(chip->dev);
 	axi_dma_suspend(chip);
 
-	devm_free_irq(chip->dev, chip->irq, chip);
-
 	of_dma_controller_free(chip->dev->of_node);
 
 	list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
-- 
2.39.2


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

* [PATCH 03/11] dmaengine: dw-axi-dmac: remove unnecessary axi_dma_enable() calling
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 02/11] dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 04/11] dmaengine: dw-axi-dmac: remove redudant axi_dma_disable() calling Jisheng Zhang
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

The dma is enabled, I.E runtime resumed during chan allocation, and
is disable, I.E runtime suspended during chan free. So when starting
xfer, we are sure the dma is enabled.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 56f12dfa410d..891776528619 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -382,8 +382,6 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
 		return;
 	}
 
-	axi_dma_enable(chan->chip);
-
 	config.dst_multblk_type = DWAXIDMAC_MBLK_TYPE_LL;
 	config.src_multblk_type = DWAXIDMAC_MBLK_TYPE_LL;
 	config.tt_fc = DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC;
-- 
2.39.2


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

* [PATCH 04/11] dmaengine: dw-axi-dmac: remove redudant axi_dma_disable() calling
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (2 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 03/11] dmaengine: dw-axi-dmac: remove unnecessary axi_dma_enable() calling Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-04-12 17:36   ` Vinod Koul
  2023-03-13 17:04 ` [PATCH 05/11] dmaengine: dw-axi-dmac: delay irq getting until request_irq Jisheng Zhang
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

axi_dma_suspend() will soon call axi_dma_disable(), remove the redudant
axi_dma_disable() callin.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 891776528619..410222e7224c 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1535,7 +1535,6 @@ static int dw_remove(struct platform_device *pdev)
 		axi_chan_disable(&chip->dw->chan[i]);
 		axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
 	}
-	axi_dma_disable(chip);
 
 	pm_runtime_disable(chip->dev);
 	axi_dma_suspend(chip);
-- 
2.39.2


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

* [PATCH 05/11] dmaengine: dw-axi-dmac: delay irq getting until request_irq
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (3 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 04/11] dmaengine: dw-axi-dmac: remove redudant axi_dma_disable() calling Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 06/11] dmaengine: dw-axi-dmac: move ch irq handling into common routine Jisheng Zhang
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

This is to prepare for per-channel irq support in next patch. In
per-channel irq case, we need to parse dt firstly to know whether
the platform is per-channel irq or not.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 410222e7224c..6087fb7d567a 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1395,10 +1395,6 @@ static int dw_probe(struct platform_device *pdev)
 	chip->dev = &pdev->dev;
 	chip->dw->hdata = hdata;
 
-	chip->irq = platform_get_irq(pdev, 0);
-	if (chip->irq < 0)
-		return chip->irq;
-
 	chip->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(chip->regs))
 		return PTR_ERR(chip->regs);
@@ -1426,6 +1422,10 @@ static int dw_probe(struct platform_device *pdev)
 	if (!dw->chan)
 		return -ENOMEM;
 
+	chip->irq = platform_get_irq(pdev, 0);
+	if (chip->irq < 0)
+		return chip->irq;
+
 	ret = devm_request_irq(chip->dev, chip->irq, dw_axi_dma_interrupt,
 			       IRQF_SHARED, KBUILD_MODNAME, chip);
 	if (ret)
-- 
2.39.2


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

* [PATCH 06/11] dmaengine: dw-axi-dmac: move ch irq handling into common routine
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (4 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 05/11] dmaengine: dw-axi-dmac: delay irq getting until request_irq Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 07/11] dmaengine: dw-axi-dmac: support per channel irq Jisheng Zhang
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

In next patch, we will add per-channel irq support, we will use the
common routine in per-channel irq handler.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 30 ++++++++++++-------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 6087fb7d567a..796fd0136781 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1101,13 +1101,30 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
 	spin_unlock_irqrestore(&chan->vc.lock, flags);
 }
 
+static void dw_axi_dma_handle_ch(struct axi_dma_chan *chan)
+{
+	u32 status;
+
+	/* Poll, clear and process this channel interrupt status */
+	status = axi_chan_irq_read(chan);
+	axi_chan_irq_clear(chan, status);
+
+	dev_vdbg(chan->chip->dev, "%s IRQ status: 0x%08x\n", axi_chan_name(chan), status);
+
+	if (status & DWAXIDMAC_IRQ_ALL_ERR)
+		axi_chan_handle_err(chan, status);
+	else if (status & DWAXIDMAC_IRQ_DMA_TRF)
+		axi_chan_block_xfer_complete(chan);
+
+}
+
 static irqreturn_t dw_axi_dma_interrupt(int irq, void *dev_id)
 {
 	struct axi_dma_chip *chip = dev_id;
 	struct dw_axi_dma *dw = chip->dw;
 	struct axi_dma_chan *chan;
 
-	u32 status, i;
+	u32 i;
 
 	/* Disable DMAC interrupts. We'll enable them after processing channels */
 	axi_dma_irq_disable(chip);
@@ -1115,16 +1132,7 @@ static irqreturn_t dw_axi_dma_interrupt(int irq, void *dev_id)
 	/* Poll, clear and process every channel interrupt status */
 	for (i = 0; i < dw->hdata->nr_channels; i++) {
 		chan = &dw->chan[i];
-		status = axi_chan_irq_read(chan);
-		axi_chan_irq_clear(chan, status);
-
-		dev_vdbg(chip->dev, "%s %u IRQ status: 0x%08x\n",
-			axi_chan_name(chan), i, status);
-
-		if (status & DWAXIDMAC_IRQ_ALL_ERR)
-			axi_chan_handle_err(chan, status);
-		else if (status & DWAXIDMAC_IRQ_DMA_TRF)
-			axi_chan_block_xfer_complete(chan);
+		dw_axi_dma_handle_ch(chan);
 	}
 
 	/* Re-enable interrupts */
-- 
2.39.2


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

* [PATCH 07/11] dmaengine: dw-axi-dmac: support per channel irq
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (5 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 06/11] dmaengine: dw-axi-dmac: move ch irq handling into common routine Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 08/11] dmaengine: dw-axi-dmac: support dma-channel-mask Jisheng Zhang
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

Each channel can have its own irq, support this case.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 48 +++++++++++++++----
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h         |  2 +
 2 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 796fd0136781..edb1c089a8eb 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1141,6 +1141,21 @@ static irqreturn_t dw_axi_dma_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t dw_axi_dma_ch_interrupt(int irq, void *dev_id)
+{
+	struct axi_dma_chan *chan = dev_id;
+
+	/* Disable DMAC interrupts. We'll enable them after processing channels */
+	axi_chan_irq_sig_set(chan, DWAXIDMAC_IRQ_NONE);
+
+	dw_axi_dma_handle_ch(chan);
+
+	/* Re-enable interrupts */
+	axi_chan_irq_sig_set(chan, DWAXIDMAC_IRQ_DMA_TRF | DWAXIDMAC_IRQ_ALL_ERR);
+
+	return IRQ_HANDLED;
+}
+
 static int dma_chan_terminate_all(struct dma_chan *dchan)
 {
 	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
@@ -1375,6 +1390,8 @@ static int parse_device_properties(struct axi_dma_chip *chip)
 		chip->dw->hdata->axi_rw_burst_len = tmp;
 	}
 
+	chip->dw->hdata->perch_irq = device_property_read_bool(dev, "snps,perch_irq");
+
 	return 0;
 }
 
@@ -1430,14 +1447,29 @@ static int dw_probe(struct platform_device *pdev)
 	if (!dw->chan)
 		return -ENOMEM;
 
-	chip->irq = platform_get_irq(pdev, 0);
-	if (chip->irq < 0)
-		return chip->irq;
-
-	ret = devm_request_irq(chip->dev, chip->irq, dw_axi_dma_interrupt,
-			       IRQF_SHARED, KBUILD_MODNAME, chip);
-	if (ret)
-		return ret;
+	if (hdata->perch_irq) {
+		char irqname[8];
+		for (i = 0; i < hdata->nr_channels; i++) {
+			snprintf(irqname, sizeof(irqname), "ch%u", i);
+			dw->chan[i].irq = platform_get_irq_byname(pdev, irqname);
+			if (dw->chan[i].irq < 0)
+				return dw->chan[i].irq;
+			ret = devm_request_irq(chip->dev, dw->chan[i].irq,
+					       dw_axi_dma_ch_interrupt,
+					       0, KBUILD_MODNAME, &dw->chan[i]);
+			if (ret)
+				return ret;
+		}
+	} else {
+		chip->irq = platform_get_irq(pdev, 0);
+		if (chip->irq < 0)
+			return chip->irq;
+
+		ret = devm_request_irq(chip->dev, chip->irq, dw_axi_dma_interrupt,
+				       IRQF_SHARED, KBUILD_MODNAME, chip);
+		if (ret)
+			return ret;
+	}
 
 	INIT_LIST_HEAD(&dw->dma.channels);
 	for (i = 0; i < hdata->nr_channels; i++) {
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index e9d5eb0fd594..83ac839b4394 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -33,6 +33,7 @@ struct dw_axi_dma_hcfg {
 	/* Register map for DMAX_NUM_CHANNELS <= 8 */
 	bool	reg_map_8_channels;
 	bool	restrict_axi_burst_len;
+	bool	perch_irq;
 };
 
 struct axi_dma_chan {
@@ -48,6 +49,7 @@ struct axi_dma_chan {
 	struct axi_dma_desc		*desc;
 	struct dma_slave_config		config;
 	enum dma_transfer_direction	direction;
+	int				irq;
 	bool				cyclic;
 	/* these other elements are all protected by vc.lock */
 	bool				is_paused;
-- 
2.39.2


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

* [PATCH 08/11] dmaengine: dw-axi-dmac: support dma-channel-mask
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (6 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 07/11] dmaengine: dw-axi-dmac: support per channel irq Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 09/11] dmaengine: dw-axi-dmac: try best to get residue when tx is running Jisheng Zhang
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

Some dma channels may not be available, so we need to tell the driver
the available dma channels, use the general dt binding
"dma-channel-mask" for this purpose.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 19 +++++++++++++++++++
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h         |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index edb1c089a8eb..a6e46cb66000 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -216,6 +216,8 @@ static void axi_dma_hw_init(struct axi_dma_chip *chip)
 	u32 i;
 
 	for (i = 0; i < chip->dw->hdata->nr_channels; i++) {
+		if (!(chip->dw->hdata->channels_mask & (1 << i)))
+			continue;
 		axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
 		axi_chan_disable(&chip->dw->chan[i]);
 	}
@@ -1390,6 +1392,14 @@ static int parse_device_properties(struct axi_dma_chip *chip)
 		chip->dw->hdata->axi_rw_burst_len = tmp;
 	}
 
+	/*
+	 * Use all channels if there's no dma-channel-mask property
+	 */
+	ret = device_property_read_u32(dev, "dma-channel-mask", &tmp);
+	if (ret)
+		tmp = GENMASK(chip->dw->hdata->nr_channels - 1, 0);
+	chip->dw->hdata->channels_mask = tmp;
+
 	chip->dw->hdata->perch_irq = device_property_read_bool(dev, "snps,perch_irq");
 
 	return 0;
@@ -1450,6 +1460,10 @@ static int dw_probe(struct platform_device *pdev)
 	if (hdata->perch_irq) {
 		char irqname[8];
 		for (i = 0; i < hdata->nr_channels; i++) {
+			if (!(hdata->channels_mask & (1 << i))) {
+				dw->chan[i].irq = -1;
+				continue;
+			}
 			snprintf(irqname, sizeof(irqname), "ch%u", i);
 			dw->chan[i].irq = platform_get_irq_byname(pdev, irqname);
 			if (dw->chan[i].irq < 0)
@@ -1475,6 +1489,9 @@ static int dw_probe(struct platform_device *pdev)
 	for (i = 0; i < hdata->nr_channels; i++) {
 		struct axi_dma_chan *chan = &dw->chan[i];
 
+		if (!(hdata->channels_mask & (1 << i)))
+			continue;
+
 		chan->chip = chip;
 		chan->id = i;
 		chan->chan_regs = chip->regs + COMMON_REG_LEN + i * CHAN_REG_LEN;
@@ -1572,6 +1589,8 @@ static int dw_remove(struct platform_device *pdev)
 	clk_prepare_enable(chip->core_clk);
 	axi_dma_irq_disable(chip);
 	for (i = 0; i < dw->hdata->nr_channels; i++) {
+		if (!(dw->hdata->channels_mask & (1 << i)))
+			continue;
 		axi_chan_disable(&chip->dw->chan[i]);
 		axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
 	}
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index 83ac839b4394..f57961620d2d 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -30,6 +30,7 @@ struct dw_axi_dma_hcfg {
 	u32	priority[DMAC_MAX_CHANNELS];
 	/* maximum supported axi burst length */
 	u32	axi_rw_burst_len;
+	u32	channels_mask;
 	/* Register map for DMAX_NUM_CHANNELS <= 8 */
 	bool	reg_map_8_channels;
 	bool	restrict_axi_burst_len;
-- 
2.39.2


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

* [PATCH 09/11] dmaengine: dw-axi-dmac: try best to get residue when tx is running
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (7 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 08/11] dmaengine: dw-axi-dmac: support dma-channel-mask Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 10/11] dmaengine: dw-axi-dmac: move dma_chan_tx_status() Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 11/11] dmaengine: dw-axi-dmac: support polled mode Jisheng Zhang
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

When tx is running, vchan_find_desc() will return NULL, try our best
to get the residue in this case.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index a6e46cb66000..1c1b9574985a 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -305,6 +305,7 @@ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
 		  struct dma_tx_state *txstate)
 {
 	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
+	struct axi_dma_desc *desc = NULL;
 	struct virt_dma_desc *vdesc;
 	enum dma_status status;
 	u32 completed_length;
@@ -322,9 +323,15 @@ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
 
 	vdesc = vchan_find_desc(&chan->vc, cookie);
 	if (vdesc) {
-		length = vd_to_axi_desc(vdesc)->length;
-		completed_blocks = vd_to_axi_desc(vdesc)->completed_blocks;
-		len = vd_to_axi_desc(vdesc)->hw_desc[0].len;
+		desc = vd_to_axi_desc(vdesc);
+	} else if (chan->desc && chan->desc->vd.tx.cookie == cookie) {
+		desc = chan->desc;
+	}
+
+	if (desc) {
+		length = desc->length;
+		completed_blocks = desc->completed_blocks;
+		len = desc->hw_desc[0].len;
 		completed_length = completed_blocks * len;
 		bytes = length - completed_length;
 	}
@@ -425,6 +432,7 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
 	axi_chan_irq_set(chan, irq_mask);
 
 	axi_chan_enable(chan);
+	chan->desc = first;
 }
 
 static void axi_chan_start_first_queued(struct axi_dma_chan *chan)
@@ -1188,6 +1196,7 @@ static int dma_chan_terminate_all(struct dma_chan *dchan)
 	spin_unlock_irqrestore(&chan->vc.lock, flags);
 
 	vchan_dma_desc_free_list(&chan->vc, &head);
+	chan->desc = NULL;
 
 	dev_vdbg(dchan2dev(dchan), "terminated: %s\n", axi_chan_name(chan));
 
-- 
2.39.2


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

* [PATCH 10/11] dmaengine: dw-axi-dmac: move dma_chan_tx_status()
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (8 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 09/11] dmaengine: dw-axi-dmac: try best to get residue when tx is running Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  2023-03-13 17:04 ` [PATCH 11/11] dmaengine: dw-axi-dmac: support polled mode Jisheng Zhang
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

We will add polled support soon, for which we need to call
dw_axi_dma_handle_ch() in dma_chan_tx_status(). Move the function
to avoid pre-declaration.

No functionality changes.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 .../dma/dw-axi-dmac/dw-axi-dmac-platform.c    | 84 +++++++++----------
 1 file changed, 42 insertions(+), 42 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 1c1b9574985a..1d00793a83bf 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -300,48 +300,6 @@ static void vchan_desc_put(struct virt_dma_desc *vdesc)
 	axi_desc_put(vd_to_axi_desc(vdesc));
 }
 
-static enum dma_status
-dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
-		  struct dma_tx_state *txstate)
-{
-	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
-	struct axi_dma_desc *desc = NULL;
-	struct virt_dma_desc *vdesc;
-	enum dma_status status;
-	u32 completed_length;
-	unsigned long flags;
-	u32 completed_blocks;
-	size_t bytes = 0;
-	u32 length;
-	u32 len;
-
-	status = dma_cookie_status(dchan, cookie, txstate);
-	if (status == DMA_COMPLETE || !txstate)
-		return status;
-
-	spin_lock_irqsave(&chan->vc.lock, flags);
-
-	vdesc = vchan_find_desc(&chan->vc, cookie);
-	if (vdesc) {
-		desc = vd_to_axi_desc(vdesc);
-	} else if (chan->desc && chan->desc->vd.tx.cookie == cookie) {
-		desc = chan->desc;
-	}
-
-	if (desc) {
-		length = desc->length;
-		completed_blocks = desc->completed_blocks;
-		len = desc->hw_desc[0].len;
-		completed_length = completed_blocks * len;
-		bytes = length - completed_length;
-	}
-
-	spin_unlock_irqrestore(&chan->vc.lock, flags);
-	dma_set_residue(txstate, bytes);
-
-	return status;
-}
-
 static void write_desc_llp(struct axi_dma_hw_desc *desc, dma_addr_t adr)
 {
 	desc->lli->llp = cpu_to_le64(adr);
@@ -1166,6 +1124,48 @@ static irqreturn_t dw_axi_dma_ch_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static enum dma_status
+dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
+		  struct dma_tx_state *txstate)
+{
+	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
+	struct axi_dma_desc *desc = NULL;
+	struct virt_dma_desc *vdesc;
+	enum dma_status status;
+	u32 completed_length;
+	unsigned long flags;
+	u32 completed_blocks;
+	size_t bytes = 0;
+	u32 length;
+	u32 len;
+
+	status = dma_cookie_status(dchan, cookie, txstate);
+	if (status == DMA_COMPLETE || !txstate)
+		return status;
+
+	spin_lock_irqsave(&chan->vc.lock, flags);
+
+	vdesc = vchan_find_desc(&chan->vc, cookie);
+	if (vdesc) {
+		desc = vd_to_axi_desc(vdesc);
+	} else if (chan->desc && chan->desc->vd.tx.cookie == cookie) {
+		desc = chan->desc;
+	}
+
+	if (desc) {
+		length = desc->length;
+		completed_blocks = desc->completed_blocks;
+		len = desc->hw_desc[0].len;
+		completed_length = completed_blocks * len;
+		bytes = length - completed_length;
+	}
+
+	spin_unlock_irqrestore(&chan->vc.lock, flags);
+	dma_set_residue(txstate, bytes);
+
+	return status;
+}
+
 static int dma_chan_terminate_all(struct dma_chan *dchan)
 {
 	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
-- 
2.39.2


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

* [PATCH 11/11] dmaengine: dw-axi-dmac: support polled mode
  2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
                   ` (9 preceding siblings ...)
  2023-03-13 17:04 ` [PATCH 10/11] dmaengine: dw-axi-dmac: move dma_chan_tx_status() Jisheng Zhang
@ 2023-03-13 17:04 ` Jisheng Zhang
  10 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-03-13 17:04 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul; +Cc: dmaengine, linux-kernel

Run in polled mode if the DMA_PREP_INTERRUPT flag is not provided.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 11 ++++++++++-
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h          |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 1d00793a83bf..8daeb22d4560 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -383,7 +383,10 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
 	write_chan_llp(chan, first->hw_desc[0].llp | lms);
 
 	irq_mask = DWAXIDMAC_IRQ_DMA_TRF | DWAXIDMAC_IRQ_ALL_ERR;
-	axi_chan_irq_sig_set(chan, irq_mask);
+	if (chan->polled)
+		axi_chan_irq_sig_set(chan, DWAXIDMAC_IRQ_NONE);
+	else
+		axi_chan_irq_sig_set(chan, irq_mask);
 
 	/* Generate 'suspend' status but don't generate interrupt */
 	irq_mask |= DWAXIDMAC_IRQ_SUSPENDED;
@@ -714,6 +717,7 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr,
 	if (unlikely(!desc))
 		goto err_desc_get;
 
+	chan->polled = !(flags & DMA_PREP_INTERRUPT);
 	chan->direction = direction;
 	desc->chan = chan;
 	chan->cyclic = true;
@@ -796,6 +800,7 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
 
 	desc->chan = chan;
 	desc->length = 0;
+	chan->polled = !(flags & DMA_PREP_INTERRUPT);
 	chan->direction = direction;
 
 	for_each_sg(sgl, sg, sg_len, i) {
@@ -859,6 +864,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
 	if (unlikely(!desc))
 		goto err_desc_get;
 
+	chan->polled = !(flags & DMA_PREP_INTERRUPT);
 	desc->chan = chan;
 	num = 0;
 	desc->length = 0;
@@ -1139,6 +1145,9 @@ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
 	u32 length;
 	u32 len;
 
+	if (chan->polled)
+		dw_axi_dma_handle_ch(chan);
+
 	status = dma_cookie_status(dchan, cookie, txstate);
 	if (status == DMA_COMPLETE || !txstate)
 		return status;
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index f57961620d2d..e4fbc38446ec 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -54,6 +54,7 @@ struct axi_dma_chan {
 	bool				cyclic;
 	/* these other elements are all protected by vc.lock */
 	bool				is_paused;
+	bool				polled;
 };
 
 struct dw_axi_dma {
-- 
2.39.2


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

* Re: [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended
  2023-03-13 17:04 ` [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended Jisheng Zhang
@ 2023-04-12 17:33   ` Vinod Koul
  2023-04-15 10:02     ` Jisheng Zhang
  0 siblings, 1 reply; 17+ messages in thread
From: Vinod Koul @ 2023-04-12 17:33 UTC (permalink / raw)
  To: Jisheng Zhang; +Cc: Eugeniy Paltsev, dmaengine, linux-kernel

s/hen/when..? or something else

On 14-03-23, 01:04, Jisheng Zhang wrote:
> We should runtime resume the device before calling
> axi_chan_is_hw_enable().

why is that can you please explain..

> 
> Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
> ---
>  drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index 7f3a60e28e38..23a10dbdecb7 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -462,13 +462,17 @@ static void dw_axi_dma_synchronize(struct dma_chan *dchan)
>  
>  static int dma_chan_alloc_chan_resources(struct dma_chan *dchan)
>  {
> +	int ret;
>  	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
>  
> +	pm_runtime_get(chan->chip->dev);
> +
>  	/* ASSERT: channel is idle */
>  	if (axi_chan_is_hw_enable(chan)) {
>  		dev_err(chan2dev(chan), "%s is non-idle!\n",
>  			axi_chan_name(chan));
> -		return -EBUSY;
> +		ret = -EBUSY;
> +		goto err_busy;
>  	}
>  
>  	/* LLI address must be aligned to a 64-byte boundary */
> @@ -478,13 +482,16 @@ static int dma_chan_alloc_chan_resources(struct dma_chan *dchan)
>  					  64, 0);
>  	if (!chan->desc_pool) {
>  		dev_err(chan2dev(chan), "No memory for descriptors\n");
> -		return -ENOMEM;
> +		ret = -ENOMEM;
> +		goto err_busy;
>  	}
>  	dev_vdbg(dchan2dev(dchan), "%s: allocating\n", axi_chan_name(chan));
>  
> -	pm_runtime_get(chan->chip->dev);
> -
>  	return 0;
> +
> +err_busy:
> +	pm_runtime_put(chan->chip->dev);
> +	return ret;
>  }
>  
>  static void dma_chan_free_chan_resources(struct dma_chan *dchan)
> -- 
> 2.39.2

-- 
~Vinod

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

* Re: [PATCH 04/11] dmaengine: dw-axi-dmac: remove redudant axi_dma_disable() calling
  2023-03-13 17:04 ` [PATCH 04/11] dmaengine: dw-axi-dmac: remove redudant axi_dma_disable() calling Jisheng Zhang
@ 2023-04-12 17:36   ` Vinod Koul
  0 siblings, 0 replies; 17+ messages in thread
From: Vinod Koul @ 2023-04-12 17:36 UTC (permalink / raw)
  To: Jisheng Zhang; +Cc: Eugeniy Paltsev, dmaengine, linux-kernel

On 14-03-23, 01:04, Jisheng Zhang wrote:
> axi_dma_suspend() will soon call axi_dma_disable(), remove the redudant

s/redudant/redundant

> axi_dma_disable() callin.
> 
> Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
> ---
>  drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index 891776528619..410222e7224c 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -1535,7 +1535,6 @@ static int dw_remove(struct platform_device *pdev)
>  		axi_chan_disable(&chip->dw->chan[i]);
>  		axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
>  	}
> -	axi_dma_disable(chip);
>  
>  	pm_runtime_disable(chip->dev);
>  	axi_dma_suspend(chip);
> -- 
> 2.39.2

-- 
~Vinod

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

* Re: [PATCH 02/11] dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling
  2023-03-13 17:04 ` [PATCH 02/11] dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling Jisheng Zhang
@ 2023-04-12 17:38   ` Vinod Koul
  2023-04-15 10:03     ` Jisheng Zhang
  0 siblings, 1 reply; 17+ messages in thread
From: Vinod Koul @ 2023-04-12 17:38 UTC (permalink / raw)
  To: Jisheng Zhang; +Cc: Eugeniy Paltsev, dmaengine, linux-kernel

On 14-03-23, 01:04, Jisheng Zhang wrote:
> In dw_remove(), We have disabled the irq from the dw-axi-dma side, so
> we are safe against the case "The irq is still ON when devices remove
> is executed and irq should be quiesced before remove is completed."

what about the interrupts which might fire spuriously after this? I
prefer to keep this explicitly here
> 
> Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
> ---
>  drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index 23a10dbdecb7..56f12dfa410d 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -1542,8 +1542,6 @@ static int dw_remove(struct platform_device *pdev)
>  	pm_runtime_disable(chip->dev);
>  	axi_dma_suspend(chip);
>  
> -	devm_free_irq(chip->dev, chip->irq, chip);
> -
>  	of_dma_controller_free(chip->dev->of_node);
>  
>  	list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
> -- 
> 2.39.2

-- 
~Vinod

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

* Re: [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended
  2023-04-12 17:33   ` Vinod Koul
@ 2023-04-15 10:02     ` Jisheng Zhang
  0 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-04-15 10:02 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Eugeniy Paltsev, dmaengine, linux-kernel

On Wed, Apr 12, 2023 at 11:03:02PM +0530, Vinod Koul wrote:
> s/hen/when..? or something else
> 
> On 14-03-23, 01:04, Jisheng Zhang wrote:
> > We should runtime resume the device before calling
> > axi_chan_is_hw_enable().
> 
> why is that can you please explain..

If the device is suspended, I.E not resumed, accessing any
registers in axi_chan_is_hw_enable() will cause cpu abort.

I will add this info into commit log of v2.

> 
> > 
> > Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
> > ---
> >  drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 15 +++++++++++----
> >  1 file changed, 11 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > index 7f3a60e28e38..23a10dbdecb7 100644
> > --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > @@ -462,13 +462,17 @@ static void dw_axi_dma_synchronize(struct dma_chan *dchan)
> >  
> >  static int dma_chan_alloc_chan_resources(struct dma_chan *dchan)
> >  {
> > +	int ret;
> >  	struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan);
> >  
> > +	pm_runtime_get(chan->chip->dev);
> > +
> >  	/* ASSERT: channel is idle */
> >  	if (axi_chan_is_hw_enable(chan)) {
> >  		dev_err(chan2dev(chan), "%s is non-idle!\n",
> >  			axi_chan_name(chan));
> > -		return -EBUSY;
> > +		ret = -EBUSY;
> > +		goto err_busy;
> >  	}
> >  
> >  	/* LLI address must be aligned to a 64-byte boundary */
> > @@ -478,13 +482,16 @@ static int dma_chan_alloc_chan_resources(struct dma_chan *dchan)
> >  					  64, 0);
> >  	if (!chan->desc_pool) {
> >  		dev_err(chan2dev(chan), "No memory for descriptors\n");
> > -		return -ENOMEM;
> > +		ret = -ENOMEM;
> > +		goto err_busy;
> >  	}
> >  	dev_vdbg(dchan2dev(dchan), "%s: allocating\n", axi_chan_name(chan));
> >  
> > -	pm_runtime_get(chan->chip->dev);
> > -
> >  	return 0;
> > +
> > +err_busy:
> > +	pm_runtime_put(chan->chip->dev);
> > +	return ret;
> >  }
> >  
> >  static void dma_chan_free_chan_resources(struct dma_chan *dchan)
> > -- 
> > 2.39.2
> 
> -- 
> ~Vinod

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

* Re: [PATCH 02/11] dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling
  2023-04-12 17:38   ` Vinod Koul
@ 2023-04-15 10:03     ` Jisheng Zhang
  0 siblings, 0 replies; 17+ messages in thread
From: Jisheng Zhang @ 2023-04-15 10:03 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Eugeniy Paltsev, dmaengine, linux-kernel

On Wed, Apr 12, 2023 at 11:08:16PM +0530, Vinod Koul wrote:
> On 14-03-23, 01:04, Jisheng Zhang wrote:
> > In dw_remove(), We have disabled the irq from the dw-axi-dma side, so
> > we are safe against the case "The irq is still ON when devices remove
> > is executed and irq should be quiesced before remove is completed."
> 
> what about the interrupts which might fire spuriously after this? I

This is impossible becuase the irq has been disabled from the dw-axi-dma
side.

> prefer to keep this explicitly here
> > 
> > Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
> > ---
> >  drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > index 23a10dbdecb7..56f12dfa410d 100644
> > --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> > @@ -1542,8 +1542,6 @@ static int dw_remove(struct platform_device *pdev)
> >  	pm_runtime_disable(chip->dev);
> >  	axi_dma_suspend(chip);
> >  
> > -	devm_free_irq(chip->dev, chip->irq, chip);
> > -
> >  	of_dma_controller_free(chip->dev->of_node);
> >  
> >  	list_for_each_entry_safe(chan, _chan, &dw->dma.channels,
> > -- 
> > 2.39.2
> 
> -- 
> ~Vinod

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

end of thread, other threads:[~2023-04-15 10:14 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-13 17:04 [PATCH 00/11] dmaengine: dw-axi_dmac: bug fix clean up and more features Jisheng Zhang
2023-03-13 17:04 ` [PATCH 01/11] dmaengine: dw-axi-dmac: fix reading register hen runtime suspended Jisheng Zhang
2023-04-12 17:33   ` Vinod Koul
2023-04-15 10:02     ` Jisheng Zhang
2023-03-13 17:04 ` [PATCH 02/11] dmaengine: dw-axi-dmac: remove unnecessary devm_free_irq() calling Jisheng Zhang
2023-04-12 17:38   ` Vinod Koul
2023-04-15 10:03     ` Jisheng Zhang
2023-03-13 17:04 ` [PATCH 03/11] dmaengine: dw-axi-dmac: remove unnecessary axi_dma_enable() calling Jisheng Zhang
2023-03-13 17:04 ` [PATCH 04/11] dmaengine: dw-axi-dmac: remove redudant axi_dma_disable() calling Jisheng Zhang
2023-04-12 17:36   ` Vinod Koul
2023-03-13 17:04 ` [PATCH 05/11] dmaengine: dw-axi-dmac: delay irq getting until request_irq Jisheng Zhang
2023-03-13 17:04 ` [PATCH 06/11] dmaengine: dw-axi-dmac: move ch irq handling into common routine Jisheng Zhang
2023-03-13 17:04 ` [PATCH 07/11] dmaengine: dw-axi-dmac: support per channel irq Jisheng Zhang
2023-03-13 17:04 ` [PATCH 08/11] dmaengine: dw-axi-dmac: support dma-channel-mask Jisheng Zhang
2023-03-13 17:04 ` [PATCH 09/11] dmaengine: dw-axi-dmac: try best to get residue when tx is running Jisheng Zhang
2023-03-13 17:04 ` [PATCH 10/11] dmaengine: dw-axi-dmac: move dma_chan_tx_status() Jisheng Zhang
2023-03-13 17:04 ` [PATCH 11/11] dmaengine: dw-axi-dmac: support polled mode Jisheng Zhang

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).