[POWERPC] pci32: Add flags modifying the PCI code behaviour
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 20 Dec 2007 03:54:46 +0000 (14:54 +1100)
committerPaul Mackerras <paulus@samba.org>
Thu, 20 Dec 2007 05:18:07 +0000 (16:18 +1100)
This adds to the 32 bits PCI code some flags, replacing the old
pci_assign_all_busses global, that allow us to control various
aspects of the PCI probing, such as whether to re-assign all
resources or not, or to not try to assign anything at all.

This also adds the flag x86 already has to avoid ISA alignment
on bridges that don't have ISA forwarding enabled (no legacy
devices on the top level bus) and sets it for PowerMacs.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
12 files changed:
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/rtas_pci.c
arch/powerpc/platforms/52xx/mpc52xx_pci.c
arch/powerpc/platforms/82xx/pq2.c
arch/powerpc/platforms/83xx/pci.c
arch/powerpc/platforms/chrp/pci.c
arch/powerpc/platforms/powermac/pci.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/grackle.c
include/asm-powerpc/pci-bridge.h
include/asm-powerpc/pci.h

index dfb1658025299b0e9eddaf2bf68d3d4009a4a5a9..beb6f0447d16a3e973de75cdb79e5585734a2df5 100644 (file)
@@ -35,6 +35,9 @@ unsigned long isa_io_base     = 0;
 unsigned long pci_dram_offset = 0;
 int pcibios_assign_bus_offset = 1;
 
+/* Default PCI flags is 0 */
+unsigned int ppc_pci_flags;
+
 void pcibios_make_OF_bus_map(void);
 
 static void pcibios_fixup_resources(struct pci_dev* dev);
@@ -48,7 +51,7 @@ static u8* pci_to_OF_bus_map;
 /* By default, we don't re-assign bus numbers. We do this only on
  * some pmacs
  */
-int pci_assign_all_buses;
+static int pci_assign_all_buses;
 
 LIST_HEAD(hose_list);
 
@@ -174,6 +177,14 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 }
 EXPORT_SYMBOL(pcibios_bus_to_resource);
 
+static int skip_isa_ioresource_align(struct pci_dev *dev)
+{
+       if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
+           !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
+               return 1;
+       return 0;
+}
+
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
@@ -195,6 +206,8 @@ void pcibios_align_resource(void *data, struct resource *res,
        if (res->flags & IORESOURCE_IO) {
                resource_size_t start = res->start;
 
+               if (skip_isa_ioresource_align(dev))
+                       return;
                if (start & 0x300) {
                        start = (start + 0x3ff) & ~0x3ff;
                        res->start = start;
@@ -251,8 +264,13 @@ pcibios_allocate_bus_resources(struct list_head *bus_list)
                                continue;
                        if (bus->parent == NULL)
                                pr = (res->flags & IORESOURCE_IO)?
-                                       &ioport_resource: &iomem_resource;
+                                       &ioport_resource : &iomem_resource;
                        else {
+                               /* Don't bother with non-root busses when
+                                * re-assigning all resources.
+                                */
+                               if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
+                                       continue;
                                pr = pci_find_parent_resource(bus->self, res);
                                if (pr == res) {
                                        /* this happens when the generic PCI
@@ -720,6 +738,9 @@ pcibios_init(void)
 
        printk(KERN_INFO "PCI: Probing PCI hardware\n");
 
+       if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
+               pci_assign_all_buses = 1;
+
        /* Scan all of the recorded PCI controllers.  */
        list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
                if (pci_assign_all_buses)
@@ -746,13 +767,18 @@ pcibios_init(void)
        if (ppc_md.pcibios_fixup)
                ppc_md.pcibios_fixup();
 
-       /* Allocate and assign resources */
+       /* Allocate and assign resources. If we re-assign everything, then
+        * we skip the allocate phase
+        */
        pcibios_allocate_bus_resources(&pci_root_buses);
-       pcibios_allocate_resources(0);
-       pcibios_allocate_resources(1);
-
-       DBG("PCI: Assigning unassigned resouces...\n");
-       pci_assign_unassigned_resources();
+       if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
+               pcibios_allocate_resources(0);
+               pcibios_allocate_resources(1);
+       }
+       if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
+               DBG("PCI: Assigning unassigned resouces...\n");
+               pci_assign_unassigned_resources();
+       }
 
        /* Call machine dependent post-init code */
        if (ppc_md.pcibios_after_init)
index f5c4628698b94fc5f7e7e4b4e608390b3ed03a6e..3e7cf7af3bf37c4255788a8539612809f98aff3a 100644 (file)
@@ -40,7 +40,6 @@
 #endif
 
 unsigned long pci_probe_only = 1;
-int pci_assign_all_buses = 0;
 
 static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void do_bus_setup(struct pci_bus *bus);
index 3650eb50c27d2c910fd072e875244bc43ef83469..99aaae3409c0bf2b5148165c4d41f69fa00ae2df 100644 (file)
@@ -311,10 +311,12 @@ void __init find_and_init_phbs(void)
                if (prop)
                        pci_probe_only = *prop;
 
+#ifdef CONFIG_PPC32 /* Will be made generic soon */
                prop = of_get_property(of_chosen,
                                "linux,pci-assign-all-buses", NULL);
-               if (prop)
-                       pci_assign_all_buses = *prop;
+               if (prop && *prop)
+                       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+#endif /* CONFIG_PPC32 */
        }
 }
 
index 4c6c82a684b1eb23bb43642b86200d564c491f29..262eda8659d07ef31be4cc715153f5cc5943032d 100644 (file)
@@ -363,7 +363,7 @@ mpc52xx_add_bridge(struct device_node *node)
 
        pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
 
-       pci_assign_all_buses = 1;
+       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
 
        if (of_address_to_resource(node, 0, &rsrc) != 0) {
                printk(KERN_ERR "Can't get %s resources\n", node->full_name);
index 11d1db8bb09154b3742226aef0d3b4094d6f11df..1b75902fad64a9a848e0bd4050c3a01345021c80 100644 (file)
@@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(struct device_node *np)
        if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
                goto err;
 
-       pci_assign_all_buses = 1;
+       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
 
        hose = pcibios_alloc_controller(np);
        if (!hose)
index 80425d7b14f8b0b24376a1de86458c61a163684e..14f1080c6c9d40c616eebbfbd37f0e26ead5b781 100644 (file)
@@ -54,7 +54,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
                       " bus 0\n", dev->full_name);
        }
 
-       pci_assign_all_buses = 1;
+       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
        hose = pcibios_alloc_controller(dev);
        if (!hose)
                return -ENOMEM;
index 0340a342f7726c8a721eacf36491f2c604d50cce..d51f83aeef7ff2d9c6f6ae5914d52298d02372e3 100644 (file)
@@ -198,7 +198,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
                printk ("RTAS supporting Pegasos OF not found, please upgrade"
                        " your firmware\n");
        }
-       pci_assign_all_buses = 1;
+       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
        /* keep the reference to the root node */
 }
 
index 589c613bcd3c290b887b01d3da3c6e59d5a155c4..a2e9b36f61ef2ffaf383b56c7bdc03e233f58159 100644 (file)
@@ -725,7 +725,7 @@ static void __init setup_bandit(struct pci_controller *hose,
 static int __init setup_uninorth(struct pci_controller *hose,
                                 struct resource *addr)
 {
-       pci_assign_all_buses = 1;
+       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
        has_uninorth = 1;
        hose->ops = &macrisc_pci_ops;
        hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -994,6 +994,9 @@ void __init pmac_pci_init(void)
        struct device_node *np, *root;
        struct device_node *ht = NULL;
 
+#ifdef CONFIG_PPC32
+       ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN;
+#endif
        root = of_find_node_by_path("/");
        if (root == NULL) {
                printk(KERN_CRIT "pmac_pci_init: can't find root "
@@ -1051,7 +1054,7 @@ void __init pmac_pci_init(void)
         * some offset between bus number and domains for now when we
         * assign all busses should help for now
         */
-       if (pci_assign_all_buses)
+       if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
                pcibios_assign_bus_offset = 0x10;
 #endif
 }
index 87e58e09b500b7b78ae22c4c210ce23c605f504d..4b1d5120c1224690bb04f12d916af1abdfc3a4a7 100644 (file)
@@ -202,7 +202,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
                printk(KERN_WARNING "Can't get bus-range for %s, assume"
                        " bus 0\n", dev->full_name);
 
-       pci_assign_all_buses = 1;
+       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
        hose = pcibios_alloc_controller(dev);
        if (!hose)
                return -ENOMEM;
index 11ad5622eb760bd71ea49139f6eb62b7c7a6bfb3..d502927644c68c69a1328c436c2030bed9349f1c 100644 (file)
@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose)
 {
        setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
        if (machine_is_compatible("PowerMac1,1"))
-               pci_assign_all_buses = 1;
+               ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
        if (machine_is_compatible("AAPL,PowerBook1998"))
                grackle_set_loop_snoop(hose, 1);
 #if 0  /* Disabled for now, HW problems ??? */
index 8245e84836c9431fdb0dd49937e9892d7a4baf20..2972f0d3afaa9a51b9b898bec0a05a2951b80152 100644 (file)
 
 struct device_node;
 
+extern unsigned int ppc_pci_flags;
+enum {
+       /* Force re-assigning all resources (ignore firmware
+        * setup completely)
+        */
+       PPC_PCI_REASSIGN_ALL_RSRC       = 0x00000001,
+
+       /* Re-assign all bus numbers */
+       PPC_PCI_REASSIGN_ALL_BUS        = 0x00000002,
+
+       /* Do not try to assign, just use existing setup */
+       PPC_PCI_PROBE_ONLY              = 0x00000004,
+
+       /* Don't bother with ISA alignment unless the bridge has
+        * ISA forwarding enabled
+        */
+       PPC_PCI_CAN_SKIP_ISA_ALIGN      = 0x00000008,
+};
+
+
 /*
  * Structure of a PCI controller (host bridge)
  */
index 7b11765c6865f31157dd30c6ee91ba5c1ecc9ad0..47cc117a1422090f628d434cbb2e9c67e7e602ca 100644 (file)
@@ -38,9 +38,12 @@ struct pci_dev;
  * Set this to 1 if you want the kernel to re-assign all PCI
  * bus numbers
  */
-extern int pci_assign_all_buses;
-#define pcibios_assign_all_busses()    (pci_assign_all_buses)
-
+#ifdef CONFIG_PPC64
+#define pcibios_assign_all_busses()    0
+#else
+#define pcibios_assign_all_busses()            (ppc_pci_flags & \
+                                        PPC_PCI_REASSIGN_ALL_BUS)
+#endif
 #define pcibios_scan_all_fns(a, b)     0
 
 static inline void pcibios_set_master(struct pci_dev *dev)