diff mbox

[1/1] dt: Add general DMA window parser

Message ID 20120418.131907.2172387798112620167.hdoyu@nvidia.com
State New
Headers show

Commit Message

Hiroshi Doyu April 18, 2012, 10:19 a.m. UTC
Hi,

Try again with fixing Thierry's commnets, Thanks.

From 9a632c24949e46df197a216ca95f684edd1db693 Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <hdoyu@nvidia.com>
Date: Wed, 18 Apr 2012 12:09:03 +0300
Subject: [PATCH 1/1] dt: Add general DMA window parser

This code was stolen from:
	"arch/microblaze/kernel/prom_parse.c"
	"arch/powerpc/kernel/prom_parse.c"

Once "ibm," prefix is removed from dts file. This generic one could
replace the originals.

Signed-off-by: Hiroshi DOYU <hdoyu@nvidia.com>
---
 drivers/of/Kconfig         |    4 ++++
 drivers/of/Makefile        |    1 +
 drivers/of/of_dma.c        |   35 +++++++++++++++++++++++++++++++++++
 include/linux/of_address.h |   10 ++++++++++
 4 files changed, 50 insertions(+), 0 deletions(-)

Comments

Thierry Reding April 18, 2012, 10:26 a.m. UTC | #1
* Hiroshi Doyu wrote:
> +	cells = prop ? *(__be32 *)prop : of_n_addr_cells(dn);

I think this needs to be:

	cells = prop ? be32_to_cpup(prop) : of_n_addr_cells(dn);

Only casting isn't enough, you need the bytes to be swapped.

> +	cells = prop ? *(__be32 *)prop : of_n_size_cells(dn);

Similarly:

	cells = prop ? be32_to_cpup(prop) : of_n_size_cells(dn);

Thierry
Stephen Warren April 18, 2012, 5:27 p.m. UTC | #2
On 04/18/2012 04:19 AM, Hiroshi Doyu wrote:

> Subject: [PATCH 1/1] dt: Add general DMA window parser
> 
> This code was stolen from:
> 	"arch/microblaze/kernel/prom_parse.c"
> 	"arch/powerpc/kernel/prom_parse.c"
> 
> Once "ibm," prefix is removed from dts file. This generic one could
> replace the originals.

> +extern void of_parse_dma_window(struct device_node *dn,
> +		       const void *dma_window_prop, unsigned long *busno,
> +			       unsigned long *phys, unsigned long *size);

At least some other of_*() parsing functions take the property name
rather than the property pointer, and also take an index into the
property in order to support multiple entries in it. See for example
of_parse_phandle and of_get_named_gpio_flags. Should this new API be
similar? E.g.:

extern void of_parse_dma_window(struct device_node *np,
			const char *propname, int index,
			unsigned long *busno,
			unsigned long *phys, unsigned long *size);
Thierry Reding April 18, 2012, 7:39 p.m. UTC | #3
* Stephen Warren wrote:
> On 04/18/2012 04:19 AM, Hiroshi Doyu wrote:
> 
> > Subject: [PATCH 1/1] dt: Add general DMA window parser
> > 
> > This code was stolen from:
> > 	"arch/microblaze/kernel/prom_parse.c"
> > 	"arch/powerpc/kernel/prom_parse.c"
> > 
> > Once "ibm," prefix is removed from dts file. This generic one could
> > replace the originals.
> 
> > +extern void of_parse_dma_window(struct device_node *dn,
> > +		       const void *dma_window_prop, unsigned long *busno,
> > +			       unsigned long *phys, unsigned long *size);
> 
> At least some other of_*() parsing functions take the property name
> rather than the property pointer, and also take an index into the
> property in order to support multiple entries in it. See for example
> of_parse_phandle and of_get_named_gpio_flags. Should this new API be
> similar? E.g.:
> 
> extern void of_parse_dma_window(struct device_node *np,
> 			const char *propname, int index,
> 			unsigned long *busno,
> 			unsigned long *phys, unsigned long *size);

In that case the function should return int for proper error handling.

Thierry
Hiroshi Doyu April 19, 2012, 12:19 p.m. UTC | #4
On Wed, 18 Apr 2012 19:27:58 +0200
Stephen Warren <swarren@wwwdotorg.org> wrote:

> On 04/18/2012 04:19 AM, Hiroshi Doyu wrote:
> 
> > Subject: [PATCH 1/1] dt: Add general DMA window parser
> > 
> > This code was stolen from:
> > 	"arch/microblaze/kernel/prom_parse.c"
> > 	"arch/powerpc/kernel/prom_parse.c"
> > 
> > Once "ibm," prefix is removed from dts file. This generic one could
> > replace the originals.

It seems that the "ibm," prefix is not used in .dts files, but it
comes from the PAPR compliant firmware and cannot be changed.

The easiest solution would be to make the function understand both
variants.

> > +extern void of_parse_dma_window(struct device_node *dn,
> > +		       const void *dma_window_prop, unsigned long *busno,
> > +			       unsigned long *phys, unsigned long *size);
> 
> At least some other of_*() parsing functions take the property name
> rather than the property pointer, and also take an index into the
> property in order to support multiple entries in it. See for example
> of_parse_phandle and of_get_named_gpio_flags. Should this new API be
> similar? E.g.:
> 
> extern void of_parse_dma_window(struct device_node *np,
> 			const char *propname, int index,
> 			unsigned long *busno,
> 			unsigned long *phys, unsigned long *size);

At least, I can add the code checking the return value of this
function, which won't change the existing code.

Does anyone know the format of "ibm,dma-window"?
Hiroshi Doyu April 19, 2012, 12:32 p.m. UTC | #5
On Wed, 18 Apr 2012 21:39:45 +0200
Thierry Reding <thierry.reding@avionic-design.de> wrote:

> * PGP Signed by an unknown key
> 
> * Stephen Warren wrote:
> > On 04/18/2012 04:19 AM, Hiroshi Doyu wrote:
> > 
> > > Subject: [PATCH 1/1] dt: Add general DMA window parser
> > > 
> > > This code was stolen from:
> > > 	"arch/microblaze/kernel/prom_parse.c"
> > > 	"arch/powerpc/kernel/prom_parse.c"
> > > 
> > > Once "ibm," prefix is removed from dts file. This generic one could
> > > replace the originals.
> > 
> > > +extern void of_parse_dma_window(struct device_node *dn,
> > > +		       const void *dma_window_prop, unsigned long *busno,
> > > +			       unsigned long *phys, unsigned long *size);
> > 
> > At least some other of_*() parsing functions take the property name
> > rather than the property pointer, and also take an index into the
> > property in order to support multiple entries in it. See for example
> > of_parse_phandle and of_get_named_gpio_flags. Should this new API be
> > similar? E.g.:
> > 
> > extern void of_parse_dma_window(struct device_node *np,
> > 			const char *propname, int index,
> > 			unsigned long *busno,
> > 			unsigned long *phys, unsigned long *size);
> 
> In that case the function should return int for proper error handling.

Good point. I'll.
diff mbox

Patch

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index dfba3e6..3b0298b 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -83,4 +83,8 @@  config OF_MTD
 	depends on MTD
 	def_bool y
 
+config OF_DMA
+	depends on HAS_DMA
+	def_bool y
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index e027f44..711ff5b 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -11,3 +11,4 @@  obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
+obj-$(CONFIG_OF_DMA)	+= of_dma.o
diff --git a/drivers/of/of_dma.c b/drivers/of/of_dma.c
new file mode 100644
index 0000000..a34db5a
--- /dev/null
+++ b/drivers/of/of_dma.c
@@ -0,0 +1,35 @@ 
+/*
+ * Stolen from:
+ *	"arch/microblaze/kernel/prom_parse.c"
+ *	"arch/powerpc/kernel/prom_parse.c"
+ */
+
+#include <linux/of_address.h>
+
+void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
+		unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+	const __be32 *dma_window;
+	u32 cells;
+	const unsigned char *prop;
+
+	dma_window = dma_window_prop;
+
+	/* busno is always one cell */
+	if (busno)
+		*busno = be32_to_cpup(dma_window++);
+
+	prop = of_get_property(dn, "#dma-address-cells", NULL);
+	if (!prop)
+		prop = of_get_property(dn, "#address-cells", NULL);
+
+	cells = prop ? *(__be32 *)prop : of_n_addr_cells(dn);
+	*phys = of_read_number(dma_window, cells);
+
+	dma_window += cells;
+
+	prop = of_get_property(dn, "#dma-size-cells", NULL);
+	cells = prop ? *(__be32 *)prop : of_n_size_cells(dn);
+	*size = of_read_number(dma_window, cells);
+}
+
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 01b925a..2a0f7c6 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -21,6 +21,10 @@  extern void __iomem *of_iomap(struct device_node *device, int index);
 extern const u32 *of_get_address(struct device_node *dev, int index,
 			   u64 *size, unsigned int *flags);
 
+extern void of_parse_dma_window(struct device_node *dn,
+		       const void *dma_window_prop, unsigned long *busno,
+			       unsigned long *phys, unsigned long *size);
+
 #ifndef pci_address_to_pio
 static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
 #define pci_address_to_pio pci_address_to_pio
@@ -48,6 +52,12 @@  static inline const u32 *of_get_address(struct device_node *dev, int index,
 {
 	return NULL;
 }
+
+static inline void of_parse_dma_window(struct device_node *dn,
+		       const void *dma_window_prop, unsigned long *busno,
+			       unsigned long *phys, unsigned long *size)
+{
+}
 #endif /* CONFIG_OF_ADDRESS */