Re: [PATCHv10 2/9] of/pci: Provide support for parsing PCI DT ranges property

2013-05-20 Thread Linus Walleij
On Sun, May 19, 2013 at 10:31 PM, Jason Cooper ja...@lakedaemon.net wrote:

 patches 2, 3, and 4 applied to mvebu/of_pci to facilitate others
 (LinusW) basing their work off of it.

Thanks, is this going to be pulled into ARM SoC soon-ish?

I think Arnd may need this for some PCI work too.

Yours,
Linus Walleij
___
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss


Re: [PATCHv10 2/9] of/pci: Provide support for parsing PCI DT ranges property

2013-05-20 Thread Jason Cooper
On Mon, May 20, 2013 at 09:03:00AM +0200, Linus Walleij wrote:
 On Sun, May 19, 2013 at 10:31 PM, Jason Cooper ja...@lakedaemon.net wrote:
 
  patches 2, 3, and 4 applied to mvebu/of_pci to facilitate others
  (LinusW) basing their work off of it.
 
 Thanks, is this going to be pulled into ARM SoC soon-ish?
 
 I think Arnd may need this for some PCI work too.

I was half expecting -rc2 to drop yesterday.  Since it didn't, I'll go
ahead and send another round of PRs, including this one.  Probably today
or tomorrow.

thx,

Jason.
___
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss


Re: [PATCHv10 2/9] of/pci: Provide support for parsing PCI DT ranges property

2013-05-19 Thread Jason Cooper
On Thu, May 16, 2013 at 05:55:17PM +0200, Thomas Petazzoni wrote:
 From: Andrew Murray andrew.mur...@arm.com
 
 This patch factors out common implementation patterns to reduce overall kernel
 code and provide a means for host bridge drivers to directly obtain struct
 resources from the DT's ranges property without relying on architecture 
 specific
 DT handling. This will make it easier to write archiecture independent host 
 bridge
 drivers and mitigate against further duplication of DT parsing code.
 
 This patch can be used in the following way:
 
   struct of_pci_range_parser parser;
   struct of_pci_range range;
 
   if (of_pci_range_parser_init(parser, np))
   ; //no ranges property
 
   for_each_of_pci_range(parser, range) {
 
   /*
   directly access properties of the address range, e.g.:
   range.pci_space, range.pci_addr, range.cpu_addr,
   range.size, range.flags
 
   alternatively obtain a struct resource, e.g.:
   struct resource res;
   of_pci_range_to_resource(range, np, res);
   */
   }
 
 Additionally the implementation takes care of adjacent ranges and merges them
 into a single range (as was the case with powerpc and microblaze).
 
 Signed-off-by: Andrew Murray andrew.mur...@arm.com
 Signed-off-by: Liviu Dudau liviu.du...@arm.com
 Signed-off-by: Thomas Petazzoni thomas.petazz...@free-electrons.com
 Reviewed-by: Rob Herring rob.herr...@calxeda.com
 Tested-by: Thomas Petazzoni thomas.petazz...@free-electrons.com
 Tested-by: Linus Walleij linus.wall...@linaro.org
 Tested-by: Jingoo Han jg1@samsung.com
 Acked-by: Grant Likely grant.lik...@secretlab.ca
 ---
  drivers/of/address.c   |   67 
 
  include/linux/of_address.h |   48 +++
  2 files changed, 115 insertions(+)

patches 2, 3, and 4 applied to mvebu/of_pci to facilitate others
(LinusW) basing their work off of it.

thx,

Jason.
___
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss


[PATCHv10 2/9] of/pci: Provide support for parsing PCI DT ranges property

2013-05-16 Thread Thomas Petazzoni
From: Andrew Murray andrew.mur...@arm.com

This patch factors out common implementation patterns to reduce overall kernel
code and provide a means for host bridge drivers to directly obtain struct
resources from the DT's ranges property without relying on architecture specific
DT handling. This will make it easier to write archiecture independent host 
bridge
drivers and mitigate against further duplication of DT parsing code.

This patch can be used in the following way:

struct of_pci_range_parser parser;
struct of_pci_range range;

if (of_pci_range_parser_init(parser, np))
; //no ranges property

for_each_of_pci_range(parser, range) {

/*
directly access properties of the address range, e.g.:
range.pci_space, range.pci_addr, range.cpu_addr,
range.size, range.flags

alternatively obtain a struct resource, e.g.:
struct resource res;
of_pci_range_to_resource(range, np, res);
*/
}

Additionally the implementation takes care of adjacent ranges and merges them
into a single range (as was the case with powerpc and microblaze).

Signed-off-by: Andrew Murray andrew.mur...@arm.com
Signed-off-by: Liviu Dudau liviu.du...@arm.com
Signed-off-by: Thomas Petazzoni thomas.petazz...@free-electrons.com
Reviewed-by: Rob Herring rob.herr...@calxeda.com
Tested-by: Thomas Petazzoni thomas.petazz...@free-electrons.com
Tested-by: Linus Walleij linus.wall...@linaro.org
Tested-by: Jingoo Han jg1@samsung.com
Acked-by: Grant Likely grant.lik...@secretlab.ca
---
 drivers/of/address.c   |   67 
 include/linux/of_address.h |   48 +++
 2 files changed, 115 insertions(+)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 04da786..fdd0636 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -227,6 +227,73 @@ int of_pci_address_to_resource(struct device_node *dev, 
int bar,
return __of_address_to_resource(dev, addrp, size, flags, NULL, r);
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+   struct device_node *node)
+{
+   const int na = 3, ns = 2;
+   int rlen;
+
+   parser-node = node;
+   parser-pna = of_n_addr_cells(node);
+   parser-np = parser-pna + na + ns;
+
+   parser-range = of_get_property(node, ranges, rlen);
+   if (parser-range == NULL)
+   return -ENOENT;
+
+   parser-end = parser-range + rlen / sizeof(__be32);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
+
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser 
*parser,
+   struct of_pci_range *range)
+{
+   const int na = 3, ns = 2;
+
+   if (!range)
+   return NULL;
+
+   if (!parser-range || parser-range + parser-np  parser-end)
+   return NULL;
+
+   range-pci_space = parser-range[0];
+   range-flags = of_bus_pci_get_flags(parser-range);
+   range-pci_addr = of_read_number(parser-range + 1, ns);
+   range-cpu_addr = of_translate_address(parser-node,
+   parser-range + na);
+   range-size = of_read_number(parser-range + parser-pna + na, ns);
+
+   parser-range += parser-np;
+
+   /* Now consume following elements while they are contiguous */
+   while (parser-range + parser-np = parser-end) {
+   u32 flags, pci_space;
+   u64 pci_addr, cpu_addr, size;
+
+   pci_space = be32_to_cpup(parser-range);
+   flags = of_bus_pci_get_flags(parser-range);
+   pci_addr = of_read_number(parser-range + 1, ns);
+   cpu_addr = of_translate_address(parser-node,
+   parser-range + na);
+   size = of_read_number(parser-range + parser-pna + na, ns);
+
+   if (flags != range-flags)
+   break;
+   if (pci_addr != range-pci_addr + range-size ||
+   cpu_addr != range-cpu_addr + range-size)
+   break;
+
+   range-size += size;
+   parser-range += parser-np;
+   }
+
+   return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+
 #endif /* CONFIG_PCI */
 
 /*
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 0506eb5..4c2e6f2 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -4,6 +4,36 @@
 #include linux/errno.h
 #include linux/of.h
 
+struct of_pci_range_parser {
+   struct device_node *node;
+   const __be32 *range;
+   const __be32 *end;
+   int np;
+   int pna;
+};
+
+struct of_pci_range {
+   u32 pci_space;
+   u64 pci_addr;
+