aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/eeh.h8
-rw-r--r--arch/powerpc/include/asm/pci.h5
-rw-r--r--arch/powerpc/kernel/pci-common.c54
-rw-r--r--arch/powerpc/kernel/pci_64.c27
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
223extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); 223extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
224extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
224 225
225extern int pci_read_irq_line(struct pci_dev *dev); 226extern 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
238extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus); 239extern void pcibios_setup_bus_devices(struct pci_bus *bus);
239 240extern 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
41static DEFINE_SPINLOCK(hose_spinlock); 42static 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
1077static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) 1078void __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
1097void __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
1110void __devinit pcibios_fixup_bus(struct pci_bus *bus) 1114void __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}
1119EXPORT_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 */
1125void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus) 1127 pcibios_setup_bus_devices(bus);
1126{
1127 __pcibios_fixup_bus(bus);
1128} 1128}
1129EXPORT_SYMBOL(pcibios_fixup_bus);
1129 1130
1130static int skip_isa_ioresource_align(struct pci_dev *dev) 1131static 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}
190EXPORT_SYMBOL(of_create_pci_dev); 190EXPORT_SYMBOL(of_create_pci_dev);
191 191
192void __devinit of_scan_bus(struct device_node *node, 192static 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}
231EXPORT_SYMBOL(of_scan_bus); 235
236void __devinit of_scan_bus(struct device_node *node,
237 struct pci_bus *bus)
238{
239 __of_scan_bus(node, bus, 0);
240}
241EXPORT_SYMBOL_GPL(of_scan_bus);
242
243void __devinit of_rescan_bus(struct device_node *node,
244 struct pci_bus *bus)
245{
246 __of_scan_bus(node, bus, 1);
247}
248EXPORT_SYMBOL_GPL(of_rescan_bus);
232 249
233void __devinit of_scan_pci_bridge(struct device_node *node, 250void __devinit of_scan_pci_bridge(struct device_node *node,
234 struct pci_dev *dev) 251 struct pci_dev *dev)