upgrade to fedora-2.6.12-1.1398.FC4 + vserver 2.0.rc7
[linux-2.6.git] / arch / ppc64 / kernel / pSeries_pci.c
index 9c5a313..0b1cca2 100644 (file)
@@ -36,7 +36,6 @@
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/naca.h>
 #include <asm/iommu.h>
 #include <asm/rtas.h>
 
@@ -53,6 +52,16 @@ static int s7a_workaround;
 
 extern struct mpic *pSeries_mpic;
 
+static int config_access_valid(struct device_node *dn, int where)
+{
+       if (where < 256)
+               return 1;
+       if (where < 4096 && dn->pci_ext_config_space)
+               return 1;
+
+       return 0;
+}
+
 static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
 {
        int returnval = -1;
@@ -61,10 +70,11 @@ static int rtas_read_config(struct device_node *dn, int where, int size, u32 *va
 
        if (!dn)
                return PCIBIOS_DEVICE_NOT_FOUND;
-       if (where & (size - 1))
+       if (!config_access_valid(dn, where))
                return PCIBIOS_BAD_REGISTER_NUMBER;
 
-       addr = (dn->busno << 16) | (dn->devfn << 8) | where;
+       addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
+               (dn->devfn << 8) | (where & 0xff);
        buid = dn->phb->buid;
        if (buid) {
                ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
@@ -109,10 +119,11 @@ static int rtas_write_config(struct device_node *dn, int where, int size, u32 va
 
        if (!dn)
                return PCIBIOS_DEVICE_NOT_FOUND;
-       if (where & (size - 1))
+       if (!config_access_valid(dn, where))
                return PCIBIOS_BAD_REGISTER_NUMBER;
 
-       addr = (dn->busno << 16) | (dn->devfn << 8) | where;
+       addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
+               (dn->devfn << 8) | (where & 0xff);
        buid = dn->phb->buid;
        if (buid) {
                ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
@@ -149,7 +160,7 @@ struct pci_ops rtas_pci_ops = {
        rtas_pci_write_config
 };
 
-static int is_python(struct device_node *dev)
+int is_python(struct device_node *dev)
 {
        char *model = (char *)get_property(dev, "model", NULL);
 
@@ -353,7 +364,7 @@ unsigned long __init find_and_init_phbs(void)
        unsigned int *opprop = NULL;
        struct device_node *root = of_find_node_by_path("/");
 
-       if (naca->interrupt_controller == IC_OPEN_PIC) {
+       if (ppc64_interrupt_controller == IC_OPEN_PIC) {
                opprop = (unsigned int *)get_property(root,
                                "platform-open-pic", NULL);
        }
@@ -375,7 +386,7 @@ unsigned long __init find_and_init_phbs(void)
                pci_process_bridge_OF_ranges(phb, node);
                pci_setup_phb_io(phb, index == 0);
 
-               if (naca->interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
+               if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
                        int addr = root_size_cells * (index + 2) - 1;
                        mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
                }
@@ -413,16 +424,18 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
        unsigned int root_size_cells = 0;
        struct pci_controller *phb;
        struct pci_bus *bus;
+       int primary;
 
        root_size_cells = prom_n_size_cells(root);
 
+       primary = list_empty(&hose_list);
        phb = alloc_phb_dynamic(dn, root_size_cells);
        if (!phb)
                return NULL;
 
        pci_process_bridge_OF_ranges(phb, dn);
 
-       pci_setup_phb_io_dynamic(phb);
+       pci_setup_phb_io_dynamic(phb, primary);
        of_node_put(root);
 
        pci_devs_phb_init_dynamic(phb);
@@ -527,6 +540,9 @@ EXPORT_SYMBOL(pcibios_remove_root_bus);
 
 static void __init pSeries_request_regions(void)
 {
+       if (!isa_io_base)
+               return;
+
        request_region(0x20,0x20,"pic1");
        request_region(0xa0,0x20,"pic2");
        request_region(0x00,0x20,"dma1");
@@ -553,10 +569,6 @@ void __init pSeries_final_fixup(void)
 
        phbs_remap_io();
        pSeries_request_regions();
-       pci_fix_bus_sysdata();
-
-       if (!of_chosen || !get_property(of_chosen, "linux,iommu-off", NULL))
-               iommu_setup_pSeries();
 
        pci_addr_cache_build();
 }