diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/eeh.h | 8 | ||||
-rw-r--r-- | arch/powerpc/include/asm/pci.h | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 54 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 27 |
4 files changed, 58 insertions, 36 deletions
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index b886bec67016..66ea9b8b95c5 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h | |||
@@ -17,8 +17,8 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #ifndef _PPC64_EEH_H | 20 | #ifndef _POWERPC_EEH_H |
21 | #define _PPC64_EEH_H | 21 | #define _POWERPC_EEH_H |
22 | #ifdef __KERNEL__ | 22 | #ifdef __KERNEL__ |
23 | 23 | ||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
@@ -110,6 +110,7 @@ static inline void eeh_remove_bus_device(struct pci_dev *dev) { } | |||
110 | #define EEH_IO_ERROR_VALUE(size) (-1UL) | 110 | #define EEH_IO_ERROR_VALUE(size) (-1UL) |
111 | #endif /* CONFIG_EEH */ | 111 | #endif /* CONFIG_EEH */ |
112 | 112 | ||
113 | #ifdef CONFIG_PPC64 | ||
113 | /* | 114 | /* |
114 | * MMIO read/write operations with EEH support. | 115 | * MMIO read/write operations with EEH support. |
115 | */ | 116 | */ |
@@ -207,5 +208,6 @@ static inline void eeh_readsl(const volatile void __iomem *addr, void * buf, | |||
207 | eeh_check_failure(addr, *(u32*)buf); | 208 | eeh_check_failure(addr, *(u32*)buf); |
208 | } | 209 | } |
209 | 210 | ||
211 | #endif /* CONFIG_PPC64 */ | ||
210 | #endif /* __KERNEL__ */ | 212 | #endif /* __KERNEL__ */ |
211 | #endif /* _PPC64_EEH_H */ | 213 | #endif /* _POWERPC_EEH_H */ |
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index 55542ac3eadb..32e03e6d25c5 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h | |||
@@ -221,6 +221,7 @@ extern void of_scan_pci_bridge(struct device_node *node, | |||
221 | struct pci_dev *dev); | 221 | struct pci_dev *dev); |
222 | 222 | ||
223 | extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); | 223 | extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); |
224 | extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus); | ||
224 | 225 | ||
225 | extern int pci_read_irq_line(struct pci_dev *dev); | 226 | extern int pci_read_irq_line(struct pci_dev *dev); |
226 | 227 | ||
@@ -235,8 +236,8 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
235 | const struct resource *rsrc, | 236 | const struct resource *rsrc, |
236 | resource_size_t *start, resource_size_t *end); | 237 | resource_size_t *start, resource_size_t *end); |
237 | 238 | ||
238 | extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus); | 239 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
239 | 240 | extern void pcibios_setup_bus_self(struct pci_bus *bus); | |
240 | 241 | ||
241 | #endif /* __KERNEL__ */ | 242 | #endif /* __KERNEL__ */ |
242 | #endif /* __ASM_POWERPC_PCI_H */ | 243 | #endif /* __ASM_POWERPC_PCI_H */ |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 780db386c1f0..0eaabd41474f 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/machdep.h> | 37 | #include <asm/machdep.h> |
38 | #include <asm/ppc-pci.h> | 38 | #include <asm/ppc-pci.h> |
39 | #include <asm/firmware.h> | 39 | #include <asm/firmware.h> |
40 | #include <asm/eeh.h> | ||
40 | 41 | ||
41 | static DEFINE_SPINLOCK(hose_spinlock); | 42 | static DEFINE_SPINLOCK(hose_spinlock); |
42 | 43 | ||
@@ -1074,31 +1075,17 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1074 | } | 1075 | } |
1075 | } | 1076 | } |
1076 | 1077 | ||
1077 | static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | 1078 | void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) |
1078 | { | 1079 | { |
1079 | struct pci_dev *dev; | 1080 | struct pci_dev *dev; |
1080 | 1081 | ||
1081 | pr_debug("PCI: Fixup bus %d (%s)\n", | 1082 | pr_debug("PCI: Fixup bus %d (%s)\n", |
1082 | bus->number, bus->self ? pci_name(bus->self) : "PHB"); | 1083 | bus->number, bus->self ? pci_name(bus->self) : "PHB"); |
1083 | 1084 | ||
1084 | /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for | ||
1085 | * now differently between 32 and 64 bits. | ||
1086 | */ | ||
1087 | if (bus->self != NULL) | ||
1088 | pcibios_fixup_bridge(bus); | ||
1089 | |||
1090 | /* Setup bus DMA mappings */ | ||
1091 | if (ppc_md.pci_dma_bus_setup) | ||
1092 | ppc_md.pci_dma_bus_setup(bus); | ||
1093 | |||
1094 | /* Setup DMA for all PCI devices on that bus */ | 1085 | /* Setup DMA for all PCI devices on that bus */ |
1095 | list_for_each_entry(dev, &bus->devices, bus_list) | 1086 | list_for_each_entry(dev, &bus->devices, bus_list) |
1096 | pcibios_setup_new_device(dev); | 1087 | pcibios_setup_new_device(dev); |
1097 | 1088 | ||
1098 | /* Platform specific bus fixups */ | ||
1099 | if (ppc_md.pcibios_fixup_bus) | ||
1100 | ppc_md.pcibios_fixup_bus(bus); | ||
1101 | |||
1102 | /* Read default IRQs and fixup if necessary */ | 1089 | /* Read default IRQs and fixup if necessary */ |
1103 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1090 | list_for_each_entry(dev, &bus->devices, bus_list) { |
1104 | pci_read_irq_line(dev); | 1091 | pci_read_irq_line(dev); |
@@ -1107,25 +1094,39 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | |||
1107 | } | 1094 | } |
1108 | } | 1095 | } |
1109 | 1096 | ||
1097 | void __devinit pcibios_setup_bus_self(struct pci_bus *bus) | ||
1098 | { | ||
1099 | /* Fix up the bus resources */ | ||
1100 | if (bus->self != NULL) | ||
1101 | pcibios_fixup_bridge(bus); | ||
1102 | |||
1103 | /* Platform specific bus fixups. This is currently only used | ||
1104 | * by fsl_pci and I'm hoping getting rid of it at some point | ||
1105 | */ | ||
1106 | if (ppc_md.pcibios_fixup_bus) | ||
1107 | ppc_md.pcibios_fixup_bus(bus); | ||
1108 | |||
1109 | /* Setup bus DMA mappings */ | ||
1110 | if (ppc_md.pci_dma_bus_setup) | ||
1111 | ppc_md.pci_dma_bus_setup(bus); | ||
1112 | } | ||
1113 | |||
1110 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 1114 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
1111 | { | 1115 | { |
1112 | /* When called from the generic PCI probe, read PCI<->PCI bridge | 1116 | /* When called from the generic PCI probe, read PCI<->PCI bridge |
1113 | * bases before proceeding | 1117 | * bases. This isn't called when generating the PCI tree from |
1118 | * the OF device-tree. | ||
1114 | */ | 1119 | */ |
1115 | if (bus->self != NULL) | 1120 | if (bus->self != NULL) |
1116 | pci_read_bridge_bases(bus); | 1121 | pci_read_bridge_bases(bus); |
1117 | __pcibios_fixup_bus(bus); | ||
1118 | } | ||
1119 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1120 | 1122 | ||
1121 | /* When building a bus from the OF tree rather than probing, we need a | 1123 | /* Now fixup the bus bus */ |
1122 | * slightly different version of the fixup which doesn't read the | 1124 | pcibios_setup_bus_self(bus); |
1123 | * bridge bases using config space accesses | 1125 | |
1124 | */ | 1126 | /* Now fixup devices on that bus */ |
1125 | void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus) | 1127 | pcibios_setup_bus_devices(bus); |
1126 | { | ||
1127 | __pcibios_fixup_bus(bus); | ||
1128 | } | 1128 | } |
1129 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1129 | 1130 | ||
1130 | static int skip_isa_ioresource_align(struct pci_dev *dev) | 1131 | static int skip_isa_ioresource_align(struct pci_dev *dev) |
1131 | { | 1132 | { |
@@ -1392,6 +1393,7 @@ void __init pcibios_resource_survey(void) | |||
1392 | } | 1393 | } |
1393 | 1394 | ||
1394 | #ifdef CONFIG_HOTPLUG | 1395 | #ifdef CONFIG_HOTPLUG |
1396 | |||
1395 | /* This is used by the pSeries hotplug driver to allocate resource | 1397 | /* This is used by the pSeries hotplug driver to allocate resource |
1396 | * of newly plugged busses. We can try to consolidate with the | 1398 | * of newly plugged busses. We can try to consolidate with the |
1397 | * rest of the code later, for now, keep it as-is | 1399 | * rest of the code later, for now, keep it as-is |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index e6e8813c364a..39fadc6e1492 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -189,8 +189,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
189 | } | 189 | } |
190 | EXPORT_SYMBOL(of_create_pci_dev); | 190 | EXPORT_SYMBOL(of_create_pci_dev); |
191 | 191 | ||
192 | void __devinit of_scan_bus(struct device_node *node, | 192 | static void __devinit __of_scan_bus(struct device_node *node, |
193 | struct pci_bus *bus) | 193 | struct pci_bus *bus, int rescan_existing) |
194 | { | 194 | { |
195 | struct device_node *child; | 195 | struct device_node *child; |
196 | const u32 *reg; | 196 | const u32 *reg; |
@@ -215,8 +215,12 @@ void __devinit of_scan_bus(struct device_node *node, | |||
215 | pr_debug(" dev header type: %x\n", dev->hdr_type); | 215 | pr_debug(" dev header type: %x\n", dev->hdr_type); |
216 | } | 216 | } |
217 | 217 | ||
218 | /* Ally all fixups */ | 218 | /* Apply all fixups necessary. We don't fixup the bus "self" |
219 | pcibios_fixup_of_probed_bus(bus); | 219 | * for an existing bridge that is being rescanned |
220 | */ | ||
221 | if (!rescan_existing) | ||
222 | pcibios_setup_bus_self(bus); | ||
223 | pcibios_setup_bus_devices(bus); | ||
220 | 224 | ||
221 | /* Now scan child busses */ | 225 | /* Now scan child busses */ |
222 | list_for_each_entry(dev, &bus->devices, bus_list) { | 226 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -228,7 +232,20 @@ void __devinit of_scan_bus(struct device_node *node, | |||
228 | } | 232 | } |
229 | } | 233 | } |
230 | } | 234 | } |
231 | EXPORT_SYMBOL(of_scan_bus); | 235 | |
236 | void __devinit of_scan_bus(struct device_node *node, | ||
237 | struct pci_bus *bus) | ||
238 | { | ||
239 | __of_scan_bus(node, bus, 0); | ||
240 | } | ||
241 | EXPORT_SYMBOL_GPL(of_scan_bus); | ||
242 | |||
243 | void __devinit of_rescan_bus(struct device_node *node, | ||
244 | struct pci_bus *bus) | ||
245 | { | ||
246 | __of_scan_bus(node, bus, 1); | ||
247 | } | ||
248 | EXPORT_SYMBOL_GPL(of_rescan_bus); | ||
232 | 249 | ||
233 | void __devinit of_scan_pci_bridge(struct device_node *node, | 250 | void __devinit of_scan_pci_bridge(struct device_node *node, |
234 | struct pci_dev *dev) | 251 | struct pci_dev *dev) |