diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 19:54:33 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 19:54:33 -0500 |
commit | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (patch) | |
tree | 08a38cd3523c42bd49882f17cd501fd879e7ca1c /arch/powerpc/platforms/pseries | |
parent | c4c9f0183b7c4e97836e8fecbb67898b06c47e78 (diff) | |
parent | ca9153a3a2a7556d091dfe080e42b0e67881fff6 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (144 commits)
powerpc/44x: Support 16K/64K base page sizes on 44x
powerpc: Force memory size to be a multiple of PAGE_SIZE
powerpc/32: Wire up the trampoline code for kdump
powerpc/32: Add the ability for a classic ppc kernel to be loaded at 32M
powerpc/32: Allow __ioremap on RAM addresses for kdump kernel
powerpc/32: Setup OF properties for kdump
powerpc/32/kdump: Implement crash_setup_regs() using ppc_save_regs()
powerpc: Prepare xmon_save_regs for use with kdump
powerpc: Remove default kexec/crash_kernel ops assignments
powerpc: Make default kexec/crash_kernel ops implicit
powerpc: Setup OF properties for ppc32 kexec
powerpc/pseries: Fix cpu hotplug
powerpc: Fix KVM build on ppc440
powerpc/cell: add QPACE as a separate Cell platform
powerpc/cell: fix build breakage with CONFIG_SPUFS disabled
powerpc/mpc5200: fix error paths in PSC UART probe function
powerpc/mpc5200: add rts/cts handling in PSC UART driver
powerpc/mpc5200: Make PSC UART driver update serial errors counters
powerpc/mpc5200: Remove obsolete code from mpc5200 MDIO driver
powerpc/mpc5200: Add MDMA/UDMA support to MPC5200 ATA driver
...
Fix trivial conflict in drivers/char/Makefile as per Paul's directions
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r-- | arch/powerpc/platforms/pseries/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/cmm.c | 29 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 44 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pci_dlpar.c | 163 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/phyp_dump.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 43 |
7 files changed, 174 insertions, 114 deletions
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 97619fd51e39..ddc2a307cd50 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
@@ -54,7 +54,7 @@ config PPC_SMLPAR | |||
54 | 54 | ||
55 | config CMM | 55 | config CMM |
56 | tristate "Collaborative memory management" | 56 | tristate "Collaborative memory management" |
57 | depends on PPC_SMLPAR | 57 | depends on PPC_SMLPAR && !CRASH_DUMP |
58 | default y | 58 | default y |
59 | help | 59 | help |
60 | Select this option, if you want to enable the kernel interface | 60 | Select this option, if you want to enable the kernel interface |
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index 5cd4d2761620..6567439fe78d 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/kthread.h> | 28 | #include <linux/kthread.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/oom.h> | 30 | #include <linux/oom.h> |
31 | #include <linux/reboot.h> | ||
31 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
32 | #include <linux/stringify.h> | 33 | #include <linux/stringify.h> |
33 | #include <linux/swap.h> | 34 | #include <linux/swap.h> |
@@ -384,6 +385,26 @@ static void cmm_unregister_sysfs(struct sys_device *sysdev) | |||
384 | } | 385 | } |
385 | 386 | ||
386 | /** | 387 | /** |
388 | * cmm_reboot_notifier - Make sure pages are not still marked as "loaned" | ||
389 | * | ||
390 | **/ | ||
391 | static int cmm_reboot_notifier(struct notifier_block *nb, | ||
392 | unsigned long action, void *unused) | ||
393 | { | ||
394 | if (action == SYS_RESTART) { | ||
395 | if (cmm_thread_ptr) | ||
396 | kthread_stop(cmm_thread_ptr); | ||
397 | cmm_thread_ptr = NULL; | ||
398 | cmm_free_pages(loaned_pages); | ||
399 | } | ||
400 | return NOTIFY_DONE; | ||
401 | } | ||
402 | |||
403 | static struct notifier_block cmm_reboot_nb = { | ||
404 | .notifier_call = cmm_reboot_notifier, | ||
405 | }; | ||
406 | |||
407 | /** | ||
387 | * cmm_init - Module initialization | 408 | * cmm_init - Module initialization |
388 | * | 409 | * |
389 | * Return value: | 410 | * Return value: |
@@ -399,9 +420,12 @@ static int cmm_init(void) | |||
399 | if ((rc = register_oom_notifier(&cmm_oom_nb)) < 0) | 420 | if ((rc = register_oom_notifier(&cmm_oom_nb)) < 0) |
400 | return rc; | 421 | return rc; |
401 | 422 | ||
402 | if ((rc = cmm_sysfs_register(&cmm_sysdev))) | 423 | if ((rc = register_reboot_notifier(&cmm_reboot_nb))) |
403 | goto out_oom_notifier; | 424 | goto out_oom_notifier; |
404 | 425 | ||
426 | if ((rc = cmm_sysfs_register(&cmm_sysdev))) | ||
427 | goto out_reboot_notifier; | ||
428 | |||
405 | if (cmm_disabled) | 429 | if (cmm_disabled) |
406 | return rc; | 430 | return rc; |
407 | 431 | ||
@@ -415,6 +439,8 @@ static int cmm_init(void) | |||
415 | 439 | ||
416 | out_unregister_sysfs: | 440 | out_unregister_sysfs: |
417 | cmm_unregister_sysfs(&cmm_sysdev); | 441 | cmm_unregister_sysfs(&cmm_sysdev); |
442 | out_reboot_notifier: | ||
443 | unregister_reboot_notifier(&cmm_reboot_nb); | ||
418 | out_oom_notifier: | 444 | out_oom_notifier: |
419 | unregister_oom_notifier(&cmm_oom_nb); | 445 | unregister_oom_notifier(&cmm_oom_nb); |
420 | return rc; | 446 | return rc; |
@@ -431,6 +457,7 @@ static void cmm_exit(void) | |||
431 | if (cmm_thread_ptr) | 457 | if (cmm_thread_ptr) |
432 | kthread_stop(cmm_thread_ptr); | 458 | kthread_stop(cmm_thread_ptr); |
433 | unregister_oom_notifier(&cmm_oom_nb); | 459 | unregister_oom_notifier(&cmm_oom_nb); |
460 | unregister_reboot_notifier(&cmm_reboot_nb); | ||
434 | cmm_free_pages(loaned_pages); | 461 | cmm_free_pages(loaned_pages); |
435 | cmm_unregister_sysfs(&cmm_sysdev); | 462 | cmm_unregister_sysfs(&cmm_sysdev); |
436 | } | 463 | } |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 54816d75b578..989d6462c154 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com> | 21 | * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com> |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #undef DEBUG | ||
25 | |||
24 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
25 | #include <linux/init.h> | 27 | #include <linux/init.h> |
26 | #include <linux/list.h> | 28 | #include <linux/list.h> |
@@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) | |||
488 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || | 490 | if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || |
489 | pdn->eeh_mode & EEH_MODE_NOCHECK) { | 491 | pdn->eeh_mode & EEH_MODE_NOCHECK) { |
490 | ignored_check++; | 492 | ignored_check++; |
491 | #ifdef DEBUG | 493 | pr_debug("EEH: Ignored check (%x) for %s %s\n", |
492 | printk ("EEH:ignored check (%x) for %s %s\n", | 494 | pdn->eeh_mode, pci_name (dev), dn->full_name); |
493 | pdn->eeh_mode, pci_name (dev), dn->full_name); | ||
494 | #endif | ||
495 | return 0; | 495 | return 0; |
496 | } | 496 | } |
497 | 497 | ||
@@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct device_node *dn, void *data) | |||
1014 | eeh_subsystem_enabled = 1; | 1014 | eeh_subsystem_enabled = 1; |
1015 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; | 1015 | pdn->eeh_mode |= EEH_MODE_SUPPORTED; |
1016 | 1016 | ||
1017 | #ifdef DEBUG | 1017 | pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n", |
1018 | printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", | 1018 | dn->full_name, pdn->eeh_config_addr, |
1019 | dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); | 1019 | pdn->eeh_pe_config_addr); |
1020 | #endif | ||
1021 | } else { | 1020 | } else { |
1022 | 1021 | ||
1023 | /* This device doesn't support EEH, but it may have an | 1022 | /* This device doesn't support EEH, but it may have an |
@@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct pci_dev *dev) | |||
1161 | if (!dev || !eeh_subsystem_enabled) | 1160 | if (!dev || !eeh_subsystem_enabled) |
1162 | return; | 1161 | return; |
1163 | 1162 | ||
1164 | #ifdef DEBUG | 1163 | pr_debug("EEH: Adding device %s\n", pci_name(dev)); |
1165 | printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev)); | ||
1166 | #endif | ||
1167 | 1164 | ||
1168 | pci_dev_get (dev); | ||
1169 | dn = pci_device_to_OF_node(dev); | 1165 | dn = pci_device_to_OF_node(dev); |
1170 | pdn = PCI_DN(dn); | 1166 | pdn = PCI_DN(dn); |
1167 | if (pdn->pcidev == dev) { | ||
1168 | pr_debug("EEH: Already referenced !\n"); | ||
1169 | return; | ||
1170 | } | ||
1171 | WARN_ON(pdn->pcidev); | ||
1172 | |||
1173 | pci_dev_get (dev); | ||
1171 | pdn->pcidev = dev; | 1174 | pdn->pcidev = dev; |
1172 | 1175 | ||
1173 | pci_addr_cache_insert_device(dev); | 1176 | pci_addr_cache_insert_device(dev); |
@@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci_dev *dev) | |||
1206 | return; | 1209 | return; |
1207 | 1210 | ||
1208 | /* Unregister the device with the EEH/PCI address search system */ | 1211 | /* Unregister the device with the EEH/PCI address search system */ |
1209 | #ifdef DEBUG | 1212 | pr_debug("EEH: Removing device %s\n", pci_name(dev)); |
1210 | printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); | ||
1211 | #endif | ||
1212 | pci_addr_cache_remove_device(dev); | ||
1213 | eeh_sysfs_remove_device(dev); | ||
1214 | 1213 | ||
1215 | dn = pci_device_to_OF_node(dev); | 1214 | dn = pci_device_to_OF_node(dev); |
1216 | if (PCI_DN(dn)->pcidev) { | 1215 | if (PCI_DN(dn)->pcidev == NULL) { |
1217 | PCI_DN(dn)->pcidev = NULL; | 1216 | pr_debug("EEH: Not referenced !\n"); |
1218 | pci_dev_put (dev); | 1217 | return; |
1219 | } | 1218 | } |
1219 | PCI_DN(dn)->pcidev = NULL; | ||
1220 | pci_dev_put (dev); | ||
1221 | |||
1222 | pci_addr_cache_remove_device(dev); | ||
1223 | eeh_sysfs_remove_device(dev); | ||
1220 | } | 1224 | } |
1221 | 1225 | ||
1222 | void eeh_remove_bus_device(struct pci_dev *dev) | 1226 | void eeh_remove_bus_device(struct pci_dev *dev) |
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 1f032483c026..a20ead87153d 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c | |||
@@ -116,7 +116,7 @@ static void pseries_cpu_die(unsigned int cpu) | |||
116 | cpu_status = query_cpu_stopped(pcpu); | 116 | cpu_status = query_cpu_stopped(pcpu); |
117 | if (cpu_status == 0 || cpu_status == -1) | 117 | if (cpu_status == 0 || cpu_status == -1) |
118 | break; | 118 | break; |
119 | msleep(200); | 119 | cpu_relax(); |
120 | } | 120 | } |
121 | if (cpu_status != 0) { | 121 | if (cpu_status != 0) { |
122 | printk("Querying DEAD? cpu %i (%i) shows %i\n", | 122 | printk("Querying DEAD? cpu %i (%i) shows %i\n", |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 7190493e9bdc..5e1ed3d60ee5 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
@@ -25,6 +25,8 @@ | |||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #undef DEBUG | ||
29 | |||
28 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
29 | #include <asm/pci-bridge.h> | 31 | #include <asm/pci-bridge.h> |
30 | #include <asm/ppc-pci.h> | 32 | #include <asm/ppc-pci.h> |
@@ -69,74 +71,25 @@ EXPORT_SYMBOL_GPL(pcibios_find_pci_bus); | |||
69 | * Remove all of the PCI devices under this bus both from the | 71 | * Remove all of the PCI devices under this bus both from the |
70 | * linux pci device tree, and from the powerpc EEH address cache. | 72 | * linux pci device tree, and from the powerpc EEH address cache. |
71 | */ | 73 | */ |
72 | void | 74 | void pcibios_remove_pci_devices(struct pci_bus *bus) |
73 | pcibios_remove_pci_devices(struct pci_bus *bus) | ||
74 | { | 75 | { |
75 | struct pci_dev *dev, *tmp; | 76 | struct pci_dev *dev, *tmp; |
77 | struct pci_bus *child_bus; | ||
78 | |||
79 | /* First go down child busses */ | ||
80 | list_for_each_entry(child_bus, &bus->children, node) | ||
81 | pcibios_remove_pci_devices(child_bus); | ||
76 | 82 | ||
83 | pr_debug("PCI: Removing devices on bus %04x:%02x\n", | ||
84 | pci_domain_nr(bus), bus->number); | ||
77 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 85 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { |
86 | pr_debug(" * Removing %s...\n", pci_name(dev)); | ||
78 | eeh_remove_bus_device(dev); | 87 | eeh_remove_bus_device(dev); |
79 | pci_remove_bus_device(dev); | 88 | pci_remove_bus_device(dev); |
80 | } | 89 | } |
81 | } | 90 | } |
82 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); | 91 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); |
83 | 92 | ||
84 | /* Must be called before pci_bus_add_devices */ | ||
85 | void | ||
86 | pcibios_fixup_new_pci_devices(struct pci_bus *bus) | ||
87 | { | ||
88 | struct pci_dev *dev; | ||
89 | |||
90 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
91 | /* Skip already-added devices */ | ||
92 | if (!dev->is_added) { | ||
93 | int i; | ||
94 | |||
95 | /* Fill device archdata and setup iommu table */ | ||
96 | pcibios_setup_new_device(dev); | ||
97 | |||
98 | pci_read_irq_line(dev); | ||
99 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
100 | struct resource *r = &dev->resource[i]; | ||
101 | |||
102 | if (r->parent || !r->start || !r->flags) | ||
103 | continue; | ||
104 | pci_claim_resource(dev, i); | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices); | ||
110 | |||
111 | static int | ||
112 | pcibios_pci_config_bridge(struct pci_dev *dev) | ||
113 | { | ||
114 | u8 sec_busno; | ||
115 | struct pci_bus *child_bus; | ||
116 | |||
117 | /* Get busno of downstream bus */ | ||
118 | pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); | ||
119 | |||
120 | /* Add to children of PCI bridge dev->bus */ | ||
121 | child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); | ||
122 | if (!child_bus) { | ||
123 | printk (KERN_ERR "%s: could not add second bus\n", __func__); | ||
124 | return -EIO; | ||
125 | } | ||
126 | sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); | ||
127 | |||
128 | pci_scan_child_bus(child_bus); | ||
129 | |||
130 | /* Fixup new pci devices */ | ||
131 | pcibios_fixup_new_pci_devices(child_bus); | ||
132 | |||
133 | /* Make the discovered devices available */ | ||
134 | pci_bus_add_devices(child_bus); | ||
135 | |||
136 | eeh_add_device_tree_late(child_bus); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | /** | 93 | /** |
141 | * pcibios_add_pci_devices - adds new pci devices to bus | 94 | * pcibios_add_pci_devices - adds new pci devices to bus |
142 | * | 95 | * |
@@ -147,10 +100,9 @@ pcibios_pci_config_bridge(struct pci_dev *dev) | |||
147 | * is how this routine differs from other, similar pcibios | 100 | * is how this routine differs from other, similar pcibios |
148 | * routines.) | 101 | * routines.) |
149 | */ | 102 | */ |
150 | void | 103 | void pcibios_add_pci_devices(struct pci_bus * bus) |
151 | pcibios_add_pci_devices(struct pci_bus * bus) | ||
152 | { | 104 | { |
153 | int slotno, num, mode; | 105 | int slotno, num, mode, pass, max; |
154 | struct pci_dev *dev; | 106 | struct pci_dev *dev; |
155 | struct device_node *dn = pci_bus_to_OF_node(bus); | 107 | struct device_node *dn = pci_bus_to_OF_node(bus); |
156 | 108 | ||
@@ -162,26 +114,23 @@ pcibios_add_pci_devices(struct pci_bus * bus) | |||
162 | 114 | ||
163 | if (mode == PCI_PROBE_DEVTREE) { | 115 | if (mode == PCI_PROBE_DEVTREE) { |
164 | /* use ofdt-based probe */ | 116 | /* use ofdt-based probe */ |
165 | of_scan_bus(dn, bus); | 117 | of_rescan_bus(dn, bus); |
166 | if (!list_empty(&bus->devices)) { | ||
167 | pcibios_fixup_new_pci_devices(bus); | ||
168 | pci_bus_add_devices(bus); | ||
169 | eeh_add_device_tree_late(bus); | ||
170 | } | ||
171 | } else if (mode == PCI_PROBE_NORMAL) { | 118 | } else if (mode == PCI_PROBE_NORMAL) { |
172 | /* use legacy probe */ | 119 | /* use legacy probe */ |
173 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); | 120 | slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); |
174 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); | 121 | num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); |
175 | if (num) { | 122 | if (!num) |
176 | pcibios_fixup_new_pci_devices(bus); | 123 | return; |
177 | pci_bus_add_devices(bus); | 124 | pcibios_setup_bus_devices(bus); |
178 | eeh_add_device_tree_late(bus); | 125 | max = bus->secondary; |
126 | for (pass=0; pass < 2; pass++) | ||
127 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
128 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
129 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
130 | max = pci_scan_bridge(bus, dev, max, pass); | ||
179 | } | 131 | } |
180 | |||
181 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
182 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
183 | pcibios_pci_config_bridge(dev); | ||
184 | } | 132 | } |
133 | pcibios_finish_adding_to_bus(bus); | ||
185 | } | 134 | } |
186 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); | 135 | EXPORT_SYMBOL_GPL(pcibios_add_pci_devices); |
187 | 136 | ||
@@ -190,6 +139,8 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | |||
190 | struct pci_controller *phb; | 139 | struct pci_controller *phb; |
191 | int primary; | 140 | int primary; |
192 | 141 | ||
142 | pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name); | ||
143 | |||
193 | primary = list_empty(&hose_list); | 144 | primary = list_empty(&hose_list); |
194 | phb = pcibios_alloc_controller(dn); | 145 | phb = pcibios_alloc_controller(dn); |
195 | if (!phb) | 146 | if (!phb) |
@@ -203,11 +154,59 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) | |||
203 | eeh_add_device_tree_early(dn); | 154 | eeh_add_device_tree_early(dn); |
204 | 155 | ||
205 | scan_phb(phb); | 156 | scan_phb(phb); |
206 | pcibios_allocate_bus_resources(phb->bus); | 157 | pcibios_finish_adding_to_bus(phb->bus); |
207 | pcibios_fixup_new_pci_devices(phb->bus); | ||
208 | pci_bus_add_devices(phb->bus); | ||
209 | eeh_add_device_tree_late(phb->bus); | ||
210 | 158 | ||
211 | return phb; | 159 | return phb; |
212 | } | 160 | } |
213 | EXPORT_SYMBOL_GPL(init_phb_dynamic); | 161 | EXPORT_SYMBOL_GPL(init_phb_dynamic); |
162 | |||
163 | /* RPA-specific bits for removing PHBs */ | ||
164 | int remove_phb_dynamic(struct pci_controller *phb) | ||
165 | { | ||
166 | struct pci_bus *b = phb->bus; | ||
167 | struct resource *res; | ||
168 | int rc, i; | ||
169 | |||
170 | pr_debug("PCI: Removing PHB %04x:%02x... \n", | ||
171 | pci_domain_nr(b), b->number); | ||
172 | |||
173 | /* We cannot to remove a root bus that has children */ | ||
174 | if (!(list_empty(&b->children) && list_empty(&b->devices))) | ||
175 | return -EBUSY; | ||
176 | |||
177 | /* We -know- there aren't any child devices anymore at this stage | ||
178 | * and thus, we can safely unmap the IO space as it's not in use | ||
179 | */ | ||
180 | res = &phb->io_resource; | ||
181 | if (res->flags & IORESOURCE_IO) { | ||
182 | rc = pcibios_unmap_io_space(b); | ||
183 | if (rc) { | ||
184 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", | ||
185 | __func__, b->name); | ||
186 | return 1; | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /* Unregister the bridge device from sysfs and remove the PCI bus */ | ||
191 | device_unregister(b->bridge); | ||
192 | phb->bus = NULL; | ||
193 | pci_remove_bus(b); | ||
194 | |||
195 | /* Now release the IO resource */ | ||
196 | if (res->flags & IORESOURCE_IO) | ||
197 | release_resource(res); | ||
198 | |||
199 | /* Release memory resources */ | ||
200 | for (i = 0; i < 3; ++i) { | ||
201 | res = &phb->mem_resources[i]; | ||
202 | if (!(res->flags & IORESOURCE_MEM)) | ||
203 | continue; | ||
204 | release_resource(res); | ||
205 | } | ||
206 | |||
207 | /* Free pci_controller data structure */ | ||
208 | pcibios_free_controller(phb); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | EXPORT_SYMBOL_GPL(remove_phb_dynamic); | ||
diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c index edbc012c2ebc..6cf35cd8d0b5 100644 --- a/arch/powerpc/platforms/pseries/phyp_dump.c +++ b/arch/powerpc/platforms/pseries/phyp_dump.c | |||
@@ -130,6 +130,9 @@ static unsigned long init_dump_header(struct phyp_dump_header *ph) | |||
130 | static void print_dump_header(const struct phyp_dump_header *ph) | 130 | static void print_dump_header(const struct phyp_dump_header *ph) |
131 | { | 131 | { |
132 | #ifdef DEBUG | 132 | #ifdef DEBUG |
133 | if (ph == NULL) | ||
134 | return; | ||
135 | |||
133 | printk(KERN_INFO "dump header:\n"); | 136 | printk(KERN_INFO "dump header:\n"); |
134 | /* setup some ph->sections required */ | 137 | /* setup some ph->sections required */ |
135 | printk(KERN_INFO "version = %d\n", ph->version); | 138 | printk(KERN_INFO "version = %d\n", ph->version); |
@@ -411,6 +414,8 @@ static int __init phyp_dump_setup(void) | |||
411 | of_node_put(rtas); | 414 | of_node_put(rtas); |
412 | } | 415 | } |
413 | 416 | ||
417 | ibm_configure_kernel_dump = rtas_token("ibm,configure-kernel-dump"); | ||
418 | |||
414 | print_dump_header(dump_header); | 419 | print_dump_header(dump_header); |
415 | dump_area_length = init_dump_header(&phdr); | 420 | dump_area_length = init_dump_header(&phdr); |
416 | /* align down */ | 421 | /* align down */ |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index e1904774a70f..f7a69021b7bf 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -579,7 +579,7 @@ static void xics_update_irq_servers(void) | |||
579 | int i, j; | 579 | int i, j; |
580 | struct device_node *np; | 580 | struct device_node *np; |
581 | u32 ilen; | 581 | u32 ilen; |
582 | const u32 *ireg, *isize; | 582 | const u32 *ireg; |
583 | u32 hcpuid; | 583 | u32 hcpuid; |
584 | 584 | ||
585 | /* Find the server numbers for the boot cpu. */ | 585 | /* Find the server numbers for the boot cpu. */ |
@@ -607,11 +607,6 @@ static void xics_update_irq_servers(void) | |||
607 | } | 607 | } |
608 | } | 608 | } |
609 | 609 | ||
610 | /* get the bit size of server numbers */ | ||
611 | isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); | ||
612 | if (isize) | ||
613 | interrupt_server_size = *isize; | ||
614 | |||
615 | of_node_put(np); | 610 | of_node_put(np); |
616 | } | 611 | } |
617 | 612 | ||
@@ -682,6 +677,7 @@ void __init xics_init_IRQ(void) | |||
682 | struct device_node *np; | 677 | struct device_node *np; |
683 | u32 indx = 0; | 678 | u32 indx = 0; |
684 | int found = 0; | 679 | int found = 0; |
680 | const u32 *isize; | ||
685 | 681 | ||
686 | ppc64_boot_msg(0x20, "XICS Init"); | 682 | ppc64_boot_msg(0x20, "XICS Init"); |
687 | 683 | ||
@@ -701,6 +697,26 @@ void __init xics_init_IRQ(void) | |||
701 | if (found == 0) | 697 | if (found == 0) |
702 | return; | 698 | return; |
703 | 699 | ||
700 | /* get the bit size of server numbers */ | ||
701 | found = 0; | ||
702 | |||
703 | for_each_compatible_node(np, NULL, "ibm,ppc-xics") { | ||
704 | isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); | ||
705 | |||
706 | if (!isize) | ||
707 | continue; | ||
708 | |||
709 | if (!found) { | ||
710 | interrupt_server_size = *isize; | ||
711 | found = 1; | ||
712 | } else if (*isize != interrupt_server_size) { | ||
713 | printk(KERN_WARNING "XICS: " | ||
714 | "mismatched ibm,interrupt-server#-size\n"); | ||
715 | interrupt_server_size = max(*isize, | ||
716 | interrupt_server_size); | ||
717 | } | ||
718 | } | ||
719 | |||
704 | xics_update_irq_servers(); | 720 | xics_update_irq_servers(); |
705 | xics_init_host(); | 721 | xics_init_host(); |
706 | 722 | ||
@@ -728,9 +744,18 @@ static void xics_set_cpu_priority(unsigned char cppr) | |||
728 | /* Have the calling processor join or leave the specified global queue */ | 744 | /* Have the calling processor join or leave the specified global queue */ |
729 | static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) | 745 | static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) |
730 | { | 746 | { |
731 | int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, | 747 | int index; |
732 | (1UL << interrupt_server_size) - 1 - gserver, join); | 748 | int status; |
733 | WARN_ON(status < 0); | 749 | |
750 | if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL)) | ||
751 | return; | ||
752 | |||
753 | index = (1UL << interrupt_server_size) - 1 - gserver; | ||
754 | |||
755 | status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join); | ||
756 | |||
757 | WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n", | ||
758 | GLOBAL_INTERRUPT_QUEUE, index, join, status); | ||
734 | } | 759 | } |
735 | 760 | ||
736 | void xics_setup_cpu(void) | 761 | void xics_setup_cpu(void) |