Prechádzať zdrojové kódy

powerpc/pci: Fix PCI<->OF matching of old style multifunc devices

Old OF variants used to create a 'dummy' parent node "multifunc-device"
for devices with more than one PCI function. Our code that matches OF
nodes to PCI devices dealt with that in one place but not in another,
this fixes it.

This has the practical effect of fixing interrupt routing of multifunction
PCI cards on some older PowerMac machines.

Signed-off-by: Tom Arbuckle <tom.d.arbuckle@gmail.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Tom Arbuckle 16 rokov pred
rodič
commit
f81786913a
1 zmenil súbory, kde vykonal 11 pridanie a 4 odobranie
  1. 11 4
      arch/powerpc/kernel/pci_32.c

+ 11 - 4
arch/powerpc/kernel/pci_32.c

@@ -218,16 +218,23 @@ scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void
 static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
 static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
 					       unsigned int devfn)
 					       unsigned int devfn)
 {
 {
-	struct device_node *np;
+	struct device_node *np, *cnp;
 	const u32 *reg;
 	const u32 *reg;
 	unsigned int psize;
 	unsigned int psize;
 
 
 	for_each_child_of_node(parent, np) {
 	for_each_child_of_node(parent, np) {
 		reg = of_get_property(np, "reg", &psize);
 		reg = of_get_property(np, "reg", &psize);
-		if (reg == NULL || psize < 4)
-			continue;
-		if (((reg[0] >> 8) & 0xff) == devfn)
+                if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn)
 			return np;
 			return np;
+
+		/* Note: some OFs create a parent node "multifunc-device" as
+		 * a fake root for all functions of a multi-function device,
+		 * we go down them as well. */
+                if (!strcmp(np->name, "multifunc-device")) {
+                        cnp = scan_OF_for_pci_dev(np, devfn);
+                        if (cnp)
+                                return cnp;
+                }
 	}
 	}
 	return NULL;
 	return NULL;
 }
 }