X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc64%2Fkernel%2Fpmac_pci.c;h=9e1a069554e7f063b03761f99e964c46b0aee1a6;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=169195713371fe505faf5657a93b4db5241744bc;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c index 169195713..9e1a06955 100644 --- a/arch/ppc64/kernel/pmac_pci.c +++ b/arch/ppc64/kernel/pmac_pci.c @@ -271,7 +271,7 @@ static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose; - struct device_node *busdn; + struct device_node *busdn, *dn; unsigned long addr; if (bus->self) @@ -284,6 +284,16 @@ static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; + /* 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 + */ + for (dn = busdn->child; dn; dn = dn->sibling) + if (dn->devfn == devfn) + break; + if (dn == NULL) + return PCIBIOS_DEVICE_NOT_FOUND; + addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -419,7 +429,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) * properties or figuring out the U3 address space decoding logic and * then read it's configuration register (if any). */ - hose->io_base_phys = 0xf4000000 + 0x00400000; + hose->io_base_phys = 0xf4000000; hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000); isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt; hose->io_resource.name = np->full_name; @@ -664,17 +674,15 @@ void __init pmac_pcibios_fixup(void) pci_fix_bus_sysdata(); -#ifdef CONFIG_PMAC_DART - iommu_setup_pmac(); -#endif /* CONFIG_PMAC_DART */ + iommu_setup_u3(); } static void __init pmac_fixup_phb_resources(void) { - struct pci_controller *hose; + struct pci_controller *hose, *tmp; - for (hose = hose_head; hose; hose = hose->next) { + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; hose->io_resource.start += offset; hose->io_resource.end += offset; @@ -746,6 +754,9 @@ void __init pmac_pci_init(void) * the exception of U3/AGP (hook into pci_set_mwi) */ pci_cache_line_size = 16; /* 64 bytes */ + + /* Allow all IO */ + io_page_mask = -1; } /* @@ -777,3 +788,4 @@ void fixup_k2_sata(struct pci_dev* dev) } } } +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);