]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/of/address.c
Merge remote-tracking branch 'dt-rh/for-next'
[karo-tx-linux.git] / drivers / of / address.c
index 7c8221d363292df921cd5341facfa48bfd06d1e3..27224c0d80a6dd170c53f99c097d851f32395b26 100644 (file)
@@ -231,6 +231,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 */
 
 /*
@@ -422,7 +489,7 @@ static u64 __of_translate_address(struct device_node *dev,
        int na, ns, pna, pns;
        u64 result = OF_BAD_ADDR;
 
-       pr_debug("OF: ** translation for device %s **\n", dev->full_name);
+       pr_debug("OF: ** translation for device %s **\n", of_node_full_name(dev));
 
        /* Increase refcount at current level */
        of_node_get(dev);
@@ -437,13 +504,13 @@ static u64 __of_translate_address(struct device_node *dev,
        bus->count_cells(dev, &na, &ns);
        if (!OF_CHECK_COUNTS(na, ns)) {
                printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
-                      dev->full_name);
+                      of_node_full_name(dev));
                goto bail;
        }
        memcpy(addr, in_addr, na * 4);
 
        pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
-           bus->name, na, ns, parent->full_name);
+           bus->name, na, ns, of_node_full_name(parent));
        of_dump_addr("OF: translating address:", addr, na);
 
        /* Translate */
@@ -559,6 +626,14 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
 }
 EXPORT_SYMBOL(of_get_address);
 
+unsigned long __weak pci_address_to_pio(phys_addr_t address)
+{
+       if (address > IO_SPACE_LIMIT)
+               return (unsigned long)-1;
+
+       return (unsigned long) address;
+}
+
 static int __of_address_to_resource(struct device_node *dev,
                const __be32 *addrp, u64 size, unsigned int flags,
                const char *name, struct resource *r)