Forum Discussion
Altera_Forum
Honored Contributor
10 years agoI further narrowed down the issue.
My top-level structure is this: struct test_pcie { struct platform_device *pdev; void __iomem *axi_slave_base_1; void __iomem *axi_slave_base_2; void __iomem *axi_slave_base_3; int irq; u8 root_bus_nr; struct irq_domain *irq_domain; struct resource bus_range; struct list_head resources; }; When I register the driver, I printed out what resources i.e. list of 'struct resource' it has, and it's types. I wrote a dump() function which lists out the resources. void dump_resources (struct platform_device *dev) { int i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; if (r->name != NULL) printk("%s: r->name=%s, r->type=%lx\n", __FUNCTION__, r->name, resource_type(r)); } } I passed "pointer_to_struct_pcie->pdev" to dump_resources and this is what I got: [ 17.078754] dump_resources: r->name=axi_slave_1, r->type=0x200 [ 17.084833] dump_resources: r->name=axi_slave_2, r->type=0x200 [ 17.090722] dump_resources: r->name=axi_slave_3, r->type=0x200 [ 17.096531] dump_resources: r->name=/sopc@0/pcie@0x000000000, r->type=0x400 So, in the beginning, the driver has 4 resources, out of which 3 are of IORESOURCE_MEM type (r->type=0x200), and 1 is of IORESOURCE_BUS type (r->type=0x400). The 3 IORESOURCE_MEM type resources i.e. axi_slave_1, axi_slave_2, axi_slave_3 are listed under the device node of "/sopc@0/pcie@0x000000000" (IORESOURCE_BUS type) as can be evidenced from the DTS file. The problem comes when I try to parse the ranges inside the "/sopc@0/pcie@0x000000000" device node, with the call to altera_pcie_parse_request_of_pci_ranges() which calls of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources, NULL), and then loops each of the pcie->resources obtained until it hits a IORESOURCE_MEM type resource. In the loop, I printed out each resource name in the list, but I found that it has ONLY one resource in the list: resource_list_for_each_entry(win, &pcie->resources) { struct resource *parent, *res = win->res; printk("resource: name=%s, flags=0x%lx\n", res->name, res->flags); switch (resource_type(res)) { case IORESOURCE_MEM: parent = &iomem_resource; res_valid |= !(res->flags & IORESOURCE_PREFETCH); printk("res_valid = %d\n", res_valid); break; default: continue; } if (!res_valid) { dev_err(dev, "non-prefetchable memory resource required\n"); err = -EINVAL; goto out_release_res; } The output I got was: [ 17.183229] resource: name=pcie, flags=0x1000 This resource "pcie" is nothing but the device node that encapsulates the sub-resources under it viz. axi_slave_1, axi_slave_2, axi_slave_3. The flags 0x1000 show the "pcie" device node as IORESOURCE_BUS type, so it doesn't fall into "case IORESOURCE_MEM" but rather into "case default" and exits. This clearly shows that axi_slave_1, axi_slave_2, axi_slave_3 are not part of "pcie->resources" list. While the device node seems to have been mapped, the sub-resources under it seem to have been not mapped. So, I feel I need to dig into of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources, NULL) and check why pcie->resources contains only one resource i.e the top-level "pcie" device node, but not the sub-resources under it. But in the beginning, when I register the driver, I could see the top-level resource as well as it's sub-resources, as given in the prints above. If someone has got clue already as to what might have gone wrong or what is needed to be done, please answer.