From: Benjamin Herrenschmidt The g5 code has special hooks to "hide" some PCI devices when they are off. Currently, this code involves some calls to match a pci_dev from the open firmware node and such things that are causing some problems with the latest version of my sungem driver who wants to do some of this in atomic contexts. This patch moves that to a list of struct device_node instead, which also ends up simplifying the code. Later, I'll go back to manipulating PCI devices in a clean way when Brian King's PCI blocking patch gets in, but only after I change sungem again to never call these in atomic context. This is a 3 step transition basically Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc/platforms/pmac_feature.c | 26 ++---------------------- 25-akpm/arch/ppc/platforms/pmac_pci.c | 8 ++----- 25-akpm/arch/ppc64/kernel/pmac_feature.c | 32 ++---------------------------- 25-akpm/arch/ppc64/kernel/pmac_pci.c | 19 ++++++++--------- 4 files changed, 18 insertions(+), 67 deletions(-) diff -puN arch/ppc64/kernel/pmac_feature.c~ppc64-ppc-cleanup-pci-skipping arch/ppc64/kernel/pmac_feature.c --- 25/arch/ppc64/kernel/pmac_feature.c~ppc64-ppc-cleanup-pci-skipping 2005-01-18 19:34:30.783661872 -0800 +++ 25-akpm/arch/ppc64/kernel/pmac_feature.c 2005-01-18 19:34:30.792660504 -0800 @@ -111,7 +111,7 @@ static u32* uninorth_base __pmacdata; static u32 uninorth_rev __pmacdata; static void *u3_ht; -extern struct pci_dev *k2_skiplist[2]; +extern struct device_node *k2_skiplist[2]; /* * For each motherboard family, we have a table of functions pointers @@ -160,30 +160,17 @@ static long __pmac g5_gmac_enable(struct { struct macio_chip* macio = &macio_chips[0]; unsigned long flags; - struct pci_dev *pdev = NULL; if (node == NULL) return -ENODEV; - /* XXX FIXME: We should fix pci_device_from_OF_node here, and - * get to a real pci_dev or we'll get into trouble with PCI - * domains the day we get overlapping numbers (like if we ever - * decide to show the HT root. - * Note that we only get the slot when value is 0. This is called - * early during boot with value 1 to enable all devices, at which - * point, we don't yet have probed pci_find_slot, so it would fail - * to look for the slot at this point. - */ - if (!value) - pdev = pci_find_slot(node->busno, node->devfn); - LOCK(flags); if (value) { MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); mb(); k2_skiplist[0] = NULL; } else { - k2_skiplist[0] = pdev; + k2_skiplist[0] = node; mb(); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); } @@ -198,30 +185,17 @@ static long __pmac g5_fw_enable(struct d { struct macio_chip* macio = &macio_chips[0]; unsigned long flags; - struct pci_dev *pdev = NULL; - /* XXX FIXME: We should fix pci_device_from_OF_node here, and - * get to a real pci_dev or we'll get into trouble with PCI - * domains the day we get overlapping numbers (like if we ever - * decide to show the HT root - * Note that we only get the slot when value is 0. This is called - * early during boot with value 1 to enable all devices, at which - * point, we don't yet have probed pci_find_slot, so it would fail - * to look for the slot at this point. - */ if (node == NULL) return -ENODEV; - if (!value) - pdev = pci_find_slot(node->busno, node->devfn); - LOCK(flags); if (value) { MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); mb(); k2_skiplist[1] = NULL; } else { - k2_skiplist[1] = pdev; + k2_skiplist[1] = node; mb(); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); } diff -puN arch/ppc64/kernel/pmac_pci.c~ppc64-ppc-cleanup-pci-skipping arch/ppc64/kernel/pmac_pci.c --- 25/arch/ppc64/kernel/pmac_pci.c~ppc64-ppc-cleanup-pci-skipping 2005-01-18 19:34:30.784661720 -0800 +++ 25-akpm/arch/ppc64/kernel/pmac_pci.c 2005-01-18 19:34:30.793660352 -0800 @@ -43,7 +43,7 @@ * assuming we won't have both UniNorth and Bandit */ static int has_uninorth; static struct pci_controller *u3_agp; -struct pci_dev *k2_skiplist[2]; +struct device_node *k2_skiplist[2]; static int __init fixup_one_level_bus_range(struct device_node *node, int higher) { @@ -233,15 +233,6 @@ static int u3_ht_skip_device(struct pci_ struct device_node *busdn, *dn; int i; - /* - * When a device in K2 is powered down, we die on config - * cycle accesses. Fix that here. - */ - for (i=0; i<2; i++) - if (k2_skiplist[i] && k2_skiplist[i]->bus == bus && - k2_skiplist[i]->devfn == devfn) - return 1; - /* We only allow config cycles to devices that are in OF device-tree * as we are apparently having some weird things going on with some * revs of K2 on recent G5s @@ -256,6 +247,14 @@ static int u3_ht_skip_device(struct pci_ if (dn == NULL) return -1; + /* + * When a device in K2 is powered down, we die on config + * cycle accesses. Fix that here. + */ + for (i=0; i<2; i++) + if (k2_skiplist[i] == dn) + return 1; + return 0; } diff -puN arch/ppc/platforms/pmac_feature.c~ppc64-ppc-cleanup-pci-skipping arch/ppc/platforms/pmac_feature.c --- 25/arch/ppc/platforms/pmac_feature.c~ppc64-ppc-cleanup-pci-skipping 2005-01-18 19:34:30.786661416 -0800 +++ 25-akpm/arch/ppc/platforms/pmac_feature.c 2005-01-18 19:35:15.998788128 -0800 @@ -56,7 +56,7 @@ extern int powersave_lowspeed; #endif extern int powersave_nap; -extern struct pci_dev *k2_skiplist[2]; +extern struct device_node *k2_skiplist[2]; /* @@ -1361,16 +1361,6 @@ g5_gmac_enable(struct device_node* node, { struct macio_chip* macio = &macio_chips[0]; unsigned long flags; - struct pci_dev *pdev; - u8 pbus, pid; - - /* XXX FIXME: We should fix pci_device_from_OF_node here, and - * get to a real pci_dev or we'll get into trouble with PCI - * domains the day we get overlapping numbers (like if we ever - * decide to show the HT root - */ - if (pci_device_from_OF_node(node, &pbus, &pid) == 0) - pdev = pci_find_slot(pbus, pid); LOCK(flags); if (value) { @@ -1378,7 +1368,7 @@ g5_gmac_enable(struct device_node* node, mb(); k2_skiplist[0] = NULL; } else { - k2_skiplist[0] = pdev; + k2_skiplist[0] = node; mb(); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); } @@ -1394,16 +1384,6 @@ g5_fw_enable(struct device_node* node, l { struct macio_chip* macio = &macio_chips[0]; unsigned long flags; - struct pci_dev *pdev; - u8 pbus, pid; - - /* XXX FIXME: We should fix pci_device_from_OF_node here, and - * get to a real pci_dev or we'll get into trouble with PCI - * domains the day we get overlapping numbers (like if we ever - * decide to show the HT root - */ - if (pci_device_from_OF_node(node, &pbus, &pid) == 0) - pdev = pci_find_slot(pbus, pid); LOCK(flags); if (value) { @@ -1411,7 +1391,7 @@ g5_fw_enable(struct device_node* node, l mb(); k2_skiplist[1] = NULL; } else { - k2_skiplist[1] = pdev; + k2_skiplist[1] = node; mb(); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); } diff -puN arch/ppc/platforms/pmac_pci.c~ppc64-ppc-cleanup-pci-skipping arch/ppc/platforms/pmac_pci.c --- 25/arch/ppc/platforms/pmac_pci.c~ppc64-ppc-cleanup-pci-skipping 2005-01-18 19:34:30.788661112 -0800 +++ 25-akpm/arch/ppc/platforms/pmac_pci.c 2005-01-18 19:34:30.797659744 -0800 @@ -52,7 +52,7 @@ static struct pci_controller *u3_agp; extern u8 pci_cache_line_size; extern int pcibios_assign_bus_offset; -struct pci_dev *k2_skiplist[2]; +struct device_node *k2_skiplist[2]; /* * Magic constants for enabling cache coherency in the bandit/PSX bridge. @@ -325,8 +325,7 @@ u3_ht_read_config(struct pci_bus *bus, u * cycle accesses. Fix that here. */ for (i=0; i<2; i++) - if (k2_skiplist[i] && k2_skiplist[i]->bus == bus && - k2_skiplist[i]->devfn == devfn) { + if (k2_skiplist[i] == np) { switch (len) { case 1: *val = 0xff; break; @@ -375,8 +374,7 @@ u3_ht_write_config(struct pci_bus *bus, * cycle accesses. Fix that here. */ for (i=0; i<2; i++) - if (k2_skiplist[i] && k2_skiplist[i]->bus == bus && - k2_skiplist[i]->devfn == devfn) + if (k2_skiplist[i] == np) return PCIBIOS_SUCCESSFUL; addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); _