Skip to contentSkip to conversation

dma: tegra: register as an OF DMA controller

PATCH Superseded Stephen Warren 5 participants 16 messages Nov 25, 2013 – Dec 6, 2013

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

From: Stephen Warren <[email protected]>

Call of_dma_controller_register() so that DMA clients can look up the Tegra DMA controller using standard APIs. This requires the OF filter function to save off the DMA slave ID, and for tegra_dma_slave_config() not to over-write this information; once DMA client drivers are converted to dma_request_slave_channel() and DT-based lookups, they won't set this field of struct dma_slave_config anymore.

Cc treding at nvidia.com
Cc pdeschrijver at nvidia.com
Cc linux-tegra at vger.kernel.org
Cc linux-arm-kernel at lists.infradead.org
Cc Dan Williams <[email protected]>
Cc Vinod Koul <[email protected]>
Cc dmaengine at vger.kernel.org

---
v2: Use of_dma_slave_xlate() rather than of_dma_simple_xlate(), as
suggested by Arnd Bergmann.

This patch is part of a series with strong internal depdendencies. I'm looking for an ack so that I can take the entire series through the Tegra and arm-soc trees. The series will be part of a stable branch that can be merged into other subsystems if needed to avoid/resolve dependencies.

---
 drivers/dma/tegra20-apb-dma.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)
drivers/dma/tegra20-apb-dma.c +34 -3
index afa5844c9346..206edd11fd2f 100644
@@ -1,7 +1,7 @@
 /*
  * DMA driver for Nvidia's Tegra20 APB DMA controller.
  *
- * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_dma.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
@@ -199,6 +200,7 @@ struct tegra_dma_channel {
 	void			*callback_param;
 
 	/* Channel-slave specific configuration */
+	unsigned int slave_id;
 	struct dma_slave_config dma_sconfig;
 	struct tegra_dma_channel_regs	channel_reg;
 };
@@ -206,6 +208,7 @@ struct tegra_dma_channel {
 /* tegra_dma: Tegra DMA specific information */
 struct tegra_dma {
 	struct dma_device		dma_dev;
+	struct of_dma_slave_xlate_info	xlate_info;
 	struct device			*dev;
 	struct clk			*dma_clk;
 	struct reset_control		*rst;
@@ -340,6 +343,8 @@ static int tegra_dma_slave_config(struct dma_chan *dc,
 	}
 
 	memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
+	if (!tdc->slave_id)
+		tdc->slave_id = sconfig->slave_id;
 	tdc->config_init = true;
 	return 0;
 }
@@ -942,7 +947,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
 	ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
 
 	csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW;
-	csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
+	csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
 	if (flags & DMA_PREP_INTERRUPT)
 		csr |= TEGRA_APBDMA_CSR_IE_EOC;
 
@@ -1086,7 +1091,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
 	csr |= TEGRA_APBDMA_CSR_FLOW;
 	if (flags & DMA_PREP_INTERRUPT)
 		csr |= TEGRA_APBDMA_CSR_IE_EOC;
-	csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
+	csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
 
 	apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
 
@@ -1206,6 +1211,18 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
 		kfree(sg_req);
 	}
 	clk_disable_unprepare(tdma->dma_clk);
+
+	tdc->slave_id = 0;
+}
+
+static int tegra_dma_of_xlate_post_alloc(struct dma_chan *chan,
+					 struct of_phandle_args *dma_spec)
+{
+	struct tegra_dma_channel *tdc = to_tegra_dma_chan(chan);
+
+	tdc->slave_id = dma_spec->args[0];
+
+	return 0;
 }
 
 /* Tegra20 specific DMA controller information */
@@ -1245,6 +1262,8 @@ static const struct of_device_id tegra_dma_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_dma_of_match);
 
+static struct platform_driver tegra_dmac_driver;
+
 static int tegra_dma_probe(struct platform_device *pdev)
 {
 	struct resource	*res;
@@ -1383,10 +1402,22 @@ static int tegra_dma_probe(struct platform_device *pdev)
 		goto err_irq;
 	}
 
+	tdma->xlate_info.device = &tdma->dma_dev;
+	tdma->xlate_info.post_alloc = tegra_dma_of_xlate_post_alloc;
+	ret = of_dma_controller_register(pdev->dev.of_node,
+					 of_dma_slave_xlate, &tdma->xlate_info);
+	if (ret < 0) {
+		dev_err(&pdev->dev,
+			"Tegra20 APB DMA OF registration failed %d\n", ret);
+		goto err_unregister_dma_dev;
+	}
+
 	dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n",
 			cdata->nr_channels);
 	return 0;
 
+err_unregister_dma_dev:
+	dma_async_device_unregister(&tdma->dma_dev);
 err_irq:
 	while (--i >= 0) {
 		struct tegra_dma_channel *tdc = &tdma->channels[i];
Signature · 1 line
1.8.1.5
#1 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 7 lines · On Monday 25 November 2013 14:53:36 Stephen Warren wrote:

v2: Use of_dma_slave_xlate() rather than of_dma_simple_xlate(), as
suggested by Arnd Bergmann.

This patch is part of a series with strong internal depdendencies. I'm looking for an ack so that I can take the entire series through the Tegra and arm-soc trees. The series will be part of a stable branch that can be merged into other subsystems if needed to avoid/resolve dependencies.

Did I suggest of_dma_slave_xlate()? I don't think I've actually heard of that function, and I can't find anything in the kernel source or using google.

Why not just use an open-coded xlate function?

Arnd

#2 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 9 lines · Arnd Bergmann
Quoted 7 lines · On Monday 25 November 2013 14:53:36 Stephen Warren wrote:

v2: Use of_dma_slave_xlate() rather than of_dma_simple_xlate(), as
suggested by Arnd Bergmann.

This patch is part of a series with strong internal depdendencies. I'm looking for an ack so that I can take the entire series through the Tegra and arm-soc trees. The series will be part of a stable branch that can be merged into other subsystems if needed to avoid/resolve dependencies.

Quoted 5 lines

Did I suggest of_dma_slave_xlate()? I don't think I've actually heard of that function, and I can't find anything in the kernel source or using google.

Why not just use an open-coded xlate function?

Well, you suggested not using of_dma_simple_xlate() since it wasn't appropriate. I then started to implement an open-coded xlate function, but found that it was 99% identical to the same thing in the mmp driver, and hence created a common of_dma_slave_xlate() so as not to just cut/paste it everywhere. Unfortunately, I only sent that patch to dmaengine at vger.kernel.org and the DMA maintainers, and there's no archive of that list:-(

#3 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 16 lines · Stephen Warren
Quoted 9 lines · Arnd Bergmann
Quoted 7 lines · On Monday 25 November 2013 14:53:36 Stephen Warren wrote:

v2: Use of_dma_slave_xlate() rather than of_dma_simple_xlate(), as
suggested by Arnd Bergmann.

This patch is part of a series with strong internal depdendencies. I'm looking for an ack so that I can take the entire series through the Tegra and arm-soc trees. The series will be part of a stable branch that can be merged into other subsystems if needed to avoid/resolve dependencies.

Quoted 5 lines

Did I suggest of_dma_slave_xlate()? I don't think I've actually heard of that function, and I can't find anything in the kernel source or using google.

Why not just use an open-coded xlate function?

Quoted 7 lines

Well, you suggested not using of_dma_simple_xlate() since it wasn't appropriate. I then started to implement an open-coded xlate function, but found that it was 99% identical to the same thing in the mmp driver, and hence created a common of_dma_slave_xlate() so as not to just cut/paste it everywhere. Unfortunately, I only sent that patch to dmaengine at vger.kernel.org and the DMA maintainers, and there's no archive of that list:-(

There is, however, an archive of the patches:

dma: add common of_dma_slave_xlate()
https://patchwork.kernel.org/patch/3234751/

dma: mmp_pdma: use of_dma_slave_xlate()
https://patchwork.kernel.org/patch/3234761/

..btw I think we should squash those two together.

#4 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 25 lines · Dan Williams
Quoted 16 lines · Stephen Warren
Quoted 9 lines · Arnd Bergmann
Quoted 7 lines · On Monday 25 November 2013 14:53:36 Stephen Warren wrote:

v2: Use of_dma_slave_xlate() rather than of_dma_simple_xlate(), as
suggested by Arnd Bergmann.

This patch is part of a series with strong internal depdendencies. I'm looking for an ack so that I can take the entire series through the Tegra and arm-soc trees. The series will be part of a stable branch that can be merged into other subsystems if needed to avoid/resolve dependencies.

Quoted 5 lines

Did I suggest of_dma_slave_xlate()? I don't think I've actually heard of that function, and I can't find anything in the kernel source or using google.

Why not just use an open-coded xlate function?

Quoted 7 lines

Well, you suggested not using of_dma_simple_xlate() since it wasn't appropriate. I then started to implement an open-coded xlate function, but found that it was 99% identical to the same thing in the mmp driver, and hence created a common of_dma_slave_xlate() so as not to just cut/paste it everywhere. Unfortunately, I only sent that patch to dmaengine at vger.kernel.org and the DMA maintainers, and there's no archive of that list:-(

Quoted 7 lines

There is, however, an archive of the patches:

dma: add common of_dma_slave_xlate()
https://patchwork.kernel.org/patch/3234751/

dma: mmp_pdma: use of_dma_slave_xlate()
https://patchwork.kernel.org/patch/3234761/

Ah, that's useful.

Quoted 1 line

..btw I think we should squash those two together.

Isn't it more typical to do core work in one patch, then port each driver individually? That keeps the patches small and logically distinct, which could help bisect in some cases. But I guess I can go either way.

#5 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 34 lines · Stephen Warren
Quoted 25 lines · Dan Williams
Quoted 16 lines · Stephen Warren
Quoted 9 lines · Arnd Bergmann
Quoted 7 lines · On Monday 25 November 2013 14:53:36 Stephen Warren wrote:

v2: Use of_dma_slave_xlate() rather than of_dma_simple_xlate(), as
suggested by Arnd Bergmann.

This patch is part of a series with strong internal depdendencies. I'm looking for an ack so that I can take the entire series through the Tegra and arm-soc trees. The series will be part of a stable branch that can be merged into other subsystems if needed to avoid/resolve dependencies.

Quoted 5 lines

Did I suggest of_dma_slave_xlate()? I don't think I've actually heard of that function, and I can't find anything in the kernel source or using google.

Why not just use an open-coded xlate function?

Quoted 7 lines

Well, you suggested not using of_dma_simple_xlate() since it wasn't appropriate. I then started to implement an open-coded xlate function, but found that it was 99% identical to the same thing in the mmp driver, and hence created a common of_dma_slave_xlate() so as not to just cut/paste it everywhere. Unfortunately, I only sent that patch to dmaengine at vger.kernel.org and the DMA maintainers, and there's no archive of that list:-(

Quoted 7 lines

There is, however, an archive of the patches:

dma: add common of_dma_slave_xlate()
https://patchwork.kernel.org/patch/3234751/

dma: mmp_pdma: use of_dma_slave_xlate()
https://patchwork.kernel.org/patch/3234761/

Quoted 8 lines

Ah, that's useful.

Quoted 1 line

..btw I think we should squash those two together.

Isn't it more typical to do core work in one patch, then port each driver individually? That keeps the patches small and logically distinct, which could help bisect in some cases. But I guess I can go either way.

Including a user conversion in the same patch that introduces the api change makes it clear what is going on... for example a reviewer could see that the code comes from mmp_pdma unmolested. Inevitably the first question is always "show me the user". The bisect case is also a good example. Since the api change by itself dead code if we revert the only user we implicitly want to revert the core change.

#6 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

In reply to Stephen Warren
Quoted 7 lines · Stephen Warren

Well, you suggested not using of_dma_simple_xlate() since it wasn't appropriate. I then started to implement an open-coded xlate function, but found that it was 99% identical to the same thing in the mmp driver, and hence created a common of_dma_slave_xlate() so as not to just cut/paste it everywhere. Unfortunately, I only sent that patch to dmaengine at vger.kernel.org and the DMA maintainers, and there's no archive of that list:-(

Ok, I see. However, I think the need for nontrivial code to be duplicated across drivers is not a sign that we are missing a generic xlate function and another indirection level, but rather that we got the interface for dma_get_slave_channel() wrong (yes, that would be my fault).

Can you try coming up with a different method to achieve the same where you use a different helper from the driver specific xlate function that does not require a callback?

I think dma_get_slave_channel is great if you have one channel per request line and you can directly look up the channel from the DT data, but it is not good if you have pick a channel and work around the race.

Arnd

#7 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 14 lines · Arnd Bergmann
Quoted 7 lines · Stephen Warren

Well, you suggested not using of_dma_simple_xlate() since it wasn't appropriate. I then started to implement an open-coded xlate function, but found that it was 99% identical to the same thing in the mmp driver, and hence created a common of_dma_slave_xlate() so as not to just cut/paste it everywhere. Unfortunately, I only sent that patch to dmaengine at vger.kernel.org and the DMA maintainers, and there's no archive of that list:-(

Ok, I see. However, I think the need for nontrivial code to be duplicated across drivers is not a sign that we are missing a generic xlate function and another indirection level, but rather that we got the interface for dma_get_slave_channel() wrong (yes, that would be my fault).

Quoted 8 lines

Can you try coming up with a different method to achieve the same where you use a different helper from the driver specific xlate function that does not require a callback?

I think dma_get_slave_channel is great if you have one channel per request line and you can directly look up the channel from the DT data, but it is not good if you have pick a channel and work around the race.

Hmm. Can you take a look at "[PATCH V4] dma: add dma_get_any_slave_channel(), for use in of_xlate()" at the link below. It still implements this via xlate, but I don't see any benefit in making drivers use a different API to request slave channels based on how the DMA controller works.

http://lkml.org/lkml/2013/11/26/408

#8 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 11 lines · Stephen Warren
Quoted 8 lines · Arnd Bergmann

Can you try coming up with a different method to achieve the same where you use a different helper from the driver specific xlate function that does not require a callback?

I think dma_get_slave_channel is great if you have one channel per request line and you can directly look up the channel from the DT data, but it is not good if you have pick a channel and work around the race.

Quoted 8 lines

Hmm. Can you take a look at "[PATCH V4] dma: add dma_get_any_slave_channel(), for use in of_xlate()" at the link below. It still implements this via xlate, but I don't see any benefit in making drivers use a different API to request slave channels based on how the DMA controller works.

http://lkml.org/lkml/2013/11/26/408

Yes, I think that is good. I can think of a few variations of that that I would prefer slightly over your code, but it's essentially what I had in mind and I'm fine with that version getting merged as well. Here are my ideas for further improvements, I'll leave it up to you and the dmaengine maintainers to decide what to do about them:

* Rather than calling private_candidate(), open-code the part you need and remove the pointless dma_cap_mask comparison:

	err = -EBUSY;
        list_for_each_entry(chan, &dev->channels, device_node) {
                if (!chan->client_count) {
			err = dma_chan_get(chan);
			break;
		}
	}

* Merge the new function with dma_get_slave_channel(). They really do different things, but I think it still makes sense as an API to require to always pass the dma_device pointer, and drivers that want to get an arbitrary channel can just pass NULL as the channel pointer.

Arnd

#9 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 30 lines · Arnd Bergmann
Quoted 11 lines · Stephen Warren
Quoted 8 lines · Arnd Bergmann

Can you try coming up with a different method to achieve the same where you use a different helper from the driver specific xlate function that does not require a callback?

I think dma_get_slave_channel is great if you have one channel per request line and you can directly look up the channel from the DT data, but it is not good if you have pick a channel and work around the race.

Quoted 7 lines

Hmm. Can you take a look at "[PATCH V4] dma: add dma_get_any_slave_channel(), for use in of_xlate()" at the link below. It still implements this via xlate, but I don't see any benefit in making drivers use a different API to request slave channels based on how the DMA controller works.

http://lkml.org/lkml/2013/11/26/408

Yes, I think that is good. I can think of a few variations of that that I would prefer slightly over your code, but it's essentially what I had in mind and I'm fine with that version getting merged as well. Here are my ideas for further improvements, I'll leave it up to you and the dmaengine maintainers to decide what to do about them:

* Rather than calling private_candidate(), open-code the part you need and remove the pointless dma_cap_mask comparison:

Quoted 7 lines
	err = -EBUSY;
        list_for_each_entry(chan, &dev->channels, device_node) {
                if (!chan->client_count) {
			err = dma_chan_get(chan);
			break;
		}
	}

Lars-Peter had specifically suggested to call private_candidate(). Lars, what do you think about open-coding this? Arnd's suggestion would skip the DMA_PRIVATE checking that private_candidate() does, and I'm not sure what the implications of that would be.

Quoted 5 lines

* Merge the new function with dma_get_slave_channel(). They really do different things, but I think it still makes sense as an API to require to always pass the dma_device pointer, and drivers that want to get an arbitrary channel can just pass NULL as the channel pointer.

I suppose one could do that, although the two operations seem pretty semantically different to me, such that merging them doesn't seem correct.

#10 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 39 lines · Stephen Warren
Quoted 30 lines · Arnd Bergmann
Quoted 11 lines · Stephen Warren
Quoted 8 lines · Arnd Bergmann

Can you try coming up with a different method to achieve the same where you use a different helper from the driver specific xlate function that does not require a callback?

I think dma_get_slave_channel is great if you have one channel per request line and you can directly look up the channel from the DT data, but it is not good if you have pick a channel and work around the race.

Quoted 7 lines

Hmm. Can you take a look at "[PATCH V4] dma: add dma_get_any_slave_channel(), for use in of_xlate()" at the link below. It still implements this via xlate, but I don't see any benefit in making drivers use a different API to request slave channels based on how the DMA controller works.

http://lkml.org/lkml/2013/11/26/408

Yes, I think that is good. I can think of a few variations of that that I would prefer slightly over your code, but it's essentially what I had in mind and I'm fine with that version getting merged as well. Here are my ideas for further improvements, I'll leave it up to you and the dmaengine maintainers to decide what to do about them:

* Rather than calling private_candidate(), open-code the part you need and remove the pointless dma_cap_mask comparison:

Quoted 7 lines
	err = -EBUSY;
        list_for_each_entry(chan, &dev->channels, device_node) {
                if (!chan->client_count) {
			err = dma_chan_get(chan);
			break;
		}
	}
Quoted 4 lines

Lars-Peter had specifically suggested to call private_candidate(). Lars, what do you think about open-coding this? Arnd's suggestion would skip the DMA_PRIVATE checking that private_candidate() does, and I'm not sure what the implications of that would be.

It's not like this is a hot path or that the mask checking is expensive. I'd keep it as it is for the sake of not having the same code twice. And the DMA_PRIVATE check should probably also stay.

- Lars

#11 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

In reply to Arnd Bergmann
Quoted 39 lines · Arnd Bergmann
Quoted 11 lines · Stephen Warren
Quoted 8 lines · Arnd Bergmann

Can you try coming up with a different method to achieve the same where you use a different helper from the driver specific xlate function that does not require a callback?

I think dma_get_slave_channel is great if you have one channel per request line and you can directly look up the channel from the DT data, but it is not good if you have pick a channel and work around the race.

Quoted 8 lines

Hmm. Can you take a look at "[PATCH V4] dma: add dma_get_any_slave_channel(), for use in of_xlate()" at the link below. It still implements this via xlate, but I don't see any benefit in making drivers use a different API to request slave channels based on how the DMA controller works.

http://lkml.org/lkml/2013/11/26/408

Yes, I think that is good. I can think of a few variations of that that I would prefer slightly over your code, but it's essentially what I had in mind and I'm fine with that version getting merged as well. Here are my ideas for further improvements, I'll leave it up to you and the dmaengine maintainers to decide what to do about them:

* Rather than calling private_candidate(), open-code the part you need and remove the pointless dma_cap_mask comparison:

        err = -EBUSY;
        list_for_each_entry(chan, &dev->channels, device_node) {
                if (!chan->client_count) {
                        err = dma_chan_get(chan);
                        break;
                }
        }
Quoted 6 lines

* Merge the new function with dma_get_slave_channel(). They really do different things, but I think it still makes sense as an API to require to always pass the dma_device pointer, and drivers that want to get an arbitrary channel can just pass NULL as the channel pointer.

* nod.

I have a similar reaction to dma_request_channel(). There should be more than enough use case to find some common ground and reduce the need for magic filter routines.

#12 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 5 lines · Dan Williams

* nod.

I have a similar reaction to dma_request_channel(). There should be more than enough use case to find some common ground and reduce the need for magic filter routines.

Right. I didn't really like the addition of the _compat variant, though I can see how it helps drivers that are transitioning from pdata to DT probing. Once we have progressed enough with the ARM DT conversion, a lot of those can surely be converted back to plain dma_request_slave_channel(), and if a significant number remain that won't use DT, we can come up with a way to use the same interface using the equivalent of clkdev to connect devices to request lines.

Also, once things have cooled down a little, we can do a mass-conversion to the ERR_PTR variant and kill off the ones that just return NULL on error.

Looking at the slave drivers that use the old dma_request_channel(), I see these classes that are not moving to DT:

* Atmel arch/avr32 (some shared with ARM mach-at91, using DT there)
* Renesas arch/sh (some shared with ARM shmobile, using DT there)
* x86 topcliff/PCH
* mfd/timberdale
* ARM ep93xx, sa11x0

The other ones are all ARM or PowerPC platforms that should migrate to describing their DMA channels in DT in the future and kill their filter functions.

Arnd

#13 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

In reply to Stephen Warren

On Mon, Nov 25, 2013 at 02:53:36PM -0700, Stephen Warren wrote:
[...]

drivers/dma/tegra20-apb-dma.c static int tegra_dma_slave_config(struct dma_chan *dc, · line 348

Quoted 4 lines
drivers/dma/tegra20-apb-dma.c +2 -0
 	memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
+	if (!tdc->slave_id)
+		tdc->slave_id = sconfig->slave_id;
 	tdc->config_init = true;

This could use some blank lines to unclutter it a bit.

drivers/dma/tegra20-apb-dma.c static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( · line 950

Quoted 8 lines
drivers/dma/tegra20-apb-dma.c +1 -1
 	return 0;
 }
@@ -942,7 +947,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
 	ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
 
 	csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW;
-	csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
+	csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;

Perhaps I'm missing something, but couldn't we reuse the .slave_id field of struct dma_slave_config? It seems like it might be overwritten by the DMA engine core or users when they call dmaengine_slave_config().

But wouldn't it be better to have the core take care of all the slave ID management, so we don't have to jump through hoops? Or perhaps the concept isn't general enough to map well to other drivers.

drivers/dma/tegra20-apb-dma.c static const struct of_device_id tegra_dma_of_match[] = { · line 1266

Quoted 7 lines
drivers/dma/tegra20-apb-dma.c +2 -0
 /* Tegra20 specific DMA controller information */
@@ -1245,6 +1262,8 @@ static const struct of_device_id tegra_dma_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_dma_of_match);
 
+static struct platform_driver tegra_dmac_driver;
+

This doesn't seem to be used anymore.

Quoted 6 lines
drivers/dma/tegra20-apb-dma.c +0 -0
 static int tegra_dma_probe(struct platform_device *pdev)
 {
 	struct resource	*res;
@@ -1383,10 +1402,22 @@ static int tegra_dma_probe(struct platform_device *pdev)
 		goto err_irq;
 	}

drivers/dma/tegra20-apb-dma.c static int tegra_dma_probe(struct platform_device *pdev) · line 1413

Quoted 10 lines
drivers/dma/tegra20-apb-dma.c +9 -0
 
+	tdma->xlate_info.device = &tdma->dma_dev;
+	tdma->xlate_info.post_alloc = tegra_dma_of_xlate_post_alloc;
+	ret = of_dma_controller_register(pdev->dev.of_node,
+					 of_dma_slave_xlate, &tdma->xlate_info);
+	if (ret < 0) {
+		dev_err(&pdev->dev,
+			"Tegra20 APB DMA OF registration failed %d\n", ret);
+		goto err_unregister_dma_dev;
+	}

Would it be useful to move this into the core and have it register the OF parts transparently to the driver? That's of course nothing that should be done in this patch.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131129/c1550f62/attachment.sig>

#14 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 7 lines · Thierry Reding

On Mon, Nov 25, 2013 at 02:53:36PM -0700, Stephen Warren wrote:
[...]

Quoted 3 lines

memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); + if
(!tdc->slave_id) + tdc->slave_id = sconfig->slave_id;
tdc->config_init = true;

This could use some blank lines to unclutter it a bit.

To be honest, I feel the opposite; random blank lines sprinkled in the middle of related code make the code structure harder to follow.

Quoted 4 lines
Quoted 4 lines
(quoted diff) +0 -0
@@ -942,7 +947,7 @@ static struct dma_async_tx_descriptor
 *tegra_dma_prep_slave_sg( ahb_seq |=
 TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
 
Quoted 8 lines
Quoted 3 lines

csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; - csr |=
tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; + csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;

Perhaps I'm missing something, but couldn't we reuse the .slave_id field of struct dma_slave_config? It seems like it might be overwritten by the DMA engine core or users when they call dmaengine_slave_config().

The slave ID seems channel-specific to me, and hence should be managed at the channel level. struct dma_slave_config is the client-specified runtime properties. As you mention, I also worry about client drivers trampling over the dma_slave_config data, so storing it where they can't doesn't seem like a good idea.

Quoted 4 lines

But wouldn't it be better to have the core take care of all the slave ID management, so we don't have to jump through hoops? Or perhaps the concept isn't general enough to map well to other drivers.

It's a HW specific detail, I think. At least, the representation of the data in a DT binding is, and hence so is the parsing of the data from DT. The rest of the code that's in the driver re: slave ID is trivial enough it doesn't seem worth sharing. And in fact, once this series is done, we can even remove the conditional assignments to slave_id and require that it be provided by DT and never from dma_slave_config, which simplifies it even further.

Quoted 4 lines
Quoted 4 lines

static int tegra_dma_probe(struct platform_device *pdev) { struct
resource *res; @@ -1383,10 +1402,22 @@ static int
tegra_dma_probe(struct platform_device *pdev) goto err_irq; }

Quoted 10 lines
Quoted 6 lines
(quoted diff) +1 -0
+	tdma->xlate_info.device = &tdma->dma_dev; +

tdma->xlate_info.post_alloc = tegra_dma_of_xlate_post_alloc; + ret = of_dma_controller_register(pdev->dev.of_node, +
of_dma_slave_xlate, &tdma->xlate_info); + if (ret < 0) { +
dev_err(&pdev->dev, + "Tegra20 APB DMA OF registration failed
%d\n", ret); + goto err_unregister_dma_dev; + }

Would it be useful to move this into the core and have it register the OF parts transparently to the driver? That's of course nothing that should be done in this patch.

That'd probably be possible, yes, given a few extra fields in struct dma_device, e.g. for the of_xlate function pointer. As you say, I won't address it in this patch though.

#15 lore raw

PATCH v2 1/1 dma: tegra: register as an OF DMA controller

Quoted 11 lines · Stephen Warren
Quoted 7 lines · Thierry Reding

On Mon, Nov 25, 2013 at 02:53:36PM -0700, Stephen Warren wrote:
[...]

Quoted 3 lines

memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); + if
(!tdc->slave_id) + tdc->slave_id = sconfig->slave_id;
tdc->config_init = true;

This could use some blank lines to unclutter it a bit.

To be honest, I feel the opposite; random blank lines sprinkled in the middle of related code make the code structure harder to follow.

I don't think they are random at all, but we can probably go on arguing about that for a long time. So if you prefer to keep it cluttered, feel free to do so. =P

Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
(quoted diff) +0 -0
@@ -942,7 +947,7 @@ static struct dma_async_tx_descriptor
 *tegra_dma_prep_slave_sg( ahb_seq |=
 TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
 
Quoted 8 lines
Quoted 3 lines

csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; - csr |=
tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; + csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;

Perhaps I'm missing something, but couldn't we reuse the .slave_id field of struct dma_slave_config? It seems like it might be overwritten by the DMA engine core or users when they call dmaengine_slave_config().

Quoted 5 lines

The slave ID seems channel-specific to me, and hence should be managed at the channel level. struct dma_slave_config is the client-specified runtime properties. As you mention, I also worry about client drivers trampling over the dma_slave_config data, so storing it where they can't doesn't seem like a good idea.

I think you meant "does seem like a good idea"? The reason why this had me puzzled is probably that I haven't seen this pattern in subsystems I'm more familiar with. Like you said, it seems like a channel-specific property, so clients should have no business modifying it.

But I assume there were valid reasons for doing things this way, so I withdraw my objections.

Quoted 15 lines
Quoted 4 lines
Quoted 4 lines

static int tegra_dma_probe(struct platform_device *pdev) { struct
resource *res; @@ -1383,10 +1402,22 @@ static int
tegra_dma_probe(struct platform_device *pdev) goto err_irq; }

Quoted 10 lines
Quoted 6 lines
(quoted diff) +1 -0
+	tdma->xlate_info.device = &tdma->dma_dev; +

tdma->xlate_info.post_alloc = tegra_dma_of_xlate_post_alloc; + ret = of_dma_controller_register(pdev->dev.of_node, +
of_dma_slave_xlate, &tdma->xlate_info); + if (ret < 0) { +
dev_err(&pdev->dev, + "Tegra20 APB DMA OF registration failed
%d\n", ret); + goto err_unregister_dma_dev; + }

Would it be useful to move this into the core and have it register the OF parts transparently to the driver? That's of course nothing that should be done in this patch.

Quoted 3 lines

That'd probably be possible, yes, given a few extra fields in struct dma_device, e.g. for the of_xlate function pointer. As you say, I won't address it in this patch though.

Okay, that's fine.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20131204/a2e263e8/attachment.sig>