aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig3
-rw-r--r--arch/alpha/Kconfig1
-rw-r--r--arch/arm/kernel/armksyms.c3
-rw-r--r--arch/arm/kernel/process.c4
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/sha1.S211
-rw-r--r--arch/avr32/Kconfig1
-rw-r--r--arch/cris/arch-v10/drivers/sync_serial.c6
-rw-r--r--arch/cris/arch-v10/kernel/irq.c3
-rw-r--r--arch/cris/include/asm/thread_info.h6
-rw-r--r--arch/frv/Kconfig1
-rw-r--r--arch/ia64/Kconfig1
-rw-r--r--arch/ia64/kernel/efi.c2
-rw-r--r--arch/m68k/Kconfig1
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/include/asm/atomic.h4
-rw-r--r--arch/parisc/include/asm/futex.h66
-rw-r--r--arch/parisc/include/asm/unistd.h3
-rw-r--r--arch/parisc/kernel/syscall_table.S1
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/s390/Kconfig9
-rw-r--r--arch/s390/include/asm/ipl.h1
-rw-r--r--arch/s390/include/asm/lowcore.h11
-rw-r--r--arch/s390/include/asm/processor.h2
-rw-r--r--arch/s390/include/asm/system.h1
-rw-r--r--arch/s390/kernel/asm-offsets.c10
-rw-r--r--arch/s390/kernel/base.S36
-rw-r--r--arch/s390/kernel/compat_signal.c43
-rw-r--r--arch/s390/kernel/entry.S28
-rw-r--r--arch/s390/kernel/entry64.S20
-rw-r--r--arch/s390/kernel/ipl.c45
-rw-r--r--arch/s390/kernel/reipl64.S80
-rw-r--r--arch/s390/kernel/setup.c25
-rw-r--r--arch/s390/kernel/signal.c61
-rw-r--r--arch/s390/kernel/smp.c24
-rw-r--r--arch/s390/mm/maccess.c16
-rw-r--r--arch/s390/mm/pgtable.c1
-rw-r--r--arch/sh/Kconfig1
-rw-r--r--arch/sh/kernel/idle.c6
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/include/asm/Kbuild5
-rw-r--r--arch/sparc/include/asm/bitops_64.h49
-rw-r--r--arch/sparc/include/asm/div64.h1
-rw-r--r--arch/sparc/include/asm/elf_64.h65
-rw-r--r--arch/sparc/include/asm/hypervisor.h13
-rw-r--r--arch/sparc/include/asm/irq_regs.h1
-rw-r--r--arch/sparc/include/asm/local.h6
-rw-r--r--arch/sparc/include/asm/local64.h1
-rw-r--r--arch/sparc/include/asm/tsb.h51
-rw-r--r--arch/sparc/kernel/cpu.c1
-rw-r--r--arch/sparc/kernel/ds.c30
-rw-r--r--arch/sparc/kernel/entry.h14
-rw-r--r--arch/sparc/kernel/head_64.S2
-rw-r--r--arch/sparc/kernel/hvapi.c6
-rw-r--r--arch/sparc/kernel/hvcalls.S7
-rw-r--r--arch/sparc/kernel/kernel.h15
-rw-r--r--arch/sparc/kernel/ktlb.S24
-rw-r--r--arch/sparc/kernel/mdesc.c30
-rw-r--r--arch/sparc/kernel/setup_64.c186
-rw-r--r--arch/sparc/kernel/sparc_ksyms_64.c11
-rw-r--r--arch/sparc/kernel/sstate.c9
-rw-r--r--arch/sparc/kernel/unaligned_64.c15
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S21
-rw-r--r--arch/sparc/lib/Makefile4
-rw-r--r--arch/sparc/lib/NG2page.S61
-rw-r--r--arch/sparc/lib/NGpage.S114
-rw-r--r--arch/sparc/lib/atomic32.c2
-rw-r--r--arch/sparc/lib/ffs.S84
-rw-r--r--arch/sparc/lib/hweight.S51
-rw-r--r--arch/sparc/mm/init_64.c42
-rw-r--r--arch/tile/Kconfig1
-rw-r--r--arch/tile/include/asm/Kbuild38
-rw-r--r--arch/tile/include/asm/bug.h1
-rw-r--r--arch/tile/include/asm/bugs.h1
-rw-r--r--arch/tile/include/asm/cputime.h1
-rw-r--r--arch/tile/include/asm/device.h1
-rw-r--r--arch/tile/include/asm/div64.h1
-rw-r--r--arch/tile/include/asm/emergency-restart.h1
-rw-r--r--arch/tile/include/asm/errno.h1
-rw-r--r--arch/tile/include/asm/fb.h1
-rw-r--r--arch/tile/include/asm/fcntl.h1
-rw-r--r--arch/tile/include/asm/fixmap.h6
-rw-r--r--arch/tile/include/asm/ioctl.h1
-rw-r--r--arch/tile/include/asm/ioctls.h1
-rw-r--r--arch/tile/include/asm/ipc.h1
-rw-r--r--arch/tile/include/asm/ipcbuf.h1
-rw-r--r--arch/tile/include/asm/irq_regs.h1
-rw-r--r--arch/tile/include/asm/kdebug.h1
-rw-r--r--arch/tile/include/asm/local.h1
-rw-r--r--arch/tile/include/asm/module.h1
-rw-r--r--arch/tile/include/asm/msgbuf.h1
-rw-r--r--arch/tile/include/asm/mutex.h1
-rw-r--r--arch/tile/include/asm/param.h1
-rw-r--r--arch/tile/include/asm/parport.h1
-rw-r--r--arch/tile/include/asm/poll.h1
-rw-r--r--arch/tile/include/asm/posix_types.h1
-rw-r--r--arch/tile/include/asm/resource.h1
-rw-r--r--arch/tile/include/asm/scatterlist.h1
-rw-r--r--arch/tile/include/asm/sembuf.h1
-rw-r--r--arch/tile/include/asm/serial.h1
-rw-r--r--arch/tile/include/asm/shmbuf.h1
-rw-r--r--arch/tile/include/asm/shmparam.h1
-rw-r--r--arch/tile/include/asm/socket.h1
-rw-r--r--arch/tile/include/asm/sockios.h1
-rw-r--r--arch/tile/include/asm/statfs.h1
-rw-r--r--arch/tile/include/asm/termbits.h1
-rw-r--r--arch/tile/include/asm/termios.h1
-rw-r--r--arch/tile/include/asm/types.h1
-rw-r--r--arch/tile/include/asm/ucontext.h1
-rw-r--r--arch/tile/include/asm/xor.h1
-rw-r--r--arch/tile/include/hv/drv_srom_intf.h41
-rw-r--r--arch/tile/kernel/time.c5
-rw-r--r--arch/tile/mm/init.c3
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/include/asm/io.h3
-rw-r--r--arch/x86/include/asm/processor.h2
-rw-r--r--arch/x86/kernel/acpi/cstate.c23
-rw-r--r--arch/x86/kernel/process.c23
-rw-r--r--arch/x86/kernel/process_32.c4
-rw-r--r--arch/x86/kernel/process_64.c4
-rw-r--r--arch/x86/platform/mrst/Makefile1
-rw-r--r--arch/x86/platform/mrst/pmu.c817
-rw-r--r--arch/x86/platform/mrst/pmu.h234
-rw-r--r--arch/x86/xen/Makefile2
-rw-r--r--arch/x86/xen/setup.c13
-rw-r--r--arch/x86/xen/trace.c1
126 files changed, 2227 insertions, 695 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 26b0e2397a57..4b0669cbb3b0 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -178,4 +178,7 @@ config HAVE_ARCH_MUTEX_CPU_RELAX
178config HAVE_RCU_TABLE_FREE 178config HAVE_RCU_TABLE_FREE
179 bool 179 bool
180 180
181config ARCH_HAVE_NMI_SAFE_CMPXCHG
182 bool
183
181source "kernel/gcov/Kconfig" 184source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index ca2da8da6e9c..60cde53d266c 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -14,6 +14,7 @@ config ALPHA
14 select AUTO_IRQ_AFFINITY if SMP 14 select AUTO_IRQ_AFFINITY if SMP
15 select GENERIC_IRQ_SHOW 15 select GENERIC_IRQ_SHOW
16 select ARCH_WANT_OPTIONAL_GPIOLIB 16 select ARCH_WANT_OPTIONAL_GPIOLIB
17 select ARCH_HAVE_NMI_SAFE_CMPXCHG
17 help 18 help
18 The Alpha is a 64-bit general-purpose processor designed and 19 The Alpha is a 64-bit general-purpose processor designed and
19 marketed by the Digital Equipment Corporation of blessed memory, 20 marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index acca35aebe28..aeef960ff795 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -112,9 +112,6 @@ EXPORT_SYMBOL(__put_user_4);
112EXPORT_SYMBOL(__put_user_8); 112EXPORT_SYMBOL(__put_user_8);
113#endif 113#endif
114 114
115 /* crypto hash */
116EXPORT_SYMBOL(sha_transform);
117
118 /* gcc lib functions */ 115 /* gcc lib functions */
119EXPORT_SYMBOL(__ashldi3); 116EXPORT_SYMBOL(__ashldi3);
120EXPORT_SYMBOL(__ashrdi3); 117EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 5e1e54197227..1a347f481e5e 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -30,6 +30,7 @@
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/random.h> 31#include <linux/random.h>
32#include <linux/hw_breakpoint.h> 32#include <linux/hw_breakpoint.h>
33#include <linux/cpuidle.h>
33 34
34#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
35#include <asm/leds.h> 36#include <asm/leds.h>
@@ -196,7 +197,8 @@ void cpu_idle(void)
196 cpu_relax(); 197 cpu_relax();
197 } else { 198 } else {
198 stop_critical_timings(); 199 stop_critical_timings();
199 pm_idle(); 200 if (cpuidle_idle_call())
201 pm_idle();
200 start_critical_timings(); 202 start_critical_timings();
201 /* 203 /*
202 * This will eventually be removed - pm_idle 204 * This will eventually be removed - pm_idle
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 59ff42ddf0ae..cf73a7f742dd 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -12,7 +12,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
12 strchr.o strrchr.o \ 12 strchr.o strrchr.o \
13 testchangebit.o testclearbit.o testsetbit.o \ 13 testchangebit.o testclearbit.o testsetbit.o \
14 ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ 14 ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
15 ucmpdi2.o lib1funcs.o div64.o sha1.o \ 15 ucmpdi2.o lib1funcs.o div64.o \
16 io-readsb.o io-writesb.o io-readsl.o io-writesl.o 16 io-readsb.o io-writesb.o io-readsl.o io-writesl.o
17 17
18mmu-y := clear_user.o copy_page.o getuser.o putuser.o 18mmu-y := clear_user.o copy_page.o getuser.o putuser.o
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
deleted file mode 100644
index eb0edb80d7b8..000000000000
--- a/arch/arm/lib/sha1.S
+++ /dev/null
@@ -1,211 +0,0 @@
1/*
2 * linux/arch/arm/lib/sha1.S
3 *
4 * SHA transform optimized for ARM
5 *
6 * Copyright: (C) 2005 by Nicolas Pitre <nico@fluxnic.net>
7 * Created: September 17, 2005
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * The reference implementation for this code is linux/lib/sha1.c
14 */
15
16#include <linux/linkage.h>
17
18 .text
19
20
21/*
22 * void sha_transform(__u32 *digest, const char *in, __u32 *W)
23 *
24 * Note: the "in" ptr may be unaligned.
25 */
26
27ENTRY(sha_transform)
28
29 stmfd sp!, {r4 - r8, lr}
30
31 @ for (i = 0; i < 16; i++)
32 @ W[i] = be32_to_cpu(in[i]);
33
34#ifdef __ARMEB__
35 mov r4, r0
36 mov r0, r2
37 mov r2, #64
38 bl memcpy
39 mov r2, r0
40 mov r0, r4
41#else
42 mov r3, r2
43 mov lr, #16
441: ldrb r4, [r1], #1
45 ldrb r5, [r1], #1
46 ldrb r6, [r1], #1
47 ldrb r7, [r1], #1
48 subs lr, lr, #1
49 orr r5, r5, r4, lsl #8
50 orr r6, r6, r5, lsl #8
51 orr r7, r7, r6, lsl #8
52 str r7, [r3], #4
53 bne 1b
54#endif
55
56 @ for (i = 0; i < 64; i++)
57 @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
58
59 sub r3, r2, #4
60 mov lr, #64
612: ldr r4, [r3, #4]!
62 subs lr, lr, #1
63 ldr r5, [r3, #8]
64 ldr r6, [r3, #32]
65 ldr r7, [r3, #52]
66 eor r4, r4, r5
67 eor r4, r4, r6
68 eor r4, r4, r7
69 mov r4, r4, ror #31
70 str r4, [r3, #64]
71 bne 2b
72
73 /*
74 * The SHA functions are:
75 *
76 * f1(B,C,D) = (D ^ (B & (C ^ D)))
77 * f2(B,C,D) = (B ^ C ^ D)
78 * f3(B,C,D) = ((B & C) | (D & (B | C)))
79 *
80 * Then the sub-blocks are processed as follows:
81 *
82 * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
83 * B' = A
84 * C' = ror(B, 2)
85 * D' = C
86 * E' = D
87 *
88 * We therefore unroll each loop 5 times to avoid register shuffling.
89 * Also the ror for C (and also D and E which are successivelyderived
90 * from it) is applied in place to cut on an additional mov insn for
91 * each round.
92 */
93
94 .macro sha_f1, A, B, C, D, E
95 ldr r3, [r2], #4
96 eor ip, \C, \D
97 add \E, r1, \E, ror #2
98 and ip, \B, ip, ror #2
99 add \E, \E, \A, ror #27
100 eor ip, ip, \D, ror #2
101 add \E, \E, r3
102 add \E, \E, ip
103 .endm
104
105 .macro sha_f2, A, B, C, D, E
106 ldr r3, [r2], #4
107 add \E, r1, \E, ror #2
108 eor ip, \B, \C, ror #2
109 add \E, \E, \A, ror #27
110 eor ip, ip, \D, ror #2
111 add \E, \E, r3
112 add \E, \E, ip
113 .endm
114
115 .macro sha_f3, A, B, C, D, E
116 ldr r3, [r2], #4
117 add \E, r1, \E, ror #2
118 orr ip, \B, \C, ror #2
119 add \E, \E, \A, ror #27
120 and ip, ip, \D, ror #2
121 add \E, \E, r3
122 and r3, \B, \C, ror #2
123 orr ip, ip, r3
124 add \E, \E, ip
125 .endm
126
127 ldmia r0, {r4 - r8}
128
129 mov lr, #4
130 ldr r1, .L_sha_K + 0
131
132 /* adjust initial values */
133 mov r6, r6, ror #30
134 mov r7, r7, ror #30
135 mov r8, r8, ror #30
136
1373: subs lr, lr, #1
138 sha_f1 r4, r5, r6, r7, r8
139 sha_f1 r8, r4, r5, r6, r7
140 sha_f1 r7, r8, r4, r5, r6
141 sha_f1 r6, r7, r8, r4, r5
142 sha_f1 r5, r6, r7, r8, r4
143 bne 3b
144
145 ldr r1, .L_sha_K + 4
146 mov lr, #4
147
1484: subs lr, lr, #1
149 sha_f2 r4, r5, r6, r7, r8
150 sha_f2 r8, r4, r5, r6, r7
151 sha_f2 r7, r8, r4, r5, r6
152 sha_f2 r6, r7, r8, r4, r5
153 sha_f2 r5, r6, r7, r8, r4
154 bne 4b
155
156 ldr r1, .L_sha_K + 8
157 mov lr, #4
158
1595: subs lr, lr, #1
160 sha_f3 r4, r5, r6, r7, r8
161 sha_f3 r8, r4, r5, r6, r7
162 sha_f3 r7, r8, r4, r5, r6
163 sha_f3 r6, r7, r8, r4, r5
164 sha_f3 r5, r6, r7, r8, r4
165 bne 5b
166
167 ldr r1, .L_sha_K + 12
168 mov lr, #4
169
1706: subs lr, lr, #1
171 sha_f2 r4, r5, r6, r7, r8
172 sha_f2 r8, r4, r5, r6, r7
173 sha_f2 r7, r8, r4, r5, r6
174 sha_f2 r6, r7, r8, r4, r5
175 sha_f2 r5, r6, r7, r8, r4
176 bne 6b
177
178 ldmia r0, {r1, r2, r3, ip, lr}
179 add r4, r1, r4
180 add r5, r2, r5
181 add r6, r3, r6, ror #2
182 add r7, ip, r7, ror #2
183 add r8, lr, r8, ror #2
184 stmia r0, {r4 - r8}
185
186 ldmfd sp!, {r4 - r8, pc}
187
188ENDPROC(sha_transform)
189
190 .align 2
191.L_sha_K:
192 .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
193
194
195/*
196 * void sha_init(__u32 *buf)
197 */
198
199 .align 2
200.L_sha_initial_digest:
201 .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
202
203ENTRY(sha_init)
204
205 str lr, [sp, #-4]!
206 adr r1, .L_sha_initial_digest
207 ldmia r1, {r1, r2, r3, ip, lr}
208 stmia r0, {r1, r2, r3, ip, lr}
209 ldr pc, [sp], #4
210
211ENDPROC(sha_init)
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index e9d689b7c833..197e96f70405 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -10,6 +10,7 @@ config AVR32
10 select GENERIC_IRQ_PROBE 10 select GENERIC_IRQ_PROBE
11 select HARDIRQS_SW_RESEND 11 select HARDIRQS_SW_RESEND
12 select GENERIC_IRQ_SHOW 12 select GENERIC_IRQ_SHOW
13 select ARCH_HAVE_NMI_SAFE_CMPXCHG
13 help 14 help
14 AVR32 is a high-performance 32-bit RISC microprocessor core, 15 AVR32 is a high-performance 32-bit RISC microprocessor core,
15 designed for cost-sensitive embedded applications, with particular 16 designed for cost-sensitive embedded applications, with particular
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c
index 850265373611..466af40c5822 100644
--- a/arch/cris/arch-v10/drivers/sync_serial.c
+++ b/arch/cris/arch-v10/drivers/sync_serial.c
@@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file);
158static int sync_serial_release(struct inode *inode, struct file *file); 158static int sync_serial_release(struct inode *inode, struct file *file);
159static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); 159static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
160 160
161static int sync_serial_ioctl(struct file *file, 161static long sync_serial_ioctl(struct file *file,
162 unsigned int cmd, unsigned long arg); 162 unsigned int cmd, unsigned long arg);
163static ssize_t sync_serial_write(struct file *file, const char *buf, 163static ssize_t sync_serial_write(struct file *file, const char *buf,
164 size_t count, loff_t *ppos); 164 size_t count, loff_t *ppos);
@@ -625,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file)
625 *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; 625 *R_IRQ_MASK1_SET = 1 << port->data_avail_bit;
626 DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); 626 DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev));
627 } 627 }
628 ret = 0; 628 err = 0;
629 629
630out: 630out:
631 mutex_unlock(&sync_serial_mutex); 631 mutex_unlock(&sync_serial_mutex);
632 return ret; 632 return err;
633} 633}
634 634
635static int sync_serial_release(struct inode *inode, struct file *file) 635static int sync_serial_release(struct inode *inode, struct file *file)
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 907cfb5a873d..ba0e5965d6e3 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -20,6 +20,9 @@
20#define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); 20#define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
21#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); 21#define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
22 22
23extern void kgdb_init(void);
24extern void breakpoint(void);
25
23/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is 26/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
24 * global just so that the kernel gdb can use it. 27 * global just so that the kernel gdb can use it.
25 */ 28 */
diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h
index 29b74a105830..332f19c54557 100644
--- a/arch/cris/include/asm/thread_info.h
+++ b/arch/cris/include/asm/thread_info.h
@@ -11,8 +11,6 @@
11 11
12#ifdef __KERNEL__ 12#ifdef __KERNEL__
13 13
14#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
15
16#ifndef __ASSEMBLY__ 14#ifndef __ASSEMBLY__
17#include <asm/types.h> 15#include <asm/types.h>
18#include <asm/processor.h> 16#include <asm/processor.h>
@@ -67,8 +65,10 @@ struct thread_info {
67 65
68#define init_thread_info (init_thread_union.thread_info) 66#define init_thread_info (init_thread_union.thread_info)
69 67
68#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
70/* thread information allocation */ 69/* thread information allocation */
71#define alloc_thread_info(tsk, node) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) 70#define alloc_thread_info_node(tsk, node) \
71 ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1))
72#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) 72#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
73 73
74#endif /* !__ASSEMBLY__ */ 74#endif /* !__ASSEMBLY__ */
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index cb884e489425..bad27a6ff407 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -7,6 +7,7 @@ config FRV
7 select HAVE_PERF_EVENTS 7 select HAVE_PERF_EVENTS
8 select HAVE_GENERIC_HARDIRQS 8 select HAVE_GENERIC_HARDIRQS
9 select GENERIC_IRQ_SHOW 9 select GENERIC_IRQ_SHOW
10 select ARCH_HAVE_NMI_SAFE_CMPXCHG
10 11
11config ZONE_DMA 12config ZONE_DMA
12 bool 13 bool
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 64c7ab7e7a81..124854714958 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -28,6 +28,7 @@ config IA64
28 select IRQ_PER_CPU 28 select IRQ_PER_CPU
29 select GENERIC_IRQ_SHOW 29 select GENERIC_IRQ_SHOW
30 select ARCH_WANT_OPTIONAL_GPIOLIB 30 select ARCH_WANT_OPTIONAL_GPIOLIB
31 select ARCH_HAVE_NMI_SAFE_CMPXCHG
31 default y 32 default y
32 help 33 help
33 The Itanium Processor Family is Intel's 64-bit successor to 34 The Itanium Processor Family is Intel's 64-bit successor to
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 6fc03aff046c..c38d22e5e902 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -156,7 +156,7 @@ prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, \
156#define STUB_SET_VARIABLE(prefix, adjust_arg) \ 156#define STUB_SET_VARIABLE(prefix, adjust_arg) \
157static efi_status_t \ 157static efi_status_t \
158prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, \ 158prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, \
159 unsigned long attr, unsigned long data_size, \ 159 u32 attr, unsigned long data_size, \
160 void *data) \ 160 void *data) \
161{ \ 161{ \
162 struct ia64_fpreg fr[6]; \ 162 struct ia64_fpreg fr[6]; \
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 284cd3771eaa..9e8ee9d2b8ca 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -6,6 +6,7 @@ config M68K
6 select GENERIC_ATOMIC64 if MMU 6 select GENERIC_ATOMIC64 if MMU
7 select HAVE_GENERIC_HARDIRQS if !MMU 7 select HAVE_GENERIC_HARDIRQS if !MMU
8 select GENERIC_IRQ_SHOW if !MMU 8 select GENERIC_IRQ_SHOW if !MMU
9 select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
9 10
10config RWSEM_GENERIC_SPINLOCK 11config RWSEM_GENERIC_SPINLOCK
11 bool 12 bool
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 65adc86a230e..e077b0bf56ca 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -15,6 +15,7 @@ config PARISC
15 select HAVE_GENERIC_HARDIRQS 15 select HAVE_GENERIC_HARDIRQS
16 select GENERIC_IRQ_PROBE 16 select GENERIC_IRQ_PROBE
17 select IRQ_PER_CPU 17 select IRQ_PER_CPU
18 select ARCH_HAVE_NMI_SAFE_CMPXCHG
18 19
19 help 20 help
20 The PA-RISC microprocessor is designed by Hewlett-Packard and used 21 The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
index b1dc71f5534e..4054b31e0fa9 100644
--- a/arch/parisc/include/asm/atomic.h
+++ b/arch/parisc/include/asm/atomic.h
@@ -258,10 +258,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
258 258
259#define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) 259#define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
260 260
261static __inline__ int 261static __inline__ s64
262__atomic64_add_return(s64 i, atomic64_t *v) 262__atomic64_add_return(s64 i, atomic64_t *v)
263{ 263{
264 int ret; 264 s64 ret;
265 unsigned long flags; 265 unsigned long flags;
266 _atomic_spin_lock_irqsave(v, flags); 266 _atomic_spin_lock_irqsave(v, flags);
267 267
diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h
index 67a33cc27ef2..2388bdb32832 100644
--- a/arch/parisc/include/asm/futex.h
+++ b/arch/parisc/include/asm/futex.h
@@ -5,11 +5,14 @@
5 5
6#include <linux/futex.h> 6#include <linux/futex.h>
7#include <linux/uaccess.h> 7#include <linux/uaccess.h>
8#include <asm/atomic.h>
8#include <asm/errno.h> 9#include <asm/errno.h>
9 10
10static inline int 11static inline int
11futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) 12futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
12{ 13{
14 unsigned long int flags;
15 u32 val;
13 int op = (encoded_op >> 28) & 7; 16 int op = (encoded_op >> 28) & 7;
14 int cmp = (encoded_op >> 24) & 15; 17 int cmp = (encoded_op >> 24) & 15;
15 int oparg = (encoded_op << 8) >> 20; 18 int oparg = (encoded_op << 8) >> 20;
@@ -18,21 +21,58 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
18 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) 21 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
19 oparg = 1 << oparg; 22 oparg = 1 << oparg;
20 23
21 if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) 24 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr)))
22 return -EFAULT; 25 return -EFAULT;
23 26
24 pagefault_disable(); 27 pagefault_disable();
25 28
29 _atomic_spin_lock_irqsave(uaddr, flags);
30
26 switch (op) { 31 switch (op) {
27 case FUTEX_OP_SET: 32 case FUTEX_OP_SET:
33 /* *(int *)UADDR2 = OPARG; */
34 ret = get_user(oldval, uaddr);
35 if (!ret)
36 ret = put_user(oparg, uaddr);
37 break;
28 case FUTEX_OP_ADD: 38 case FUTEX_OP_ADD:
39 /* *(int *)UADDR2 += OPARG; */
40 ret = get_user(oldval, uaddr);
41 if (!ret) {
42 val = oldval + oparg;
43 ret = put_user(val, uaddr);
44 }
45 break;
29 case FUTEX_OP_OR: 46 case FUTEX_OP_OR:
47 /* *(int *)UADDR2 |= OPARG; */
48 ret = get_user(oldval, uaddr);
49 if (!ret) {
50 val = oldval | oparg;
51 ret = put_user(val, uaddr);
52 }
53 break;
30 case FUTEX_OP_ANDN: 54 case FUTEX_OP_ANDN:
55 /* *(int *)UADDR2 &= ~OPARG; */
56 ret = get_user(oldval, uaddr);
57 if (!ret) {
58 val = oldval & ~oparg;
59 ret = put_user(val, uaddr);
60 }
61 break;
31 case FUTEX_OP_XOR: 62 case FUTEX_OP_XOR:
63 /* *(int *)UADDR2 ^= OPARG; */
64 ret = get_user(oldval, uaddr);
65 if (!ret) {
66 val = oldval ^ oparg;
67 ret = put_user(val, uaddr);
68 }
69 break;
32 default: 70 default:
33 ret = -ENOSYS; 71 ret = -ENOSYS;
34 } 72 }
35 73
74 _atomic_spin_unlock_irqrestore(uaddr, flags);
75
36 pagefault_enable(); 76 pagefault_enable();
37 77
38 if (!ret) { 78 if (!ret) {
@@ -54,7 +94,9 @@ static inline int
54futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, 94futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
55 u32 oldval, u32 newval) 95 u32 oldval, u32 newval)
56{ 96{
97 int ret;
57 u32 val; 98 u32 val;
99 unsigned long flags;
58 100
59 /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is 101 /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is
60 * our gateway page, and causes no end of trouble... 102 * our gateway page, and causes no end of trouble...
@@ -65,12 +107,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
65 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) 107 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
66 return -EFAULT; 108 return -EFAULT;
67 109
68 if (get_user(val, uaddr)) 110 /* HPPA has no cmpxchg in hardware and therefore the
69 return -EFAULT; 111 * best we can do here is use an array of locks. The
70 if (val == oldval && put_user(newval, uaddr)) 112 * lock selected is based on a hash of the userspace
71 return -EFAULT; 113 * address. This should scale to a couple of CPUs.
114 */
115
116 _atomic_spin_lock_irqsave(uaddr, flags);
117
118 ret = get_user(val, uaddr);
119
120 if (!ret && val == oldval)
121 ret = put_user(newval, uaddr);
122
72 *uval = val; 123 *uval = val;
73 return 0; 124
125 _atomic_spin_unlock_irqrestore(uaddr, flags);
126
127 return ret;
74} 128}
75 129
76#endif /*__KERNEL__*/ 130#endif /*__KERNEL__*/
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index 3392de3e7be0..d61de64f990a 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -821,8 +821,9 @@
821#define __NR_open_by_handle_at (__NR_Linux + 326) 821#define __NR_open_by_handle_at (__NR_Linux + 326)
822#define __NR_syncfs (__NR_Linux + 327) 822#define __NR_syncfs (__NR_Linux + 327)
823#define __NR_setns (__NR_Linux + 328) 823#define __NR_setns (__NR_Linux + 328)
824#define __NR_sendmmsg (__NR_Linux + 329)
824 825
825#define __NR_Linux_syscalls (__NR_setns + 1) 826#define __NR_Linux_syscalls (__NR_sendmmsg + 1)
826 827
827 828
828#define __IGNORE_select /* newselect */ 829#define __IGNORE_select /* newselect */
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 34a4f5a2fffb..e66366fd2abc 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -427,6 +427,7 @@
427 ENTRY_COMP(open_by_handle_at) 427 ENTRY_COMP(open_by_handle_at)
428 ENTRY_SAME(syncfs) 428 ENTRY_SAME(syncfs)
429 ENTRY_SAME(setns) 429 ENTRY_SAME(setns)
430 ENTRY_COMP(sendmmsg)
430 431
431 /* Nothing yet */ 432 /* Nothing yet */
432 433
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 374c475e56a3..6926b61acfea 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -136,6 +136,7 @@ config PPC
136 select HAVE_SYSCALL_TRACEPOINTS 136 select HAVE_SYSCALL_TRACEPOINTS
137 select HAVE_BPF_JIT if (PPC64 && NET) 137 select HAVE_BPF_JIT if (PPC64 && NET)
138 select HAVE_ARCH_JUMP_LABEL 138 select HAVE_ARCH_JUMP_LABEL
139 select ARCH_HAVE_NMI_SAFE_CMPXCHG
139 140
140config EARLY_PRINTK 141config EARLY_PRINTK
141 bool 142 bool
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index c03fef7a9c22..ed5cb5af5281 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -81,6 +81,7 @@ config S390
81 select INIT_ALL_POSSIBLE 81 select INIT_ALL_POSSIBLE
82 select HAVE_IRQ_WORK 82 select HAVE_IRQ_WORK
83 select HAVE_PERF_EVENTS 83 select HAVE_PERF_EVENTS
84 select ARCH_HAVE_NMI_SAFE_CMPXCHG
84 select HAVE_KERNEL_GZIP 85 select HAVE_KERNEL_GZIP
85 select HAVE_KERNEL_BZIP2 86 select HAVE_KERNEL_BZIP2
86 select HAVE_KERNEL_LZMA 87 select HAVE_KERNEL_LZMA
@@ -273,11 +274,11 @@ config MARCH_Z10
273 on older machines. 274 on older machines.
274 275
275config MARCH_Z196 276config MARCH_Z196
276 bool "IBM zEnterprise 196" 277 bool "IBM zEnterprise 114 and 196"
277 help 278 help
278 Select this to enable optimizations for IBM zEnterprise 196 279 Select this to enable optimizations for IBM zEnterprise 114 and 196
279 (2817 series). The kernel will be slightly faster but will not work 280 (2818 and 2817 series). The kernel will be slightly faster but will
280 on older machines. 281 not work on older machines.
281 282
282endchoice 283endchoice
283 284
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index 5e95d95450b3..97cc4403fabf 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -167,5 +167,6 @@ enum diag308_rc {
167}; 167};
168 168
169extern int diag308(unsigned long subcode, void *addr); 169extern int diag308(unsigned long subcode, void *addr);
170extern void diag308_reset(void);
170 171
171#endif /* _ASM_S390_IPL_H */ 172#endif /* _ASM_S390_IPL_H */
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index f26280d9e88d..e85c911aabf0 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -18,6 +18,7 @@ void system_call(void);
18void pgm_check_handler(void); 18void pgm_check_handler(void);
19void mcck_int_handler(void); 19void mcck_int_handler(void);
20void io_int_handler(void); 20void io_int_handler(void);
21void psw_restart_int_handler(void);
21 22
22#ifdef CONFIG_32BIT 23#ifdef CONFIG_32BIT
23 24
@@ -150,7 +151,10 @@ struct _lowcore {
150 */ 151 */
151 __u32 ipib; /* 0x0e00 */ 152 __u32 ipib; /* 0x0e00 */
152 __u32 ipib_checksum; /* 0x0e04 */ 153 __u32 ipib_checksum; /* 0x0e04 */
153 __u8 pad_0x0e08[0x0f00-0x0e08]; /* 0x0e08 */ 154
155 /* 64 bit save area */
156 __u64 save_area_64; /* 0x0e08 */
157 __u8 pad_0x0e10[0x0f00-0x0e10]; /* 0x0e10 */
154 158
155 /* Extended facility list */ 159 /* Extended facility list */
156 __u64 stfle_fac_list[32]; /* 0x0f00 */ 160 __u64 stfle_fac_list[32]; /* 0x0f00 */
@@ -286,7 +290,10 @@ struct _lowcore {
286 */ 290 */
287 __u64 ipib; /* 0x0e00 */ 291 __u64 ipib; /* 0x0e00 */
288 __u32 ipib_checksum; /* 0x0e08 */ 292 __u32 ipib_checksum; /* 0x0e08 */
289 __u8 pad_0x0e0c[0x0f00-0x0e0c]; /* 0x0e0c */ 293
294 /* 64 bit save area */
295 __u64 save_area_64; /* 0x0e0c */
296 __u8 pad_0x0e14[0x0f00-0x0e14]; /* 0x0e14 */
290 297
291 /* Extended facility list */ 298 /* Extended facility list */
292 __u64 stfle_fac_list[32]; /* 0x0f00 */ 299 __u64 stfle_fac_list[32]; /* 0x0f00 */
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 55dfcc8bdc0d..a4b6229e5d4b 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -119,14 +119,12 @@ struct stack_frame {
119 * Do necessary setup to start up a new thread. 119 * Do necessary setup to start up a new thread.
120 */ 120 */
121#define start_thread(regs, new_psw, new_stackp) do { \ 121#define start_thread(regs, new_psw, new_stackp) do { \
122 set_fs(USER_DS); \
123 regs->psw.mask = psw_user_bits; \ 122 regs->psw.mask = psw_user_bits; \
124 regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ 123 regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
125 regs->gprs[15] = new_stackp; \ 124 regs->gprs[15] = new_stackp; \
126} while (0) 125} while (0)
127 126
128#define start_thread31(regs, new_psw, new_stackp) do { \ 127#define start_thread31(regs, new_psw, new_stackp) do { \
129 set_fs(USER_DS); \
130 regs->psw.mask = psw_user32_bits; \ 128 regs->psw.mask = psw_user32_bits; \
131 regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ 129 regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
132 regs->gprs[15] = new_stackp; \ 130 regs->gprs[15] = new_stackp; \
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index d382629a0172..6582f69f2389 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -113,6 +113,7 @@ extern void pfault_fini(void);
113 113
114extern void cmma_init(void); 114extern void cmma_init(void);
115extern int memcpy_real(void *, void *, size_t); 115extern int memcpy_real(void *, void *, size_t);
116extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
116 117
117#define finish_arch_switch(prev) do { \ 118#define finish_arch_switch(prev) do { \
118 set_fs(current->thread.mm_segment); \ 119 set_fs(current->thread.mm_segment); \
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 05d8f38734ec..532fd4322156 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -27,12 +27,9 @@ int main(void)
27 BLANK(); 27 BLANK();
28 DEFINE(__TASK_pid, offsetof(struct task_struct, pid)); 28 DEFINE(__TASK_pid, offsetof(struct task_struct, pid));
29 BLANK(); 29 BLANK();
30 DEFINE(__THREAD_per_cause, 30 DEFINE(__THREAD_per_cause, offsetof(struct task_struct, thread.per_event.cause));
31 offsetof(struct task_struct, thread.per_event.cause)); 31 DEFINE(__THREAD_per_address, offsetof(struct task_struct, thread.per_event.address));
32 DEFINE(__THREAD_per_address, 32 DEFINE(__THREAD_per_paid, offsetof(struct task_struct, thread.per_event.paid));
33 offsetof(struct task_struct, thread.per_event.address));
34 DEFINE(__THREAD_per_paid,
35 offsetof(struct task_struct, thread.per_event.paid));
36 BLANK(); 33 BLANK();
37 DEFINE(__TI_task, offsetof(struct thread_info, task)); 34 DEFINE(__TI_task, offsetof(struct thread_info, task));
38 DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); 35 DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain));
@@ -142,6 +139,7 @@ int main(void)
142 DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area)); 139 DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
143 DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area)); 140 DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
144 DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area)); 141 DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
142 DEFINE(__LC_SAVE_AREA_64, offsetof(struct _lowcore, save_area_64));
145#ifdef CONFIG_32BIT 143#ifdef CONFIG_32BIT
146 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr)); 144 DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
147#else /* CONFIG_32BIT */ 145#else /* CONFIG_32BIT */
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index 209938c1dfc8..255435663bf8 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -76,6 +76,42 @@ s390_base_pgm_handler_fn:
76 .quad 0 76 .quad 0
77 .previous 77 .previous
78 78
79#
80# Calls diag 308 subcode 1 and continues execution
81#
82# The following conditions must be ensured before calling this function:
83# * Prefix register = 0
84# * Lowcore protection is disabled
85#
86ENTRY(diag308_reset)
87 larl %r4,.Lctlregs # Save control registers
88 stctg %c0,%c15,0(%r4)
89 larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0
90 lghi %r3,0
91 lg %r4,0(%r4) # Save PSW
92 sturg %r4,%r3 # Use sturg, because of large pages
93 lghi %r1,1
94 diag %r1,%r1,0x308
95.Lrestart_part2:
96 lhi %r0,0 # Load r0 with zero
97 lhi %r1,2 # Use mode 2 = ESAME (dump)
98 sigp %r1,%r0,0x12 # Switch to ESAME mode
99 sam64 # Switch to 64 bit addressing mode
100 larl %r4,.Lctlregs # Restore control registers
101 lctlg %c0,%c15,0(%r4)
102 br %r14
103.align 16
104.Lrestart_psw:
105 .long 0x00080000,0x80000000 + .Lrestart_part2
106
107 .section .bss
108.align 8
109.Lctlregs:
110 .rept 16
111 .quad 0
112 .endr
113 .previous
114
79#else /* CONFIG_64BIT */ 115#else /* CONFIG_64BIT */
80 116
81ENTRY(s390_base_mcck_handler) 117ENTRY(s390_base_mcck_handler)
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index eee999853a7c..a9a285b8c4ad 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -380,20 +380,13 @@ asmlinkage long sys32_sigreturn(void)
380 goto badframe; 380 goto badframe;
381 if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) 381 if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
382 goto badframe; 382 goto badframe;
383
384 sigdelsetmask(&set, ~_BLOCKABLE); 383 sigdelsetmask(&set, ~_BLOCKABLE);
385 spin_lock_irq(&current->sighand->siglock); 384 set_current_blocked(&set);
386 current->blocked = set;
387 recalc_sigpending();
388 spin_unlock_irq(&current->sighand->siglock);
389
390 if (restore_sigregs32(regs, &frame->sregs)) 385 if (restore_sigregs32(regs, &frame->sregs))
391 goto badframe; 386 goto badframe;
392 if (restore_sigregs_gprs_high(regs, frame->gprs_high)) 387 if (restore_sigregs_gprs_high(regs, frame->gprs_high))
393 goto badframe; 388 goto badframe;
394
395 return regs->gprs[2]; 389 return regs->gprs[2];
396
397badframe: 390badframe:
398 force_sig(SIGSEGV, current); 391 force_sig(SIGSEGV, current);
399 return 0; 392 return 0;
@@ -413,31 +406,22 @@ asmlinkage long sys32_rt_sigreturn(void)
413 goto badframe; 406 goto badframe;
414 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 407 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
415 goto badframe; 408 goto badframe;
416
417 sigdelsetmask(&set, ~_BLOCKABLE); 409 sigdelsetmask(&set, ~_BLOCKABLE);
418 spin_lock_irq(&current->sighand->siglock); 410 set_current_blocked(&set);
419 current->blocked = set;
420 recalc_sigpending();
421 spin_unlock_irq(&current->sighand->siglock);
422
423 if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) 411 if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
424 goto badframe; 412 goto badframe;
425 if (restore_sigregs_gprs_high(regs, frame->gprs_high)) 413 if (restore_sigregs_gprs_high(regs, frame->gprs_high))
426 goto badframe; 414 goto badframe;
427
428 err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); 415 err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
429 st.ss_sp = compat_ptr(ss_sp); 416 st.ss_sp = compat_ptr(ss_sp);
430 err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); 417 err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size);
431 err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); 418 err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
432 if (err) 419 if (err)
433 goto badframe; 420 goto badframe;
434
435 set_fs (KERNEL_DS); 421 set_fs (KERNEL_DS);
436 do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]); 422 do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]);
437 set_fs (old_fs); 423 set_fs (old_fs);
438
439 return regs->gprs[2]; 424 return regs->gprs[2];
440
441badframe: 425badframe:
442 force_sig(SIGSEGV, current); 426 force_sig(SIGSEGV, current);
443 return 0; 427 return 0;
@@ -605,10 +589,10 @@ give_sigsegv:
605 * OK, we're invoking a handler 589 * OK, we're invoking a handler
606 */ 590 */
607 591
608int 592int handle_signal32(unsigned long sig, struct k_sigaction *ka,
609handle_signal32(unsigned long sig, struct k_sigaction *ka, 593 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
610 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
611{ 594{
595 sigset_t blocked;
612 int ret; 596 int ret;
613 597
614 /* Set up the stack frame */ 598 /* Set up the stack frame */
@@ -616,15 +600,12 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka,
616 ret = setup_rt_frame32(sig, ka, info, oldset, regs); 600 ret = setup_rt_frame32(sig, ka, info, oldset, regs);
617 else 601 else
618 ret = setup_frame32(sig, ka, oldset, regs); 602 ret = setup_frame32(sig, ka, oldset, regs);
619 603 if (ret)
620 if (ret == 0) { 604 return ret;
621 spin_lock_irq(&current->sighand->siglock); 605 sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
622 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 606 if (!(ka->sa.sa_flags & SA_NODEFER))
623 if (!(ka->sa.sa_flags & SA_NODEFER)) 607 sigaddset(&blocked, sig);
624 sigaddset(&current->blocked,sig); 608 set_current_blocked(&blocked);
625 recalc_sigpending(); 609 return 0;
626 spin_unlock_irq(&current->sighand->siglock);
627 }
628 return ret;
629} 610}
630 611
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 3eab7cfab07c..02ec8fe7d03f 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -849,6 +849,34 @@ restart_crash:
849restart_go: 849restart_go:
850#endif 850#endif
851 851
852#
853# PSW restart interrupt handler
854#
855ENTRY(psw_restart_int_handler)
856 st %r15,__LC_SAVE_AREA_64(%r0) # save r15
857 basr %r15,0
8580: l %r15,.Lrestart_stack-0b(%r15) # load restart stack
859 l %r15,0(%r15)
860 ahi %r15,-SP_SIZE # make room for pt_regs
861 stm %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack
862 mvc SP_R15(4,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
863 mvc SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw
864 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
865 basr %r14,0
8661: l %r14,.Ldo_restart-1b(%r14)
867 basr %r14,%r14
868
869 basr %r14,0 # load disabled wait PSW if
8702: lpsw restart_psw_crash-2b(%r14) # do_restart returns
871 .align 4
872.Ldo_restart:
873 .long do_restart
874.Lrestart_stack:
875 .long restart_stack
876 .align 8
877restart_psw_crash:
878 .long 0x000a0000,0x00000000 + restart_psw_crash
879
852 .section .kprobes.text, "ax" 880 .section .kprobes.text, "ax"
853 881
854#ifdef CONFIG_CHECK_STACK 882#ifdef CONFIG_CHECK_STACK
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7a0fd426ca92..5f729d627cef 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -865,6 +865,26 @@ restart_crash:
865restart_go: 865restart_go:
866#endif 866#endif
867 867
868#
869# PSW restart interrupt handler
870#
871ENTRY(psw_restart_int_handler)
872 stg %r15,__LC_SAVE_AREA_64(%r0) # save r15
873 larl %r15,restart_stack # load restart stack
874 lg %r15,0(%r15)
875 aghi %r15,-SP_SIZE # make room for pt_regs
876 stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack
877 mvc SP_R15(8,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
878 mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw
879 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
880 brasl %r14,do_restart
881
882 larl %r14,restart_psw_crash # load disabled wait PSW if
883 lpswe 0(%r14) # do_restart returns
884 .align 8
885restart_psw_crash:
886 .quad 0x0002000080000000,0x0000000000000000 + restart_psw_crash
887
868 .section .kprobes.text, "ax" 888 .section .kprobes.text, "ax"
869 889
870#ifdef CONFIG_CHECK_STACK 890#ifdef CONFIG_CHECK_STACK
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index a689070be287..04361d5a4279 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -45,11 +45,13 @@
45 * - halt 45 * - halt
46 * - power off 46 * - power off
47 * - reipl 47 * - reipl
48 * - restart
48 */ 49 */
49#define ON_PANIC_STR "on_panic" 50#define ON_PANIC_STR "on_panic"
50#define ON_HALT_STR "on_halt" 51#define ON_HALT_STR "on_halt"
51#define ON_POFF_STR "on_poff" 52#define ON_POFF_STR "on_poff"
52#define ON_REIPL_STR "on_reboot" 53#define ON_REIPL_STR "on_reboot"
54#define ON_RESTART_STR "on_restart"
53 55
54struct shutdown_action; 56struct shutdown_action;
55struct shutdown_trigger { 57struct shutdown_trigger {
@@ -1544,17 +1546,20 @@ static char vmcmd_on_reboot[128];
1544static char vmcmd_on_panic[128]; 1546static char vmcmd_on_panic[128];
1545static char vmcmd_on_halt[128]; 1547static char vmcmd_on_halt[128];
1546static char vmcmd_on_poff[128]; 1548static char vmcmd_on_poff[128];
1549static char vmcmd_on_restart[128];
1547 1550
1548DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot); 1551DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
1549DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic); 1552DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
1550DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt); 1553DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
1551DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff); 1554DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
1555DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
1552 1556
1553static struct attribute *vmcmd_attrs[] = { 1557static struct attribute *vmcmd_attrs[] = {
1554 &sys_vmcmd_on_reboot_attr.attr, 1558 &sys_vmcmd_on_reboot_attr.attr,
1555 &sys_vmcmd_on_panic_attr.attr, 1559 &sys_vmcmd_on_panic_attr.attr,
1556 &sys_vmcmd_on_halt_attr.attr, 1560 &sys_vmcmd_on_halt_attr.attr,
1557 &sys_vmcmd_on_poff_attr.attr, 1561 &sys_vmcmd_on_poff_attr.attr,
1562 &sys_vmcmd_on_restart_attr.attr,
1558 NULL, 1563 NULL,
1559}; 1564};
1560 1565
@@ -1576,6 +1581,8 @@ static void vmcmd_run(struct shutdown_trigger *trigger)
1576 cmd = vmcmd_on_halt; 1581 cmd = vmcmd_on_halt;
1577 else if (strcmp(trigger->name, ON_POFF_STR) == 0) 1582 else if (strcmp(trigger->name, ON_POFF_STR) == 0)
1578 cmd = vmcmd_on_poff; 1583 cmd = vmcmd_on_poff;
1584 else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
1585 cmd = vmcmd_on_restart;
1579 else 1586 else
1580 return; 1587 return;
1581 1588
@@ -1707,6 +1714,34 @@ static void do_panic(void)
1707 stop_run(&on_panic_trigger); 1714 stop_run(&on_panic_trigger);
1708} 1715}
1709 1716
1717/* on restart */
1718
1719static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
1720 &reipl_action};
1721
1722static ssize_t on_restart_show(struct kobject *kobj,
1723 struct kobj_attribute *attr, char *page)
1724{
1725 return sprintf(page, "%s\n", on_restart_trigger.action->name);
1726}
1727
1728static ssize_t on_restart_store(struct kobject *kobj,
1729 struct kobj_attribute *attr,
1730 const char *buf, size_t len)
1731{
1732 return set_trigger(buf, &on_restart_trigger, len);
1733}
1734
1735static struct kobj_attribute on_restart_attr =
1736 __ATTR(on_restart, 0644, on_restart_show, on_restart_store);
1737
1738void do_restart(void)
1739{
1740 smp_send_stop();
1741 on_restart_trigger.action->fn(&on_restart_trigger);
1742 stop_run(&on_restart_trigger);
1743}
1744
1710/* on halt */ 1745/* on halt */
1711 1746
1712static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action}; 1747static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
@@ -1783,7 +1818,9 @@ static void __init shutdown_triggers_init(void)
1783 if (sysfs_create_file(&shutdown_actions_kset->kobj, 1818 if (sysfs_create_file(&shutdown_actions_kset->kobj,
1784 &on_poff_attr.attr)) 1819 &on_poff_attr.attr))
1785 goto fail; 1820 goto fail;
1786 1821 if (sysfs_create_file(&shutdown_actions_kset->kobj,
1822 &on_restart_attr.attr))
1823 goto fail;
1787 return; 1824 return;
1788fail: 1825fail:
1789 panic("shutdown_triggers_init failed\n"); 1826 panic("shutdown_triggers_init failed\n");
@@ -1959,6 +1996,12 @@ static void do_reset_calls(void)
1959{ 1996{
1960 struct reset_call *reset; 1997 struct reset_call *reset;
1961 1998
1999#ifdef CONFIG_64BIT
2000 if (diag308_set_works) {
2001 diag308_reset();
2002 return;
2003 }
2004#endif
1962 list_for_each_entry(reset, &rcall, list) 2005 list_for_each_entry(reset, &rcall, list)
1963 reset->fn(); 2006 reset->fn();
1964} 2007}
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 78eb7cfbd3d1..e690975403f4 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright IBM Corp 2000,2009 2 * Copyright IBM Corp 2000,2011
3 * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>, 3 * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
4 * Denis Joseph Barrow, 4 * Denis Joseph Barrow,
5 */ 5 */
@@ -8,6 +8,64 @@
8#include <asm/asm-offsets.h> 8#include <asm/asm-offsets.h>
9 9
10# 10#
11# store_status
12#
13# Prerequisites to run this function:
14# - Prefix register is set to zero
15# - Original prefix register is stored in "dump_prefix_page"
16# - Lowcore protection is off
17#
18ENTRY(store_status)
19 /* Save register one and load save area base */
20 stg %r1,__LC_SAVE_AREA_64(%r0)
21 lghi %r1,SAVE_AREA_BASE
22 /* General purpose registers */
23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
24 lg %r2,__LC_SAVE_AREA_64(%r0)
25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
26 /* Control registers */
27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
28 /* Access registers */
29 stam %a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
30 /* Floating point registers */
31 std %f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
32 std %f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
33 std %f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
34 std %f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
35 std %f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
36 std %f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
37 std %f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
38 std %f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
39 std %f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
40 std %f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
41 std %f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
42 std %f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
43 std %f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
44 std %f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
45 std %f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
46 std %f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
47 /* Floating point control register */
48 stfpc __LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1)
49 /* CPU timer */
50 stpt __LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1)
51 /* Saved prefix register */
52 larl %r2,dump_prefix_page
53 mvc __LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2)
54 /* Clock comparator - seven bytes */
55 larl %r2,.Lclkcmp
56 stckc 0(%r2)
57 mvc __LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2)
58 /* Program status word */
59 epsw %r2,%r3
60 st %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1)
61 st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1)
62 larl %r2,store_status
63 stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1)
64 br %r14
65.align 8
66.Lclkcmp: .quad 0x0000000000000000
67
68#
11# do_reipl_asm 69# do_reipl_asm
12# Parameter: r2 = schid of reipl device 70# Parameter: r2 = schid of reipl device
13# 71#
@@ -15,22 +73,7 @@
15ENTRY(do_reipl_asm) 73ENTRY(do_reipl_asm)
16 basr %r13,0 74 basr %r13,0
17.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) 75.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
18.Lpg1: # do store status of all registers 76.Lpg1: brasl %r14,store_status
19
20 stg %r1,.Lregsave-.Lpg0(%r13)
21 lghi %r1,0x1000
22 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
23 lg %r0,.Lregsave-.Lpg0(%r13)
24 stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1)
25 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1)
26 stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1)
27 lg %r10,.Ldump_pfx-.Lpg0(%r13)
28 mvc __LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10)
29 stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1)
30 stckc .Lclkcmp-.Lpg0(%r13)
31 mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13)
32 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
33 stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
34 77
35 lctlg %c6,%c6,.Lall-.Lpg0(%r13) 78 lctlg %c6,%c6,.Lall-.Lpg0(%r13)
36 lgr %r1,%r2 79 lgr %r1,%r2
@@ -67,10 +110,7 @@ ENTRY(do_reipl_asm)
67 st %r14,.Ldispsw+12-.Lpg0(%r13) 110 st %r14,.Ldispsw+12-.Lpg0(%r13)
68 lpswe .Ldispsw-.Lpg0(%r13) 111 lpswe .Ldispsw-.Lpg0(%r13)
69 .align 8 112 .align 8
70.Lclkcmp: .quad 0x0000000000000000
71.Lall: .quad 0x00000000ff000000 113.Lall: .quad 0x00000000ff000000
72.Ldump_pfx: .quad dump_prefix_page
73.Lregsave: .quad 0x0000000000000000
74 .align 16 114 .align 16
75/* 115/*
76 * These addresses have to be 31 bit otherwise 116 * These addresses have to be 31 bit otherwise
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 0c35dee10b00..7b371c37061d 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -346,7 +346,7 @@ setup_lowcore(void)
346 lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); 346 lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
347 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; 347 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
348 lc->restart_psw.addr = 348 lc->restart_psw.addr =
349 PSW_ADDR_AMODE | (unsigned long) restart_int_handler; 349 PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
350 if (user_mode != HOME_SPACE_MODE) 350 if (user_mode != HOME_SPACE_MODE)
351 lc->restart_psw.mask |= PSW_ASC_HOME; 351 lc->restart_psw.mask |= PSW_ASC_HOME;
352 lc->external_new_psw.mask = psw_kernel_bits; 352 lc->external_new_psw.mask = psw_kernel_bits;
@@ -529,6 +529,27 @@ static void __init setup_memory_end(void)
529 memory_end = memory_size; 529 memory_end = memory_size;
530} 530}
531 531
532void *restart_stack __attribute__((__section__(".data")));
533
534/*
535 * Setup new PSW and allocate stack for PSW restart interrupt
536 */
537static void __init setup_restart_psw(void)
538{
539 psw_t psw;
540
541 restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
542 restart_stack += ASYNC_SIZE;
543
544 /*
545 * Setup restart PSW for absolute zero lowcore. This is necesary
546 * if PSW restart is done on an offline CPU that has lowcore zero
547 */
548 psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
549 psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
550 copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
551}
552
532static void __init 553static void __init
533setup_memory(void) 554setup_memory(void)
534{ 555{
@@ -731,6 +752,7 @@ static void __init setup_hwcaps(void)
731 strcpy(elf_platform, "z10"); 752 strcpy(elf_platform, "z10");
732 break; 753 break;
733 case 0x2817: 754 case 0x2817:
755 case 0x2818:
734 strcpy(elf_platform, "z196"); 756 strcpy(elf_platform, "z196");
735 break; 757 break;
736 } 758 }
@@ -792,6 +814,7 @@ setup_arch(char **cmdline_p)
792 setup_addressing_mode(); 814 setup_addressing_mode();
793 setup_memory(); 815 setup_memory();
794 setup_resources(); 816 setup_resources();
817 setup_restart_psw();
795 setup_lowcore(); 818 setup_lowcore();
796 819
797 cpu_init(); 820 cpu_init();
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index abbb3c3c7aab..9a40e1cc5ec3 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -57,17 +57,15 @@ typedef struct
57 */ 57 */
58SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) 58SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask)
59{ 59{
60 mask &= _BLOCKABLE; 60 sigset_t blocked;
61 spin_lock_irq(&current->sighand->siglock);
62 current->saved_sigmask = current->blocked;
63 siginitset(&current->blocked, mask);
64 recalc_sigpending();
65 spin_unlock_irq(&current->sighand->siglock);
66 61
62 current->saved_sigmask = current->blocked;
63 mask &= _BLOCKABLE;
64 siginitset(&blocked, mask);
65 set_current_blocked(&blocked);
67 set_current_state(TASK_INTERRUPTIBLE); 66 set_current_state(TASK_INTERRUPTIBLE);
68 schedule(); 67 schedule();
69 set_thread_flag(TIF_RESTORE_SIGMASK); 68 set_restore_sigmask();
70
71 return -ERESTARTNOHAND; 69 return -ERESTARTNOHAND;
72} 70}
73 71
@@ -172,18 +170,11 @@ SYSCALL_DEFINE0(sigreturn)
172 goto badframe; 170 goto badframe;
173 if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE)) 171 if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
174 goto badframe; 172 goto badframe;
175
176 sigdelsetmask(&set, ~_BLOCKABLE); 173 sigdelsetmask(&set, ~_BLOCKABLE);
177 spin_lock_irq(&current->sighand->siglock); 174 set_current_blocked(&set);
178 current->blocked = set;
179 recalc_sigpending();
180 spin_unlock_irq(&current->sighand->siglock);
181
182 if (restore_sigregs(regs, &frame->sregs)) 175 if (restore_sigregs(regs, &frame->sregs))
183 goto badframe; 176 goto badframe;
184
185 return regs->gprs[2]; 177 return regs->gprs[2];
186
187badframe: 178badframe:
188 force_sig(SIGSEGV, current); 179 force_sig(SIGSEGV, current);
189 return 0; 180 return 0;
@@ -199,21 +190,14 @@ SYSCALL_DEFINE0(rt_sigreturn)
199 goto badframe; 190 goto badframe;
200 if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set))) 191 if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
201 goto badframe; 192 goto badframe;
202
203 sigdelsetmask(&set, ~_BLOCKABLE); 193 sigdelsetmask(&set, ~_BLOCKABLE);
204 spin_lock_irq(&current->sighand->siglock); 194 set_current_blocked(&set);
205 current->blocked = set;
206 recalc_sigpending();
207 spin_unlock_irq(&current->sighand->siglock);
208
209 if (restore_sigregs(regs, &frame->uc.uc_mcontext)) 195 if (restore_sigregs(regs, &frame->uc.uc_mcontext))
210 goto badframe; 196 goto badframe;
211
212 if (do_sigaltstack(&frame->uc.uc_stack, NULL, 197 if (do_sigaltstack(&frame->uc.uc_stack, NULL,
213 regs->gprs[15]) == -EFAULT) 198 regs->gprs[15]) == -EFAULT)
214 goto badframe; 199 goto badframe;
215 return regs->gprs[2]; 200 return regs->gprs[2];
216
217badframe: 201badframe:
218 force_sig(SIGSEGV, current); 202 force_sig(SIGSEGV, current);
219 return 0; 203 return 0;
@@ -385,14 +369,11 @@ give_sigsegv:
385 return -EFAULT; 369 return -EFAULT;
386} 370}
387 371
388/* 372static int handle_signal(unsigned long sig, struct k_sigaction *ka,
389 * OK, we're invoking a handler 373 siginfo_t *info, sigset_t *oldset,
390 */ 374 struct pt_regs *regs)
391
392static int
393handle_signal(unsigned long sig, struct k_sigaction *ka,
394 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
395{ 375{
376 sigset_t blocked;
396 int ret; 377 int ret;
397 378
398 /* Set up the stack frame */ 379 /* Set up the stack frame */
@@ -400,17 +381,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
400 ret = setup_rt_frame(sig, ka, info, oldset, regs); 381 ret = setup_rt_frame(sig, ka, info, oldset, regs);
401 else 382 else
402 ret = setup_frame(sig, ka, oldset, regs); 383 ret = setup_frame(sig, ka, oldset, regs);
403 384 if (ret)
404 if (ret == 0) { 385 return ret;
405 spin_lock_irq(&current->sighand->siglock); 386 sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
406 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 387 if (!(ka->sa.sa_flags & SA_NODEFER))
407 if (!(ka->sa.sa_flags & SA_NODEFER)) 388 sigaddset(&blocked, sig);
408 sigaddset(&current->blocked,sig); 389 set_current_blocked(&blocked);
409 recalc_sigpending(); 390 return 0;
410 spin_unlock_irq(&current->sighand->siglock);
411 }
412
413 return ret;
414} 391}
415 392
416/* 393/*
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index a6d85c0a7f20..6ab16ac64d29 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -452,23 +452,27 @@ out:
452 */ 452 */
453int __cpuinit start_secondary(void *cpuvoid) 453int __cpuinit start_secondary(void *cpuvoid)
454{ 454{
455 /* Setup the cpu */
456 cpu_init(); 455 cpu_init();
457 preempt_disable(); 456 preempt_disable();
458 /* Enable TOD clock interrupts on the secondary cpu. */
459 init_cpu_timer(); 457 init_cpu_timer();
460 /* Enable cpu timer interrupts on the secondary cpu. */
461 init_cpu_vtimer(); 458 init_cpu_vtimer();
462 /* Enable pfault pseudo page faults on this cpu. */
463 pfault_init(); 459 pfault_init();
464 460
465 /* call cpu notifiers */
466 notify_cpu_starting(smp_processor_id()); 461 notify_cpu_starting(smp_processor_id());
467 /* Mark this cpu as online */
468 ipi_call_lock(); 462 ipi_call_lock();
469 set_cpu_online(smp_processor_id(), true); 463 set_cpu_online(smp_processor_id(), true);
470 ipi_call_unlock(); 464 ipi_call_unlock();
471 /* Switch on interrupts */ 465 __ctl_clear_bit(0, 28); /* Disable lowcore protection */
466 S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
467 S390_lowcore.restart_psw.addr =
468 PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
469 __ctl_set_bit(0, 28); /* Enable lowcore protection */
470 /*
471 * Wait until the cpu which brought this one up marked it
472 * active before enabling interrupts.
473 */
474 while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask))
475 cpu_relax();
472 local_irq_enable(); 476 local_irq_enable();
473 /* cpu_idle will call schedule for us */ 477 /* cpu_idle will call schedule for us */
474 cpu_idle(); 478 cpu_idle();
@@ -507,7 +511,11 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
507 memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512); 511 memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
508 lowcore->async_stack = async_stack + ASYNC_SIZE; 512 lowcore->async_stack = async_stack + ASYNC_SIZE;
509 lowcore->panic_stack = panic_stack + PAGE_SIZE; 513 lowcore->panic_stack = panic_stack + PAGE_SIZE;
510 514 lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
515 lowcore->restart_psw.addr =
516 PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
517 if (user_mode != HOME_SPACE_MODE)
518 lowcore->restart_psw.mask |= PSW_ASC_HOME;
511#ifndef CONFIG_64BIT 519#ifndef CONFIG_64BIT
512 if (MACHINE_HAS_IEEE) { 520 if (MACHINE_HAS_IEEE) {
513 unsigned long save_area; 521 unsigned long save_area;
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 51e5cd9b906a..5dbbaa6e594c 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -85,3 +85,19 @@ int memcpy_real(void *dest, void *src, size_t count)
85 arch_local_irq_restore(flags); 85 arch_local_irq_restore(flags);
86 return rc; 86 return rc;
87} 87}
88
89/*
90 * Copy memory to absolute zero
91 */
92void copy_to_absolute_zero(void *dest, void *src, size_t count)
93{
94 unsigned long cr0;
95
96 BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore));
97 preempt_disable();
98 __ctl_store(cr0, 0, 0);
99 __ctl_clear_bit(0, 28); /* disable lowcore protection */
100 memcpy_real(dest + store_prefix(), src, count);
101 __ctl_load(cr0, 0, 0);
102 preempt_enable();
103}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 2adb23938a7f..4d1f2bce87b3 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -528,6 +528,7 @@ static inline void page_table_free_pgste(unsigned long *table)
528static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, 528static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm,
529 unsigned long vmaddr) 529 unsigned long vmaddr)
530{ 530{
531 return NULL;
531} 532}
532 533
533static inline void page_table_free_pgste(unsigned long *table) 534static inline void page_table_free_pgste(unsigned long *table)
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 748ff1920068..ff9177c8f643 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -11,6 +11,7 @@ config SUPERH
11 select HAVE_DMA_ATTRS 11 select HAVE_DMA_ATTRS
12 select HAVE_IRQ_WORK 12 select HAVE_IRQ_WORK
13 select HAVE_PERF_EVENTS 13 select HAVE_PERF_EVENTS
14 select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
14 select PERF_USE_VMALLOC 15 select PERF_USE_VMALLOC
15 select HAVE_KERNEL_GZIP 16 select HAVE_KERNEL_GZIP
16 select HAVE_KERNEL_BZIP2 17 select HAVE_KERNEL_BZIP2
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 84db0d6ccd0d..32114e0941ae 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -16,12 +16,13 @@
16#include <linux/thread_info.h> 16#include <linux/thread_info.h>
17#include <linux/irqflags.h> 17#include <linux/irqflags.h>
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/cpuidle.h>
19#include <asm/pgalloc.h> 20#include <asm/pgalloc.h>
20#include <asm/system.h> 21#include <asm/system.h>
21#include <linux/atomic.h> 22#include <linux/atomic.h>
22#include <asm/smp.h> 23#include <asm/smp.h>
23 24
24void (*pm_idle)(void) = NULL; 25static void (*pm_idle)(void);
25 26
26static int hlt_counter; 27static int hlt_counter;
27 28
@@ -100,7 +101,8 @@ void cpu_idle(void)
100 local_irq_disable(); 101 local_irq_disable();
101 /* Don't trace irqs off for idle */ 102 /* Don't trace irqs off for idle */
102 stop_critical_timings(); 103 stop_critical_timings();
103 pm_idle(); 104 if (cpuidle_idle_call())
105 pm_idle();
104 /* 106 /*
105 * Sanity check to ensure that pm_idle() returns 107 * Sanity check to ensure that pm_idle() returns
106 * with IRQs enabled 108 * with IRQs enabled
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 1074dddcb104..42c67beadcae 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -54,6 +54,7 @@ config SPARC64
54 select HAVE_PERF_EVENTS 54 select HAVE_PERF_EVENTS
55 select PERF_USE_VMALLOC 55 select PERF_USE_VMALLOC
56 select IRQ_PREFLOW_FASTEOI 56 select IRQ_PREFLOW_FASTEOI
57 select ARCH_HAVE_NMI_SAFE_CMPXCHG
57 58
58config ARCH_DEFCONFIG 59config ARCH_DEFCONFIG
59 string 60 string
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 3c93f08ce187..2c2e38821f60 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -16,3 +16,8 @@ header-y += traps.h
16header-y += uctx.h 16header-y += uctx.h
17header-y += utrap.h 17header-y += utrap.h
18header-y += watchdog.h 18header-y += watchdog.h
19
20generic-y += div64.h
21generic-y += local64.h
22generic-y += irq_regs.h
23generic-y += local.h
diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h
index 325e295d60de..29011cc0e4be 100644
--- a/arch/sparc/include/asm/bitops_64.h
+++ b/arch/sparc/include/asm/bitops_64.h
@@ -26,61 +26,28 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr);
26#define smp_mb__before_clear_bit() barrier() 26#define smp_mb__before_clear_bit() barrier()
27#define smp_mb__after_clear_bit() barrier() 27#define smp_mb__after_clear_bit() barrier()
28 28
29#include <asm-generic/bitops/ffz.h>
30#include <asm-generic/bitops/__ffs.h>
31#include <asm-generic/bitops/fls.h> 29#include <asm-generic/bitops/fls.h>
32#include <asm-generic/bitops/__fls.h> 30#include <asm-generic/bitops/__fls.h>
33#include <asm-generic/bitops/fls64.h> 31#include <asm-generic/bitops/fls64.h>
34 32
35#ifdef __KERNEL__ 33#ifdef __KERNEL__
36 34
35extern int ffs(int x);
36extern unsigned long __ffs(unsigned long);
37
38#include <asm-generic/bitops/ffz.h>
37#include <asm-generic/bitops/sched.h> 39#include <asm-generic/bitops/sched.h>
38#include <asm-generic/bitops/ffs.h>
39 40
40/* 41/*
41 * hweightN: returns the hamming weight (i.e. the number 42 * hweightN: returns the hamming weight (i.e. the number
42 * of bits set) of a N-bit word 43 * of bits set) of a N-bit word
43 */ 44 */
44 45
45#ifdef ULTRA_HAS_POPULATION_COUNT 46extern unsigned long __arch_hweight64(__u64 w);
46 47extern unsigned int __arch_hweight32(unsigned int w);
47static inline unsigned int __arch_hweight64(unsigned long w) 48extern unsigned int __arch_hweight16(unsigned int w);
48{ 49extern unsigned int __arch_hweight8(unsigned int w);
49 unsigned int res;
50
51 __asm__ ("popc %1,%0" : "=r" (res) : "r" (w));
52 return res;
53}
54
55static inline unsigned int __arch_hweight32(unsigned int w)
56{
57 unsigned int res;
58
59 __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff));
60 return res;
61}
62 50
63static inline unsigned int __arch_hweight16(unsigned int w)
64{
65 unsigned int res;
66
67 __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff));
68 return res;
69}
70
71static inline unsigned int __arch_hweight8(unsigned int w)
72{
73 unsigned int res;
74
75 __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff));
76 return res;
77}
78
79#else
80
81#include <asm-generic/bitops/arch_hweight.h>
82
83#endif
84#include <asm-generic/bitops/const_hweight.h> 51#include <asm-generic/bitops/const_hweight.h>
85#include <asm-generic/bitops/lock.h> 52#include <asm-generic/bitops/lock.h>
86#endif /* __KERNEL__ */ 53#endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/div64.h b/arch/sparc/include/asm/div64.h
deleted file mode 100644
index 6cd978cefb28..000000000000
--- a/arch/sparc/include/asm/div64.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/div64.h>
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index 64f7a00b3747..7df8b7f544d4 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -59,15 +59,33 @@
59#define R_SPARC_6 45 59#define R_SPARC_6 45
60 60
61/* Bits present in AT_HWCAP, primarily for Sparc32. */ 61/* Bits present in AT_HWCAP, primarily for Sparc32. */
62 62#define HWCAP_SPARC_FLUSH 0x00000001
63#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ 63#define HWCAP_SPARC_STBAR 0x00000002
64#define HWCAP_SPARC_STBAR 2 64#define HWCAP_SPARC_SWAP 0x00000004
65#define HWCAP_SPARC_SWAP 4 65#define HWCAP_SPARC_MULDIV 0x00000008
66#define HWCAP_SPARC_MULDIV 8 66#define HWCAP_SPARC_V9 0x00000010
67#define HWCAP_SPARC_V9 16 67#define HWCAP_SPARC_ULTRA3 0x00000020
68#define HWCAP_SPARC_ULTRA3 32 68#define HWCAP_SPARC_BLKINIT 0x00000040
69#define HWCAP_SPARC_BLKINIT 64 69#define HWCAP_SPARC_N2 0x00000080
70#define HWCAP_SPARC_N2 128 70
71/* Solaris compatible AT_HWCAP bits. */
72#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */
73#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */
74#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */
75#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */
76#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */
77#define AV_SPARC_VIS 0x00002000 /* VIS insns available */
78#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */
79#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */
80#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */
81#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */
82#define AV_SPARC_HPC 0x00040000 /* HPC insns available */
83#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */
84#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */
85#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */
86#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */
87#define AV_SPARC_ASI_CACHE_SPARING \
88 0x00800000 /* cache sparing ASIs available */
71 89
72#define CORE_DUMP_USE_REGSET 90#define CORE_DUMP_USE_REGSET
73 91
@@ -162,33 +180,8 @@ typedef struct {
162#define ELF_ET_DYN_BASE 0x0000010000000000UL 180#define ELF_ET_DYN_BASE 0x0000010000000000UL
163#define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL 181#define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
164 182
165 183extern unsigned long sparc64_elf_hwcap;
166/* This yields a mask that user programs can use to figure out what 184#define ELF_HWCAP sparc64_elf_hwcap
167 instruction set this cpu supports. */
168
169/* On Ultra, we support all of the v8 capabilities. */
170static inline unsigned int sparc64_elf_hwcap(void)
171{
172 unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
173 HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV |
174 HWCAP_SPARC_V9);
175
176 if (tlb_type == cheetah || tlb_type == cheetah_plus)
177 cap |= HWCAP_SPARC_ULTRA3;
178 else if (tlb_type == hypervisor) {
179 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 ||
180 sun4v_chip_type == SUN4V_CHIP_NIAGARA2 ||
181 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
182 cap |= HWCAP_SPARC_BLKINIT;
183 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 ||
184 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
185 cap |= HWCAP_SPARC_N2;
186 }
187
188 return cap;
189}
190
191#define ELF_HWCAP sparc64_elf_hwcap()
192 185
193/* This yields a string that ld.so will use to load implementation 186/* This yields a string that ld.so will use to load implementation
194 specific libraries for optimization. This is more specific in 187 specific libraries for optimization. This is more specific in
diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h
index 7a5f80df15d0..015a761eaa32 100644
--- a/arch/sparc/include/asm/hypervisor.h
+++ b/arch/sparc/include/asm/hypervisor.h
@@ -2927,6 +2927,13 @@ extern unsigned long sun4v_ncs_request(unsigned long request,
2927#define HV_FAST_FIRE_GET_PERFREG 0x120 2927#define HV_FAST_FIRE_GET_PERFREG 0x120
2928#define HV_FAST_FIRE_SET_PERFREG 0x121 2928#define HV_FAST_FIRE_SET_PERFREG 0x121
2929 2929
2930#define HV_FAST_REBOOT_DATA_SET 0x172
2931
2932#ifndef __ASSEMBLY__
2933extern unsigned long sun4v_reboot_data_set(unsigned long ra,
2934 unsigned long len);
2935#endif
2936
2930/* Function numbers for HV_CORE_TRAP. */ 2937/* Function numbers for HV_CORE_TRAP. */
2931#define HV_CORE_SET_VER 0x00 2938#define HV_CORE_SET_VER 0x00
2932#define HV_CORE_PUTCHAR 0x01 2939#define HV_CORE_PUTCHAR 0x01
@@ -2940,11 +2947,17 @@ extern unsigned long sun4v_ncs_request(unsigned long request,
2940#define HV_GRP_CORE 0x0001 2947#define HV_GRP_CORE 0x0001
2941#define HV_GRP_INTR 0x0002 2948#define HV_GRP_INTR 0x0002
2942#define HV_GRP_SOFT_STATE 0x0003 2949#define HV_GRP_SOFT_STATE 0x0003
2950#define HV_GRP_TM 0x0080
2943#define HV_GRP_PCI 0x0100 2951#define HV_GRP_PCI 0x0100
2944#define HV_GRP_LDOM 0x0101 2952#define HV_GRP_LDOM 0x0101
2945#define HV_GRP_SVC_CHAN 0x0102 2953#define HV_GRP_SVC_CHAN 0x0102
2946#define HV_GRP_NCS 0x0103 2954#define HV_GRP_NCS 0x0103
2947#define HV_GRP_RNG 0x0104 2955#define HV_GRP_RNG 0x0104
2956#define HV_GRP_PBOOT 0x0105
2957#define HV_GRP_TPM 0x0107
2958#define HV_GRP_SDIO 0x0108
2959#define HV_GRP_SDIO_ERR 0x0109
2960#define HV_GRP_REBOOT_DATA 0x0110
2948#define HV_GRP_NIAG_PERF 0x0200 2961#define HV_GRP_NIAG_PERF 0x0200
2949#define HV_GRP_FIRE_PERF 0x0201 2962#define HV_GRP_FIRE_PERF 0x0201
2950#define HV_GRP_N2_CPU 0x0202 2963#define HV_GRP_N2_CPU 0x0202
diff --git a/arch/sparc/include/asm/irq_regs.h b/arch/sparc/include/asm/irq_regs.h
deleted file mode 100644
index 3dd9c0b70270..000000000000
--- a/arch/sparc/include/asm/irq_regs.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/irq_regs.h>
diff --git a/arch/sparc/include/asm/local.h b/arch/sparc/include/asm/local.h
deleted file mode 100644
index bc80815a435c..000000000000
--- a/arch/sparc/include/asm/local.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _SPARC_LOCAL_H
2#define _SPARC_LOCAL_H
3
4#include <asm-generic/local.h>
5
6#endif
diff --git a/arch/sparc/include/asm/local64.h b/arch/sparc/include/asm/local64.h
deleted file mode 100644
index 36c93b5cc239..000000000000
--- a/arch/sparc/include/asm/local64.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/local64.h>
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h
index 83c571d8c8a7..1a8afd1ad04f 100644
--- a/arch/sparc/include/asm/tsb.h
+++ b/arch/sparc/include/asm/tsb.h
@@ -133,29 +133,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
133 sub TSB, 0x8, TSB; \ 133 sub TSB, 0x8, TSB; \
134 TSB_STORE(TSB, TAG); 134 TSB_STORE(TSB, TAG);
135 135
136#define KTSB_LOAD_QUAD(TSB, REG) \
137 ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG;
138
139#define KTSB_STORE(ADDR, VAL) \
140 stxa VAL, [ADDR] ASI_N;
141
142#define KTSB_LOCK_TAG(TSB, REG1, REG2) \
14399: lduwa [TSB] ASI_N, REG1; \
144 sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\
145 andcc REG1, REG2, %g0; \
146 bne,pn %icc, 99b; \
147 nop; \
148 casa [TSB] ASI_N, REG1, REG2;\
149 cmp REG1, REG2; \
150 bne,pn %icc, 99b; \
151 nop; \
152
153#define KTSB_WRITE(TSB, TTE, TAG) \
154 add TSB, 0x8, TSB; \
155 stxa TTE, [TSB] ASI_N; \
156 sub TSB, 0x8, TSB; \
157 stxa TAG, [TSB] ASI_N;
158
159 /* Do a kernel page table walk. Leaves physical PTE pointer in 136 /* Do a kernel page table walk. Leaves physical PTE pointer in
160 * REG1. Jumps to FAIL_LABEL on early page table walk termination. 137 * REG1. Jumps to FAIL_LABEL on early page table walk termination.
161 * VADDR will not be clobbered, but REG2 will. 138 * VADDR will not be clobbered, but REG2 will.
@@ -239,6 +216,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
239 (KERNEL_TSB_SIZE_BYTES / 16) 216 (KERNEL_TSB_SIZE_BYTES / 16)
240#define KERNEL_TSB4M_NENTRIES 4096 217#define KERNEL_TSB4M_NENTRIES 4096
241 218
219#define KTSB_PHYS_SHIFT 15
220
242 /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL 221 /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL
243 * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries 222 * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries
244 * and the found TTE will be left in REG1. REG3 and REG4 must 223 * and the found TTE will be left in REG1. REG3 and REG4 must
@@ -247,13 +226,22 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
247 * VADDR and TAG will be preserved and not clobbered by this macro. 226 * VADDR and TAG will be preserved and not clobbered by this macro.
248 */ 227 */
249#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ 228#define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
250 sethi %hi(swapper_tsb), REG1; \ 229661: sethi %hi(swapper_tsb), REG1; \
251 or REG1, %lo(swapper_tsb), REG1; \ 230 or REG1, %lo(swapper_tsb), REG1; \
231 .section .swapper_tsb_phys_patch, "ax"; \
232 .word 661b; \
233 .previous; \
234661: nop; \
235 .section .tsb_ldquad_phys_patch, "ax"; \
236 .word 661b; \
237 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
238 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
239 .previous; \
252 srlx VADDR, PAGE_SHIFT, REG2; \ 240 srlx VADDR, PAGE_SHIFT, REG2; \
253 and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ 241 and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \
254 sllx REG2, 4, REG2; \ 242 sllx REG2, 4, REG2; \
255 add REG1, REG2, REG2; \ 243 add REG1, REG2, REG2; \
256 KTSB_LOAD_QUAD(REG2, REG3); \ 244 TSB_LOAD_QUAD(REG2, REG3); \
257 cmp REG3, TAG; \ 245 cmp REG3, TAG; \
258 be,a,pt %xcc, OK_LABEL; \ 246 be,a,pt %xcc, OK_LABEL; \
259 mov REG4, REG1; 247 mov REG4, REG1;
@@ -263,12 +251,21 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end;
263 * we can make use of that for the index computation. 251 * we can make use of that for the index computation.
264 */ 252 */
265#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ 253#define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
266 sethi %hi(swapper_4m_tsb), REG1; \ 254661: sethi %hi(swapper_4m_tsb), REG1; \
267 or REG1, %lo(swapper_4m_tsb), REG1; \ 255 or REG1, %lo(swapper_4m_tsb), REG1; \
256 .section .swapper_4m_tsb_phys_patch, "ax"; \
257 .word 661b; \
258 .previous; \
259661: nop; \
260 .section .tsb_ldquad_phys_patch, "ax"; \
261 .word 661b; \
262 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
263 sllx REG1, KTSB_PHYS_SHIFT, REG1; \
264 .previous; \
268 and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ 265 and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
269 sllx REG2, 4, REG2; \ 266 sllx REG2, 4, REG2; \
270 add REG1, REG2, REG2; \ 267 add REG1, REG2, REG2; \
271 KTSB_LOAD_QUAD(REG2, REG3); \ 268 TSB_LOAD_QUAD(REG2, REG3); \
272 cmp REG3, TAG; \ 269 cmp REG3, TAG; \
273 be,a,pt %xcc, OK_LABEL; \ 270 be,a,pt %xcc, OK_LABEL; \
274 mov REG4, REG1; 271 mov REG4, REG1;
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 17cf290dc2bc..9810fd881058 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -396,6 +396,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
396 , cpu_data(0).clock_tick 396 , cpu_data(0).clock_tick
397#endif 397#endif
398 ); 398 );
399 cpucap_info(m);
399#ifdef CONFIG_SMP 400#ifdef CONFIG_SMP
400 smp_bogo(m); 401 smp_bogo(m);
401#endif 402#endif
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index dd1342c0a3be..490e5418740d 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -15,12 +15,15 @@
15#include <linux/reboot.h> 15#include <linux/reboot.h>
16#include <linux/cpu.h> 16#include <linux/cpu.h>
17 17
18#include <asm/hypervisor.h>
18#include <asm/ldc.h> 19#include <asm/ldc.h>
19#include <asm/vio.h> 20#include <asm/vio.h>
20#include <asm/mdesc.h> 21#include <asm/mdesc.h>
21#include <asm/head.h> 22#include <asm/head.h>
22#include <asm/irq.h> 23#include <asm/irq.h>
23 24
25#include "kernel.h"
26
24#define DRV_MODULE_NAME "ds" 27#define DRV_MODULE_NAME "ds"
25#define PFX DRV_MODULE_NAME ": " 28#define PFX DRV_MODULE_NAME ": "
26#define DRV_MODULE_VERSION "1.0" 29#define DRV_MODULE_VERSION "1.0"
@@ -828,18 +831,32 @@ void ldom_set_var(const char *var, const char *value)
828 } 831 }
829} 832}
830 833
834static char full_boot_str[256] __attribute__((aligned(32)));
835static int reboot_data_supported;
836
831void ldom_reboot(const char *boot_command) 837void ldom_reboot(const char *boot_command)
832{ 838{
833 /* Don't bother with any of this if the boot_command 839 /* Don't bother with any of this if the boot_command
834 * is empty. 840 * is empty.
835 */ 841 */
836 if (boot_command && strlen(boot_command)) { 842 if (boot_command && strlen(boot_command)) {
837 char full_boot_str[256]; 843 unsigned long len;
838 844
839 strcpy(full_boot_str, "boot "); 845 strcpy(full_boot_str, "boot ");
840 strcpy(full_boot_str + strlen("boot "), boot_command); 846 strcpy(full_boot_str + strlen("boot "), boot_command);
847 len = strlen(full_boot_str);
841 848
842 ldom_set_var("reboot-command", full_boot_str); 849 if (reboot_data_supported) {
850 unsigned long ra = kimage_addr_to_ra(full_boot_str);
851 unsigned long hv_ret;
852
853 hv_ret = sun4v_reboot_data_set(ra, len);
854 if (hv_ret != HV_EOK)
855 pr_err("SUN4V: Unable to set reboot data "
856 "hv_ret=%lu\n", hv_ret);
857 } else {
858 ldom_set_var("reboot-command", full_boot_str);
859 }
843 } 860 }
844 sun4v_mach_sir(); 861 sun4v_mach_sir();
845} 862}
@@ -1237,6 +1254,15 @@ static struct vio_driver ds_driver = {
1237 1254
1238static int __init ds_init(void) 1255static int __init ds_init(void)
1239{ 1256{
1257 unsigned long hv_ret, major, minor;
1258
1259 hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor);
1260 if (hv_ret == HV_EOK) {
1261 pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n",
1262 major, minor);
1263 reboot_data_supported = 1;
1264 }
1265
1240 kthread_run(ds_thread, NULL, "kldomd"); 1266 kthread_run(ds_thread, NULL, "kldomd");
1241 1267
1242 return vio_register_driver(&ds_driver); 1268 return vio_register_driver(&ds_driver);
diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h
index d1f1361c4167..e27f8ea8656e 100644
--- a/arch/sparc/kernel/entry.h
+++ b/arch/sparc/kernel/entry.h
@@ -42,6 +42,20 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
42extern void fpload(unsigned long *fpregs, unsigned long *fsr); 42extern void fpload(unsigned long *fpregs, unsigned long *fsr);
43 43
44#else /* CONFIG_SPARC32 */ 44#else /* CONFIG_SPARC32 */
45struct popc_3insn_patch_entry {
46 unsigned int addr;
47 unsigned int insns[3];
48};
49extern struct popc_3insn_patch_entry __popc_3insn_patch,
50 __popc_3insn_patch_end;
51
52struct popc_6insn_patch_entry {
53 unsigned int addr;
54 unsigned int insns[6];
55};
56extern struct popc_6insn_patch_entry __popc_6insn_patch,
57 __popc_6insn_patch_end;
58
45extern void __init per_cpu_patch(void); 59extern void __init per_cpu_patch(void);
46extern void __init sun4v_patch(void); 60extern void __init sun4v_patch(void);
47extern void __init boot_cpu_id_too_large(int cpu); 61extern void __init boot_cpu_id_too_large(int cpu);
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index c752603a7c0d..0eac1b2fc53d 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -559,7 +559,7 @@ niagara2_patch:
559 nop 559 nop
560 call niagara_patch_bzero 560 call niagara_patch_bzero
561 nop 561 nop
562 call niagara2_patch_pageops 562 call niagara_patch_pageops
563 nop 563 nop
564 564
565 ba,a,pt %xcc, 80f 565 ba,a,pt %xcc, 80f
diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c
index d306e648c33c..c2d055d8ba9e 100644
--- a/arch/sparc/kernel/hvapi.c
+++ b/arch/sparc/kernel/hvapi.c
@@ -28,11 +28,17 @@ static struct api_info api_table[] = {
28 { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, 28 { .group = HV_GRP_CORE, .flags = FLAG_PRE_API },
29 { .group = HV_GRP_INTR, }, 29 { .group = HV_GRP_INTR, },
30 { .group = HV_GRP_SOFT_STATE, }, 30 { .group = HV_GRP_SOFT_STATE, },
31 { .group = HV_GRP_TM, },
31 { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, 32 { .group = HV_GRP_PCI, .flags = FLAG_PRE_API },
32 { .group = HV_GRP_LDOM, }, 33 { .group = HV_GRP_LDOM, },
33 { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, 34 { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API },
34 { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, 35 { .group = HV_GRP_NCS, .flags = FLAG_PRE_API },
35 { .group = HV_GRP_RNG, }, 36 { .group = HV_GRP_RNG, },
37 { .group = HV_GRP_PBOOT, },
38 { .group = HV_GRP_TPM, },
39 { .group = HV_GRP_SDIO, },
40 { .group = HV_GRP_SDIO_ERR, },
41 { .group = HV_GRP_REBOOT_DATA, },
36 { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, 42 { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API },
37 { .group = HV_GRP_FIRE_PERF, }, 43 { .group = HV_GRP_FIRE_PERF, },
38 { .group = HV_GRP_N2_CPU, }, 44 { .group = HV_GRP_N2_CPU, },
diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S
index 8a5f35ffb15e..58d60de4d65b 100644
--- a/arch/sparc/kernel/hvcalls.S
+++ b/arch/sparc/kernel/hvcalls.S
@@ -798,3 +798,10 @@ ENTRY(sun4v_niagara2_setperf)
798 retl 798 retl
799 nop 799 nop
800ENDPROC(sun4v_niagara2_setperf) 800ENDPROC(sun4v_niagara2_setperf)
801
802ENTRY(sun4v_reboot_data_set)
803 mov HV_FAST_REBOOT_DATA_SET, %o5
804 ta HV_FAST_TRAP
805 retl
806 nop
807ENDPROC(sun4v_reboot_data_set)
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 6f6544cfa0ef..fd6c36b1df74 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -4,12 +4,27 @@
4#include <linux/interrupt.h> 4#include <linux/interrupt.h>
5 5
6#include <asm/traps.h> 6#include <asm/traps.h>
7#include <asm/head.h>
8#include <asm/io.h>
7 9
8/* cpu.c */ 10/* cpu.c */
9extern const char *sparc_pmu_type; 11extern const char *sparc_pmu_type;
10extern unsigned int fsr_storage; 12extern unsigned int fsr_storage;
11extern int ncpus_probed; 13extern int ncpus_probed;
12 14
15#ifdef CONFIG_SPARC64
16/* setup_64.c */
17struct seq_file;
18extern void cpucap_info(struct seq_file *);
19
20static inline unsigned long kimage_addr_to_ra(const char *p)
21{
22 unsigned long val = (unsigned long) p;
23
24 return kern_base + (val - KERNBASE);
25}
26#endif
27
13#ifdef CONFIG_SPARC32 28#ifdef CONFIG_SPARC32
14/* cpu.c */ 29/* cpu.c */
15extern void cpu_probe(void); 30extern void cpu_probe(void);
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S
index 1d361477d7d6..79f310364849 100644
--- a/arch/sparc/kernel/ktlb.S
+++ b/arch/sparc/kernel/ktlb.S
@@ -47,16 +47,16 @@ kvmap_itlb_tsb_miss:
47kvmap_itlb_vmalloc_addr: 47kvmap_itlb_vmalloc_addr:
48 KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) 48 KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath)
49 49
50 KTSB_LOCK_TAG(%g1, %g2, %g7) 50 TSB_LOCK_TAG(%g1, %g2, %g7)
51 51
52 /* Load and check PTE. */ 52 /* Load and check PTE. */
53 ldxa [%g5] ASI_PHYS_USE_EC, %g5 53 ldxa [%g5] ASI_PHYS_USE_EC, %g5
54 mov 1, %g7 54 mov 1, %g7
55 sllx %g7, TSB_TAG_INVALID_BIT, %g7 55 sllx %g7, TSB_TAG_INVALID_BIT, %g7
56 brgez,a,pn %g5, kvmap_itlb_longpath 56 brgez,a,pn %g5, kvmap_itlb_longpath
57 KTSB_STORE(%g1, %g7) 57 TSB_STORE(%g1, %g7)
58 58
59 KTSB_WRITE(%g1, %g5, %g6) 59 TSB_WRITE(%g1, %g5, %g6)
60 60
61 /* fallthrough to TLB load */ 61 /* fallthrough to TLB load */
62 62
@@ -102,9 +102,9 @@ kvmap_itlb_longpath:
102kvmap_itlb_obp: 102kvmap_itlb_obp:
103 OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) 103 OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath)
104 104
105 KTSB_LOCK_TAG(%g1, %g2, %g7) 105 TSB_LOCK_TAG(%g1, %g2, %g7)
106 106
107 KTSB_WRITE(%g1, %g5, %g6) 107 TSB_WRITE(%g1, %g5, %g6)
108 108
109 ba,pt %xcc, kvmap_itlb_load 109 ba,pt %xcc, kvmap_itlb_load
110 nop 110 nop
@@ -112,17 +112,17 @@ kvmap_itlb_obp:
112kvmap_dtlb_obp: 112kvmap_dtlb_obp:
113 OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) 113 OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath)
114 114
115 KTSB_LOCK_TAG(%g1, %g2, %g7) 115 TSB_LOCK_TAG(%g1, %g2, %g7)
116 116
117 KTSB_WRITE(%g1, %g5, %g6) 117 TSB_WRITE(%g1, %g5, %g6)
118 118
119 ba,pt %xcc, kvmap_dtlb_load 119 ba,pt %xcc, kvmap_dtlb_load
120 nop 120 nop
121 121
122 .align 32 122 .align 32
123kvmap_dtlb_tsb4m_load: 123kvmap_dtlb_tsb4m_load:
124 KTSB_LOCK_TAG(%g1, %g2, %g7) 124 TSB_LOCK_TAG(%g1, %g2, %g7)
125 KTSB_WRITE(%g1, %g5, %g6) 125 TSB_WRITE(%g1, %g5, %g6)
126 ba,pt %xcc, kvmap_dtlb_load 126 ba,pt %xcc, kvmap_dtlb_load
127 nop 127 nop
128 128
@@ -222,16 +222,16 @@ kvmap_linear_patch:
222kvmap_dtlb_vmalloc_addr: 222kvmap_dtlb_vmalloc_addr:
223 KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) 223 KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath)
224 224
225 KTSB_LOCK_TAG(%g1, %g2, %g7) 225 TSB_LOCK_TAG(%g1, %g2, %g7)
226 226
227 /* Load and check PTE. */ 227 /* Load and check PTE. */
228 ldxa [%g5] ASI_PHYS_USE_EC, %g5 228 ldxa [%g5] ASI_PHYS_USE_EC, %g5
229 mov 1, %g7 229 mov 1, %g7
230 sllx %g7, TSB_TAG_INVALID_BIT, %g7 230 sllx %g7, TSB_TAG_INVALID_BIT, %g7
231 brgez,a,pn %g5, kvmap_dtlb_longpath 231 brgez,a,pn %g5, kvmap_dtlb_longpath
232 KTSB_STORE(%g1, %g7) 232 TSB_STORE(%g1, %g7)
233 233
234 KTSB_WRITE(%g1, %g5, %g6) 234 TSB_WRITE(%g1, %g5, %g6)
235 235
236 /* fallthrough to TLB load */ 236 /* fallthrough to TLB load */
237 237
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 42f28c7420e1..acaebb63c4fd 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -508,6 +508,8 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node)
508} 508}
509EXPORT_SYMBOL(mdesc_node_name); 509EXPORT_SYMBOL(mdesc_node_name);
510 510
511static u64 max_cpus = 64;
512
511static void __init report_platform_properties(void) 513static void __init report_platform_properties(void)
512{ 514{
513 struct mdesc_handle *hp = mdesc_grab(); 515 struct mdesc_handle *hp = mdesc_grab();
@@ -543,8 +545,10 @@ static void __init report_platform_properties(void)
543 if (v) 545 if (v)
544 printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); 546 printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v);
545 v = mdesc_get_property(hp, pn, "max-cpus", NULL); 547 v = mdesc_get_property(hp, pn, "max-cpus", NULL);
546 if (v) 548 if (v) {
547 printk("PLATFORM: max-cpus [%llu]\n", *v); 549 max_cpus = *v;
550 printk("PLATFORM: max-cpus [%llu]\n", max_cpus);
551 }
548 552
549#ifdef CONFIG_SMP 553#ifdef CONFIG_SMP
550 { 554 {
@@ -715,7 +719,7 @@ static void __cpuinit set_proc_ids(struct mdesc_handle *hp)
715} 719}
716 720
717static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, 721static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask,
718 unsigned char def) 722 unsigned long def, unsigned long max)
719{ 723{
720 u64 val; 724 u64 val;
721 725
@@ -726,6 +730,9 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask,
726 if (!val || val >= 64) 730 if (!val || val >= 64)
727 goto use_default; 731 goto use_default;
728 732
733 if (val > max)
734 val = max;
735
729 *mask = ((1U << val) * 64U) - 1U; 736 *mask = ((1U << val) * 64U) - 1U;
730 return; 737 return;
731 738
@@ -736,19 +743,28 @@ use_default:
736static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, 743static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp,
737 struct trap_per_cpu *tb) 744 struct trap_per_cpu *tb)
738{ 745{
746 static int printed;
739 const u64 *val; 747 const u64 *val;
740 748
741 val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); 749 val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL);
742 get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); 750 get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2));
743 751
744 val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); 752 val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL);
745 get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); 753 get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8);
746 754
747 val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); 755 val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL);
748 get_one_mondo_bits(val, &tb->resum_qmask, 6); 756 get_one_mondo_bits(val, &tb->resum_qmask, 6, 7);
749 757
750 val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); 758 val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL);
751 get_one_mondo_bits(val, &tb->nonresum_qmask, 2); 759 get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2);
760 if (!printed++) {
761 pr_info("SUN4V: Mondo queue sizes "
762 "[cpu(%u) dev(%u) r(%u) nr(%u)]\n",
763 tb->cpu_mondo_qmask + 1,
764 tb->dev_mondo_qmask + 1,
765 tb->resum_qmask + 1,
766 tb->nonresum_qmask + 1);
767 }
752} 768}
753 769
754static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) 770static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index c4dd0999da86..3e9daea1653d 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -29,6 +29,7 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/cpu.h> 30#include <linux/cpu.h>
31#include <linux/initrd.h> 31#include <linux/initrd.h>
32#include <linux/module.h>
32 33
33#include <asm/system.h> 34#include <asm/system.h>
34#include <asm/io.h> 35#include <asm/io.h>
@@ -46,6 +47,8 @@
46#include <asm/mmu.h> 47#include <asm/mmu.h>
47#include <asm/ns87303.h> 48#include <asm/ns87303.h>
48#include <asm/btext.h> 49#include <asm/btext.h>
50#include <asm/elf.h>
51#include <asm/mdesc.h>
49 52
50#ifdef CONFIG_IP_PNP 53#ifdef CONFIG_IP_PNP
51#include <net/ipconfig.h> 54#include <net/ipconfig.h>
@@ -269,6 +272,40 @@ void __init sun4v_patch(void)
269 sun4v_hvapi_init(); 272 sun4v_hvapi_init();
270} 273}
271 274
275static void __init popc_patch(void)
276{
277 struct popc_3insn_patch_entry *p3;
278 struct popc_6insn_patch_entry *p6;
279
280 p3 = &__popc_3insn_patch;
281 while (p3 < &__popc_3insn_patch_end) {
282 unsigned long i, addr = p3->addr;
283
284 for (i = 0; i < 3; i++) {
285 *(unsigned int *) (addr + (i * 4)) = p3->insns[i];
286 wmb();
287 __asm__ __volatile__("flush %0"
288 : : "r" (addr + (i * 4)));
289 }
290
291 p3++;
292 }
293
294 p6 = &__popc_6insn_patch;
295 while (p6 < &__popc_6insn_patch_end) {
296 unsigned long i, addr = p6->addr;
297
298 for (i = 0; i < 6; i++) {
299 *(unsigned int *) (addr + (i * 4)) = p6->insns[i];
300 wmb();
301 __asm__ __volatile__("flush %0"
302 : : "r" (addr + (i * 4)));
303 }
304
305 p6++;
306 }
307}
308
272#ifdef CONFIG_SMP 309#ifdef CONFIG_SMP
273void __init boot_cpu_id_too_large(int cpu) 310void __init boot_cpu_id_too_large(int cpu)
274{ 311{
@@ -278,6 +315,154 @@ void __init boot_cpu_id_too_large(int cpu)
278} 315}
279#endif 316#endif
280 317
318/* On Ultra, we support all of the v8 capabilities. */
319unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
320 HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV |
321 HWCAP_SPARC_V9);
322EXPORT_SYMBOL(sparc64_elf_hwcap);
323
324static const char *hwcaps[] = {
325 "flush", "stbar", "swap", "muldiv", "v9",
326 "ultra3", "blkinit", "n2",
327
328 /* These strings are as they appear in the machine description
329 * 'hwcap-list' property for cpu nodes.
330 */
331 "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2",
332 "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau",
333 "ima", "cspare",
334};
335
336void cpucap_info(struct seq_file *m)
337{
338 unsigned long caps = sparc64_elf_hwcap;
339 int i, printed = 0;
340
341 seq_puts(m, "cpucaps\t\t: ");
342 for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
343 unsigned long bit = 1UL << i;
344 if (caps & bit) {
345 seq_printf(m, "%s%s",
346 printed ? "," : "", hwcaps[i]);
347 printed++;
348 }
349 }
350 seq_putc(m, '\n');
351}
352
353static void __init report_hwcaps(unsigned long caps)
354{
355 int i, printed = 0;
356
357 printk(KERN_INFO "CPU CAPS: [");
358 for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
359 unsigned long bit = 1UL << i;
360 if (caps & bit) {
361 printk(KERN_CONT "%s%s",
362 printed ? "," : "", hwcaps[i]);
363 if (++printed == 8) {
364 printk(KERN_CONT "]\n");
365 printk(KERN_INFO "CPU CAPS: [");
366 printed = 0;
367 }
368 }
369 }
370 printk(KERN_CONT "]\n");
371}
372
373static unsigned long __init mdesc_cpu_hwcap_list(void)
374{
375 struct mdesc_handle *hp;
376 unsigned long caps = 0;
377 const char *prop;
378 int len;
379 u64 pn;
380
381 hp = mdesc_grab();
382 if (!hp)
383 return 0;
384
385 pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu");
386 if (pn == MDESC_NODE_NULL)
387 goto out;
388
389 prop = mdesc_get_property(hp, pn, "hwcap-list", &len);
390 if (!prop)
391 goto out;
392
393 while (len) {
394 int i, plen;
395
396 for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
397 unsigned long bit = 1UL << i;
398
399 if (!strcmp(prop, hwcaps[i])) {
400 caps |= bit;
401 break;
402 }
403 }
404
405 plen = strlen(prop) + 1;
406 prop += plen;
407 len -= plen;
408 }
409
410out:
411 mdesc_release(hp);
412 return caps;
413}
414
415/* This yields a mask that user programs can use to figure out what
416 * instruction set this cpu supports.
417 */
418static void __init init_sparc64_elf_hwcap(void)
419{
420 unsigned long cap = sparc64_elf_hwcap;
421 unsigned long mdesc_caps;
422
423 if (tlb_type == cheetah || tlb_type == cheetah_plus)
424 cap |= HWCAP_SPARC_ULTRA3;
425 else if (tlb_type == hypervisor) {
426 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 ||
427 sun4v_chip_type == SUN4V_CHIP_NIAGARA2 ||
428 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
429 cap |= HWCAP_SPARC_BLKINIT;
430 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 ||
431 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
432 cap |= HWCAP_SPARC_N2;
433 }
434
435 cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS);
436
437 mdesc_caps = mdesc_cpu_hwcap_list();
438 if (!mdesc_caps) {
439 if (tlb_type == spitfire)
440 cap |= AV_SPARC_VIS;
441 if (tlb_type == cheetah || tlb_type == cheetah_plus)
442 cap |= AV_SPARC_VIS | AV_SPARC_VIS2;
443 if (tlb_type == cheetah_plus)
444 cap |= AV_SPARC_POPC;
445 if (tlb_type == hypervisor) {
446 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1)
447 cap |= AV_SPARC_ASI_BLK_INIT;
448 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 ||
449 sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
450 cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 |
451 AV_SPARC_ASI_BLK_INIT |
452 AV_SPARC_POPC);
453 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3)
454 cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC |
455 AV_SPARC_FMAF);
456 }
457 }
458 sparc64_elf_hwcap = cap | mdesc_caps;
459
460 report_hwcaps(sparc64_elf_hwcap);
461
462 if (sparc64_elf_hwcap & AV_SPARC_POPC)
463 popc_patch();
464}
465
281void __init setup_arch(char **cmdline_p) 466void __init setup_arch(char **cmdline_p)
282{ 467{
283 /* Initialize PROM console and command line. */ 468 /* Initialize PROM console and command line. */
@@ -337,6 +522,7 @@ void __init setup_arch(char **cmdline_p)
337 init_cur_cpu_trap(current_thread_info()); 522 init_cur_cpu_trap(current_thread_info());
338 523
339 paging_init(); 524 paging_init();
525 init_sparc64_elf_hwcap();
340} 526}
341 527
342extern int stop_a_enabled; 528extern int stop_a_enabled;
diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c
index 372ad59c4cba..83b47ab02d96 100644
--- a/arch/sparc/kernel/sparc_ksyms_64.c
+++ b/arch/sparc/kernel/sparc_ksyms_64.c
@@ -8,6 +8,7 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/pci.h> 9#include <linux/pci.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/bitops.h>
11 12
12#include <asm/system.h> 13#include <asm/system.h>
13#include <asm/cpudata.h> 14#include <asm/cpudata.h>
@@ -38,5 +39,15 @@ EXPORT_SYMBOL(sun4v_niagara_setperf);
38EXPORT_SYMBOL(sun4v_niagara2_getperf); 39EXPORT_SYMBOL(sun4v_niagara2_getperf);
39EXPORT_SYMBOL(sun4v_niagara2_setperf); 40EXPORT_SYMBOL(sun4v_niagara2_setperf);
40 41
42/* from hweight.S */
43EXPORT_SYMBOL(__arch_hweight8);
44EXPORT_SYMBOL(__arch_hweight16);
45EXPORT_SYMBOL(__arch_hweight32);
46EXPORT_SYMBOL(__arch_hweight64);
47
48/* from ffs_ffz.S */
49EXPORT_SYMBOL(ffs);
50EXPORT_SYMBOL(__ffs);
51
41/* Exporting a symbol from /init/main.c */ 52/* Exporting a symbol from /init/main.c */
42EXPORT_SYMBOL(saved_command_line); 53EXPORT_SYMBOL(saved_command_line);
diff --git a/arch/sparc/kernel/sstate.c b/arch/sparc/kernel/sstate.c
index 8cdbe5946b43..c59af546f522 100644
--- a/arch/sparc/kernel/sstate.c
+++ b/arch/sparc/kernel/sstate.c
@@ -14,14 +14,9 @@
14#include <asm/head.h> 14#include <asm/head.h>
15#include <asm/io.h> 15#include <asm/io.h>
16 16
17static int hv_supports_soft_state; 17#include "kernel.h"
18
19static unsigned long kimage_addr_to_ra(const char *p)
20{
21 unsigned long val = (unsigned long) p;
22 18
23 return kern_base + (val - KERNBASE); 19static int hv_supports_soft_state;
24}
25 20
26static void do_set_sstate(unsigned long state, const char *msg) 21static void do_set_sstate(unsigned long state, const char *msg)
27{ 22{
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index 35cff1673aa4..76e4ac1a13e1 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -22,6 +22,7 @@
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <linux/perf_event.h> 23#include <linux/perf_event.h>
24#include <linux/ratelimit.h> 24#include <linux/ratelimit.h>
25#include <linux/bitops.h>
25#include <asm/fpumacro.h> 26#include <asm/fpumacro.h>
26 27
27enum direction { 28enum direction {
@@ -373,16 +374,11 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
373 } 374 }
374} 375}
375 376
376static char popc_helper[] = {
3770, 1, 1, 2, 1, 2, 2, 3,
3781, 2, 2, 3, 2, 3, 3, 4,
379};
380
381int handle_popc(u32 insn, struct pt_regs *regs) 377int handle_popc(u32 insn, struct pt_regs *regs)
382{ 378{
383 u64 value;
384 int ret, i, rd = ((insn >> 25) & 0x1f);
385 int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; 379 int from_kernel = (regs->tstate & TSTATE_PRIV) != 0;
380 int ret, rd = ((insn >> 25) & 0x1f);
381 u64 value;
386 382
387 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); 383 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
388 if (insn & 0x2000) { 384 if (insn & 0x2000) {
@@ -392,10 +388,7 @@ int handle_popc(u32 insn, struct pt_regs *regs)
392 maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); 388 maybe_flush_windows(0, insn & 0x1f, rd, from_kernel);
393 value = fetch_reg(insn & 0x1f, regs); 389 value = fetch_reg(insn & 0x1f, regs);
394 } 390 }
395 for (ret = 0, i = 0; i < 16; i++) { 391 ret = hweight64(value);
396 ret += popc_helper[value & 0xf];
397 value >>= 4;
398 }
399 if (rd < 16) { 392 if (rd < 16) {
400 if (rd) 393 if (rd)
401 regs->u_regs[rd] = ret; 394 regs->u_regs[rd] = ret;
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index c0220759003e..0e1605697b49 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -107,7 +107,26 @@ SECTIONS
107 *(.sun4v_2insn_patch) 107 *(.sun4v_2insn_patch)
108 __sun4v_2insn_patch_end = .; 108 __sun4v_2insn_patch_end = .;
109 } 109 }
110 110 .swapper_tsb_phys_patch : {
111 __swapper_tsb_phys_patch = .;
112 *(.swapper_tsb_phys_patch)
113 __swapper_tsb_phys_patch_end = .;
114 }
115 .swapper_4m_tsb_phys_patch : {
116 __swapper_4m_tsb_phys_patch = .;
117 *(.swapper_4m_tsb_phys_patch)
118 __swapper_4m_tsb_phys_patch_end = .;
119 }
120 .popc_3insn_patch : {
121 __popc_3insn_patch = .;
122 *(.popc_3insn_patch)
123 __popc_3insn_patch_end = .;
124 }
125 .popc_6insn_patch : {
126 __popc_6insn_patch = .;
127 *(.popc_6insn_patch)
128 __popc_6insn_patch_end = .;
129 }
111 PERCPU_SECTION(SMP_CACHE_BYTES) 130 PERCPU_SECTION(SMP_CACHE_BYTES)
112 131
113 . = ALIGN(PAGE_SIZE); 132 . = ALIGN(PAGE_SIZE);
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 7f01b8fce8bc..a3fc4375a150 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -31,13 +31,13 @@ lib-$(CONFIG_SPARC64) += NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o
31lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o 31lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o
32 32
33lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o 33lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o
34lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o 34lib-$(CONFIG_SPARC64) += NG2patch.o
35 35
36lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o 36lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o
37lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o 37lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o
38 38
39lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o 39lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o
40lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o 40lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
41 41
42obj-y += iomap.o 42obj-y += iomap.o
43obj-$(CONFIG_SPARC32) += atomic32.o 43obj-$(CONFIG_SPARC32) += atomic32.o
diff --git a/arch/sparc/lib/NG2page.S b/arch/sparc/lib/NG2page.S
deleted file mode 100644
index 73b6b7c72cbf..000000000000
--- a/arch/sparc/lib/NG2page.S
+++ /dev/null
@@ -1,61 +0,0 @@
1/* NG2page.S: Niagara-2 optimized clear and copy page.
2 *
3 * Copyright (C) 2007 (davem@davemloft.net)
4 */
5
6#include <asm/asi.h>
7#include <asm/page.h>
8#include <asm/visasm.h>
9
10 .text
11 .align 32
12
13 /* This is heavily simplified from the sun4u variants
14 * because Niagara-2 does not have any D-cache aliasing issues.
15 */
16NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
17 prefetch [%o1 + 0x00], #one_read
18 prefetch [%o1 + 0x40], #one_read
19 VISEntryHalf
20 set PAGE_SIZE, %g7
21 sub %o0, %o1, %g3
221: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P
23 subcc %g7, 64, %g7
24 ldda [%o1] ASI_BLK_P, %f0
25 stda %f0, [%o1 + %g3] ASI_BLK_P
26 add %o1, 64, %o1
27 bne,pt %xcc, 1b
28 prefetch [%o1 + 0x40], #one_read
29 membar #Sync
30 VISExitHalf
31 retl
32 nop
33
34#define BRANCH_ALWAYS 0x10680000
35#define NOP 0x01000000
36#define NG_DO_PATCH(OLD, NEW) \
37 sethi %hi(NEW), %g1; \
38 or %g1, %lo(NEW), %g1; \
39 sethi %hi(OLD), %g2; \
40 or %g2, %lo(OLD), %g2; \
41 sub %g1, %g2, %g1; \
42 sethi %hi(BRANCH_ALWAYS), %g3; \
43 sll %g1, 11, %g1; \
44 srl %g1, 11 + 2, %g1; \
45 or %g3, %lo(BRANCH_ALWAYS), %g3; \
46 or %g3, %g1, %g3; \
47 stw %g3, [%g2]; \
48 sethi %hi(NOP), %g3; \
49 or %g3, %lo(NOP), %g3; \
50 stw %g3, [%g2 + 0x4]; \
51 flush %g2;
52
53 .globl niagara2_patch_pageops
54 .type niagara2_patch_pageops,#function
55niagara2_patch_pageops:
56 NG_DO_PATCH(copy_user_page, NG2copy_user_page)
57 NG_DO_PATCH(_clear_page, NGclear_page)
58 NG_DO_PATCH(clear_user_page, NGclear_user_page)
59 retl
60 nop
61 .size niagara2_patch_pageops,.-niagara2_patch_pageops
diff --git a/arch/sparc/lib/NGpage.S b/arch/sparc/lib/NGpage.S
index 428920de05ba..b9e790b9c6b8 100644
--- a/arch/sparc/lib/NGpage.S
+++ b/arch/sparc/lib/NGpage.S
@@ -16,55 +16,91 @@
16 */ 16 */
17 17
18NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ 18NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
19 prefetch [%o1 + 0x00], #one_read 19 save %sp, -192, %sp
20 mov 8, %g1 20 rd %asi, %g3
21 mov 16, %g2 21 wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
22 mov 24, %g3
23 set PAGE_SIZE, %g7 22 set PAGE_SIZE, %g7
23 prefetch [%i1 + 0x00], #one_read
24 prefetch [%i1 + 0x40], #one_read
24 25
251: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 261: prefetch [%i1 + 0x80], #one_read
26 ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 27 prefetch [%i1 + 0xc0], #one_read
27 prefetch [%o1 + 0x40], #one_read 28 ldda [%i1 + 0x00] %asi, %o2
28 add %o1, 32, %o1 29 ldda [%i1 + 0x10] %asi, %o4
29 stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 30 ldda [%i1 + 0x20] %asi, %l2
30 stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 31 ldda [%i1 + 0x30] %asi, %l4
31 ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 32 stxa %o2, [%i0 + 0x00] %asi
32 stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 33 stxa %o3, [%i0 + 0x08] %asi
33 stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 34 stxa %o4, [%i0 + 0x10] %asi
34 ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 35 stxa %o5, [%i0 + 0x18] %asi
35 add %o1, 32, %o1 36 stxa %l2, [%i0 + 0x20] %asi
36 add %o0, 32, %o0 37 stxa %l3, [%i0 + 0x28] %asi
37 stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 38 stxa %l4, [%i0 + 0x30] %asi
38 stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 39 stxa %l5, [%i0 + 0x38] %asi
39 stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 40 ldda [%i1 + 0x40] %asi, %o2
40 stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 41 ldda [%i1 + 0x50] %asi, %o4
41 subcc %g7, 64, %g7 42 ldda [%i1 + 0x60] %asi, %l2
43 ldda [%i1 + 0x70] %asi, %l4
44 stxa %o2, [%i0 + 0x40] %asi
45 stxa %o3, [%i0 + 0x48] %asi
46 stxa %o4, [%i0 + 0x50] %asi
47 stxa %o5, [%i0 + 0x58] %asi
48 stxa %l2, [%i0 + 0x60] %asi
49 stxa %l3, [%i0 + 0x68] %asi
50 stxa %l4, [%i0 + 0x70] %asi
51 stxa %l5, [%i0 + 0x78] %asi
52 add %i1, 128, %i1
53 subcc %g7, 128, %g7
42 bne,pt %xcc, 1b 54 bne,pt %xcc, 1b
43 add %o0, 32, %o0 55 add %i0, 128, %i0
56 wr %g3, 0x0, %asi
44 membar #Sync 57 membar #Sync
45 retl 58 ret
46 nop 59 restore
47 60
48 .globl NGclear_page, NGclear_user_page 61 .align 32
49NGclear_page: /* %o0=dest */ 62NGclear_page: /* %o0=dest */
50NGclear_user_page: /* %o0=dest, %o1=vaddr */ 63NGclear_user_page: /* %o0=dest, %o1=vaddr */
51 mov 8, %g1 64 rd %asi, %g3
52 mov 16, %g2 65 wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
53 mov 24, %g3
54 set PAGE_SIZE, %g7 66 set PAGE_SIZE, %g7
55 67
561: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 681: stxa %g0, [%o0 + 0x00] %asi
57 stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 69 stxa %g0, [%o0 + 0x08] %asi
58 stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 70 stxa %g0, [%o0 + 0x10] %asi
59 stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 71 stxa %g0, [%o0 + 0x18] %asi
60 add %o0, 32, %o0 72 stxa %g0, [%o0 + 0x20] %asi
61 stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P 73 stxa %g0, [%o0 + 0x28] %asi
62 stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P 74 stxa %g0, [%o0 + 0x30] %asi
63 stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P 75 stxa %g0, [%o0 + 0x38] %asi
64 stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P 76 stxa %g0, [%o0 + 0x40] %asi
65 subcc %g7, 64, %g7 77 stxa %g0, [%o0 + 0x48] %asi
78 stxa %g0, [%o0 + 0x50] %asi
79 stxa %g0, [%o0 + 0x58] %asi
80 stxa %g0, [%o0 + 0x60] %asi
81 stxa %g0, [%o0 + 0x68] %asi
82 stxa %g0, [%o0 + 0x70] %asi
83 stxa %g0, [%o0 + 0x78] %asi
84 stxa %g0, [%o0 + 0x80] %asi
85 stxa %g0, [%o0 + 0x88] %asi
86 stxa %g0, [%o0 + 0x90] %asi
87 stxa %g0, [%o0 + 0x98] %asi
88 stxa %g0, [%o0 + 0xa0] %asi
89 stxa %g0, [%o0 + 0xa8] %asi
90 stxa %g0, [%o0 + 0xb0] %asi
91 stxa %g0, [%o0 + 0xb8] %asi
92 stxa %g0, [%o0 + 0xc0] %asi
93 stxa %g0, [%o0 + 0xc8] %asi
94 stxa %g0, [%o0 + 0xd0] %asi
95 stxa %g0, [%o0 + 0xd8] %asi
96 stxa %g0, [%o0 + 0xe0] %asi
97 stxa %g0, [%o0 + 0xe8] %asi
98 stxa %g0, [%o0 + 0xf0] %asi
99 stxa %g0, [%o0 + 0xf8] %asi
100 subcc %g7, 256, %g7
66 bne,pt %xcc, 1b 101 bne,pt %xcc, 1b
67 add %o0, 32, %o0 102 add %o0, 256, %o0
103 wr %g3, 0x0, %asi
68 membar #Sync 104 membar #Sync
69 retl 105 retl
70 nop 106 nop
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 8600eb2461b5..1d32b54089aa 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -65,7 +65,7 @@ int __atomic_add_unless(atomic_t *v, int a, int u)
65 if (ret != u) 65 if (ret != u)
66 v->counter += a; 66 v->counter += a;
67 spin_unlock_irqrestore(ATOMIC_HASH(v), flags); 67 spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
68 return ret != u; 68 return ret;
69} 69}
70EXPORT_SYMBOL(__atomic_add_unless); 70EXPORT_SYMBOL(__atomic_add_unless);
71 71
diff --git a/arch/sparc/lib/ffs.S b/arch/sparc/lib/ffs.S
new file mode 100644
index 000000000000..b39389f69899
--- /dev/null
+++ b/arch/sparc/lib/ffs.S
@@ -0,0 +1,84 @@
1#include <linux/linkage.h>
2
3 .register %g2,#scratch
4
5 .text
6 .align 32
7
8ENTRY(ffs)
9 brnz,pt %o0, 1f
10 mov 1, %o1
11 retl
12 clr %o0
13 nop
14 nop
15ENTRY(__ffs)
16 sllx %o0, 32, %g1 /* 1 */
17 srlx %o0, 32, %g2
18
19 clr %o1 /* 2 */
20 movrz %g1, %g2, %o0
21
22 movrz %g1, 32, %o1 /* 3 */
231: clr %o2
24
25 sllx %o0, (64 - 16), %g1 /* 4 */
26 srlx %o0, 16, %g2
27
28 movrz %g1, %g2, %o0 /* 5 */
29 clr %o3
30
31 movrz %g1, 16, %o2 /* 6 */
32 clr %o4
33
34 and %o0, 0xff, %g1 /* 7 */
35 srlx %o0, 8, %g2
36
37 movrz %g1, %g2, %o0 /* 8 */
38 clr %o5
39
40 movrz %g1, 8, %o3 /* 9 */
41 add %o2, %o1, %o2
42
43 and %o0, 0xf, %g1 /* 10 */
44 srlx %o0, 4, %g2
45
46 movrz %g1, %g2, %o0 /* 11 */
47 add %o2, %o3, %o2
48
49 movrz %g1, 4, %o4 /* 12 */
50
51 and %o0, 0x3, %g1 /* 13 */
52 srlx %o0, 2, %g2
53
54 movrz %g1, %g2, %o0 /* 14 */
55 add %o2, %o4, %o2
56
57 movrz %g1, 2, %o5 /* 15 */
58
59 and %o0, 0x1, %g1 /* 16 */
60
61 add %o2, %o5, %o2 /* 17 */
62 xor %g1, 0x1, %g1
63
64 retl /* 18 */
65 add %o2, %g1, %o0
66ENDPROC(ffs)
67ENDPROC(__ffs)
68
69 .section .popc_6insn_patch, "ax"
70 .word ffs
71 brz,pn %o0, 98f
72 neg %o0, %g1
73 xnor %o0, %g1, %o1
74 popc %o1, %o0
7598: retl
76 nop
77 .word __ffs
78 neg %o0, %g1
79 xnor %o0, %g1, %o1
80 popc %o1, %o0
81 retl
82 sub %o0, 1, %o0
83 nop
84 .previous
diff --git a/arch/sparc/lib/hweight.S b/arch/sparc/lib/hweight.S
new file mode 100644
index 000000000000..95414e0a6808
--- /dev/null
+++ b/arch/sparc/lib/hweight.S
@@ -0,0 +1,51 @@
1#include <linux/linkage.h>
2
3 .text
4 .align 32
5ENTRY(__arch_hweight8)
6 ba,pt %xcc, __sw_hweight8
7 nop
8 nop
9ENDPROC(__arch_hweight8)
10 .section .popc_3insn_patch, "ax"
11 .word __arch_hweight8
12 sllx %o0, 64-8, %g1
13 retl
14 popc %g1, %o0
15 .previous
16
17ENTRY(__arch_hweight16)
18 ba,pt %xcc, __sw_hweight16
19 nop
20 nop
21ENDPROC(__arch_hweight16)
22 .section .popc_3insn_patch, "ax"
23 .word __arch_hweight16
24 sllx %o0, 64-16, %g1
25 retl
26 popc %g1, %o0
27 .previous
28
29ENTRY(__arch_hweight32)
30 ba,pt %xcc, __sw_hweight32
31 nop
32 nop
33ENDPROC(__arch_hweight32)
34 .section .popc_3insn_patch, "ax"
35 .word __arch_hweight32
36 sllx %o0, 64-32, %g1
37 retl
38 popc %g1, %o0
39 .previous
40
41ENTRY(__arch_hweight64)
42 ba,pt %xcc, __sw_hweight64
43 nop
44 nop
45ENDPROC(__arch_hweight64)
46 .section .popc_3insn_patch, "ax"
47 .word __arch_hweight64
48 retl
49 popc %o0, %o0
50 nop
51 .previous
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 3fd8e18bed80..581531dbc8b5 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1597,6 +1597,44 @@ static void __init tsb_phys_patch(void)
1597static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; 1597static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR];
1598extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; 1598extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
1599 1599
1600static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa)
1601{
1602 pa >>= KTSB_PHYS_SHIFT;
1603
1604 while (start < end) {
1605 unsigned int *ia = (unsigned int *)(unsigned long)*start;
1606
1607 ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10);
1608 __asm__ __volatile__("flush %0" : : "r" (ia));
1609
1610 ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff);
1611 __asm__ __volatile__("flush %0" : : "r" (ia + 1));
1612
1613 start++;
1614 }
1615}
1616
1617static void ktsb_phys_patch(void)
1618{
1619 extern unsigned int __swapper_tsb_phys_patch;
1620 extern unsigned int __swapper_tsb_phys_patch_end;
1621 unsigned long ktsb_pa;
1622
1623 ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE);
1624 patch_one_ktsb_phys(&__swapper_tsb_phys_patch,
1625 &__swapper_tsb_phys_patch_end, ktsb_pa);
1626#ifndef CONFIG_DEBUG_PAGEALLOC
1627 {
1628 extern unsigned int __swapper_4m_tsb_phys_patch;
1629 extern unsigned int __swapper_4m_tsb_phys_patch_end;
1630 ktsb_pa = (kern_base +
1631 ((unsigned long)&swapper_4m_tsb[0] - KERNBASE));
1632 patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch,
1633 &__swapper_4m_tsb_phys_patch_end, ktsb_pa);
1634 }
1635#endif
1636}
1637
1600static void __init sun4v_ktsb_init(void) 1638static void __init sun4v_ktsb_init(void)
1601{ 1639{
1602 unsigned long ktsb_pa; 1640 unsigned long ktsb_pa;
@@ -1716,8 +1754,10 @@ void __init paging_init(void)
1716 sun4u_pgprot_init(); 1754 sun4u_pgprot_init();
1717 1755
1718 if (tlb_type == cheetah_plus || 1756 if (tlb_type == cheetah_plus ||
1719 tlb_type == hypervisor) 1757 tlb_type == hypervisor) {
1720 tsb_phys_patch(); 1758 tsb_phys_patch();
1759 ktsb_phys_patch();
1760 }
1721 1761
1722 if (tlb_type == hypervisor) { 1762 if (tlb_type == hypervisor) {
1723 sun4v_patch_tlb_handlers(); 1763 sun4v_patch_tlb_handlers();
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 0249b8b4db54..b30f71ac0d06 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -12,6 +12,7 @@ config TILE
12 select GENERIC_PENDING_IRQ if SMP 12 select GENERIC_PENDING_IRQ if SMP
13 select GENERIC_IRQ_SHOW 13 select GENERIC_IRQ_SHOW
14 select SYS_HYPERVISOR 14 select SYS_HYPERVISOR
15 select ARCH_HAVE_NMI_SAFE_CMPXCHG if !M386
15 16
16# FIXME: investigate whether we need/want these options. 17# FIXME: investigate whether we need/want these options.
17# select HAVE_IOREMAP_PROT 18# select HAVE_IOREMAP_PROT
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 849ab2fa1f5c..aec60dc06007 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -2,3 +2,41 @@ include include/asm-generic/Kbuild.asm
2 2
3header-y += ucontext.h 3header-y += ucontext.h
4header-y += hardwall.h 4header-y += hardwall.h
5
6generic-y += bug.h
7generic-y += bugs.h
8generic-y += cputime.h
9generic-y += device.h
10generic-y += div64.h
11generic-y += emergency-restart.h
12generic-y += errno.h
13generic-y += fb.h
14generic-y += fcntl.h
15generic-y += ioctl.h
16generic-y += ioctls.h
17generic-y += ipc.h
18generic-y += ipcbuf.h
19generic-y += irq_regs.h
20generic-y += kdebug.h
21generic-y += local.h
22generic-y += module.h
23generic-y += msgbuf.h
24generic-y += mutex.h
25generic-y += param.h
26generic-y += parport.h
27generic-y += poll.h
28generic-y += posix_types.h
29generic-y += resource.h
30generic-y += scatterlist.h
31generic-y += sembuf.h
32generic-y += serial.h
33generic-y += shmbuf.h
34generic-y += shmparam.h
35generic-y += socket.h
36generic-y += sockios.h
37generic-y += statfs.h
38generic-y += termbits.h
39generic-y += termios.h
40generic-y += types.h
41generic-y += ucontext.h
42generic-y += xor.h
diff --git a/arch/tile/include/asm/bug.h b/arch/tile/include/asm/bug.h
deleted file mode 100644
index b12fd89e42e9..000000000000
--- a/arch/tile/include/asm/bug.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/bug.h>
diff --git a/arch/tile/include/asm/bugs.h b/arch/tile/include/asm/bugs.h
deleted file mode 100644
index 61791e1ad9f5..000000000000
--- a/arch/tile/include/asm/bugs.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/bugs.h>
diff --git a/arch/tile/include/asm/cputime.h b/arch/tile/include/asm/cputime.h
deleted file mode 100644
index 6d68ad7e0ea3..000000000000
--- a/arch/tile/include/asm/cputime.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/cputime.h>
diff --git a/arch/tile/include/asm/device.h b/arch/tile/include/asm/device.h
deleted file mode 100644
index f0a4c256403b..000000000000
--- a/arch/tile/include/asm/device.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/device.h>
diff --git a/arch/tile/include/asm/div64.h b/arch/tile/include/asm/div64.h
deleted file mode 100644
index 6cd978cefb28..000000000000
--- a/arch/tile/include/asm/div64.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/div64.h>
diff --git a/arch/tile/include/asm/emergency-restart.h b/arch/tile/include/asm/emergency-restart.h
deleted file mode 100644
index 3711bd9d50bd..000000000000
--- a/arch/tile/include/asm/emergency-restart.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/emergency-restart.h>
diff --git a/arch/tile/include/asm/errno.h b/arch/tile/include/asm/errno.h
deleted file mode 100644
index 4c82b503d92f..000000000000
--- a/arch/tile/include/asm/errno.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/errno.h>
diff --git a/arch/tile/include/asm/fb.h b/arch/tile/include/asm/fb.h
deleted file mode 100644
index 3a4988e8df45..000000000000
--- a/arch/tile/include/asm/fb.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/fb.h>
diff --git a/arch/tile/include/asm/fcntl.h b/arch/tile/include/asm/fcntl.h
deleted file mode 100644
index 46ab12db5739..000000000000
--- a/arch/tile/include/asm/fcntl.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/fcntl.h>
diff --git a/arch/tile/include/asm/fixmap.h b/arch/tile/include/asm/fixmap.h
index 51537ff9265a..c66f7933beaa 100644
--- a/arch/tile/include/asm/fixmap.h
+++ b/arch/tile/include/asm/fixmap.h
@@ -75,12 +75,6 @@ extern void __set_fixmap(enum fixed_addresses idx,
75 75
76#define set_fixmap(idx, phys) \ 76#define set_fixmap(idx, phys) \
77 __set_fixmap(idx, phys, PAGE_KERNEL) 77 __set_fixmap(idx, phys, PAGE_KERNEL)
78/*
79 * Some hardware wants to get fixmapped without caching.
80 */
81#define set_fixmap_nocache(idx, phys) \
82 __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
83
84#define clear_fixmap(idx) \ 78#define clear_fixmap(idx) \
85 __set_fixmap(idx, 0, __pgprot(0)) 79 __set_fixmap(idx, 0, __pgprot(0))
86 80
diff --git a/arch/tile/include/asm/ioctl.h b/arch/tile/include/asm/ioctl.h
deleted file mode 100644
index b279fe06dfe5..000000000000
--- a/arch/tile/include/asm/ioctl.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/ioctl.h>
diff --git a/arch/tile/include/asm/ioctls.h b/arch/tile/include/asm/ioctls.h
deleted file mode 100644
index ec34c760665e..000000000000
--- a/arch/tile/include/asm/ioctls.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/ioctls.h>
diff --git a/arch/tile/include/asm/ipc.h b/arch/tile/include/asm/ipc.h
deleted file mode 100644
index a46e3d9c2a3f..000000000000
--- a/arch/tile/include/asm/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/ipc.h>
diff --git a/arch/tile/include/asm/ipcbuf.h b/arch/tile/include/asm/ipcbuf.h
deleted file mode 100644
index 84c7e51cb6d0..000000000000
--- a/arch/tile/include/asm/ipcbuf.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/ipcbuf.h>
diff --git a/arch/tile/include/asm/irq_regs.h b/arch/tile/include/asm/irq_regs.h
deleted file mode 100644
index 3dd9c0b70270..000000000000
--- a/arch/tile/include/asm/irq_regs.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/irq_regs.h>
diff --git a/arch/tile/include/asm/kdebug.h b/arch/tile/include/asm/kdebug.h
deleted file mode 100644
index 6ece1b037665..000000000000
--- a/arch/tile/include/asm/kdebug.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/kdebug.h>
diff --git a/arch/tile/include/asm/local.h b/arch/tile/include/asm/local.h
deleted file mode 100644
index c11c530f74d0..000000000000
--- a/arch/tile/include/asm/local.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/local.h>
diff --git a/arch/tile/include/asm/module.h b/arch/tile/include/asm/module.h
deleted file mode 100644
index 1e4b79fe8584..000000000000
--- a/arch/tile/include/asm/module.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/module.h>
diff --git a/arch/tile/include/asm/msgbuf.h b/arch/tile/include/asm/msgbuf.h
deleted file mode 100644
index 809134c644a6..000000000000
--- a/arch/tile/include/asm/msgbuf.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/msgbuf.h>
diff --git a/arch/tile/include/asm/mutex.h b/arch/tile/include/asm/mutex.h
deleted file mode 100644
index ff6101aa2c71..000000000000
--- a/arch/tile/include/asm/mutex.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/mutex-dec.h>
diff --git a/arch/tile/include/asm/param.h b/arch/tile/include/asm/param.h
deleted file mode 100644
index 965d45427975..000000000000
--- a/arch/tile/include/asm/param.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/param.h>
diff --git a/arch/tile/include/asm/parport.h b/arch/tile/include/asm/parport.h
deleted file mode 100644
index cf252af64590..000000000000
--- a/arch/tile/include/asm/parport.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/parport.h>
diff --git a/arch/tile/include/asm/poll.h b/arch/tile/include/asm/poll.h
deleted file mode 100644
index c98509d3149e..000000000000
--- a/arch/tile/include/asm/poll.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/poll.h>
diff --git a/arch/tile/include/asm/posix_types.h b/arch/tile/include/asm/posix_types.h
deleted file mode 100644
index 22cae6230ceb..000000000000
--- a/arch/tile/include/asm/posix_types.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/posix_types.h>
diff --git a/arch/tile/include/asm/resource.h b/arch/tile/include/asm/resource.h
deleted file mode 100644
index 04bc4db8921b..000000000000
--- a/arch/tile/include/asm/resource.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/resource.h>
diff --git a/arch/tile/include/asm/scatterlist.h b/arch/tile/include/asm/scatterlist.h
deleted file mode 100644
index 35d786fe93ae..000000000000
--- a/arch/tile/include/asm/scatterlist.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/scatterlist.h>
diff --git a/arch/tile/include/asm/sembuf.h b/arch/tile/include/asm/sembuf.h
deleted file mode 100644
index 7673b83cfef7..000000000000
--- a/arch/tile/include/asm/sembuf.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/sembuf.h>
diff --git a/arch/tile/include/asm/serial.h b/arch/tile/include/asm/serial.h
deleted file mode 100644
index a0cb0caff152..000000000000
--- a/arch/tile/include/asm/serial.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/serial.h>
diff --git a/arch/tile/include/asm/shmbuf.h b/arch/tile/include/asm/shmbuf.h
deleted file mode 100644
index 83c05fc2de38..000000000000
--- a/arch/tile/include/asm/shmbuf.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/shmbuf.h>
diff --git a/arch/tile/include/asm/shmparam.h b/arch/tile/include/asm/shmparam.h
deleted file mode 100644
index 93f30deb95d0..000000000000
--- a/arch/tile/include/asm/shmparam.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/shmparam.h>
diff --git a/arch/tile/include/asm/socket.h b/arch/tile/include/asm/socket.h
deleted file mode 100644
index 6b71384b9d8b..000000000000
--- a/arch/tile/include/asm/socket.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/socket.h>
diff --git a/arch/tile/include/asm/sockios.h b/arch/tile/include/asm/sockios.h
deleted file mode 100644
index def6d4746ee7..000000000000
--- a/arch/tile/include/asm/sockios.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/sockios.h>
diff --git a/arch/tile/include/asm/statfs.h b/arch/tile/include/asm/statfs.h
deleted file mode 100644
index 0b91fe198c20..000000000000
--- a/arch/tile/include/asm/statfs.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/statfs.h>
diff --git a/arch/tile/include/asm/termbits.h b/arch/tile/include/asm/termbits.h
deleted file mode 100644
index 3935b106de79..000000000000
--- a/arch/tile/include/asm/termbits.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/termbits.h>
diff --git a/arch/tile/include/asm/termios.h b/arch/tile/include/asm/termios.h
deleted file mode 100644
index 280d78a9d966..000000000000
--- a/arch/tile/include/asm/termios.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/termios.h>
diff --git a/arch/tile/include/asm/types.h b/arch/tile/include/asm/types.h
deleted file mode 100644
index b9e79bc580dd..000000000000
--- a/arch/tile/include/asm/types.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/types.h>
diff --git a/arch/tile/include/asm/ucontext.h b/arch/tile/include/asm/ucontext.h
deleted file mode 100644
index 9bc07b9f30fb..000000000000
--- a/arch/tile/include/asm/ucontext.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/ucontext.h>
diff --git a/arch/tile/include/asm/xor.h b/arch/tile/include/asm/xor.h
deleted file mode 100644
index c82eb12a5b18..000000000000
--- a/arch/tile/include/asm/xor.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-generic/xor.h>
diff --git a/arch/tile/include/hv/drv_srom_intf.h b/arch/tile/include/hv/drv_srom_intf.h
new file mode 100644
index 000000000000..6395faa6d9e6
--- /dev/null
+++ b/arch/tile/include/hv/drv_srom_intf.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
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, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15/**
16 * @file drv_srom_intf.h
17 * Interface definitions for the SPI Flash ROM driver.
18 */
19
20#ifndef _SYS_HV_INCLUDE_DRV_SROM_INTF_H
21#define _SYS_HV_INCLUDE_DRV_SROM_INTF_H
22
23/** Read this offset to get the total device size. */
24#define SROM_TOTAL_SIZE_OFF 0xF0000000
25
26/** Read this offset to get the device sector size. */
27#define SROM_SECTOR_SIZE_OFF 0xF0000004
28
29/** Read this offset to get the device page size. */
30#define SROM_PAGE_SIZE_OFF 0xF0000008
31
32/** Write this offset to flush any pending writes. */
33#define SROM_FLUSH_OFF 0xF1000000
34
35/** Write this offset, plus the byte offset of the start of a sector, to
36 * erase a sector. Any write data is ignored, but there must be at least
37 * one byte of write data. Only applies when the driver is in MTD mode.
38 */
39#define SROM_ERASE_OFF 0xF2000000
40
41#endif /* _SYS_HV_INCLUDE_DRV_SROM_INTF_H */
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c
index c4be58cc5d50..f6f50f2a5e37 100644
--- a/arch/tile/kernel/time.c
+++ b/arch/tile/kernel/time.c
@@ -78,7 +78,6 @@ static struct clocksource cycle_counter_cs = {
78 .rating = 300, 78 .rating = 300,
79 .read = clocksource_get_cycles, 79 .read = clocksource_get_cycles,
80 .mask = CLOCKSOURCE_MASK(64), 80 .mask = CLOCKSOURCE_MASK(64),
81 .shift = 22, /* typical value, e.g. x86 tsc uses this */
82 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 81 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
83}; 82};
84 83
@@ -91,8 +90,6 @@ void __init setup_clock(void)
91 cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED); 90 cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED);
92 sched_clock_mult = 91 sched_clock_mult =
93 clocksource_hz2mult(cycles_per_sec, SCHED_CLOCK_SHIFT); 92 clocksource_hz2mult(cycles_per_sec, SCHED_CLOCK_SHIFT);
94 cycle_counter_cs.mult =
95 clocksource_hz2mult(cycles_per_sec, cycle_counter_cs.shift);
96} 93}
97 94
98void __init calibrate_delay(void) 95void __init calibrate_delay(void)
@@ -107,7 +104,7 @@ void __init calibrate_delay(void)
107void __init time_init(void) 104void __init time_init(void)
108{ 105{
109 /* Initialize and register the clock source. */ 106 /* Initialize and register the clock source. */
110 clocksource_register(&cycle_counter_cs); 107 clocksource_register_hz(&cycle_counter_cs, cycles_per_sec);
111 108
112 /* Start up the tile-timer interrupt source on the boot cpu. */ 109 /* Start up the tile-timer interrupt source on the boot cpu. */
113 setup_tile_timer(); 110 setup_tile_timer();
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
index 4e10c4023028..7309988c9794 100644
--- a/arch/tile/mm/init.c
+++ b/arch/tile/mm/init.c
@@ -836,8 +836,7 @@ void __init mem_init(void)
836#endif 836#endif
837 837
838#ifdef CONFIG_FLATMEM 838#ifdef CONFIG_FLATMEM
839 if (!mem_map) 839 BUG_ON(!mem_map);
840 BUG();
841#endif 840#endif
842 841
843#ifdef CONFIG_HIGHMEM 842#ifdef CONFIG_HIGHMEM
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7cf916fc1ce7..6a47bb22657f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -72,6 +72,7 @@ config X86
72 select USE_GENERIC_SMP_HELPERS if SMP 72 select USE_GENERIC_SMP_HELPERS if SMP
73 select HAVE_BPF_JIT if (X86_64 && NET) 73 select HAVE_BPF_JIT if (X86_64 && NET)
74 select CLKEVT_I8253 74 select CLKEVT_I8253
75 select ARCH_HAVE_NMI_SAFE_CMPXCHG
75 76
76config INSTRUCTION_DECODER 77config INSTRUCTION_DECODER
77 def_bool (KPROBES || PERF_EVENTS) 78 def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index d02804d650c4..d8e8eefbe24c 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -40,8 +40,6 @@
40#include <linux/compiler.h> 40#include <linux/compiler.h>
41#include <asm/page.h> 41#include <asm/page.h>
42 42
43#include <xen/xen.h>
44
45#define build_mmio_read(name, size, type, reg, barrier) \ 43#define build_mmio_read(name, size, type, reg, barrier) \
46static inline type name(const volatile void __iomem *addr) \ 44static inline type name(const volatile void __iomem *addr) \
47{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \ 45{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \
@@ -334,6 +332,7 @@ extern void fixup_early_ioremap(void);
334extern bool is_early_ioremap_ptep(pte_t *ptep); 332extern bool is_early_ioremap_ptep(pte_t *ptep);
335 333
336#ifdef CONFIG_XEN 334#ifdef CONFIG_XEN
335#include <xen/xen.h>
337struct bio_vec; 336struct bio_vec;
338 337
339extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, 338extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 219371546afd..0d1171c97729 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -751,8 +751,6 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
751 :: "a" (eax), "c" (ecx)); 751 :: "a" (eax), "c" (ecx));
752} 752}
753 753
754extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
755
756extern void select_idle_routine(const struct cpuinfo_x86 *c); 754extern void select_idle_routine(const struct cpuinfo_x86 *c);
757extern void init_amd_e400_c1e_mask(void); 755extern void init_amd_e400_c1e_mask(void);
758 756
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index 5812404a0d4c..f50e7fb2a201 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -149,6 +149,29 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
149} 149}
150EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); 150EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
151 151
152/*
153 * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
154 * which can obviate IPI to trigger checking of need_resched.
155 * We execute MONITOR against need_resched and enter optimized wait state
156 * through MWAIT. Whenever someone changes need_resched, we would be woken
157 * up from MWAIT (without an IPI).
158 *
159 * New with Core Duo processors, MWAIT can take some hints based on CPU
160 * capability.
161 */
162void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
163{
164 if (!need_resched()) {
165 if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
166 clflush((void *)&current_thread_info()->flags);
167
168 __monitor((void *)&current_thread_info()->flags, 0, 0);
169 smp_mb();
170 if (!need_resched())
171 __mwait(ax, cx);
172 }
173}
174
152void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) 175void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
153{ 176{
154 unsigned int cpu = smp_processor_id(); 177 unsigned int cpu = smp_processor_id();
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index e1ba8cb24e4e..e7e3b019c439 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -438,29 +438,6 @@ void cpu_idle_wait(void)
438} 438}
439EXPORT_SYMBOL_GPL(cpu_idle_wait); 439EXPORT_SYMBOL_GPL(cpu_idle_wait);
440 440
441/*
442 * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
443 * which can obviate IPI to trigger checking of need_resched.
444 * We execute MONITOR against need_resched and enter optimized wait state
445 * through MWAIT. Whenever someone changes need_resched, we would be woken
446 * up from MWAIT (without an IPI).
447 *
448 * New with Core Duo processors, MWAIT can take some hints based on CPU
449 * capability.
450 */
451void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
452{
453 if (!need_resched()) {
454 if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
455 clflush((void *)&current_thread_info()->flags);
456
457 __monitor((void *)&current_thread_info()->flags, 0, 0);
458 smp_mb();
459 if (!need_resched())
460 __mwait(ax, cx);
461 }
462}
463
464/* Default MONITOR/MWAIT with no hints, used for default C1 state */ 441/* Default MONITOR/MWAIT with no hints, used for default C1 state */
465static void mwait_idle(void) 442static void mwait_idle(void)
466{ 443{
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index a3d0dc59067b..7a3b65107a27 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -38,6 +38,7 @@
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/io.h> 39#include <linux/io.h>
40#include <linux/kdebug.h> 40#include <linux/kdebug.h>
41#include <linux/cpuidle.h>
41 42
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
43#include <asm/system.h> 44#include <asm/system.h>
@@ -109,7 +110,8 @@ void cpu_idle(void)
109 local_irq_disable(); 110 local_irq_disable();
110 /* Don't trace irqs off for idle */ 111 /* Don't trace irqs off for idle */
111 stop_critical_timings(); 112 stop_critical_timings();
112 pm_idle(); 113 if (cpuidle_idle_call())
114 pm_idle();
113 start_critical_timings(); 115 start_critical_timings();
114 } 116 }
115 tick_nohz_restart_sched_tick(); 117 tick_nohz_restart_sched_tick();
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ca6f7ab8df33..f693e44e1bf6 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -37,6 +37,7 @@
37#include <linux/uaccess.h> 37#include <linux/uaccess.h>
38#include <linux/io.h> 38#include <linux/io.h>
39#include <linux/ftrace.h> 39#include <linux/ftrace.h>
40#include <linux/cpuidle.h>
40 41
41#include <asm/pgtable.h> 42#include <asm/pgtable.h>
42#include <asm/system.h> 43#include <asm/system.h>
@@ -136,7 +137,8 @@ void cpu_idle(void)
136 enter_idle(); 137 enter_idle();
137 /* Don't trace irqs off for idle */ 138 /* Don't trace irqs off for idle */
138 stop_critical_timings(); 139 stop_critical_timings();
139 pm_idle(); 140 if (cpuidle_idle_call())
141 pm_idle();
140 start_critical_timings(); 142 start_critical_timings();
141 143
142 /* In many cases the interrupt that ended idle 144 /* In many cases the interrupt that ended idle
diff --git a/arch/x86/platform/mrst/Makefile b/arch/x86/platform/mrst/Makefile
index f61ccdd49341..1ea38775a6d3 100644
--- a/arch/x86/platform/mrst/Makefile
+++ b/arch/x86/platform/mrst/Makefile
@@ -1,3 +1,4 @@
1obj-$(CONFIG_X86_MRST) += mrst.o 1obj-$(CONFIG_X86_MRST) += mrst.o
2obj-$(CONFIG_X86_MRST) += vrtc.o 2obj-$(CONFIG_X86_MRST) += vrtc.o
3obj-$(CONFIG_EARLY_PRINTK_MRST) += early_printk_mrst.o 3obj-$(CONFIG_EARLY_PRINTK_MRST) += early_printk_mrst.o
4obj-$(CONFIG_X86_MRST) += pmu.o
diff --git a/arch/x86/platform/mrst/pmu.c b/arch/x86/platform/mrst/pmu.c
new file mode 100644
index 000000000000..9281da7d91bd
--- /dev/null
+++ b/arch/x86/platform/mrst/pmu.c
@@ -0,0 +1,817 @@
1/*
2 * mrst/pmu.c - driver for MRST Power Management Unit
3 *
4 * Copyright (c) 2011, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include <linux/cpuidle.h>
21#include <linux/debugfs.h>
22#include <linux/delay.h>
23#include <linux/interrupt.h>
24#include <linux/module.h>
25#include <linux/pci.h>
26#include <linux/seq_file.h>
27#include <linux/sfi.h>
28#include <asm/intel_scu_ipc.h>
29#include "pmu.h"
30
31#define IPCMSG_FW_REVISION 0xF4
32
33struct mrst_device {
34 u16 pci_dev_num; /* DEBUG only */
35 u16 lss;
36 u16 latest_request;
37 unsigned int pci_state_counts[PCI_D3cold + 1]; /* DEBUG only */
38};
39
40/*
41 * comlete list of MRST PCI devices
42 */
43static struct mrst_device mrst_devs[] = {
44/* 0 */ { 0x0800, LSS_SPI0 }, /* Moorestown SPI Ctrl 0 */
45/* 1 */ { 0x0801, LSS_SPI1 }, /* Moorestown SPI Ctrl 1 */
46/* 2 */ { 0x0802, LSS_I2C0 }, /* Moorestown I2C 0 */
47/* 3 */ { 0x0803, LSS_I2C1 }, /* Moorestown I2C 1 */
48/* 4 */ { 0x0804, LSS_I2C2 }, /* Moorestown I2C 2 */
49/* 5 */ { 0x0805, LSS_KBD }, /* Moorestown Keyboard Ctrl */
50/* 6 */ { 0x0806, LSS_USB_HC }, /* Moorestown USB Ctrl */
51/* 7 */ { 0x0807, LSS_SD_HC0 }, /* Moorestown SD Host Ctrl 0 */
52/* 8 */ { 0x0808, LSS_SD_HC1 }, /* Moorestown SD Host Ctrl 1 */
53/* 9 */ { 0x0809, LSS_NAND }, /* Moorestown NAND Ctrl */
54/* 10 */ { 0x080a, LSS_AUDIO }, /* Moorestown Audio Ctrl */
55/* 11 */ { 0x080b, LSS_IMAGING }, /* Moorestown ISP */
56/* 12 */ { 0x080c, LSS_SECURITY }, /* Moorestown Security Controller */
57/* 13 */ { 0x080d, LSS_DISPLAY }, /* Moorestown External Displays */
58/* 14 */ { 0x080e, 0 }, /* Moorestown SCU IPC */
59/* 15 */ { 0x080f, LSS_GPIO }, /* Moorestown GPIO Controller */
60/* 16 */ { 0x0810, 0 }, /* Moorestown Power Management Unit */
61/* 17 */ { 0x0811, LSS_USB_OTG }, /* Moorestown OTG Ctrl */
62/* 18 */ { 0x0812, LSS_SPI2 }, /* Moorestown SPI Ctrl 2 */
63/* 19 */ { 0x0813, 0 }, /* Moorestown SC DMA */
64/* 20 */ { 0x0814, LSS_AUDIO_LPE }, /* Moorestown LPE DMA */
65/* 21 */ { 0x0815, LSS_AUDIO_SSP }, /* Moorestown SSP0 */
66
67/* 22 */ { 0x084F, LSS_SD_HC2 }, /* Moorestown SD Host Ctrl 2 */
68
69/* 23 */ { 0x4102, 0 }, /* Lincroft */
70/* 24 */ { 0x4110, 0 }, /* Lincroft */
71};
72
73/* n.b. We ignore PCI-id 0x815 in LSS9 b/c MeeGo has no driver for it */
74static u16 mrst_lss9_pci_ids[] = {0x080a, 0x0814, 0};
75static u16 mrst_lss10_pci_ids[] = {0x0800, 0x0801, 0x0802, 0x0803,
76 0x0804, 0x0805, 0x080f, 0};
77
78/* handle concurrent SMP invokations of pmu_pci_set_power_state() */
79static spinlock_t mrst_pmu_power_state_lock;
80
81static unsigned int wake_counters[MRST_NUM_LSS]; /* DEBUG only */
82static unsigned int pmu_irq_stats[INT_INVALID + 1]; /* DEBUG only */
83
84static int graphics_is_off;
85static int lss_s0i3_enabled;
86static bool mrst_pmu_s0i3_enable;
87
88/* debug counters */
89static u32 pmu_wait_ready_calls;
90static u32 pmu_wait_ready_udelays;
91static u32 pmu_wait_ready_udelays_max;
92static u32 pmu_wait_done_calls;
93static u32 pmu_wait_done_udelays;
94static u32 pmu_wait_done_udelays_max;
95static u32 pmu_set_power_state_entry;
96static u32 pmu_set_power_state_send_cmd;
97
98static struct mrst_device *pci_id_2_mrst_dev(u16 pci_dev_num)
99{
100 int index = 0;
101
102 if ((pci_dev_num >= 0x0800) && (pci_dev_num <= 0x815))
103 index = pci_dev_num - 0x800;
104 else if (pci_dev_num == 0x084F)
105 index = 22;
106 else if (pci_dev_num == 0x4102)
107 index = 23;
108 else if (pci_dev_num == 0x4110)
109 index = 24;
110
111 if (pci_dev_num != mrst_devs[index].pci_dev_num) {
112 WARN_ONCE(1, FW_BUG "Unknown PCI device 0x%04X\n", pci_dev_num);
113 return 0;
114 }
115
116 return &mrst_devs[index];
117}
118
119/**
120 * mrst_pmu_validate_cstates
121 * @dev: cpuidle_device
122 *
123 * Certain states are not appropriate for governor to pick in some cases.
124 * This function will be called as cpuidle_device's prepare callback and
125 * thus tells governor to ignore such states when selecting the next state
126 * to enter.
127 */
128
129#define IDLE_STATE4_IS_C6 4
130#define IDLE_STATE5_IS_S0I3 5
131
132int mrst_pmu_invalid_cstates(void)
133{
134 int cpu = smp_processor_id();
135
136 /*
137 * Demote to C4 if the PMU is busy.
138 * Since LSS changes leave the busy bit clear...
139 * busy means either the PMU is waiting for an ACK-C6 that
140 * isn't coming due to an MWAIT that returned immediately;
141 * or we returned from S0i3 successfully, and the PMU
142 * is not done sending us interrupts.
143 */
144 if (pmu_read_busy_status())
145 return 1 << IDLE_STATE4_IS_C6 | 1 << IDLE_STATE5_IS_S0I3;
146
147 /*
148 * Disallow S0i3 if: PMU is not initialized, or CPU1 is active,
149 * or if device LSS is insufficient, or the GPU is active,
150 * or if it has been explicitly disabled.
151 */
152 if (!pmu_reg || !cpumask_equal(cpu_online_mask, cpumask_of(cpu)) ||
153 !lss_s0i3_enabled || !graphics_is_off || !mrst_pmu_s0i3_enable)
154 return 1 << IDLE_STATE5_IS_S0I3;
155 else
156 return 0;
157}
158
159/*
160 * pmu_update_wake_counters(): read PM_WKS, update wake_counters[]
161 * DEBUG only.
162 */
163static void pmu_update_wake_counters(void)
164{
165 int lss;
166 u32 wake_status;
167
168 wake_status = pmu_read_wks();
169
170 for (lss = 0; lss < MRST_NUM_LSS; ++lss) {
171 if (wake_status & (1 << lss))
172 wake_counters[lss]++;
173 }
174}
175
176int mrst_pmu_s0i3_entry(void)
177{
178 int status;
179
180 /* Clear any possible error conditions */
181 pmu_write_ics(0x300);
182
183 /* set wake control to current D-states */
184 pmu_write_wssc(S0I3_SSS_TARGET);
185
186 status = mrst_s0i3_entry(PM_S0I3_COMMAND, &pmu_reg->pm_cmd);
187 pmu_update_wake_counters();
188 return status;
189}
190
191/* poll for maximum of 5ms for busy bit to clear */
192static int pmu_wait_ready(void)
193{
194 int udelays;
195
196 pmu_wait_ready_calls++;
197
198 for (udelays = 0; udelays < 500; ++udelays) {
199 if (udelays > pmu_wait_ready_udelays_max)
200 pmu_wait_ready_udelays_max = udelays;
201
202 if (pmu_read_busy_status() == 0)
203 return 0;
204
205 udelay(10);
206 pmu_wait_ready_udelays++;
207 }
208
209 /*
210 * if this fires, observe
211 * /sys/kernel/debug/mrst_pmu_wait_ready_calls
212 * /sys/kernel/debug/mrst_pmu_wait_ready_udelays
213 */
214 WARN_ONCE(1, "SCU not ready for 5ms");
215 return -EBUSY;
216}
217/* poll for maximum of 50ms us for busy bit to clear */
218static int pmu_wait_done(void)
219{
220 int udelays;
221
222 pmu_wait_done_calls++;
223
224 for (udelays = 0; udelays < 500; ++udelays) {
225 if (udelays > pmu_wait_done_udelays_max)
226 pmu_wait_done_udelays_max = udelays;
227
228 if (pmu_read_busy_status() == 0)
229 return 0;
230
231 udelay(100);
232 pmu_wait_done_udelays++;
233 }
234
235 /*
236 * if this fires, observe
237 * /sys/kernel/debug/mrst_pmu_wait_done_calls
238 * /sys/kernel/debug/mrst_pmu_wait_done_udelays
239 */
240 WARN_ONCE(1, "SCU not done for 50ms");
241 return -EBUSY;
242}
243
244u32 mrst_pmu_msi_is_disabled(void)
245{
246 return pmu_msi_is_disabled();
247}
248
249void mrst_pmu_enable_msi(void)
250{
251 pmu_msi_enable();
252}
253
254/**
255 * pmu_irq - pmu driver interrupt handler
256 * Context: interrupt context
257 */
258static irqreturn_t pmu_irq(int irq, void *dummy)
259{
260 union pmu_pm_ics pmu_ics;
261
262 pmu_ics.value = pmu_read_ics();
263
264 if (!pmu_ics.bits.pending)
265 return IRQ_NONE;
266
267 switch (pmu_ics.bits.cause) {
268 case INT_SPURIOUS:
269 case INT_CMD_DONE:
270 case INT_CMD_ERR:
271 case INT_WAKE_RX:
272 case INT_SS_ERROR:
273 case INT_S0IX_MISS:
274 case INT_NO_ACKC6:
275 pmu_irq_stats[pmu_ics.bits.cause]++;
276 break;
277 default:
278 pmu_irq_stats[INT_INVALID]++;
279 }
280
281 pmu_write_ics(pmu_ics.value); /* Clear pending interrupt */
282
283 return IRQ_HANDLED;
284}
285
286/*
287 * Translate PCI power management to MRST LSS D-states
288 */
289static int pci_2_mrst_state(int lss, pci_power_t pci_state)
290{
291 switch (pci_state) {
292 case PCI_D0:
293 if (SSMSK(D0i1, lss) & D0I1_ACG_SSS_TARGET)
294 return D0i1;
295 else
296 return D0;
297 case PCI_D1:
298 return D0i1;
299 case PCI_D2:
300 return D0i2;
301 case PCI_D3hot:
302 case PCI_D3cold:
303 return D0i3;
304 default:
305 WARN(1, "pci_state %d\n", pci_state);
306 return 0;
307 }
308}
309
310static int pmu_issue_command(u32 pm_ssc)
311{
312 union pmu_pm_set_cfg_cmd_t command;
313
314 if (pmu_read_busy_status()) {
315 pr_debug("pmu is busy, Operation not permitted\n");
316 return -1;
317 }
318
319 /*
320 * enable interrupts in PMU so that interrupts are
321 * propagated when ioc bit for a particular set
322 * command is set
323 */
324
325 pmu_irq_enable();
326
327 /* Configure the sub systems for pmu2 */
328
329 pmu_write_ssc(pm_ssc);
330
331 /*
332 * Send the set config command for pmu its configured
333 * for mode CM_IMMEDIATE & hence with No Trigger
334 */
335
336 command.pmu2_params.d_param.cfg_mode = CM_IMMEDIATE;
337 command.pmu2_params.d_param.cfg_delay = 0;
338 command.pmu2_params.d_param.rsvd = 0;
339
340 /* construct the command to send SET_CFG to particular PMU */
341 command.pmu2_params.d_param.cmd = SET_CFG_CMD;
342 command.pmu2_params.d_param.ioc = 0;
343 command.pmu2_params.d_param.mode_id = 0;
344 command.pmu2_params.d_param.sys_state = SYS_STATE_S0I0;
345
346 /* write the value of PM_CMD into particular PMU */
347 pr_debug("pmu command being written %x\n",
348 command.pmu_pm_set_cfg_cmd_value);
349
350 pmu_write_cmd(command.pmu_pm_set_cfg_cmd_value);
351
352 return 0;
353}
354
355static u16 pmu_min_lss_pci_req(u16 *ids, u16 pci_state)
356{
357 u16 existing_request;
358 int i;
359
360 for (i = 0; ids[i]; ++i) {
361 struct mrst_device *mrst_dev;
362
363 mrst_dev = pci_id_2_mrst_dev(ids[i]);
364 if (unlikely(!mrst_dev))
365 continue;
366
367 existing_request = mrst_dev->latest_request;
368 if (existing_request < pci_state)
369 pci_state = existing_request;
370 }
371 return pci_state;
372}
373
374/**
375 * pmu_pci_set_power_state - Callback function is used by all the PCI devices
376 * for a platform specific device power on/shutdown.
377 */
378
379int pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t pci_state)
380{
381 u32 old_sss, new_sss;
382 int status = 0;
383 struct mrst_device *mrst_dev;
384
385 pmu_set_power_state_entry++;
386
387 BUG_ON(pdev->vendor != PCI_VENDOR_ID_INTEL);
388 BUG_ON(pci_state < PCI_D0 || pci_state > PCI_D3cold);
389
390 mrst_dev = pci_id_2_mrst_dev(pdev->device);
391 if (unlikely(!mrst_dev))
392 return -ENODEV;
393
394 mrst_dev->pci_state_counts[pci_state]++; /* count invocations */
395
396 /* PMU driver calls self as part of PCI initialization, ignore */
397 if (pdev->device == PCI_DEV_ID_MRST_PMU)
398 return 0;
399
400 BUG_ON(!pmu_reg); /* SW bug if called before initialized */
401
402 spin_lock(&mrst_pmu_power_state_lock);
403
404 if (pdev->d3_delay) {
405 dev_dbg(&pdev->dev, "d3_delay %d, should be 0\n",
406 pdev->d3_delay);
407 pdev->d3_delay = 0;
408 }
409 /*
410 * If Lincroft graphics, simply remember state
411 */
412 if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY
413 && !((pdev->class & PCI_SUB_CLASS_MASK) >> 8)) {
414 if (pci_state == PCI_D0)
415 graphics_is_off = 0;
416 else
417 graphics_is_off = 1;
418 goto ret;
419 }
420
421 if (!mrst_dev->lss)
422 goto ret; /* device with no LSS */
423
424 if (mrst_dev->latest_request == pci_state)
425 goto ret; /* no change */
426
427 mrst_dev->latest_request = pci_state; /* record latest request */
428
429 /*
430 * LSS9 and LSS10 contain multiple PCI devices.
431 * Use the lowest numbered (highest power) state in the LSS
432 */
433 if (mrst_dev->lss == 9)
434 pci_state = pmu_min_lss_pci_req(mrst_lss9_pci_ids, pci_state);
435 else if (mrst_dev->lss == 10)
436 pci_state = pmu_min_lss_pci_req(mrst_lss10_pci_ids, pci_state);
437
438 status = pmu_wait_ready();
439 if (status)
440 goto ret;
441
442 old_sss = pmu_read_sss();
443 new_sss = old_sss & ~SSMSK(3, mrst_dev->lss);
444 new_sss |= SSMSK(pci_2_mrst_state(mrst_dev->lss, pci_state),
445 mrst_dev->lss);
446
447 if (new_sss == old_sss)
448 goto ret; /* nothing to do */
449
450 pmu_set_power_state_send_cmd++;
451
452 status = pmu_issue_command(new_sss);
453
454 if (unlikely(status != 0)) {
455 dev_err(&pdev->dev, "Failed to Issue a PM command\n");
456 goto ret;
457 }
458
459 if (pmu_wait_done())
460 goto ret;
461
462 lss_s0i3_enabled =
463 ((pmu_read_sss() & S0I3_SSS_TARGET) == S0I3_SSS_TARGET);
464ret:
465 spin_unlock(&mrst_pmu_power_state_lock);
466 return status;
467}
468
469#ifdef CONFIG_DEBUG_FS
470static char *d0ix_names[] = {"D0", "D0i1", "D0i2", "D0i3"};
471
472static inline const char *d0ix_name(int state)
473{
474 return d0ix_names[(int) state];
475}
476
477static int debug_mrst_pmu_show(struct seq_file *s, void *unused)
478{
479 struct pci_dev *pdev = NULL;
480 u32 cur_pmsss;
481 int lss;
482
483 seq_printf(s, "0x%08X D0I1_ACG_SSS_TARGET\n", D0I1_ACG_SSS_TARGET);
484
485 cur_pmsss = pmu_read_sss();
486
487 seq_printf(s, "0x%08X S0I3_SSS_TARGET\n", S0I3_SSS_TARGET);
488
489 seq_printf(s, "0x%08X Current SSS ", cur_pmsss);
490 seq_printf(s, lss_s0i3_enabled ? "\n" : "[BLOCKS s0i3]\n");
491
492 if (cpumask_equal(cpu_online_mask, cpumask_of(0)))
493 seq_printf(s, "cpu0 is only cpu online\n");
494 else
495 seq_printf(s, "cpu0 is NOT only cpu online [BLOCKS S0i3]\n");
496
497 seq_printf(s, "GFX: %s\n", graphics_is_off ? "" : "[BLOCKS s0i3]");
498
499
500 for_each_pci_dev(pdev) {
501 int pos;
502 u16 pmcsr;
503 struct mrst_device *mrst_dev;
504 int i;
505
506 mrst_dev = pci_id_2_mrst_dev(pdev->device);
507
508 seq_printf(s, "%s %04x/%04X %-16.16s ",
509 dev_name(&pdev->dev),
510 pdev->vendor, pdev->device,
511 dev_driver_string(&pdev->dev));
512
513 if (unlikely (!mrst_dev)) {
514 seq_printf(s, " UNKNOWN\n");
515 continue;
516 }
517
518 if (mrst_dev->lss)
519 seq_printf(s, "LSS %2d %-4s ", mrst_dev->lss,
520 d0ix_name(((cur_pmsss >>
521 (mrst_dev->lss * 2)) & 0x3)));
522 else
523 seq_printf(s, " ");
524
525 /* PCI PM config space setting */
526 pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
527 if (pos != 0) {
528 pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
529 seq_printf(s, "PCI-%-4s",
530 pci_power_name(pmcsr & PCI_PM_CTRL_STATE_MASK));
531 } else {
532 seq_printf(s, " ");
533 }
534
535 seq_printf(s, " %s ", pci_power_name(mrst_dev->latest_request));
536 for (i = 0; i <= PCI_D3cold; ++i)
537 seq_printf(s, "%d ", mrst_dev->pci_state_counts[i]);
538
539 if (mrst_dev->lss) {
540 unsigned int lssmask;
541
542 lssmask = SSMSK(D0i3, mrst_dev->lss);
543
544 if ((lssmask & S0I3_SSS_TARGET) &&
545 ((lssmask & cur_pmsss) !=
546 (lssmask & S0I3_SSS_TARGET)))
547 seq_printf(s , "[BLOCKS s0i3]");
548 }
549
550 seq_printf(s, "\n");
551 }
552 seq_printf(s, "Wake Counters:\n");
553 for (lss = 0; lss < MRST_NUM_LSS; ++lss)
554 seq_printf(s, "LSS%d %d\n", lss, wake_counters[lss]);
555
556 seq_printf(s, "Interrupt Counters:\n");
557 seq_printf(s,
558 "INT_SPURIOUS \t%8u\n" "INT_CMD_DONE \t%8u\n"
559 "INT_CMD_ERR \t%8u\n" "INT_WAKE_RX \t%8u\n"
560 "INT_SS_ERROR \t%8u\n" "INT_S0IX_MISS\t%8u\n"
561 "INT_NO_ACKC6 \t%8u\n" "INT_INVALID \t%8u\n",
562 pmu_irq_stats[INT_SPURIOUS], pmu_irq_stats[INT_CMD_DONE],
563 pmu_irq_stats[INT_CMD_ERR], pmu_irq_stats[INT_WAKE_RX],
564 pmu_irq_stats[INT_SS_ERROR], pmu_irq_stats[INT_S0IX_MISS],
565 pmu_irq_stats[INT_NO_ACKC6], pmu_irq_stats[INT_INVALID]);
566
567 seq_printf(s, "mrst_pmu_wait_ready_calls %8d\n",
568 pmu_wait_ready_calls);
569 seq_printf(s, "mrst_pmu_wait_ready_udelays %8d\n",
570 pmu_wait_ready_udelays);
571 seq_printf(s, "mrst_pmu_wait_ready_udelays_max %8d\n",
572 pmu_wait_ready_udelays_max);
573 seq_printf(s, "mrst_pmu_wait_done_calls %8d\n",
574 pmu_wait_done_calls);
575 seq_printf(s, "mrst_pmu_wait_done_udelays %8d\n",
576 pmu_wait_done_udelays);
577 seq_printf(s, "mrst_pmu_wait_done_udelays_max %8d\n",
578 pmu_wait_done_udelays_max);
579 seq_printf(s, "mrst_pmu_set_power_state_entry %8d\n",
580 pmu_set_power_state_entry);
581 seq_printf(s, "mrst_pmu_set_power_state_send_cmd %8d\n",
582 pmu_set_power_state_send_cmd);
583 seq_printf(s, "SCU busy: %d\n", pmu_read_busy_status());
584
585 return 0;
586}
587
588static int debug_mrst_pmu_open(struct inode *inode, struct file *file)
589{
590 return single_open(file, debug_mrst_pmu_show, NULL);
591}
592
593static const struct file_operations devices_state_operations = {
594 .open = debug_mrst_pmu_open,
595 .read = seq_read,
596 .llseek = seq_lseek,
597 .release = single_release,
598};
599#endif /* DEBUG_FS */
600
601/*
602 * Validate SCU PCI shim PCI vendor capability byte
603 * against LSS hard-coded in mrst_devs[] above.
604 * DEBUG only.
605 */
606static void pmu_scu_firmware_debug(void)
607{
608 struct pci_dev *pdev = NULL;
609
610 for_each_pci_dev(pdev) {
611 struct mrst_device *mrst_dev;
612 u8 pci_config_lss;
613 int pos;
614
615 mrst_dev = pci_id_2_mrst_dev(pdev->device);
616 if (unlikely(!mrst_dev)) {
617 printk(KERN_ERR FW_BUG "pmu: Unknown "
618 "PCI device 0x%04X\n", pdev->device);
619 continue;
620 }
621
622 if (mrst_dev->lss == 0)
623 continue; /* no LSS in our table */
624
625 pos = pci_find_capability(pdev, PCI_CAP_ID_VNDR);
626 if (!pos != 0) {
627 printk(KERN_ERR FW_BUG "pmu: 0x%04X "
628 "missing PCI Vendor Capability\n",
629 pdev->device);
630 continue;
631 }
632 pci_read_config_byte(pdev, pos + 4, &pci_config_lss);
633 if (!(pci_config_lss & PCI_VENDOR_CAP_LOG_SS_MASK)) {
634 printk(KERN_ERR FW_BUG "pmu: 0x%04X "
635 "invalid PCI Vendor Capability 0x%x "
636 " expected LSS 0x%X\n",
637 pdev->device, pci_config_lss, mrst_dev->lss);
638 continue;
639 }
640 pci_config_lss &= PCI_VENDOR_CAP_LOG_ID_MASK;
641
642 if (mrst_dev->lss == pci_config_lss)
643 continue;
644
645 printk(KERN_ERR FW_BUG "pmu: 0x%04X LSS = %d, expected %d\n",
646 pdev->device, pci_config_lss, mrst_dev->lss);
647 }
648}
649
650/**
651 * pmu_probe
652 */
653static int __devinit pmu_probe(struct pci_dev *pdev,
654 const struct pci_device_id *pci_id)
655{
656 int ret;
657 struct mrst_pmu_reg *pmu;
658
659 /* Init the device */
660 ret = pci_enable_device(pdev);
661 if (ret) {
662 dev_err(&pdev->dev, "Unable to Enable PCI device\n");
663 return ret;
664 }
665
666 ret = pci_request_regions(pdev, MRST_PMU_DRV_NAME);
667 if (ret < 0) {
668 dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
669 goto out_err1;
670 }
671
672 /* Map the memory of PMU reg base */
673 pmu = pci_iomap(pdev, 0, 0);
674 if (!pmu) {
675 dev_err(&pdev->dev, "Unable to map the PMU address space\n");
676 ret = -ENOMEM;
677 goto out_err2;
678 }
679
680#ifdef CONFIG_DEBUG_FS
681 /* /sys/kernel/debug/mrst_pmu */
682 (void) debugfs_create_file("mrst_pmu", S_IFREG | S_IRUGO,
683 NULL, NULL, &devices_state_operations);
684#endif
685 pmu_reg = pmu; /* success */
686
687 if (request_irq(pdev->irq, pmu_irq, 0, MRST_PMU_DRV_NAME, NULL)) {
688 dev_err(&pdev->dev, "Registering isr has failed\n");
689 ret = -1;
690 goto out_err3;
691 }
692
693 pmu_scu_firmware_debug();
694
695 pmu_write_wkc(S0I3_WAKE_SOURCES); /* Enable S0i3 wakeup sources */
696
697 pmu_wait_ready();
698
699 pmu_write_ssc(D0I1_ACG_SSS_TARGET); /* Enable Auto-Clock_Gating */
700 pmu_write_cmd(0x201);
701
702 spin_lock_init(&mrst_pmu_power_state_lock);
703
704 /* Enable the hardware interrupt */
705 pmu_irq_enable();
706 return 0;
707
708out_err3:
709 free_irq(pdev->irq, NULL);
710 pci_iounmap(pdev, pmu_reg);
711 pmu_reg = NULL;
712out_err2:
713 pci_release_region(pdev, 0);
714out_err1:
715 pci_disable_device(pdev);
716 return ret;
717}
718
719static void __devexit pmu_remove(struct pci_dev *pdev)
720{
721 dev_err(&pdev->dev, "Mid PM pmu_remove called\n");
722
723 /* Freeing up the irq */
724 free_irq(pdev->irq, NULL);
725
726 pci_iounmap(pdev, pmu_reg);
727 pmu_reg = NULL;
728
729 /* disable the current PCI device */
730 pci_release_region(pdev, 0);
731 pci_disable_device(pdev);
732}
733
734static DEFINE_PCI_DEVICE_TABLE(pmu_pci_ids) = {
735 { PCI_VDEVICE(INTEL, PCI_DEV_ID_MRST_PMU), 0 },
736 { }
737};
738
739MODULE_DEVICE_TABLE(pci, pmu_pci_ids);
740
741static struct pci_driver driver = {
742 .name = MRST_PMU_DRV_NAME,
743 .id_table = pmu_pci_ids,
744 .probe = pmu_probe,
745 .remove = __devexit_p(pmu_remove),
746};
747
748/**
749 * pmu_pci_register - register the PMU driver as PCI device
750 */
751static int __init pmu_pci_register(void)
752{
753 return pci_register_driver(&driver);
754}
755
756/* Register and probe via fs_initcall() to preceed device_initcall() */
757fs_initcall(pmu_pci_register);
758
759static void __exit mid_pci_cleanup(void)
760{
761 pci_unregister_driver(&driver);
762}
763
764static int ia_major;
765static int ia_minor;
766
767static int pmu_sfi_parse_oem(struct sfi_table_header *table)
768{
769 struct sfi_table_simple *sb;
770
771 sb = (struct sfi_table_simple *)table;
772 ia_major = (sb->pentry[1] >> 0) & 0xFFFF;
773 ia_minor = (sb->pentry[1] >> 16) & 0xFFFF;
774 printk(KERN_INFO "mrst_pmu: IA FW version v%x.%x\n",
775 ia_major, ia_minor);
776
777 return 0;
778}
779
780static int __init scu_fw_check(void)
781{
782 int ret;
783 u32 fw_version;
784
785 if (!pmu_reg)
786 return 0; /* this driver didn't probe-out */
787
788 sfi_table_parse("OEMB", NULL, NULL, pmu_sfi_parse_oem);
789
790 if (ia_major < 0x6005 || ia_minor < 0x1525) {
791 WARN(1, "mrst_pmu: IA FW version too old\n");
792 return -1;
793 }
794
795 ret = intel_scu_ipc_command(IPCMSG_FW_REVISION, 0, NULL, 0,
796 &fw_version, 1);
797
798 if (ret) {
799 WARN(1, "mrst_pmu: IPC FW version? %d\n", ret);
800 } else {
801 int scu_major = (fw_version >> 8) & 0xFF;
802 int scu_minor = (fw_version >> 0) & 0xFF;
803
804 printk(KERN_INFO "mrst_pmu: firmware v%x\n", fw_version);
805
806 if ((scu_major >= 0xC0) && (scu_minor >= 0x49)) {
807 printk(KERN_INFO "mrst_pmu: enabling S0i3\n");
808 mrst_pmu_s0i3_enable = true;
809 } else {
810 WARN(1, "mrst_pmu: S0i3 disabled, old firmware %X.%X",
811 scu_major, scu_minor);
812 }
813 }
814 return 0;
815}
816late_initcall(scu_fw_check);
817module_exit(mid_pci_cleanup);
diff --git a/arch/x86/platform/mrst/pmu.h b/arch/x86/platform/mrst/pmu.h
new file mode 100644
index 000000000000..bfbfe64b167b
--- /dev/null
+++ b/arch/x86/platform/mrst/pmu.h
@@ -0,0 +1,234 @@
1/*
2 * mrst/pmu.h - private definitions for MRST Power Management Unit mrst/pmu.c
3 *
4 * Copyright (c) 2011, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifndef _MRST_PMU_H_
21#define _MRST_PMU_H_
22
23#define PCI_DEV_ID_MRST_PMU 0x0810
24#define MRST_PMU_DRV_NAME "mrst_pmu"
25#define PCI_SUB_CLASS_MASK 0xFF00
26
27#define PCI_VENDOR_CAP_LOG_ID_MASK 0x7F
28#define PCI_VENDOR_CAP_LOG_SS_MASK 0x80
29
30#define SUB_SYS_ALL_D0I1 0x01155555
31#define S0I3_WAKE_SOURCES 0x00001FFF
32
33#define PM_S0I3_COMMAND \
34 ((0 << 31) | /* Reserved */ \
35 (0 << 30) | /* Core must be idle */ \
36 (0xc2 << 22) | /* ACK C6 trigger */ \
37 (3 << 19) | /* Trigger on DMI message */ \
38 (3 << 16) | /* Enter S0i3 */ \
39 (0 << 13) | /* Numeric mode ID (sw) */ \
40 (3 << 9) | /* Trigger mode */ \
41 (0 << 8) | /* Do not interrupt */ \
42 (1 << 0)) /* Set configuration */
43
44#define LSS_DMI 0
45#define LSS_SD_HC0 1
46#define LSS_SD_HC1 2
47#define LSS_NAND 3
48#define LSS_IMAGING 4
49#define LSS_SECURITY 5
50#define LSS_DISPLAY 6
51#define LSS_USB_HC 7
52#define LSS_USB_OTG 8
53#define LSS_AUDIO 9
54#define LSS_AUDIO_LPE 9
55#define LSS_AUDIO_SSP 9
56#define LSS_I2C0 10
57#define LSS_I2C1 10
58#define LSS_I2C2 10
59#define LSS_KBD 10
60#define LSS_SPI0 10
61#define LSS_SPI1 10
62#define LSS_SPI2 10
63#define LSS_GPIO 10
64#define LSS_SRAM 11 /* used by SCU, do not touch */
65#define LSS_SD_HC2 12
66/* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */
67#define MRST_NUM_LSS 13
68
69#define MIN(a, b) (((a) < (b)) ? (a) : (b))
70
71#define SSMSK(mask, lss) ((mask) << ((lss) * 2))
72#define D0 0
73#define D0i1 1
74#define D0i2 2
75#define D0i3 3
76
77#define S0I3_SSS_TARGET ( \
78 SSMSK(D0i1, LSS_DMI) | \
79 SSMSK(D0i3, LSS_SD_HC0) | \
80 SSMSK(D0i3, LSS_SD_HC1) | \
81 SSMSK(D0i3, LSS_NAND) | \
82 SSMSK(D0i3, LSS_SD_HC2) | \
83 SSMSK(D0i3, LSS_IMAGING) | \
84 SSMSK(D0i3, LSS_SECURITY) | \
85 SSMSK(D0i3, LSS_DISPLAY) | \
86 SSMSK(D0i3, LSS_USB_HC) | \
87 SSMSK(D0i3, LSS_USB_OTG) | \
88 SSMSK(D0i3, LSS_AUDIO) | \
89 SSMSK(D0i1, LSS_I2C0))
90
91/*
92 * D0i1 on Langwell is Autonomous Clock Gating (ACG).
93 * Enable ACG on every LSS except camera and audio
94 */
95#define D0I1_ACG_SSS_TARGET \
96 (SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO))
97
98enum cm_mode {
99 CM_NOP, /* ignore the config mode value */
100 CM_IMMEDIATE,
101 CM_DELAY,
102 CM_TRIGGER,
103 CM_INVALID
104};
105
106enum sys_state {
107 SYS_STATE_S0I0,
108 SYS_STATE_S0I1,
109 SYS_STATE_S0I2,
110 SYS_STATE_S0I3,
111 SYS_STATE_S3,
112 SYS_STATE_S5
113};
114
115#define SET_CFG_CMD 1
116
117enum int_status {
118 INT_SPURIOUS = 0,
119 INT_CMD_DONE = 1,
120 INT_CMD_ERR = 2,
121 INT_WAKE_RX = 3,
122 INT_SS_ERROR = 4,
123 INT_S0IX_MISS = 5,
124 INT_NO_ACKC6 = 6,
125 INT_INVALID = 7,
126};
127
128/* PMU register interface */
129static struct mrst_pmu_reg {
130 u32 pm_sts; /* 0x00 */
131 u32 pm_cmd; /* 0x04 */
132 u32 pm_ics; /* 0x08 */
133 u32 _resv1; /* 0x0C */
134 u32 pm_wkc[2]; /* 0x10 */
135 u32 pm_wks[2]; /* 0x18 */
136 u32 pm_ssc[4]; /* 0x20 */
137 u32 pm_sss[4]; /* 0x30 */
138 u32 pm_wssc[4]; /* 0x40 */
139 u32 pm_c3c4; /* 0x50 */
140 u32 pm_c5c6; /* 0x54 */
141 u32 pm_msi_disable; /* 0x58 */
142} *pmu_reg;
143
144static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); }
145static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); }
146static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); }
147static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); }
148
149static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); }
150static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); }
151static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); }
152static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); }
153static inline void pmu_write_wssc(u32 arg)
154 { writel(arg, &pmu_reg->pm_wssc[0]); }
155
156static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); }
157static inline u32 pmu_msi_is_disabled(void)
158 { return readl(&pmu_reg->pm_msi_disable); }
159
160union pmu_pm_ics {
161 struct {
162 u32 cause:8;
163 u32 enable:1;
164 u32 pending:1;
165 u32 reserved:22;
166 } bits;
167 u32 value;
168};
169
170static inline void pmu_irq_enable(void)
171{
172 union pmu_pm_ics pmu_ics;
173
174 pmu_ics.value = pmu_read_ics();
175 pmu_ics.bits.enable = 1;
176 pmu_write_ics(pmu_ics.value);
177}
178
179union pmu_pm_status {
180 struct {
181 u32 pmu_rev:8;
182 u32 pmu_busy:1;
183 u32 mode_id:4;
184 u32 Reserved:19;
185 } pmu_status_parts;
186 u32 pmu_status_value;
187};
188
189static inline int pmu_read_busy_status(void)
190{
191 union pmu_pm_status result;
192
193 result.pmu_status_value = pmu_read_sts();
194
195 return result.pmu_status_parts.pmu_busy;
196}
197
198/* pmu set config parameters */
199struct cfg_delay_param_t {
200 u32 cmd:8;
201 u32 ioc:1;
202 u32 cfg_mode:4;
203 u32 mode_id:3;
204 u32 sys_state:3;
205 u32 cfg_delay:8;
206 u32 rsvd:5;
207};
208
209struct cfg_trig_param_t {
210 u32 cmd:8;
211 u32 ioc:1;
212 u32 cfg_mode:4;
213 u32 mode_id:3;
214 u32 sys_state:3;
215 u32 cfg_trig_type:3;
216 u32 cfg_trig_val:8;
217 u32 cmbi:1;
218 u32 rsvd1:1;
219};
220
221union pmu_pm_set_cfg_cmd_t {
222 union {
223 struct cfg_delay_param_t d_param;
224 struct cfg_trig_param_t t_param;
225 } pmu2_params;
226 u32 pmu_pm_set_cfg_cmd_value;
227};
228
229#ifdef FUTURE_PATCH
230extern int mrst_s0i3_entry(u32 regval, u32 *regaddr);
231#else
232static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; }
233#endif
234#endif
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
index 45e94aca5bce..3326204e251f 100644
--- a/arch/x86/xen/Makefile
+++ b/arch/x86/xen/Makefile
@@ -15,7 +15,7 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
15 grant-table.o suspend.o platform-pci-unplug.o \ 15 grant-table.o suspend.o platform-pci-unplug.o \
16 p2m.o 16 p2m.o
17 17
18obj-$(CONFIG_FUNCTION_TRACER) += trace.o 18obj-$(CONFIG_FTRACE) += trace.o
19 19
20obj-$(CONFIG_SMP) += smp.o 20obj-$(CONFIG_SMP) += smp.o
21obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o 21obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 60aeeb56948f..df118a825f39 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -9,6 +9,7 @@
9#include <linux/mm.h> 9#include <linux/mm.h>
10#include <linux/pm.h> 10#include <linux/pm.h>
11#include <linux/memblock.h> 11#include <linux/memblock.h>
12#include <linux/cpuidle.h>
12 13
13#include <asm/elf.h> 14#include <asm/elf.h>
14#include <asm/vdso.h> 15#include <asm/vdso.h>
@@ -92,8 +93,6 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr,
92 if (end <= start) 93 if (end <= start)
93 return 0; 94 return 0;
94 95
95 printk(KERN_INFO "xen_release_chunk: looking at area pfn %lx-%lx: ",
96 start, end);
97 for(pfn = start; pfn < end; pfn++) { 96 for(pfn = start; pfn < end; pfn++) {
98 unsigned long mfn = pfn_to_mfn(pfn); 97 unsigned long mfn = pfn_to_mfn(pfn);
99 98
@@ -106,14 +105,14 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr,
106 105
107 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 106 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
108 &reservation); 107 &reservation);
109 WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n", 108 WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret);
110 start, end, ret);
111 if (ret == 1) { 109 if (ret == 1) {
112 __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); 110 __set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
113 len++; 111 len++;
114 } 112 }
115 } 113 }
116 printk(KERN_CONT "%ld pages freed\n", len); 114 printk(KERN_INFO "Freeing %lx-%lx pfn range: %lu pages freed\n",
115 start, end, len);
117 116
118 return len; 117 return len;
119} 118}
@@ -139,7 +138,7 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
139 if (last_end < max_addr) 138 if (last_end < max_addr)
140 released += xen_release_chunk(last_end, max_addr); 139 released += xen_release_chunk(last_end, max_addr);
141 140
142 printk(KERN_INFO "released %ld pages of unused memory\n", released); 141 printk(KERN_INFO "released %lu pages of unused memory\n", released);
143 return released; 142 return released;
144} 143}
145 144
@@ -426,7 +425,7 @@ void __init xen_arch_setup(void)
426#ifdef CONFIG_X86_32 425#ifdef CONFIG_X86_32
427 boot_cpu_data.hlt_works_ok = 1; 426 boot_cpu_data.hlt_works_ok = 1;
428#endif 427#endif
429 pm_idle = default_idle; 428 disable_cpuidle();
430 boot_option_idle_override = IDLE_HALT; 429 boot_option_idle_override = IDLE_HALT;
431 430
432 fiddle_vdso(); 431 fiddle_vdso();
diff --git a/arch/x86/xen/trace.c b/arch/x86/xen/trace.c
index 734beba2a08c..520022d1a181 100644
--- a/arch/x86/xen/trace.c
+++ b/arch/x86/xen/trace.c
@@ -1,4 +1,5 @@
1#include <linux/ftrace.h> 1#include <linux/ftrace.h>
2#include <xen/interface/xen.h>
2 3
3#define N(x) [__HYPERVISOR_##x] = "("#x")" 4#define N(x) [__HYPERVISOR_##x] = "("#x")"
4static const char *xen_hypercall_names[] = { 5static const char *xen_hypercall_names[] = {