if (!bridge)
                return -ENOMEM;
 
-       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, NULL);
+       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             &bridge->dma_ranges, NULL);
        if (ret)
                return ret;
 
 
        }
 
        ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
-                                             &bus);
+                                             &bridge->dma_ranges, &bus);
        if (ret) {
                dev_err(dev, "Failed to parse resources\n");
                return ret;
 
        if (IS_ERR(p->base))
                return PTR_ERR(p->base);
 
-       ret = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL);
+       ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
+                                             &host->dma_ranges, NULL);
        if (ret)
                return ret;
 
 
        struct pci_config_window *cfg;
 
        /* Parse our PCI ranges and request their resources */
-       err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
+       err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range);
        if (err)
                return ERR_PTR(err);
 
 
        if (IS_ERR(v3->config_base))
                return PTR_ERR(v3->config_base);
 
-       ret = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL);
+       ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
+                                             &host->dma_ranges, NULL);
        if (ret)
                return ret;
 
 
        if (IS_ERR(versatile_cfg_base[1]))
                return PTR_ERR(versatile_cfg_base[1]);
 
-       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, NULL);
+       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             NULL, NULL);
        if (ret)
                return ret;
 
 
        if (ret)
                return ret;
 
-       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, NULL);
+       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             &bridge->dma_ranges, NULL);
        if (ret)
                return ret;
 
 
        }
 
        ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
-                                             NULL);
+                                             &bridge->dma_ranges, NULL);
        if (ret) {
                dev_err(dev, "Failed add resources\n");
                return ret;
 
        int err;
 
        /* Parse our PCI ranges and request their resources */
-       err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
+       err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range);
        if (err)
                return err;
 
 
        if (IS_ERR(pcie->phy))
                return PTR_ERR(pcie->phy);
 
-       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, NULL);
+       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             &bridge->dma_ranges, NULL);
        if (ret) {
                dev_err(dev, "unable to get PCI host bridge resources\n");
                return ret;
 
        int err;
 
        err = pci_parse_request_of_pci_ranges(dev, windows,
-                                             &bus);
+                                             &host->dma_ranges, &bus);
        if (err)
                return err;
 
 
        }
 
        /* parse the host bridge base addresses from the device tree file */
-       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows, NULL);
+       ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             &bridge->dma_ranges, NULL);
        if (ret) {
                dev_err(dev, "Getting bridge resources failed\n");
                return ret;
 
        pcie->dev = dev;
        platform_set_drvdata(pdev, pcie);
 
-       err = pci_parse_request_of_pci_ranges(dev, &pcie->resources, NULL);
+       err = pci_parse_request_of_pci_ranges(dev, &pcie->resources,
+                                             &bridge->dma_ranges, NULL);
        if (err)
                goto err_free_bridge;
 
 
        if (err < 0)
                goto err_deinit_port;
 
-       err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, &bus_res);
+       err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             &bridge->dma_ranges, &bus_res);
        if (err)
                goto err_remove_irq_domain;
 
 
                return err;
        }
 
-       err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, NULL);
+       err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             &bridge->dma_ranges, NULL);
        if (err) {
                dev_err(dev, "Getting bridge resources failed\n");
                return err;
 
                return err;
        }
 
-       err = pci_parse_request_of_pci_ranges(dev, &bridge->windows, NULL);
+       err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
+                                             &bridge->dma_ranges, NULL);
        if (err) {
                dev_err(dev, "Getting bridge resources failed\n");
                return err;
 
  */
 int devm_of_pci_get_host_bridge_resources(struct device *dev,
                        unsigned char busno, unsigned char bus_max,
-                       struct list_head *resources, resource_size_t *io_base)
+                       struct list_head *resources,
+                       struct list_head *ib_resources,
+                       resource_size_t *io_base)
 {
        struct device_node *dev_node = dev->of_node;
        struct resource *res, tmp_res;
        struct resource *bus_range;
        struct of_pci_range range;
        struct of_pci_range_parser parser;
-       char range_type[4];
+       const char *range_type;
        int err;
 
        if (io_base)
        for_each_of_pci_range(&parser, &range) {
                /* Read next ranges element */
                if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
-                       snprintf(range_type, 4, " IO");
+                       range_type = "IO";
                else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
-                       snprintf(range_type, 4, "MEM");
+                       range_type = "MEM";
                else
-                       snprintf(range_type, 4, "err");
-               dev_info(dev, "  %s %#010llx..%#010llx -> %#010llx\n",
+                       range_type = "err";
+               dev_info(dev, "  %6s %#012llx..%#012llx -> %#012llx\n",
                         range_type, range.cpu_addr,
                         range.cpu_addr + range.size - 1, range.pci_addr);
 
                pci_add_resource_offset(resources, res, res->start - range.pci_addr);
        }
 
+       /* Check for dma-ranges property */
+       if (!ib_resources)
+               return 0;
+       err = of_pci_dma_range_parser_init(&parser, dev_node);
+       if (err)
+               return 0;
+
+       dev_dbg(dev, "Parsing dma-ranges property...\n");
+       for_each_of_pci_range(&parser, &range) {
+               struct resource_entry *entry;
+               /*
+                * If we failed translation or got a zero-sized region
+                * then skip this range
+                */
+               if (((range.flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM) ||
+                   range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+                       continue;
+
+               dev_info(dev, "  %6s %#012llx..%#012llx -> %#012llx\n",
+                        "IB MEM", range.cpu_addr,
+                        range.cpu_addr + range.size - 1, range.pci_addr);
+
+
+               err = of_pci_range_to_resource(&range, dev_node, &tmp_res);
+               if (err)
+                       continue;
+
+               res = devm_kmemdup(dev, &tmp_res, sizeof(tmp_res), GFP_KERNEL);
+               if (!res) {
+                       err = -ENOMEM;
+                       goto failed;
+               }
+
+               /* Keep the resource list sorted */
+               resource_list_for_each_entry(entry, ib_resources)
+                       if (entry->res->start > res->start)
+                               break;
+
+               pci_add_resource_offset(&entry->node, res,
+                                       res->start - range.pci_addr);
+       }
+
        return 0;
 
 failed:
 
 int pci_parse_request_of_pci_ranges(struct device *dev,
                                    struct list_head *resources,
+                                   struct list_head *ib_resources,
                                    struct resource **bus_range)
 {
        int err, res_valid = 0;
        struct resource_entry *win, *tmp;
 
        INIT_LIST_HEAD(resources);
+       if (ib_resources)
+               INIT_LIST_HEAD(ib_resources);
        err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, resources,
-                                                   &iobase);
+                                                   ib_resources, &iobase);
        if (err)
                return err;
 
 
 #if defined(CONFIG_OF_ADDRESS)
 int devm_of_pci_get_host_bridge_resources(struct device *dev,
                        unsigned char busno, unsigned char bus_max,
-                       struct list_head *resources, resource_size_t *io_base);
+                       struct list_head *resources,
+                       struct list_head *ib_resources,
+                       resource_size_t *io_base);
 #else
 static inline int devm_of_pci_get_host_bridge_resources(struct device *dev,
                        unsigned char busno, unsigned char bus_max,
-                       struct list_head *resources, resource_size_t *io_base)
+                       struct list_head *resources,
+                       struct list_head *ib_resources,
+                       resource_size_t *io_base)
 {
        return -EINVAL;
 }
 
 struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
 int pci_parse_request_of_pci_ranges(struct device *dev,
                                    struct list_head *resources,
+                                   struct list_head *ib_resources,
                                    struct resource **bus_range);
 
 /* Arch may override this (weak) */
 #else  /* CONFIG_OF */
 static inline struct irq_domain *
 pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
-static inline int pci_parse_request_of_pci_ranges(struct device *dev,
-                                                 struct list_head *resources,
-                                                 struct resource **bus_range)
+static inline int
+pci_parse_request_of_pci_ranges(struct device *dev,
+                               struct list_head *resources,
+                               struct list_head *ib_resources,
+                               struct resource **bus_range)
 {
        return -EINVAL;
 }