aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:50:19 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:50:19 -0400
commitdf6d3916f3b7b7e2067567a256dd4f0c1ea854a2 (patch)
tree0fdeab1ab5d566605fc99aeb5ea3f621f11e7608 /arch/powerpc/kernel
parent74add80cbd7fe246c893b93ee75ac59acdd01dd4 (diff)
parent197686dfe0038fd190326d118b743ff65ad20c0e (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (77 commits) [POWERPC] Abolish powerpc_flash_init() [POWERPC] Early serial debug support for PPC44x [POWERPC] Support for the Ebony 440GP reference board in arch/powerpc [POWERPC] Add device tree for Ebony [POWERPC] Add powerpc/platforms/44x, disable platforms/4xx for now [POWERPC] MPIC U3/U4 MSI backend [POWERPC] MPIC MSI allocator [POWERPC] Enable MSI mappings for MPIC [POWERPC] Tell Phyp we support MSI [POWERPC] RTAS MSI implementation [POWERPC] PowerPC MSI infrastructure [POWERPC] Rip out the existing powerpc msi stubs [POWERPC] Remove use of 4level-fixup.h for ppc32 [POWERPC] Add powerpc PCI-E reset API implementation [POWERPC] Holly bootwrapper [POWERPC] Holly DTS [POWERPC] Holly defconfig [POWERPC] Add support for 750CL Holly board [POWERPC] Generalize tsi108 PCI setup [POWERPC] Generalize tsi108 PHY types ... Fixed conflict in include/asm-powerpc/kdebug.h manually Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c4
-rw-r--r--arch/powerpc/kernel/head_44x.S48
-rw-r--r--arch/powerpc/kernel/idle.c5
-rw-r--r--arch/powerpc/kernel/idle_power4.S21
-rw-r--r--arch/powerpc/kernel/irq.c38
-rw-r--r--arch/powerpc/kernel/kprobes.c10
-rw-r--r--arch/powerpc/kernel/legacy_serial.c14
-rw-r--r--arch/powerpc/kernel/msi.c38
-rw-r--r--arch/powerpc/kernel/of_device.c7
-rw-r--r--arch/powerpc/kernel/of_platform.c1
-rw-r--r--arch/powerpc/kernel/pci_32.c2
-rw-r--r--arch/powerpc/kernel/pci_64.c9
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/prom_init.c12
-rw-r--r--arch/powerpc/kernel/prom_parse.c25
-rw-r--r--arch/powerpc/kernel/smp.c73
-rw-r--r--arch/powerpc/kernel/swsusp.c43
-rw-r--r--arch/powerpc/kernel/swsusp_64.c24
-rw-r--r--arch/powerpc/kernel/swsusp_asm64.S228
-rw-r--r--arch/powerpc/kernel/sysfs.c2
-rw-r--r--arch/powerpc/kernel/udbg.c3
-rw-r--r--arch/powerpc/kernel/udbg_16550.c23
-rw-r--r--arch/powerpc/kernel/vio.c2
24 files changed, 521 insertions, 116 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index aa693d0f151a..3e779f07f21b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -36,8 +36,9 @@ obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
37obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o 37obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
38obj-$(CONFIG_TAU) += tau_6xx.o 38obj-$(CONFIG_TAU) += tau_6xx.o
39obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o suspend.o
39obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o 40obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
40obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o 41obj64-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_64.o swsusp_asm64.o
41obj32-$(CONFIG_MODULES) += module_32.o 42obj32-$(CONFIG_MODULES) += module_32.o
42 43
43ifeq ($(CONFIG_PPC_MERGE),y) 44ifeq ($(CONFIG_PPC_MERGE),y)
@@ -67,6 +68,7 @@ obj-$(CONFIG_MODULES) += $(module-y)
67pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o 68pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o
68pci32-$(CONFIG_PPC32) := pci_32.o 69pci32-$(CONFIG_PPC32) := pci_32.o
69obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) 70obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
71obj-$(CONFIG_PCI_MSI) += msi.o
70kexec-$(CONFIG_PPC64) := machine_kexec_64.o 72kexec-$(CONFIG_PPC64) := machine_kexec_64.o
71kexec-$(CONFIG_PPC32) := machine_kexec_32.o 73kexec-$(CONFIG_PPC32) := machine_kexec_32.o
72obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y) 74obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 0c5150c69175..8f48560b7ee2 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -21,12 +21,12 @@
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/mman.h> 22#include <linux/mman.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/suspend.h>
24#ifdef CONFIG_PPC64 25#ifdef CONFIG_PPC64
25#include <linux/time.h> 26#include <linux/time.h>
26#include <linux/hardirq.h> 27#include <linux/hardirq.h>
27#else 28#else
28#include <linux/ptrace.h> 29#include <linux/ptrace.h>
29#include <linux/suspend.h>
30#endif 30#endif
31 31
32#include <asm/io.h> 32#include <asm/io.h>
@@ -257,11 +257,11 @@ int main(void)
257 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); 257 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
258 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); 258 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
259 259
260#ifndef CONFIG_PPC64
261 DEFINE(pbe_address, offsetof(struct pbe, address)); 260 DEFINE(pbe_address, offsetof(struct pbe, address));
262 DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); 261 DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
263 DEFINE(pbe_next, offsetof(struct pbe, next)); 262 DEFINE(pbe_next, offsetof(struct pbe, next));
264 263
264#ifndef CONFIG_PPC64
265 DEFINE(TASK_SIZE, TASK_SIZE); 265 DEFINE(TASK_SIZE, TASK_SIZE);
266 DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); 266 DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
267#endif /* ! CONFIG_PPC64 */ 267#endif /* ! CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index a15d4b8cce48..88695963f587 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -120,8 +120,8 @@ skpinv: addi r4,r4,1 /* Increment */
120 * Configure and load pinned entry into TLB slot 63. 120 * Configure and load pinned entry into TLB slot 63.
121 */ 121 */
122 122
123 lis r3,KERNELBASE@h /* Load the kernel virtual address */ 123 lis r3,PAGE_OFFSET@h
124 ori r3,r3,KERNELBASE@l 124 ori r3,r3,PAGE_OFFSET@l
125 125
126 /* Kernel is at the base of RAM */ 126 /* Kernel is at the base of RAM */
127 li r4, 0 /* Load the kernel physical address */ 127 li r4, 0 /* Load the kernel physical address */
@@ -172,36 +172,28 @@ skpinv: addi r4,r4,1 /* Increment */
172 isync 172 isync
173 173
1744: 1744:
175#ifdef CONFIG_SERIAL_TEXT_DEBUG 175#ifdef CONFIG_PPC_EARLY_DEBUG_44x
176 /* 176 /* Add UART mapping for early debug. */
177 * Add temporary UART mapping for early debug. 177
178 * We can map UART registers wherever we want as long as they don't
179 * interfere with other system mappings (e.g. with pinned entries).
180 * For an example of how we handle this - see ocotea.h. --ebs
181 */
182 /* pageid fields */ 178 /* pageid fields */
183 lis r3,UART0_IO_BASE@h 179 lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
184 ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K 180 ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K
185 181
186 /* xlat fields */ 182 /* xlat fields */
187 lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */ 183 lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
188#ifndef CONFIG_440EP 184 ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
189 ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
190#endif
191 185
192 /* attrib fields */ 186 /* attrib fields */
193 li r5,0 187 li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G)
194 ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) 188 li r0,62 /* TLB slot 0 */
195 189
196 li r0,0 /* TLB slot 0 */ 190 tlbwe r3,r0,PPC44x_TLB_PAGEID
197 191 tlbwe r4,r0,PPC44x_TLB_XLAT
198 tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ 192 tlbwe r5,r0,PPC44x_TLB_ATTRIB
199 tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
200 tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
201 193
202 /* Force context change */ 194 /* Force context change */
203 isync 195 isync
204#endif /* CONFIG_SERIAL_TEXT_DEBUG */ 196#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
205 197
206 /* Establish the interrupt vector offsets */ 198 /* Establish the interrupt vector offsets */
207 SET_IVOR(0, CriticalInput); 199 SET_IVOR(0, CriticalInput);
@@ -709,16 +701,6 @@ _GLOBAL(giveup_fpu)
709 blr 701 blr
710#endif 702#endif
711 703
712/*
713 * extern void abort(void)
714 *
715 * At present, this routine just applies a system reset.
716 */
717_GLOBAL(abort)
718 mfspr r13,SPRN_DBCR0
719 oris r13,r13,DBCR0_RST_SYSTEM@h
720 mtspr SPRN_DBCR0,r13
721
722_GLOBAL(set_context) 704_GLOBAL(set_context)
723 705
724#ifdef CONFIG_BDI_SWITCH 706#ifdef CONFIG_BDI_SWITCH
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 6e7f50967bab..a9e9cbd32975 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -33,8 +33,11 @@
33#include <asm/smp.h> 33#include <asm/smp.h>
34 34
35#ifdef CONFIG_HOTPLUG_CPU 35#ifdef CONFIG_HOTPLUG_CPU
36/* this is used for software suspend, and that shuts down
37 * CPUs even while the system is still booting... */
36#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \ 38#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
37 system_state == SYSTEM_RUNNING) 39 (system_state == SYSTEM_RUNNING \
40 || system_state == SYSTEM_BOOTING))
38#else 41#else
39#define cpu_should_die() 0 42#define cpu_should_die() 0
40#endif 43#endif
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index ba3195478600..5328709eeedc 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -53,3 +53,24 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
53 isync 53 isync
54 b 1b 54 b 1b
55 55
56_GLOBAL(power4_cpu_offline_powersave)
57 /* Go to NAP now */
58 mfmsr r7
59 rldicl r0,r7,48,1
60 rotldi r0,r0,16
61 mtmsrd r0,1 /* hard-disable interrupts */
62 li r0,1
63 li r6,0
64 stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */
65 stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */
66BEGIN_FTR_SECTION
67 DSSALL
68 sync
69END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
70 ori r7,r7,MSR_EE
71 oris r7,r7,MSR_POW@h
72 sync
73 isync
74 mtmsrd r7
75 isync
76 blr
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 6c83fe229e60..9ed4931af164 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
67#ifdef CONFIG_PPC64 67#ifdef CONFIG_PPC64
68#include <asm/paca.h> 68#include <asm/paca.h>
69#include <asm/firmware.h> 69#include <asm/firmware.h>
70#include <asm/lv1call.h>
70#endif 71#endif
71 72
72int __irq_offset_value; 73int __irq_offset_value;
@@ -162,6 +163,16 @@ void local_irq_restore(unsigned long en)
162 local_paca->hard_enabled = en; 163 local_paca->hard_enabled = en;
163 if ((int)mfspr(SPRN_DEC) < 0) 164 if ((int)mfspr(SPRN_DEC) < 0)
164 mtspr(SPRN_DEC, 1); 165 mtspr(SPRN_DEC, 1);
166
167 /*
168 * Force the delivery of pending soft-disabled interrupts on PS3.
169 * Any HV call will have this side effect.
170 */
171 if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
172 u64 tmp;
173 lv1_get_version_info(&tmp);
174 }
175
165 hard_irq_enable(); 176 hard_irq_enable();
166} 177}
167#endif /* CONFIG_PPC64 */ 178#endif /* CONFIG_PPC64 */
@@ -947,33 +958,6 @@ arch_initcall(irq_late_init);
947 958
948#endif /* CONFIG_PPC_MERGE */ 959#endif /* CONFIG_PPC_MERGE */
949 960
950#ifdef CONFIG_PCI_MSI
951int pci_enable_msi(struct pci_dev * pdev)
952{
953 if (ppc_md.enable_msi)
954 return ppc_md.enable_msi(pdev);
955 else
956 return -1;
957}
958EXPORT_SYMBOL(pci_enable_msi);
959
960void pci_disable_msi(struct pci_dev * pdev)
961{
962 if (ppc_md.disable_msi)
963 ppc_md.disable_msi(pdev);
964}
965EXPORT_SYMBOL(pci_disable_msi);
966
967void pci_scan_msi_device(struct pci_dev *dev) {}
968int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
969void pci_disable_msix(struct pci_dev *dev) {}
970void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
971void pci_no_msi(void) {}
972EXPORT_SYMBOL(pci_enable_msix);
973EXPORT_SYMBOL(pci_disable_msix);
974
975#endif
976
977#ifdef CONFIG_PPC64 961#ifdef CONFIG_PPC64
978static int __init setup_noirqdistrib(char *str) 962static int __init setup_noirqdistrib(char *str)
979{ 963{
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 088b8c6defa0..0c96611f02f4 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -401,7 +401,7 @@ out:
401 return 1; 401 return 1;
402} 402}
403 403
404static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) 404int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
405{ 405{
406 struct kprobe *cur = kprobe_running(); 406 struct kprobe *cur = kprobe_running();
407 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 407 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -486,14 +486,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
486 if (post_kprobe_handler(args->regs)) 486 if (post_kprobe_handler(args->regs))
487 ret = NOTIFY_STOP; 487 ret = NOTIFY_STOP;
488 break; 488 break;
489 case DIE_PAGE_FAULT:
490 /* kprobe_running() needs smp_processor_id() */
491 preempt_disable();
492 if (kprobe_running() &&
493 kprobe_fault_handler(args->regs, args->trapnr))
494 ret = NOTIFY_STOP;
495 preempt_enable();
496 break;
497 default: 489 default:
498 break; 490 break;
499 } 491 }
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index ae4836ea7442..cea8045ba40b 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -244,9 +244,9 @@ static int __init add_legacy_pci_port(struct device_node *np,
244 * doesn't work for these settings, you'll have to add your own special 244 * doesn't work for these settings, you'll have to add your own special
245 * cases here 245 * cases here
246 */ 246 */
247 if (device_is_compatible(pci_dev, "pci13a8,152") || 247 if (of_device_is_compatible(pci_dev, "pci13a8,152") ||
248 device_is_compatible(pci_dev, "pci13a8,154") || 248 of_device_is_compatible(pci_dev, "pci13a8,154") ||
249 device_is_compatible(pci_dev, "pci13a8,158")) { 249 of_device_is_compatible(pci_dev, "pci13a8,158")) {
250 addr += 0x200 * lindex; 250 addr += 0x200 * lindex;
251 base += 0x200 * lindex; 251 base += 0x200 * lindex;
252 } else { 252 } else {
@@ -365,11 +365,11 @@ void __init find_legacy_serial_ports(void)
365 /* Check for known pciclass, and also check wether we have 365 /* Check for known pciclass, and also check wether we have
366 * a device with child nodes for ports or not 366 * a device with child nodes for ports or not
367 */ 367 */
368 if (device_is_compatible(np, "pciclass,0700") || 368 if (of_device_is_compatible(np, "pciclass,0700") ||
369 device_is_compatible(np, "pciclass,070002")) 369 of_device_is_compatible(np, "pciclass,070002"))
370 pci = np; 370 pci = np;
371 else if (device_is_compatible(parent, "pciclass,0700") || 371 else if (of_device_is_compatible(parent, "pciclass,0700") ||
372 device_is_compatible(parent, "pciclass,070002")) 372 of_device_is_compatible(parent, "pciclass,070002"))
373 pci = parent; 373 pci = parent;
374 else { 374 else {
375 of_node_put(parent); 375 of_node_put(parent);
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
new file mode 100644
index 000000000000..c62d1012c013
--- /dev/null
+++ b/arch/powerpc/kernel/msi.c
@@ -0,0 +1,38 @@
1/*
2 * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/kernel.h>
11#include <linux/msi.h>
12
13#include <asm/machdep.h>
14
15int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
16{
17 if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
18 pr_debug("msi: Platform doesn't provide MSI callbacks.\n");
19 return -ENOSYS;
20 }
21
22 if (ppc_md.msi_check_device) {
23 pr_debug("msi: Using platform check routine.\n");
24 return ppc_md.msi_check_device(dev, nvec, type);
25 }
26
27 return 0;
28}
29
30int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
31{
32 return ppc_md.setup_msi_irqs(dev, nvec, type);
33}
34
35void arch_teardown_msi_irqs(struct pci_dev *dev)
36{
37 return ppc_md.teardown_msi_irqs(dev);
38}
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 0c8ea7659d92..a464d67248df 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -27,7 +27,7 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
27 match &= node->type 27 match &= node->type
28 && !strcmp(matches->type, node->type); 28 && !strcmp(matches->type, node->type);
29 if (matches->compatible[0]) 29 if (matches->compatible[0])
30 match &= device_is_compatible(node, 30 match &= of_device_is_compatible(node,
31 matches->compatible); 31 matches->compatible);
32 if (match) 32 if (match)
33 return matches; 33 return matches;
@@ -120,8 +120,8 @@ void of_device_unregister(struct of_device *ofdev)
120} 120}
121 121
122 122
123static ssize_t of_device_get_modalias(struct of_device *ofdev, 123ssize_t of_device_get_modalias(struct of_device *ofdev,
124 char *str, ssize_t len) 124 char *str, ssize_t len)
125{ 125{
126 const char *compat; 126 const char *compat;
127 int cplen, i; 127 int cplen, i;
@@ -239,3 +239,4 @@ EXPORT_SYMBOL(of_dev_get);
239EXPORT_SYMBOL(of_dev_put); 239EXPORT_SYMBOL(of_dev_put);
240EXPORT_SYMBOL(of_release_dev); 240EXPORT_SYMBOL(of_release_dev);
241EXPORT_SYMBOL(of_device_uevent); 241EXPORT_SYMBOL(of_device_uevent);
242EXPORT_SYMBOL(of_device_get_modalias);
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 908ed7926db4..84c34d979a88 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -29,7 +29,6 @@
29#include <asm/ppc-pci.h> 29#include <asm/ppc-pci.h>
30#include <asm/atomic.h> 30#include <asm/atomic.h>
31 31
32
33/* 32/*
34 * The list of OF IDs below is used for matching bus types in the 33 * The list of OF IDs below is used for matching bus types in the
35 * system whose devices are to be exposed as of_platform_devices. 34 * system whose devices are to be exposed as of_platform_devices.
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index f022862de344..e66064b5093a 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -1658,7 +1658,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
1658 int i; 1658 int i;
1659 1659
1660 if (page_is_ram(pfn)) 1660 if (page_is_ram(pfn))
1661 return prot; 1661 return __pgprot(prot);
1662 1662
1663 prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; 1663 prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
1664 1664
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 7138092826aa..6d05a1f377b5 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1006,8 +1006,9 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
1006 1006
1007 switch ((pci_space >> 24) & 0x3) { 1007 switch ((pci_space >> 24) & 0x3) {
1008 case 1: /* I/O space */ 1008 case 1: /* I/O space */
1009 hose->io_base_phys = cpu_phys_addr; 1009 hose->io_base_phys = cpu_phys_addr - pci_addr;
1010 hose->pci_io_size = size; 1010 /* handle from 0 to top of I/O window */
1011 hose->pci_io_size = pci_addr + size;
1011 1012
1012 res = &hose->io_resource; 1013 res = &hose->io_resource;
1013 res->flags = IORESOURCE_IO; 1014 res->flags = IORESOURCE_IO;
@@ -1117,8 +1118,8 @@ static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
1117 } else { 1118 } else {
1118 /* Root Bus */ 1119 /* Root Bus */
1119 res = &hose->io_resource; 1120 res = &hose->io_resource;
1120 *start_phys = hose->io_base_phys; 1121 *start_phys = hose->io_base_phys + res->start;
1121 *start_virt = (unsigned long) hose->io_base_virt; 1122 *start_virt = (unsigned long) hose->io_base_virt + res->start;
1122 if (res->end > res->start) 1123 if (res->end > res->start)
1123 *size = res->end - res->start + 1; 1124 *size = res->end - res->start + 1;
1124 else { 1125 else {
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index ff252aaead12..c96fa9bd35a4 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -66,7 +66,6 @@ EXPORT_SYMBOL(clear_pages);
66EXPORT_SYMBOL(ISA_DMA_THRESHOLD); 66EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
67EXPORT_SYMBOL(DMA_MODE_READ); 67EXPORT_SYMBOL(DMA_MODE_READ);
68EXPORT_SYMBOL(DMA_MODE_WRITE); 68EXPORT_SYMBOL(DMA_MODE_WRITE);
69EXPORT_SYMBOL(__div64_32);
70 69
71EXPORT_SYMBOL(do_signal); 70EXPORT_SYMBOL(do_signal);
72EXPORT_SYMBOL(transfer_to_handler); 71EXPORT_SYMBOL(transfer_to_handler);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index e27d9d1b6e67..d6047c441034 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -635,6 +635,12 @@ static void __init early_cmdline_parse(void)
635/* ibm,dynamic-reconfiguration-memory property supported */ 635/* ibm,dynamic-reconfiguration-memory property supported */
636#define OV5_DRCONF_MEMORY 0x20 636#define OV5_DRCONF_MEMORY 0x20
637#define OV5_LARGE_PAGES 0x10 /* large pages supported */ 637#define OV5_LARGE_PAGES 0x10 /* large pages supported */
638/* PCIe/MSI support. Without MSI full PCIe is not supported */
639#ifdef CONFIG_PCI_MSI
640#define OV5_MSI 0x01 /* PCIe/MSI support */
641#else
642#define OV5_MSI 0x00
643#endif /* CONFIG_PCI_MSI */
638 644
639/* 645/*
640 * The architecture vector has an array of PVR mask/value pairs, 646 * The architecture vector has an array of PVR mask/value pairs,
@@ -679,7 +685,7 @@ static unsigned char ibm_architecture_vec[] = {
679 /* option vector 5: PAPR/OF options */ 685 /* option vector 5: PAPR/OF options */
680 3 - 2, /* length */ 686 3 - 2, /* length */
681 0, /* don't ignore, don't halt */ 687 0, /* don't ignore, don't halt */
682 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY, 688 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | OV5_MSI,
683}; 689};
684 690
685/* Old method - ELF header with PT_NOTE sections */ 691/* Old method - ELF header with PT_NOTE sections */
@@ -967,7 +973,7 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp)
967 * If problems seem to show up, it would be a good start to track 973 * If problems seem to show up, it would be a good start to track
968 * them down. 974 * them down.
969 */ 975 */
970static void reserve_mem(u64 base, u64 size) 976static void __init reserve_mem(u64 base, u64 size)
971{ 977{
972 u64 top = base + size; 978 u64 top = base + size;
973 unsigned long cnt = RELOC(mem_reserve_cnt); 979 unsigned long cnt = RELOC(mem_reserve_cnt);
@@ -2153,7 +2159,7 @@ static void __init fixup_device_tree_efika(void)
2153 3,12,0, 3,13,0, 3,14,0, 3,15,0 }; 2159 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
2154 struct subst_entry efika_subst_table[] = { 2160 struct subst_entry efika_subst_table[] = {
2155 { "/", "device_type", prop_cstr("efika") }, 2161 { "/", "device_type", prop_cstr("efika") },
2156 { "/builtin", "compatible", prop_cstr("soc") }, 2162 { "/builtin", "device_type", prop_cstr("soc") },
2157 { "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc5200-ata"), }, 2163 { "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
2158 { "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") }, 2164 { "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
2159 { "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) }, 2165 { "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) },
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index aa40a5307294..b5c96af955c6 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -1042,3 +1042,28 @@ const void *of_get_mac_address(struct device_node *np)
1042} 1042}
1043EXPORT_SYMBOL(of_get_mac_address); 1043EXPORT_SYMBOL(of_get_mac_address);
1044 1044
1045int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
1046{
1047 int irq = irq_of_parse_and_map(dev, index);
1048
1049 /* Only dereference the resource if both the
1050 * resource and the irq are valid. */
1051 if (r && irq != NO_IRQ) {
1052 r->start = r->end = irq;
1053 r->flags = IORESOURCE_IRQ;
1054 }
1055
1056 return irq;
1057}
1058EXPORT_SYMBOL_GPL(of_irq_to_resource);
1059
1060void __iomem *of_iomap(struct device_node *np, int index)
1061{
1062 struct resource res;
1063
1064 if (of_address_to_resource(np, index, &res))
1065 return NULL;
1066
1067 return ioremap(res.start, 1 + res.end - res.start);
1068}
1069EXPORT_SYMBOL(of_iomap);
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d8e503b2e1af..22f1ef1b3100 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -176,10 +176,10 @@ static struct call_data_struct {
176#define SMP_CALL_TIMEOUT 8 176#define SMP_CALL_TIMEOUT 8
177 177
178/* 178/*
179 * This function sends a 'generic call function' IPI to all other CPUs 179 * These functions send a 'generic call function' IPI to other online
180 * in the system. 180 * CPUS in the system.
181 * 181 *
182 * [SUMMARY] Run a function on all other CPUs. 182 * [SUMMARY] Run a function on other CPUs.
183 * <func> The function to run. This must be fast and non-blocking. 183 * <func> The function to run. This must be fast and non-blocking.
184 * <info> An arbitrary pointer to pass to the function. 184 * <info> An arbitrary pointer to pass to the function.
185 * <nonatomic> currently unused. 185 * <nonatomic> currently unused.
@@ -190,18 +190,26 @@ static struct call_data_struct {
190 * You must not call this function with disabled interrupts or from a 190 * You must not call this function with disabled interrupts or from a
191 * hardware interrupt handler or from a bottom half handler. 191 * hardware interrupt handler or from a bottom half handler.
192 */ 192 */
193int smp_call_function (void (*func) (void *info), void *info, int nonatomic, 193int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
194 int wait) 194 int wait, cpumask_t map)
195{ 195{
196 struct call_data_struct data; 196 struct call_data_struct data;
197 int ret = -1, cpus; 197 int ret = -1, num_cpus;
198 int cpu;
198 u64 timeout; 199 u64 timeout;
199 200
200 /* Can deadlock when called with interrupts disabled */ 201 /* Can deadlock when called with interrupts disabled */
201 WARN_ON(irqs_disabled()); 202 WARN_ON(irqs_disabled());
202 203
204 /* remove 'self' from the map */
205 if (cpu_isset(smp_processor_id(), map))
206 cpu_clear(smp_processor_id(), map);
207
208 /* sanity check the map, remove any non-online processors. */
209 cpus_and(map, map, cpu_online_map);
210
203 if (unlikely(smp_ops == NULL)) 211 if (unlikely(smp_ops == NULL))
204 return -1; 212 return ret;
205 213
206 data.func = func; 214 data.func = func;
207 data.info = info; 215 data.info = info;
@@ -213,40 +221,42 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
213 spin_lock(&call_lock); 221 spin_lock(&call_lock);
214 /* Must grab online cpu count with preempt disabled, otherwise 222 /* Must grab online cpu count with preempt disabled, otherwise
215 * it can change. */ 223 * it can change. */
216 cpus = num_online_cpus() - 1; 224 num_cpus = num_online_cpus() - 1;
217 if (!cpus) { 225 if (!num_cpus || cpus_empty(map)) {
218 ret = 0; 226 ret = 0;
219 goto out; 227 goto out;
220 } 228 }
221 229
222 call_data = &data; 230 call_data = &data;
223 smp_wmb(); 231 smp_wmb();
224 /* Send a message to all other CPUs and wait for them to respond */ 232 /* Send a message to all CPUs in the map */
225 smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); 233 for_each_cpu_mask(cpu, map)
234 smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION);
226 235
227 timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec; 236 timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec;
228 237
229 /* Wait for response */ 238 /* Wait for indication that they have received the message */
230 while (atomic_read(&data.started) != cpus) { 239 while (atomic_read(&data.started) != num_cpus) {
231 HMT_low(); 240 HMT_low();
232 if (get_tb() >= timeout) { 241 if (get_tb() >= timeout) {
233 printk("smp_call_function on cpu %d: other cpus not " 242 printk("smp_call_function on cpu %d: other cpus not "
234 "responding (%d)\n", smp_processor_id(), 243 "responding (%d)\n", smp_processor_id(),
235 atomic_read(&data.started)); 244 atomic_read(&data.started));
236 debugger(NULL); 245 debugger(NULL);
237 goto out; 246 goto out;
238 } 247 }
239 } 248 }
240 249
250 /* optionally wait for the CPUs to complete */
241 if (wait) { 251 if (wait) {
242 while (atomic_read(&data.finished) != cpus) { 252 while (atomic_read(&data.finished) != num_cpus) {
243 HMT_low(); 253 HMT_low();
244 if (get_tb() >= timeout) { 254 if (get_tb() >= timeout) {
245 printk("smp_call_function on cpu %d: other " 255 printk("smp_call_function on cpu %d: other "
246 "cpus not finishing (%d/%d)\n", 256 "cpus not finishing (%d/%d)\n",
247 smp_processor_id(), 257 smp_processor_id(),
248 atomic_read(&data.finished), 258 atomic_read(&data.finished),
249 atomic_read(&data.started)); 259 atomic_read(&data.started));
250 debugger(NULL); 260 debugger(NULL);
251 goto out; 261 goto out;
252 } 262 }
@@ -262,8 +272,29 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
262 return ret; 272 return ret;
263} 273}
264 274
275int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
276 int wait)
277{
278 return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map);
279}
265EXPORT_SYMBOL(smp_call_function); 280EXPORT_SYMBOL(smp_call_function);
266 281
282int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic,
283 int wait)
284{
285 cpumask_t map=CPU_MASK_NONE;
286
287 if (!cpu_online(cpu))
288 return -EINVAL;
289
290 if (cpu == smp_processor_id())
291 return -EBUSY;
292
293 cpu_set(cpu, map);
294 return smp_call_function_map(func,info,nonatomic,wait,map);
295}
296EXPORT_SYMBOL(smp_call_function_single);
297
267void smp_call_function_interrupt(void) 298void smp_call_function_interrupt(void)
268{ 299{
269 void (*func) (void *info); 300 void (*func) (void *info);
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
new file mode 100644
index 000000000000..064a7ba4f02c
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp.c
@@ -0,0 +1,43 @@
1/*
2 * Common powerpc suspend code for 32 and 64 bits
3 *
4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/sched.h>
13#include <asm/suspend.h>
14#include <asm/system.h>
15#include <asm/current.h>
16#include <asm/mmu_context.h>
17
18void save_processor_state(void)
19{
20 /*
21 * flush out all the special registers so we don't need
22 * to save them in the snapshot
23 */
24 flush_fp_to_thread(current);
25 flush_altivec_to_thread(current);
26 flush_spe_to_thread(current);
27
28#ifdef CONFIG_PPC64
29 hard_irq_disable();
30#endif
31
32}
33
34void restore_processor_state(void)
35{
36#ifdef CONFIG_PPC32
37 set_context(current->active_mm->context.id, current->active_mm->pgd);
38#endif
39
40#ifdef CONFIG_PPC64
41 hard_irq_enable();
42#endif
43}
diff --git a/arch/powerpc/kernel/swsusp_64.c b/arch/powerpc/kernel/swsusp_64.c
new file mode 100644
index 000000000000..6f3f0697274e
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_64.c
@@ -0,0 +1,24 @@
1/*
2 * PowerPC 64-bit swsusp implementation
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPLv2
7 */
8
9#include <asm/system.h>
10#include <asm/iommu.h>
11#include <linux/irq.h>
12#include <linux/interrupt.h>
13
14void do_after_copyback(void)
15{
16 iommu_restore();
17 touch_softlockup_watchdog();
18 mb();
19}
20
21void _iommu_save(void)
22{
23 iommu_save();
24}
diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S
new file mode 100644
index 000000000000..e092c3cbdb9b
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_asm64.S
@@ -0,0 +1,228 @@
1/*
2 * PowerPC 64-bit swsusp implementation
3 *
4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
5 *
6 * GPLv2
7 */
8
9#include <linux/threads.h>
10#include <asm/processor.h>
11#include <asm/page.h>
12#include <asm/cputable.h>
13#include <asm/thread_info.h>
14#include <asm/ppc_asm.h>
15#include <asm/asm-offsets.h>
16
17/*
18 * Structure for storing CPU registers on the save area.
19 */
20#define SL_r1 0x00 /* stack pointer */
21#define SL_PC 0x08
22#define SL_MSR 0x10
23#define SL_SDR1 0x18
24#define SL_XER 0x20
25#define SL_TB 0x40
26#define SL_r2 0x48
27#define SL_CR 0x50
28#define SL_LR 0x58
29#define SL_r12 0x60
30#define SL_r13 0x68
31#define SL_r14 0x70
32#define SL_r15 0x78
33#define SL_r16 0x80
34#define SL_r17 0x88
35#define SL_r18 0x90
36#define SL_r19 0x98
37#define SL_r20 0xa0
38#define SL_r21 0xa8
39#define SL_r22 0xb0
40#define SL_r23 0xb8
41#define SL_r24 0xc0
42#define SL_r25 0xc8
43#define SL_r26 0xd0
44#define SL_r27 0xd8
45#define SL_r28 0xe0
46#define SL_r29 0xe8
47#define SL_r30 0xf0
48#define SL_r31 0xf8
49#define SL_SIZE SL_r31+8
50
51/* these macros rely on the save area being
52 * pointed to by r11 */
53#define SAVE_SPECIAL(special) \
54 mf##special r0 ;\
55 std r0, SL_##special(r11)
56#define RESTORE_SPECIAL(special) \
57 ld r0, SL_##special(r11) ;\
58 mt##special r0
59#define SAVE_REGISTER(reg) \
60 std reg, SL_##reg(r11)
61#define RESTORE_REGISTER(reg) \
62 ld reg, SL_##reg(r11)
63
64/* space for storing cpu state */
65 .section .data
66 .align 5
67swsusp_save_area:
68 .space SL_SIZE
69
70 .section ".toc","aw"
71swsusp_save_area_ptr:
72 .tc swsusp_save_area[TC],swsusp_save_area
73restore_pblist_ptr:
74 .tc restore_pblist[TC],restore_pblist
75
76 .section .text
77 .align 5
78_GLOBAL(swsusp_arch_suspend)
79 ld r11,swsusp_save_area_ptr@toc(r2)
80 SAVE_SPECIAL(LR)
81 SAVE_REGISTER(r1)
82 SAVE_SPECIAL(CR)
83 SAVE_SPECIAL(TB)
84 SAVE_REGISTER(r2)
85 SAVE_REGISTER(r12)
86 SAVE_REGISTER(r13)
87 SAVE_REGISTER(r14)
88 SAVE_REGISTER(r15)
89 SAVE_REGISTER(r16)
90 SAVE_REGISTER(r17)
91 SAVE_REGISTER(r18)
92 SAVE_REGISTER(r19)
93 SAVE_REGISTER(r20)
94 SAVE_REGISTER(r21)
95 SAVE_REGISTER(r22)
96 SAVE_REGISTER(r23)
97 SAVE_REGISTER(r24)
98 SAVE_REGISTER(r25)
99 SAVE_REGISTER(r26)
100 SAVE_REGISTER(r27)
101 SAVE_REGISTER(r28)
102 SAVE_REGISTER(r29)
103 SAVE_REGISTER(r30)
104 SAVE_REGISTER(r31)
105 SAVE_SPECIAL(MSR)
106 SAVE_SPECIAL(SDR1)
107 SAVE_SPECIAL(XER)
108
109 /* we push the stack up 128 bytes but don't store the
110 * stack pointer on the stack like a real stackframe */
111 addi r1,r1,-128
112
113 bl _iommu_save
114 bl swsusp_save
115
116 /* restore LR */
117 ld r11,swsusp_save_area_ptr@toc(r2)
118 RESTORE_SPECIAL(LR)
119 addi r1,r1,128
120
121 blr
122
123/* Resume code */
124_GLOBAL(swsusp_arch_resume)
125 /* Stop pending alitvec streams and memory accesses */
126BEGIN_FTR_SECTION
127 DSSALL
128END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
129 sync
130
131 ld r12,restore_pblist_ptr@toc(r2)
132 ld r12,0(r12)
133
134 cmpdi r12,0
135 beq- nothing_to_copy
136 li r15,512
137copyloop:
138 ld r13,pbe_address(r12)
139 ld r14,pbe_orig_address(r12)
140
141 mtctr r15
142 li r10,0
143copy_page_loop:
144 ldx r0,r10,r13
145 stdx r0,r10,r14
146 addi r10,r10,8
147 bdnz copy_page_loop
148
149 ld r12,pbe_next(r12)
150 cmpdi r12,0
151 bne+ copyloop
152nothing_to_copy:
153
154 /* flush caches */
155 lis r3, 0x10
156 mtctr r3
157 li r3, 0
158 ori r3, r3, CONFIG_KERNEL_START>>48
159 li r0, 48
160 sld r3, r3, r0
161 li r0, 0
1621:
163 dcbf r0,r3
164 addi r3,r3,0x20
165 bdnz 1b
166
167 sync
168
169 tlbia
170
171 ld r11,swsusp_save_area_ptr@toc(r2)
172
173 RESTORE_SPECIAL(CR)
174
175 /* restore timebase */
176 /* load saved tb */
177 ld r1, SL_TB(r11)
178 /* get upper 32 bits of it */
179 srdi r2, r1, 32
180 /* clear tb lower to avoid wrap */
181 li r0, 0
182 mttbl r0
183 /* set tb upper */
184 mttbu r2
185 /* set tb lower */
186 mttbl r1
187
188 /* restore registers */
189 RESTORE_REGISTER(r1)
190 RESTORE_REGISTER(r2)
191 RESTORE_REGISTER(r12)
192 RESTORE_REGISTER(r13)
193 RESTORE_REGISTER(r14)
194 RESTORE_REGISTER(r15)
195 RESTORE_REGISTER(r16)
196 RESTORE_REGISTER(r17)
197 RESTORE_REGISTER(r18)
198 RESTORE_REGISTER(r19)
199 RESTORE_REGISTER(r20)
200 RESTORE_REGISTER(r21)
201 RESTORE_REGISTER(r22)
202 RESTORE_REGISTER(r23)
203 RESTORE_REGISTER(r24)
204 RESTORE_REGISTER(r25)
205 RESTORE_REGISTER(r26)
206 RESTORE_REGISTER(r27)
207 RESTORE_REGISTER(r28)
208 RESTORE_REGISTER(r29)
209 RESTORE_REGISTER(r30)
210 RESTORE_REGISTER(r31)
211 /* can't use RESTORE_SPECIAL(MSR) */
212 ld r0, SL_MSR(r11)
213 mtmsrd r0, 0
214 RESTORE_SPECIAL(SDR1)
215 RESTORE_SPECIAL(XER)
216
217 sync
218
219 addi r1,r1,-128
220 bl slb_flush_and_rebolt
221 bl do_after_copyback
222 addi r1,r1,128
223
224 ld r11,swsusp_save_area_ptr@toc(r2)
225 RESTORE_SPECIAL(LR)
226
227 li r3, 0
228 blr
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 933e214c33e8..cae39d9dfe48 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -499,4 +499,4 @@ static int __init topology_init(void)
499 499
500 return 0; 500 return 0;
501} 501}
502__initcall(topology_init); 502subsys_initcall(topology_init);
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 147a2d83de10..87703df87509 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -51,6 +51,9 @@ void __init udbg_early_init(void)
51 udbg_init_pas_realmode(); 51 udbg_init_pas_realmode();
52#elif defined(CONFIG_BOOTX_TEXT) 52#elif defined(CONFIG_BOOTX_TEXT)
53 udbg_init_btext(); 53 udbg_init_btext();
54#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
55 /* PPC44x debug */
56 udbg_init_44x_as1();
54#endif 57#endif
55} 58}
56 59
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index a963f657222b..7afab5bcd61a 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -191,3 +191,26 @@ void udbg_init_pas_realmode(void)
191 udbg_getc_poll = NULL; 191 udbg_getc_poll = NULL;
192} 192}
193#endif /* CONFIG_PPC_MAPLE */ 193#endif /* CONFIG_PPC_MAPLE */
194
195#ifdef CONFIG_PPC_EARLY_DEBUG_44x
196#include <platforms/44x/44x.h>
197
198static void udbg_44x_as1_putc(char c)
199{
200 if (udbg_comport) {
201 while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
202 /* wait for idle */;
203 as1_writeb(c, &udbg_comport->thr); eieio();
204 if (c == '\n')
205 udbg_44x_as1_putc('\r');
206 }
207}
208
209void __init udbg_init_44x_as1(void)
210{
211 udbg_comport =
212 (volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
213
214 udbg_putc = udbg_44x_as1_putc;
215}
216#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index b2c1b67a10a7..62c1bc12ea39 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -117,7 +117,7 @@ static const struct vio_device_id *vio_match_device(
117{ 117{
118 while (ids->type[0] != '\0') { 118 while (ids->type[0] != '\0') {
119 if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && 119 if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
120 device_is_compatible(dev->dev.archdata.of_node, 120 of_device_is_compatible(dev->dev.archdata.of_node,
121 ids->compat)) 121 ids->compat))
122 return ids; 122 return ids;
123 ids++; 123 ids++;