diff options
Diffstat (limited to 'arch/ppc64/kernel')
-rw-r--r-- | arch/ppc64/kernel/LparData.c | 88 | ||||
-rw-r--r-- | arch/ppc64/kernel/head.S | 42 | ||||
-rw-r--r-- | arch/ppc64/kernel/machine_kexec.c | 12 | ||||
-rw-r--r-- | arch/ppc64/kernel/misc.S | 6 | ||||
-rw-r--r-- | arch/ppc64/kernel/mpic.c | 4 | ||||
-rw-r--r-- | arch/ppc64/kernel/mpic.h | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/pci.c | 20 | ||||
-rw-r--r-- | arch/ppc64/kernel/pmac_setup.c | 12 | ||||
-rw-r--r-- | arch/ppc64/kernel/prom.c | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/smp.c | 15 | ||||
-rw-r--r-- | arch/ppc64/kernel/udbg.c | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/xics.c | 31 |
13 files changed, 150 insertions, 88 deletions
diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index 6ffcf67dd507..76cfd1449d52 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c | |||
@@ -33,17 +33,36 @@ | |||
33 | * the hypervisor and Linux. | 33 | * the hypervisor and Linux. |
34 | */ | 34 | */ |
35 | 35 | ||
36 | /* | ||
37 | * WARNING - magic here | ||
38 | * | ||
39 | * Ok, this is a horrid hack below, but marginally better than the | ||
40 | * alternatives. What we really want is just to initialize | ||
41 | * hvReleaseData in C as in the #if 0 section here. However, gcc | ||
42 | * refuses to believe that (u32)&x is a constant expression, so will | ||
43 | * not allow the xMsNucDataOffset field to be properly initialized. | ||
44 | * So, we declare hvReleaseData in inline asm instead. We use inline | ||
45 | * asm, rather than a .S file, because the assembler won't generate | ||
46 | * the necessary relocation for the LparMap either, unless that symbol | ||
47 | * is declared in the same source file. Finally, we put the asm in a | ||
48 | * dummy, attribute-used function, instead of at file scope, because | ||
49 | * file scope asms don't allow contraints. We want to use the "i" | ||
50 | * constraints to put sizeof() and offsetof() expressions in there, | ||
51 | * because including asm/offsets.h in C code then stringifying causes | ||
52 | * all manner of warnings. | ||
53 | */ | ||
54 | #if 0 | ||
36 | struct HvReleaseData hvReleaseData = { | 55 | struct HvReleaseData hvReleaseData = { |
37 | .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ | 56 | .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ |
38 | .xSize = sizeof(struct HvReleaseData), | 57 | .xSize = sizeof(struct HvReleaseData), |
39 | .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), | 58 | .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), |
40 | .xSlicNacaAddr = &naca, /* 64-bit Naca address */ | 59 | .xSlicNacaAddr = &naca, /* 64-bit Naca address */ |
41 | .xMsNucDataOffset = 0x4800, /* offset of LparMap within loadarea (see head.S) */ | 60 | .xMsNucDataOffset = (u32)((unsigned long)&xLparMap - KERNELBASE), |
42 | .xTagsMode = 1, /* tags inactive */ | 61 | .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ |
43 | .xAddressSize = 0, /* 64 bit */ | 62 | /* 64 bit */ |
44 | .xNoSharedProcs = 0, /* shared processors */ | 63 | /* shared processors */ |
45 | .xNoHMT = 0, /* HMT allowed */ | 64 | /* HMT allowed */ |
46 | .xRsvd2 = 6, /* TEMP: This allows non-GA driver */ | 65 | | 6, /* TEMP: This allows non-GA driver */ |
47 | .xVrmIndex = 4, /* We are v5r2m0 */ | 66 | .xVrmIndex = 4, /* We are v5r2m0 */ |
48 | .xMinSupportedPlicVrmIndex = 3, /* v5r1m0 */ | 67 | .xMinSupportedPlicVrmIndex = 3, /* v5r1m0 */ |
49 | .xMinCompatablePlicVrmIndex = 3, /* v5r1m0 */ | 68 | .xMinCompatablePlicVrmIndex = 3, /* v5r1m0 */ |
@@ -51,6 +70,63 @@ struct HvReleaseData hvReleaseData = { | |||
51 | 0xa7, 0x40, 0xf2, 0x4b, | 70 | 0xa7, 0x40, 0xf2, 0x4b, |
52 | 0xf4, 0x4b, 0xf6, 0xf4 }, | 71 | 0xf4, 0x4b, 0xf6, 0xf4 }, |
53 | }; | 72 | }; |
73 | #endif | ||
74 | |||
75 | |||
76 | extern struct HvReleaseData hvReleaseData; | ||
77 | |||
78 | static void __attribute_used__ hvReleaseData_wrapper(void) | ||
79 | { | ||
80 | /* This doesn't appear to need any alignment (even 4 byte) */ | ||
81 | asm volatile ( | ||
82 | " lparMapPhys = xLparMap - %3\n" | ||
83 | " .data\n" | ||
84 | " .globl hvReleaseData\n" | ||
85 | "hvReleaseData:\n" | ||
86 | " .long 0xc8a5d9c4\n" /* xDesc */ | ||
87 | /* "HvRD" in ebcdic */ | ||
88 | " .short %0\n" /* xSize */ | ||
89 | " .short %1\n" /* xVpdAreasPtrOffset */ | ||
90 | " .llong naca\n" /* xSlicNacaAddr */ | ||
91 | " .long lparMapPhys\n" /* xMsNucDataOffset */ | ||
92 | " .long 0\n" /* xRsvd1 */ | ||
93 | " .short %2\n" /* xFlags */ | ||
94 | " .short 4\n" /* xVrmIndex - v5r2m0 */ | ||
95 | " .short 3\n" /* xMinSupportedPlicVrmIndex - v5r1m0 */ | ||
96 | " .short 3\n" /* xMinCompatablePlicVrmIndex - v5r1m0 */ | ||
97 | " .long 0xd38995a4\n" /* xVrmName */ | ||
98 | " .long 0xa740f24b\n" /* "Linux 2.4.64" ebcdic */ | ||
99 | " .long 0xf44bf6f4\n" | ||
100 | " . = hvReleaseData + %0\n" | ||
101 | " .previous\n" | ||
102 | : : "i"(sizeof(hvReleaseData)), | ||
103 | "i"(offsetof(struct naca_struct, xItVpdAreas)), | ||
104 | "i"(HVREL_TAGSINACTIVE /* tags inactive, 64 bit, */ | ||
105 | /* shared processors, HMT allowed */ | ||
106 | | 6), /* TEMP: This allows non-GA drivers */ | ||
107 | "i"(KERNELBASE) | ||
108 | ); | ||
109 | } | ||
110 | |||
111 | struct LparMap __attribute__((aligned (16))) xLparMap = { | ||
112 | .xNumberEsids = HvEsidsToMap, | ||
113 | .xNumberRanges = HvRangesToMap, | ||
114 | .xSegmentTableOffs = STAB0_PAGE, | ||
115 | |||
116 | .xEsids = { | ||
117 | { .xKernelEsid = GET_ESID(KERNELBASE), | ||
118 | .xKernelVsid = KERNEL_VSID(KERNELBASE), }, | ||
119 | { .xKernelEsid = GET_ESID(VMALLOCBASE), | ||
120 | .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, | ||
121 | }, | ||
122 | |||
123 | .xRanges = { | ||
124 | { .xPages = HvPagesToMap, | ||
125 | .xOffset = 0, | ||
126 | .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), | ||
127 | }, | ||
128 | }, | ||
129 | }; | ||
54 | 130 | ||
55 | extern void system_reset_iSeries(void); | 131 | extern void system_reset_iSeries(void); |
56 | extern void machine_check_iSeries(void); | 132 | extern void machine_check_iSeries(void); |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 93ebcac0d5a2..784f56d4684c 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -522,36 +522,9 @@ __end_interrupts: | |||
522 | #ifdef CONFIG_PPC_ISERIES | 522 | #ifdef CONFIG_PPC_ISERIES |
523 | .globl naca | 523 | .globl naca |
524 | naca: | 524 | naca: |
525 | .llong itVpdAreas | 525 | .llong itVpdAreas |
526 | 526 | .llong 0 /* xRamDisk */ | |
527 | /* | 527 | .llong 0 /* xRamDiskSize */ |
528 | * The iSeries LPAR map is at this fixed address | ||
529 | * so that the HvReleaseData structure can address | ||
530 | * it with a 32-bit offset. | ||
531 | * | ||
532 | * The VSID values below are dependent on the | ||
533 | * VSID generation algorithm. See include/asm/mmu_context.h. | ||
534 | */ | ||
535 | |||
536 | . = 0x4800 | ||
537 | |||
538 | .llong 2 /* # ESIDs to be mapped by hypervisor */ | ||
539 | .llong 1 /* # memory ranges to be mapped by hypervisor */ | ||
540 | .llong STAB0_PAGE /* Page # of segment table within load area */ | ||
541 | .llong 0 /* Reserved */ | ||
542 | .llong 0 /* Reserved */ | ||
543 | .llong 0 /* Reserved */ | ||
544 | .llong 0 /* Reserved */ | ||
545 | .llong 0 /* Reserved */ | ||
546 | .llong (KERNELBASE>>SID_SHIFT) | ||
547 | .llong 0x408f92c94 /* KERNELBASE VSID */ | ||
548 | /* We have to list the bolted VMALLOC segment here, too, so that it | ||
549 | * will be restored on shared processor switch */ | ||
550 | .llong (VMALLOCBASE>>SID_SHIFT) | ||
551 | .llong 0xf09b89af5 /* VMALLOCBASE VSID */ | ||
552 | .llong 8192 /* # pages to map (32 MB) */ | ||
553 | .llong 0 /* Offset from start of loadarea to start of map */ | ||
554 | .llong 0x408f92c940000 /* VPN of first page to map */ | ||
555 | 528 | ||
556 | . = 0x6100 | 529 | . = 0x6100 |
557 | 530 | ||
@@ -2098,7 +2071,7 @@ _GLOBAL(hmt_start_secondary) | |||
2098 | blr | 2071 | blr |
2099 | #endif | 2072 | #endif |
2100 | 2073 | ||
2101 | #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) | 2074 | #if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)) |
2102 | _GLOBAL(smp_release_cpus) | 2075 | _GLOBAL(smp_release_cpus) |
2103 | /* All secondary cpus are spinning on a common | 2076 | /* All secondary cpus are spinning on a common |
2104 | * spinloop, release them all now so they can start | 2077 | * spinloop, release them all now so they can start |
@@ -2131,13 +2104,6 @@ empty_zero_page: | |||
2131 | swapper_pg_dir: | 2104 | swapper_pg_dir: |
2132 | .space 4096 | 2105 | .space 4096 |
2133 | 2106 | ||
2134 | #ifdef CONFIG_SMP | ||
2135 | /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */ | ||
2136 | .globl stab_array | ||
2137 | stab_array: | ||
2138 | .space 4096 * 48 | ||
2139 | #endif | ||
2140 | |||
2141 | /* | 2107 | /* |
2142 | * This space gets a copy of optional info passed to us by the bootstrap | 2108 | * This space gets a copy of optional info passed to us by the bootstrap |
2143 | * Used to pass parameters into the kernel like root=/dev/sda1, etc. | 2109 | * Used to pass parameters into the kernel like root=/dev/sda1, etc. |
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c index fdb2fc649d72..4775f12a013c 100644 --- a/arch/ppc64/kernel/machine_kexec.c +++ b/arch/ppc64/kernel/machine_kexec.c | |||
@@ -185,7 +185,7 @@ void kexec_copy_flush(struct kimage *image) | |||
185 | void kexec_smp_down(void *arg) | 185 | void kexec_smp_down(void *arg) |
186 | { | 186 | { |
187 | if (ppc_md.cpu_irq_down) | 187 | if (ppc_md.cpu_irq_down) |
188 | ppc_md.cpu_irq_down(); | 188 | ppc_md.cpu_irq_down(1); |
189 | 189 | ||
190 | local_irq_disable(); | 190 | local_irq_disable(); |
191 | kexec_smp_wait(); | 191 | kexec_smp_wait(); |
@@ -232,7 +232,7 @@ static void kexec_prepare_cpus(void) | |||
232 | 232 | ||
233 | /* after we tell the others to go down */ | 233 | /* after we tell the others to go down */ |
234 | if (ppc_md.cpu_irq_down) | 234 | if (ppc_md.cpu_irq_down) |
235 | ppc_md.cpu_irq_down(); | 235 | ppc_md.cpu_irq_down(0); |
236 | 236 | ||
237 | put_cpu(); | 237 | put_cpu(); |
238 | 238 | ||
@@ -243,15 +243,19 @@ static void kexec_prepare_cpus(void) | |||
243 | 243 | ||
244 | static void kexec_prepare_cpus(void) | 244 | static void kexec_prepare_cpus(void) |
245 | { | 245 | { |
246 | extern void smp_release_cpus(void); | ||
246 | /* | 247 | /* |
247 | * move the secondarys to us so that we can copy | 248 | * move the secondarys to us so that we can copy |
248 | * the new kernel 0-0x100 safely | 249 | * the new kernel 0-0x100 safely |
249 | * | 250 | * |
250 | * do this if kexec in setup.c ? | 251 | * do this if kexec in setup.c ? |
252 | * | ||
253 | * We need to release the cpus if we are ever going from an | ||
254 | * UP to an SMP kernel. | ||
251 | */ | 255 | */ |
252 | smp_relase_cpus(); | 256 | smp_release_cpus(); |
253 | if (ppc_md.cpu_irq_down) | 257 | if (ppc_md.cpu_irq_down) |
254 | ppc_md.cpu_irq_down(); | 258 | ppc_md.cpu_irq_down(0); |
255 | local_irq_disable(); | 259 | local_irq_disable(); |
256 | } | 260 | } |
257 | 261 | ||
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 59f4f9973818..a05b50b738e9 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -1129,6 +1129,9 @@ _GLOBAL(sys_call_table32) | |||
1129 | .llong .compat_sys_waitid | 1129 | .llong .compat_sys_waitid |
1130 | .llong .sys32_ioprio_set | 1130 | .llong .sys32_ioprio_set |
1131 | .llong .sys32_ioprio_get | 1131 | .llong .sys32_ioprio_get |
1132 | .llong .sys_inotify_init /* 275 */ | ||
1133 | .llong .sys_inotify_add_watch | ||
1134 | .llong .sys_inotify_rm_watch | ||
1132 | 1135 | ||
1133 | .balign 8 | 1136 | .balign 8 |
1134 | _GLOBAL(sys_call_table) | 1137 | _GLOBAL(sys_call_table) |
@@ -1407,3 +1410,6 @@ _GLOBAL(sys_call_table) | |||
1407 | .llong .sys_waitid | 1410 | .llong .sys_waitid |
1408 | .llong .sys_ioprio_set | 1411 | .llong .sys_ioprio_set |
1409 | .llong .sys_ioprio_get | 1412 | .llong .sys_ioprio_get |
1413 | .llong .sys_inotify_init /* 275 */ | ||
1414 | .llong .sys_inotify_add_watch | ||
1415 | .llong .sys_inotify_rm_watch | ||
diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c index e8fbab1df37f..cc262a05ddb4 100644 --- a/arch/ppc64/kernel/mpic.c +++ b/arch/ppc64/kernel/mpic.c | |||
@@ -794,10 +794,10 @@ void mpic_setup_this_cpu(void) | |||
794 | 794 | ||
795 | /* | 795 | /* |
796 | * XXX: someone who knows mpic should check this. | 796 | * XXX: someone who knows mpic should check this. |
797 | * do we need to eoi the ipi here (see xics comments)? | 797 | * do we need to eoi the ipi including for kexec cpu here (see xics comments)? |
798 | * or can we reset the mpic in the new kernel? | 798 | * or can we reset the mpic in the new kernel? |
799 | */ | 799 | */ |
800 | void mpic_teardown_this_cpu(void) | 800 | void mpic_teardown_this_cpu(int secondary) |
801 | { | 801 | { |
802 | struct mpic *mpic = mpic_primary; | 802 | struct mpic *mpic = mpic_primary; |
803 | unsigned long flags; | 803 | unsigned long flags; |
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h index 99fbbc9a084c..ca78a7f10528 100644 --- a/arch/ppc64/kernel/mpic.h +++ b/arch/ppc64/kernel/mpic.h | |||
@@ -256,7 +256,7 @@ extern unsigned int mpic_irq_get_priority(unsigned int irq); | |||
256 | extern void mpic_setup_this_cpu(void); | 256 | extern void mpic_setup_this_cpu(void); |
257 | 257 | ||
258 | /* Clean up for kexec (or cpu offline or ...) */ | 258 | /* Clean up for kexec (or cpu offline or ...) */ |
259 | extern void mpic_teardown_this_cpu(void); | 259 | extern void mpic_teardown_this_cpu(int secondary); |
260 | 260 | ||
261 | /* Request IPIs on primary mpic */ | 261 | /* Request IPIs on primary mpic */ |
262 | extern void mpic_request_ipis(void); | 262 | extern void mpic_request_ipis(void); |
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index ae6f579d3fa0..d0d55c7908ef 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
@@ -108,8 +108,28 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region | |||
108 | region->end = res->end - offset; | 108 | region->end = res->end - offset; |
109 | } | 109 | } |
110 | 110 | ||
111 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
112 | struct pci_bus_region *region) | ||
113 | { | ||
114 | unsigned long offset = 0; | ||
115 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
116 | |||
117 | if (!hose) | ||
118 | return; | ||
119 | |||
120 | if (res->flags & IORESOURCE_IO) | ||
121 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | ||
122 | |||
123 | if (res->flags & IORESOURCE_MEM) | ||
124 | offset = hose->pci_mem_offset; | ||
125 | |||
126 | res->start = region->start + offset; | ||
127 | res->end = region->end + offset; | ||
128 | } | ||
129 | |||
111 | #ifdef CONFIG_HOTPLUG | 130 | #ifdef CONFIG_HOTPLUG |
112 | EXPORT_SYMBOL(pcibios_resource_to_bus); | 131 | EXPORT_SYMBOL(pcibios_resource_to_bus); |
132 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
113 | #endif | 133 | #endif |
114 | 134 | ||
115 | /* | 135 | /* |
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index 3013cdb5f933..e40877fa67cd 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c | |||
@@ -97,7 +97,7 @@ EXPORT_SYMBOL(smu_cmdbuf_abs); | |||
97 | 97 | ||
98 | extern void udbg_init_scc(struct device_node *np); | 98 | extern void udbg_init_scc(struct device_node *np); |
99 | 99 | ||
100 | void __pmac pmac_show_cpuinfo(struct seq_file *m) | 100 | static void __pmac pmac_show_cpuinfo(struct seq_file *m) |
101 | { | 101 | { |
102 | struct device_node *np; | 102 | struct device_node *np; |
103 | char *pp; | 103 | char *pp; |
@@ -144,7 +144,7 @@ void __pmac pmac_show_cpuinfo(struct seq_file *m) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | 146 | ||
147 | void __init pmac_setup_arch(void) | 147 | static void __init pmac_setup_arch(void) |
148 | { | 148 | { |
149 | /* init to some ~sane value until calibrate_delay() runs */ | 149 | /* init to some ~sane value until calibrate_delay() runs */ |
150 | loops_per_jiffy = 50000000; | 150 | loops_per_jiffy = 50000000; |
@@ -230,7 +230,7 @@ void __pmac note_bootable_part(dev_t dev, int part, int goodness) | |||
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | void __pmac pmac_restart(char *cmd) | 233 | static void __pmac pmac_restart(char *cmd) |
234 | { | 234 | { |
235 | switch(sys_ctrler) { | 235 | switch(sys_ctrler) { |
236 | #ifdef CONFIG_ADB_PMU | 236 | #ifdef CONFIG_ADB_PMU |
@@ -249,7 +249,7 @@ void __pmac pmac_restart(char *cmd) | |||
249 | } | 249 | } |
250 | } | 250 | } |
251 | 251 | ||
252 | void __pmac pmac_power_off(void) | 252 | static void __pmac pmac_power_off(void) |
253 | { | 253 | { |
254 | switch(sys_ctrler) { | 254 | switch(sys_ctrler) { |
255 | #ifdef CONFIG_ADB_PMU | 255 | #ifdef CONFIG_ADB_PMU |
@@ -267,7 +267,7 @@ void __pmac pmac_power_off(void) | |||
267 | } | 267 | } |
268 | } | 268 | } |
269 | 269 | ||
270 | void __pmac pmac_halt(void) | 270 | static void __pmac pmac_halt(void) |
271 | { | 271 | { |
272 | pmac_power_off(); | 272 | pmac_power_off(); |
273 | } | 273 | } |
@@ -327,7 +327,7 @@ static void __init init_boot_display(void) | |||
327 | /* | 327 | /* |
328 | * Early initialization. | 328 | * Early initialization. |
329 | */ | 329 | */ |
330 | void __init pmac_init_early(void) | 330 | static void __init pmac_init_early(void) |
331 | { | 331 | { |
332 | DBG(" -> pmac_init_early\n"); | 332 | DBG(" -> pmac_init_early\n"); |
333 | 333 | ||
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 47727a6f7346..5aca01ddd81f 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -916,6 +916,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
916 | } | 916 | } |
917 | } | 917 | } |
918 | 918 | ||
919 | #ifdef CONFIG_ALTIVEC | ||
919 | /* Check if we have a VMX and eventually update CPU features */ | 920 | /* Check if we have a VMX and eventually update CPU features */ |
920 | prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL); | 921 | prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL); |
921 | if (prop && (*prop) > 0) { | 922 | if (prop && (*prop) > 0) { |
@@ -929,6 +930,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
929 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; | 930 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; |
930 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | 931 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; |
931 | } | 932 | } |
933 | #endif /* CONFIG_ALTIVEC */ | ||
932 | 934 | ||
933 | /* | 935 | /* |
934 | * Check for an SMT capable CPU and set the CPU feature. We do | 936 | * Check for an SMT capable CPU and set the CPU feature. We do |
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index e80f10c89824..687e85595208 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -1068,6 +1068,8 @@ void __init setup_arch(char **cmdline_p) | |||
1068 | irqstack_early_init(); | 1068 | irqstack_early_init(); |
1069 | emergency_stack_init(); | 1069 | emergency_stack_init(); |
1070 | 1070 | ||
1071 | stabs_alloc(); | ||
1072 | |||
1071 | /* set up the bootmem stuff with available memory */ | 1073 | /* set up the bootmem stuff with available memory */ |
1072 | do_init_bootmem(); | 1074 | do_init_bootmem(); |
1073 | sparse_init(); | 1075 | sparse_init(); |
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 2fcddfcb594d..793b562da653 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c | |||
@@ -65,8 +65,6 @@ struct smp_ops_t *smp_ops; | |||
65 | 65 | ||
66 | static volatile unsigned int cpu_callin_map[NR_CPUS]; | 66 | static volatile unsigned int cpu_callin_map[NR_CPUS]; |
67 | 67 | ||
68 | extern unsigned char stab_array[]; | ||
69 | |||
70 | void smp_call_function_interrupt(void); | 68 | void smp_call_function_interrupt(void); |
71 | 69 | ||
72 | int smt_enabled_at_boot = 1; | 70 | int smt_enabled_at_boot = 1; |
@@ -492,19 +490,6 @@ int __devinit __cpu_up(unsigned int cpu) | |||
492 | 490 | ||
493 | paca[cpu].default_decr = tb_ticks_per_jiffy; | 491 | paca[cpu].default_decr = tb_ticks_per_jiffy; |
494 | 492 | ||
495 | if (!cpu_has_feature(CPU_FTR_SLB)) { | ||
496 | void *tmp; | ||
497 | |||
498 | /* maximum of 48 CPUs on machines with a segment table */ | ||
499 | if (cpu >= 48) | ||
500 | BUG(); | ||
501 | |||
502 | tmp = &stab_array[PAGE_SIZE * cpu]; | ||
503 | memset(tmp, 0, PAGE_SIZE); | ||
504 | paca[cpu].stab_addr = (unsigned long)tmp; | ||
505 | paca[cpu].stab_real = virt_to_abs(tmp); | ||
506 | } | ||
507 | |||
508 | /* Make sure callin-map entry is 0 (can be leftover a CPU | 493 | /* Make sure callin-map entry is 0 (can be leftover a CPU |
509 | * hotplug | 494 | * hotplug |
510 | */ | 495 | */ |
diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c index d4ccd6f1ef47..c0da45540f0f 100644 --- a/arch/ppc64/kernel/udbg.c +++ b/arch/ppc64/kernel/udbg.c | |||
@@ -141,7 +141,7 @@ void udbg_init_scc(struct device_node *np) | |||
141 | 141 | ||
142 | #endif /* CONFIG_PPC_PMAC */ | 142 | #endif /* CONFIG_PPC_PMAC */ |
143 | 143 | ||
144 | #if CONFIG_PPC_PMAC | 144 | #ifdef CONFIG_PPC_PMAC |
145 | static void udbg_real_putc(unsigned char c) | 145 | static void udbg_real_putc(unsigned char c) |
146 | { | 146 | { |
147 | while ((real_readb(sccc) & SCC_TXRDY) == 0) | 147 | while ((real_readb(sccc) & SCC_TXRDY) == 0) |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 677c4450984a..d9dc6f28d050 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
@@ -647,29 +647,30 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) | |||
647 | } | 647 | } |
648 | } | 648 | } |
649 | 649 | ||
650 | void xics_teardown_cpu(void) | 650 | void xics_teardown_cpu(int secondary) |
651 | { | 651 | { |
652 | int cpu = smp_processor_id(); | 652 | int cpu = smp_processor_id(); |
653 | int status; | ||
654 | 653 | ||
655 | ops->cppr_info(cpu, 0x00); | 654 | ops->cppr_info(cpu, 0x00); |
656 | iosync(); | 655 | iosync(); |
657 | 656 | ||
658 | /* | 657 | /* |
659 | * we need to EOI the IPI if we got here from kexec down IPI | 658 | * Some machines need to have at least one cpu in the GIQ, |
660 | * | 659 | * so leave the master cpu in the group. |
661 | * xics doesn't care if we duplicate an EOI as long as we | ||
662 | * don't EOI and raise priority. | ||
663 | * | ||
664 | * probably need to check all the other interrupts too | ||
665 | * should we be flagging idle loop instead? | ||
666 | * or creating some task to be scheduled? | ||
667 | */ | 660 | */ |
668 | ops->xirr_info_set(cpu, XICS_IPI); | 661 | if (secondary) { |
669 | 662 | /* | |
670 | status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | 663 | * we need to EOI the IPI if we got here from kexec down IPI |
671 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); | 664 | * |
672 | WARN_ON(status != 0); | 665 | * probably need to check all the other interrupts too |
666 | * should we be flagging idle loop instead? | ||
667 | * or creating some task to be scheduled? | ||
668 | */ | ||
669 | ops->xirr_info_set(cpu, XICS_IPI); | ||
670 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
671 | (1UL << interrupt_server_size) - 1 - | ||
672 | default_distrib_server, 0); | ||
673 | } | ||
673 | } | 674 | } |
674 | 675 | ||
675 | #ifdef CONFIG_HOTPLUG_CPU | 676 | #ifdef CONFIG_HOTPLUG_CPU |