aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-19 22:54:46 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-20 00:18:07 -0500
commitfc3fb71c3e1850a6a1099dd1cb7bcd7e69ac7b73 (patch)
treec9885bd47237c6e09b42a3c42496b5865c0caa02
parentb9baa20b0a50947f2e86d7775c9dba87c0d946ef (diff)
[POWERPC] pci32: Add flags modifying the PCI code behaviour
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>
-rw-r--r--arch/powerpc/kernel/pci_32.c42
-rw-r--r--arch/powerpc/kernel/pci_64.c1
-rw-r--r--arch/powerpc/kernel/rtas_pci.c6
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c2
-rw-r--r--arch/powerpc/platforms/82xx/pq2.c2
-rw-r--r--arch/powerpc/platforms/83xx/pci.c2
-rw-r--r--arch/powerpc/platforms/chrp/pci.c2
-rw-r--r--arch/powerpc/platforms/powermac/pci.c7
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c2
-rw-r--r--arch/powerpc/sysdev/grackle.c2
-rw-r--r--include/asm-powerpc/pci-bridge.h20
-rw-r--r--include/asm-powerpc/pci.h9
12 files changed, 75 insertions, 22 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index dfb165802529..beb6f0447d16 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -35,6 +35,9 @@ unsigned long isa_io_base = 0;
35unsigned long pci_dram_offset = 0; 35unsigned long pci_dram_offset = 0;
36int pcibios_assign_bus_offset = 1; 36int pcibios_assign_bus_offset = 1;
37 37
38/* Default PCI flags is 0 */
39unsigned int ppc_pci_flags;
40
38void pcibios_make_OF_bus_map(void); 41void pcibios_make_OF_bus_map(void);
39 42
40static void pcibios_fixup_resources(struct pci_dev* dev); 43static void pcibios_fixup_resources(struct pci_dev* dev);
@@ -48,7 +51,7 @@ static u8* pci_to_OF_bus_map;
48/* By default, we don't re-assign bus numbers. We do this only on 51/* By default, we don't re-assign bus numbers. We do this only on
49 * some pmacs 52 * some pmacs
50 */ 53 */
51int pci_assign_all_buses; 54static int pci_assign_all_buses;
52 55
53LIST_HEAD(hose_list); 56LIST_HEAD(hose_list);
54 57
@@ -174,6 +177,14 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
174} 177}
175EXPORT_SYMBOL(pcibios_bus_to_resource); 178EXPORT_SYMBOL(pcibios_bus_to_resource);
176 179
180static int skip_isa_ioresource_align(struct pci_dev *dev)
181{
182 if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
183 !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
184 return 1;
185 return 0;
186}
187
177/* 188/*
178 * We need to avoid collisions with `mirrored' VGA ports 189 * We need to avoid collisions with `mirrored' VGA ports
179 * and other strange ISA hardware, so we always want the 190 * and other strange ISA hardware, so we always want the
@@ -195,6 +206,8 @@ void pcibios_align_resource(void *data, struct resource *res,
195 if (res->flags & IORESOURCE_IO) { 206 if (res->flags & IORESOURCE_IO) {
196 resource_size_t start = res->start; 207 resource_size_t start = res->start;
197 208
209 if (skip_isa_ioresource_align(dev))
210 return;
198 if (start & 0x300) { 211 if (start & 0x300) {
199 start = (start + 0x3ff) & ~0x3ff; 212 start = (start + 0x3ff) & ~0x3ff;
200 res->start = start; 213 res->start = start;
@@ -251,8 +264,13 @@ pcibios_allocate_bus_resources(struct list_head *bus_list)
251 continue; 264 continue;
252 if (bus->parent == NULL) 265 if (bus->parent == NULL)
253 pr = (res->flags & IORESOURCE_IO)? 266 pr = (res->flags & IORESOURCE_IO)?
254 &ioport_resource: &iomem_resource; 267 &ioport_resource : &iomem_resource;
255 else { 268 else {
269 /* Don't bother with non-root busses when
270 * re-assigning all resources.
271 */
272 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
273 continue;
256 pr = pci_find_parent_resource(bus->self, res); 274 pr = pci_find_parent_resource(bus->self, res);
257 if (pr == res) { 275 if (pr == res) {
258 /* this happens when the generic PCI 276 /* this happens when the generic PCI
@@ -720,6 +738,9 @@ pcibios_init(void)
720 738
721 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 739 printk(KERN_INFO "PCI: Probing PCI hardware\n");
722 740
741 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
742 pci_assign_all_buses = 1;
743
723 /* Scan all of the recorded PCI controllers. */ 744 /* Scan all of the recorded PCI controllers. */
724 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 745 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
725 if (pci_assign_all_buses) 746 if (pci_assign_all_buses)
@@ -746,13 +767,18 @@ pcibios_init(void)
746 if (ppc_md.pcibios_fixup) 767 if (ppc_md.pcibios_fixup)
747 ppc_md.pcibios_fixup(); 768 ppc_md.pcibios_fixup();
748 769
749 /* Allocate and assign resources */ 770 /* Allocate and assign resources. If we re-assign everything, then
771 * we skip the allocate phase
772 */
750 pcibios_allocate_bus_resources(&pci_root_buses); 773 pcibios_allocate_bus_resources(&pci_root_buses);
751 pcibios_allocate_resources(0); 774 if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
752 pcibios_allocate_resources(1); 775 pcibios_allocate_resources(0);
753 776 pcibios_allocate_resources(1);
754 DBG("PCI: Assigning unassigned resouces...\n"); 777 }
755 pci_assign_unassigned_resources(); 778 if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
779 DBG("PCI: Assigning unassigned resouces...\n");
780 pci_assign_unassigned_resources();
781 }
756 782
757 /* Call machine dependent post-init code */ 783 /* Call machine dependent post-init code */
758 if (ppc_md.pcibios_after_init) 784 if (ppc_md.pcibios_after_init)
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index f5c4628698b9..3e7cf7af3bf3 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -40,7 +40,6 @@
40#endif 40#endif
41 41
42unsigned long pci_probe_only = 1; 42unsigned long pci_probe_only = 1;
43int pci_assign_all_buses = 0;
44 43
45static void fixup_resource(struct resource *res, struct pci_dev *dev); 44static void fixup_resource(struct resource *res, struct pci_dev *dev);
46static void do_bus_setup(struct pci_bus *bus); 45static void do_bus_setup(struct pci_bus *bus);
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 3650eb50c27d..99aaae3409c0 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -311,10 +311,12 @@ void __init find_and_init_phbs(void)
311 if (prop) 311 if (prop)
312 pci_probe_only = *prop; 312 pci_probe_only = *prop;
313 313
314#ifdef CONFIG_PPC32 /* Will be made generic soon */
314 prop = of_get_property(of_chosen, 315 prop = of_get_property(of_chosen,
315 "linux,pci-assign-all-buses", NULL); 316 "linux,pci-assign-all-buses", NULL);
316 if (prop) 317 if (prop && *prop)
317 pci_assign_all_buses = *prop; 318 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
319#endif /* CONFIG_PPC32 */
318 } 320 }
319} 321}
320 322
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 4c6c82a684b1..262eda8659d0 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -363,7 +363,7 @@ mpc52xx_add_bridge(struct device_node *node)
363 363
364 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); 364 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
365 365
366 pci_assign_all_buses = 1; 366 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
367 367
368 if (of_address_to_resource(node, 0, &rsrc) != 0) { 368 if (of_address_to_resource(node, 0, &rsrc) != 0) {
369 printk(KERN_ERR "Can't get %s resources\n", node->full_name); 369 printk(KERN_ERR "Can't get %s resources\n", node->full_name);
diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
index 11d1db8bb091..1b75902fad64 100644
--- a/arch/powerpc/platforms/82xx/pq2.c
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(struct device_node *np)
53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b) 53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
54 goto err; 54 goto err;
55 55
56 pci_assign_all_buses = 1; 56 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
57 57
58 hose = pcibios_alloc_controller(np); 58 hose = pcibios_alloc_controller(np);
59 if (!hose) 59 if (!hose)
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 80425d7b14f8..14f1080c6c9d 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -54,7 +54,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
54 " bus 0\n", dev->full_name); 54 " bus 0\n", dev->full_name);
55 } 55 }
56 56
57 pci_assign_all_buses = 1; 57 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
58 hose = pcibios_alloc_controller(dev); 58 hose = pcibios_alloc_controller(dev);
59 if (!hose) 59 if (!hose)
60 return -ENOMEM; 60 return -ENOMEM;
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 0340a342f772..d51f83aeef7f 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -198,7 +198,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
198 printk ("RTAS supporting Pegasos OF not found, please upgrade" 198 printk ("RTAS supporting Pegasos OF not found, please upgrade"
199 " your firmware\n"); 199 " your firmware\n");
200 } 200 }
201 pci_assign_all_buses = 1; 201 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
202 /* keep the reference to the root node */ 202 /* keep the reference to the root node */
203} 203}
204 204
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 589c613bcd3c..a2e9b36f61ef 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -725,7 +725,7 @@ static void __init setup_bandit(struct pci_controller *hose,
725static int __init setup_uninorth(struct pci_controller *hose, 725static int __init setup_uninorth(struct pci_controller *hose,
726 struct resource *addr) 726 struct resource *addr)
727{ 727{
728 pci_assign_all_buses = 1; 728 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
729 has_uninorth = 1; 729 has_uninorth = 1;
730 hose->ops = &macrisc_pci_ops; 730 hose->ops = &macrisc_pci_ops;
731 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); 731 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -994,6 +994,9 @@ void __init pmac_pci_init(void)
994 struct device_node *np, *root; 994 struct device_node *np, *root;
995 struct device_node *ht = NULL; 995 struct device_node *ht = NULL;
996 996
997#ifdef CONFIG_PPC32
998 ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN;
999#endif
997 root = of_find_node_by_path("/"); 1000 root = of_find_node_by_path("/");
998 if (root == NULL) { 1001 if (root == NULL) {
999 printk(KERN_CRIT "pmac_pci_init: can't find root " 1002 printk(KERN_CRIT "pmac_pci_init: can't find root "
@@ -1051,7 +1054,7 @@ void __init pmac_pci_init(void)
1051 * some offset between bus number and domains for now when we 1054 * some offset between bus number and domains for now when we
1052 * assign all busses should help for now 1055 * assign all busses should help for now
1053 */ 1056 */
1054 if (pci_assign_all_buses) 1057 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
1055 pcibios_assign_bus_offset = 0x10; 1058 pcibios_assign_bus_offset = 0x10;
1056#endif 1059#endif
1057} 1060}
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 87e58e09b500..4b1d5120c122 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -202,7 +202,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
202 printk(KERN_WARNING "Can't get bus-range for %s, assume" 202 printk(KERN_WARNING "Can't get bus-range for %s, assume"
203 " bus 0\n", dev->full_name); 203 " bus 0\n", dev->full_name);
204 204
205 pci_assign_all_buses = 1; 205 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
206 hose = pcibios_alloc_controller(dev); 206 hose = pcibios_alloc_controller(dev);
207 if (!hose) 207 if (!hose)
208 return -ENOMEM; 208 return -ENOMEM;
diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c
index 11ad5622eb76..d502927644c6 100644
--- a/arch/powerpc/sysdev/grackle.c
+++ b/arch/powerpc/sysdev/grackle.c
@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose)
57{ 57{
58 setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); 58 setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
59 if (machine_is_compatible("PowerMac1,1")) 59 if (machine_is_compatible("PowerMac1,1"))
60 pci_assign_all_buses = 1; 60 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
61 if (machine_is_compatible("AAPL,PowerBook1998")) 61 if (machine_is_compatible("AAPL,PowerBook1998"))
62 grackle_set_loop_snoop(hose, 1); 62 grackle_set_loop_snoop(hose, 1);
63#if 0 /* Disabled for now, HW problems ??? */ 63#if 0 /* Disabled for now, HW problems ??? */
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 8245e84836c9..2972f0d3afaa 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -13,6 +13,26 @@
13 13
14struct device_node; 14struct device_node;
15 15
16extern unsigned int ppc_pci_flags;
17enum {
18 /* Force re-assigning all resources (ignore firmware
19 * setup completely)
20 */
21 PPC_PCI_REASSIGN_ALL_RSRC = 0x00000001,
22
23 /* Re-assign all bus numbers */
24 PPC_PCI_REASSIGN_ALL_BUS = 0x00000002,
25
26 /* Do not try to assign, just use existing setup */
27 PPC_PCI_PROBE_ONLY = 0x00000004,
28
29 /* Don't bother with ISA alignment unless the bridge has
30 * ISA forwarding enabled
31 */
32 PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008,
33};
34
35
16/* 36/*
17 * Structure of a PCI controller (host bridge) 37 * Structure of a PCI controller (host bridge)
18 */ 38 */
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h
index 7b11765c6865..47cc117a1422 100644
--- a/include/asm-powerpc/pci.h
+++ b/include/asm-powerpc/pci.h
@@ -38,9 +38,12 @@ struct pci_dev;
38 * Set this to 1 if you want the kernel to re-assign all PCI 38 * Set this to 1 if you want the kernel to re-assign all PCI
39 * bus numbers 39 * bus numbers
40 */ 40 */
41extern int pci_assign_all_buses; 41#ifdef CONFIG_PPC64
42#define pcibios_assign_all_busses() (pci_assign_all_buses) 42#define pcibios_assign_all_busses() 0
43 43#else
44#define pcibios_assign_all_busses() (ppc_pci_flags & \
45 PPC_PCI_REASSIGN_ALL_BUS)
46#endif
44#define pcibios_scan_all_fns(a, b) 0 47#define pcibios_scan_all_fns(a, b) 0
45 48
46static inline void pcibios_set_master(struct pci_dev *dev) 49static inline void pcibios_set_master(struct pci_dev *dev)