aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-08-18 12:20:04 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-08-18 12:20:04 -0400
commited0da6fc9d3096f54c4a76737eeae57ac81418cf (patch)
tree3bf45a192d991c5a5c80ac86eb333f9a4f796044 /arch/powerpc/kernel
parent774bd8613d0188cda72408f8ffce258d73953cad (diff)
parent9e8a9bc2d2c3ac3b8542cc5c2544248df6f3f1c5 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/cpu_setup_power4.S2
-rw-r--r--arch/powerpc/kernel/crash.c11
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/kprobes.c2
-rw-r--r--arch/powerpc/kernel/machine_kexec.c56
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c57
-rw-r--r--arch/powerpc/kernel/rtas.c21
-rw-r--r--arch/powerpc/kernel/traps.c16
9 files changed, 108 insertions, 63 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 814f242aeb8c..956c2e5564b7 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -67,9 +67,9 @@ pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
67 pci_direct_iommu.o iomap.o 67 pci_direct_iommu.o iomap.o
68pci32-$(CONFIG_PPC32) := pci_32.o 68pci32-$(CONFIG_PPC32) := pci_32.o
69obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) 69obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
70kexec-$(CONFIG_PPC64) := machine_kexec_64.o crash.o 70kexec-$(CONFIG_PPC64) := machine_kexec_64.o
71kexec-$(CONFIG_PPC32) := machine_kexec_32.o 71kexec-$(CONFIG_PPC32) := machine_kexec_32.o
72obj-$(CONFIG_KEXEC) += machine_kexec.o $(kexec-y) 72obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
73 73
74ifeq ($(CONFIG_PPC_ISERIES),y) 74ifeq ($(CONFIG_PPC_ISERIES),y)
75$(obj)/head_64.o: $(obj)/lparmap.s 75$(obj)/head_64.o: $(obj)/lparmap.s
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_power4.S
index f69af2c5d7b3..76e97aa71c45 100644
--- a/arch/powerpc/kernel/cpu_setup_power4.S
+++ b/arch/powerpc/kernel/cpu_setup_power4.S
@@ -76,6 +76,8 @@ _GLOBAL(__setup_cpu_ppc970)
76 mfspr r0,SPRN_HID0 76 mfspr r0,SPRN_HID0
77 li r11,5 /* clear DOZE and SLEEP */ 77 li r11,5 /* clear DOZE and SLEEP */
78 rldimi r0,r11,52,8 /* set NAP and DPM */ 78 rldimi r0,r11,52,8 /* set NAP and DPM */
79 li r11,0
80 rldimi r0,r11,32,31 /* clear EN_ATTN */
79 mtspr SPRN_HID0,r0 81 mtspr SPRN_HID0,r0
80 mfspr r0,SPRN_HID0 82 mfspr r0,SPRN_HID0
81 mfspr r0,SPRN_HID0 83 mfspr r0,SPRN_HID0
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 358cecdc6aef..f04c18e08b8b 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -44,6 +44,7 @@
44/* This keeps a track of which one is crashing cpu. */ 44/* This keeps a track of which one is crashing cpu. */
45int crashing_cpu = -1; 45int crashing_cpu = -1;
46static cpumask_t cpus_in_crash = CPU_MASK_NONE; 46static cpumask_t cpus_in_crash = CPU_MASK_NONE;
47cpumask_t cpus_in_sr = CPU_MASK_NONE;
47 48
48static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, 49static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
49 size_t data_len) 50 size_t data_len)
@@ -139,7 +140,13 @@ void crash_ipi_callback(struct pt_regs *regs)
139 140
140 if (ppc_md.kexec_cpu_down) 141 if (ppc_md.kexec_cpu_down)
141 ppc_md.kexec_cpu_down(1, 1); 142 ppc_md.kexec_cpu_down(1, 1);
143
144#ifdef CONFIG_PPC64
142 kexec_smp_wait(); 145 kexec_smp_wait();
146#else
147 for (;;); /* FIXME */
148#endif
149
143 /* NOTREACHED */ 150 /* NOTREACHED */
144} 151}
145 152
@@ -255,7 +262,11 @@ static void crash_kexec_prepare_cpus(int cpu)
255 * 262 *
256 * do this if kexec in setup.c ? 263 * do this if kexec in setup.c ?
257 */ 264 */
265#ifdef CONFIG_PPC64
258 smp_release_cpus(); 266 smp_release_cpus();
267#else
268 /* FIXME */
269#endif
259} 270}
260 271
261void crash_kexec_secondary(struct pt_regs *regs) 272void crash_kexec_secondary(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 01bdae35cb55..7ee685433319 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -693,7 +693,7 @@ unsigned int irq_radix_revmap(struct irq_host *host,
693 /* If not there, try to insert it */ 693 /* If not there, try to insert it */
694 virq = irq_find_mapping(host, hwirq); 694 virq = irq_find_mapping(host, hwirq);
695 if (virq != NO_IRQ) 695 if (virq != NO_IRQ)
696 radix_tree_insert(tree, virq, &irq_map[virq]); 696 radix_tree_insert(tree, hwirq, &irq_map[virq]);
697 bail: 697 bail:
698 spin_unlock_irqrestore(&irq_big_lock, flags); 698 spin_unlock_irqrestore(&irq_big_lock, flags);
699 return virq; 699 return virq;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 9f0898c89759..cd65c367b8b6 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -61,6 +61,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
61 if (!ret) { 61 if (!ret) {
62 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 62 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
63 p->opcode = *p->addr; 63 p->opcode = *p->addr;
64 flush_icache_range((unsigned long)p->ainsn.insn,
65 (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t));
64 } 66 }
65 67
66 return ret; 68 return ret;
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index a81ca1b841ec..e60a0c544d63 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -13,6 +13,7 @@
13#include <linux/reboot.h> 13#include <linux/reboot.h>
14#include <linux/threads.h> 14#include <linux/threads.h>
15#include <asm/machdep.h> 15#include <asm/machdep.h>
16#include <asm/lmb.h>
16 17
17void machine_crash_shutdown(struct pt_regs *regs) 18void machine_crash_shutdown(struct pt_regs *regs)
18{ 19{
@@ -59,3 +60,58 @@ NORET_TYPE void machine_kexec(struct kimage *image)
59 } 60 }
60 for(;;); 61 for(;;);
61} 62}
63
64static int __init early_parse_crashk(char *p)
65{
66 unsigned long size;
67
68 if (!p)
69 return 1;
70
71 size = memparse(p, &p);
72
73 if (*p == '@')
74 crashk_res.start = memparse(p + 1, &p);
75 else
76 crashk_res.start = KDUMP_KERNELBASE;
77
78 crashk_res.end = crashk_res.start + size - 1;
79
80 return 0;
81}
82early_param("crashkernel", early_parse_crashk);
83
84void __init reserve_crashkernel(void)
85{
86 unsigned long size;
87
88 if (crashk_res.start == 0)
89 return;
90
91 /* We might have got these values via the command line or the
92 * device tree, either way sanitise them now. */
93
94 size = crashk_res.end - crashk_res.start + 1;
95
96 if (crashk_res.start != KDUMP_KERNELBASE)
97 printk("Crash kernel location must be 0x%x\n",
98 KDUMP_KERNELBASE);
99
100 crashk_res.start = KDUMP_KERNELBASE;
101 size = PAGE_ALIGN(size);
102 crashk_res.end = crashk_res.start + size - 1;
103
104 /* Crash kernel trumps memory limit */
105 if (memory_limit && memory_limit <= crashk_res.end) {
106 memory_limit = crashk_res.end + 1;
107 printk("Adjusted memory limit for crashkernel, now 0x%lx\n",
108 memory_limit);
109 }
110
111 lmb_reserve(crashk_res.start, size);
112}
113
114int overlaps_crashkernel(unsigned long start, unsigned long size)
115{
116 return (start + size) > crashk_res.start && start <= crashk_res.end;
117}
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index b438d45a068c..be58985c7681 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12 12
13#include <linux/cpumask.h>
14#include <linux/kexec.h> 13#include <linux/kexec.h>
15#include <linux/smp.h> 14#include <linux/smp.h>
16#include <linux/thread_info.h> 15#include <linux/thread_info.h>
@@ -21,7 +20,6 @@
21#include <asm/machdep.h> 20#include <asm/machdep.h>
22#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
23#include <asm/paca.h> 22#include <asm/paca.h>
24#include <asm/lmb.h>
25#include <asm/mmu.h> 23#include <asm/mmu.h>
26#include <asm/sections.h> /* _end */ 24#include <asm/sections.h> /* _end */
27#include <asm/prom.h> 25#include <asm/prom.h>
@@ -385,58 +383,3 @@ static int __init kexec_setup(void)
385 return 0; 383 return 0;
386} 384}
387__initcall(kexec_setup); 385__initcall(kexec_setup);
388
389static int __init early_parse_crashk(char *p)
390{
391 unsigned long size;
392
393 if (!p)
394 return 1;
395
396 size = memparse(p, &p);
397
398 if (*p == '@')
399 crashk_res.start = memparse(p + 1, &p);
400 else
401 crashk_res.start = KDUMP_KERNELBASE;
402
403 crashk_res.end = crashk_res.start + size - 1;
404
405 return 0;
406}
407early_param("crashkernel", early_parse_crashk);
408
409void __init reserve_crashkernel(void)
410{
411 unsigned long size;
412
413 if (crashk_res.start == 0)
414 return;
415
416 /* We might have got these values via the command line or the
417 * device tree, either way sanitise them now. */
418
419 size = crashk_res.end - crashk_res.start + 1;
420
421 if (crashk_res.start != KDUMP_KERNELBASE)
422 printk("Crash kernel location must be 0x%x\n",
423 KDUMP_KERNELBASE);
424
425 crashk_res.start = KDUMP_KERNELBASE;
426 size = PAGE_ALIGN(size);
427 crashk_res.end = crashk_res.start + size - 1;
428
429 /* Crash kernel trumps memory limit */
430 if (memory_limit && memory_limit <= crashk_res.end) {
431 memory_limit = crashk_res.end + 1;
432 printk("Adjusted memory limit for crashkernel, now 0x%lx\n",
433 memory_limit);
434 }
435
436 lmb_reserve(crashk_res.start, size);
437}
438
439int overlaps_crashkernel(unsigned long start, unsigned long size)
440{
441 return (start + size) > crashk_res.start && start <= crashk_res.end;
442}
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 4a4cb5598402..77f1e06d208d 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -569,6 +569,27 @@ int rtas_set_indicator(int indicator, int index, int new_value)
569} 569}
570EXPORT_SYMBOL(rtas_set_indicator); 570EXPORT_SYMBOL(rtas_set_indicator);
571 571
572/*
573 * Ignoring RTAS extended delay
574 */
575int rtas_set_indicator_fast(int indicator, int index, int new_value)
576{
577 int rc;
578 int token = rtas_token("set-indicator");
579
580 if (token == RTAS_UNKNOWN_SERVICE)
581 return -ENOENT;
582
583 rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value);
584
585 WARN_ON(rc == -2 || (rc >= 9900 && rc <= 9905));
586
587 if (rc < 0)
588 return rtas_error_rc(rc);
589
590 return rc;
591}
592
572void rtas_restart(char *cmd) 593void rtas_restart(char *cmd)
573{ 594{
574 if (rtas_flash_term_hook) 595 if (rtas_flash_term_hook)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 05682a24b210..e4d1713e8aea 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -55,9 +55,6 @@
55 55
56#ifdef CONFIG_PPC64 /* XXX */ 56#ifdef CONFIG_PPC64 /* XXX */
57#define _IO_BASE pci_io_base 57#define _IO_BASE pci_io_base
58#ifdef CONFIG_KEXEC
59cpumask_t cpus_in_sr = CPU_MASK_NONE;
60#endif
61#endif 58#endif
62 59
63#ifdef CONFIG_DEBUGGER 60#ifdef CONFIG_DEBUGGER
@@ -211,6 +208,19 @@ void system_reset_exception(struct pt_regs *regs)
211 208
212 die("System Reset", regs, SIGABRT); 209 die("System Reset", regs, SIGABRT);
213 210
211 /*
212 * Some CPUs when released from the debugger will execute this path.
213 * These CPUs entered the debugger via a soft-reset. If the CPU was
214 * hung before entering the debugger it will return to the hung
215 * state when exiting this function. This causes a problem in
216 * kdump since the hung CPU(s) will not respond to the IPI sent
217 * from kdump. To prevent the problem we call crash_kexec_secondary()
218 * here. If a kdump had not been initiated or we exit the debugger
219 * with the "exit and recover" command (x) crash_kexec_secondary()
220 * will return after 5ms and the CPU returns to its previous state.
221 */
222 crash_kexec_secondary(regs);
223
214 /* Must die if the interrupt is not recoverable */ 224 /* Must die if the interrupt is not recoverable */
215 if (!(regs->msr & MSR_RI)) 225 if (!(regs->msr & MSR_RI))
216 panic("Unrecoverable System Reset"); 226 panic("Unrecoverable System Reset");