Commit dead1c84 authored by Alexey Kardashevskiy's avatar Alexey Kardashevskiy Committed by Michael Ellerman

powerpc/pci/of: Parse unassigned resources

The pseries platform uses the PCI_PROBE_DEVTREE method of PCI probing
which reads "assigned-addresses" of every PCI device and initializes
the device resources. However if the property is missing or zero sized,
then there is no fallback of any kind and the PCI resources remain
undiscovered, i.e. pdev->resource[] array remains empty.

This adds a fallback which parses the "reg" property in pretty much same
way except it marks resources as "unset" which later make Linux assign
those resources proper addresses.

This has an effect when:
1. a hypervisor failed to assign any resource for a device;
2. /chosen/linux,pci-probe-only=0 is in the DT so the system may try
assigning a resource.
Neither is likely to happen under PowerVM.
Signed-off-by: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 1a047cc7
...@@ -82,10 +82,16 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) ...@@ -82,10 +82,16 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
const __be32 *addrs; const __be32 *addrs;
u32 i; u32 i;
int proplen; int proplen;
bool mark_unset = false;
addrs = of_get_property(node, "assigned-addresses", &proplen); addrs = of_get_property(node, "assigned-addresses", &proplen);
if (!addrs) if (!addrs || !proplen) {
return; addrs = of_get_property(node, "reg", &proplen);
if (!addrs || !proplen)
return;
mark_unset = true;
}
pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs); pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
for (; proplen >= 20; proplen -= 20, addrs += 5) { for (; proplen >= 20; proplen -= 20, addrs += 5) {
flags = pci_parse_of_flags(of_read_number(addrs, 1), 0); flags = pci_parse_of_flags(of_read_number(addrs, 1), 0);
...@@ -110,6 +116,8 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) ...@@ -110,6 +116,8 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
continue; continue;
} }
res->flags = flags; res->flags = flags;
if (mark_unset)
res->flags |= IORESOURCE_UNSET;
res->name = pci_name(dev); res->name = pci_name(dev);
region.start = base; region.start = base;
region.end = base + size - 1; region.end = base + size - 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment