aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2010-05-22 02:36:56 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-05-22 02:36:56 -0400
commitcf9b59e9d3e008591d1f54830f570982bb307a0d (patch)
tree113478ce8fd8c832ba726ffdf59b82cb46356476 /arch/sparc
parent44504b2bebf8b5823c59484e73096a7d6574471d (diff)
parentf4b87dee923342505e1ddba8d34ce9de33e75050 (diff)
Merge remote branch 'origin' into secretlab/next-devicetree
Merging in current state of Linus' tree to deal with merge conflicts and build failures in vio.c after merge. Conflicts: drivers/i2c/busses/i2c-cpm.c drivers/i2c/busses/i2c-mpc.c drivers/net/gianfar.c Also fixed up one line in arch/powerpc/kernel/vio.c to use the correct node pointer. Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/include/asm/atomic_32.h2
-rw-r--r--arch/sparc/include/asm/atomic_64.h4
-rw-r--r--arch/sparc/include/asm/bitops_64.h11
-rw-r--r--arch/sparc/include/asm/cache.h2
-rw-r--r--arch/sparc/include/asm/thread_info_32.h2
-rw-r--r--arch/sparc/include/asm/thread_info_64.h4
-rw-r--r--arch/sparc/kernel/irq_64.c20
-rw-r--r--arch/sparc/kernel/kgdb_32.c6
-rw-r--r--arch/sparc/kernel/kgdb_64.c6
-rw-r--r--arch/sparc/kernel/kstack.h19
-rw-r--r--arch/sparc/kernel/nmi.c7
-rw-r--r--arch/sparc/kernel/perf_event.c14
-rw-r--r--arch/sparc/kernel/process_64.c1
-rw-r--r--arch/sparc/kernel/rtrap_64.S12
-rw-r--r--arch/sparc/kernel/stacktrace.c23
-rw-r--r--arch/sparc/kernel/time_32.c18
-rw-r--r--arch/sparc/kernel/traps_64.c14
-rw-r--r--arch/sparc/kernel/unaligned_64.c6
-rw-r--r--arch/sparc/lib/mcount.S8
20 files changed, 129 insertions, 52 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 9908d477ccd9..d6781ce687e2 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -75,7 +75,7 @@ config ARCH_USES_GETTIMEOFFSET
75 75
76config GENERIC_CMOS_UPDATE 76config GENERIC_CMOS_UPDATE
77 bool 77 bool
78 default y if SPARC64 78 default y
79 79
80config GENERIC_CLOCKEVENTS 80config GENERIC_CLOCKEVENTS
81 bool 81 bool
diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h
index f0d343c3b956..7ae128b19d3f 100644
--- a/arch/sparc/include/asm/atomic_32.h
+++ b/arch/sparc/include/asm/atomic_32.h
@@ -25,7 +25,7 @@ extern int atomic_cmpxchg(atomic_t *, int, int);
25extern int atomic_add_unless(atomic_t *, int, int); 25extern int atomic_add_unless(atomic_t *, int, int);
26extern void atomic_set(atomic_t *, int); 26extern void atomic_set(atomic_t *, int);
27 27
28#define atomic_read(v) ((v)->counter) 28#define atomic_read(v) (*(volatile int *)&(v)->counter)
29 29
30#define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v))) 30#define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v)))
31#define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v))) 31#define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v)))
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index f2e48009989e..2050ca02c423 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -13,8 +13,8 @@
13#define ATOMIC_INIT(i) { (i) } 13#define ATOMIC_INIT(i) { (i) }
14#define ATOMIC64_INIT(i) { (i) } 14#define ATOMIC64_INIT(i) { (i) }
15 15
16#define atomic_read(v) ((v)->counter) 16#define atomic_read(v) (*(volatile int *)&(v)->counter)
17#define atomic64_read(v) ((v)->counter) 17#define atomic64_read(v) (*(volatile long *)&(v)->counter)
18 18
19#define atomic_set(v, i) (((v)->counter) = i) 19#define atomic_set(v, i) (((v)->counter) = i)
20#define atomic64_set(v, i) (((v)->counter) = i) 20#define atomic64_set(v, i) (((v)->counter) = i)
diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h
index e72ac9cdfb98..766121a67a24 100644
--- a/arch/sparc/include/asm/bitops_64.h
+++ b/arch/sparc/include/asm/bitops_64.h
@@ -44,7 +44,7 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr);
44 44
45#ifdef ULTRA_HAS_POPULATION_COUNT 45#ifdef ULTRA_HAS_POPULATION_COUNT
46 46
47static inline unsigned int hweight64(unsigned long w) 47static inline unsigned int __arch_hweight64(unsigned long w)
48{ 48{
49 unsigned int res; 49 unsigned int res;
50 50
@@ -52,7 +52,7 @@ static inline unsigned int hweight64(unsigned long w)
52 return res; 52 return res;
53} 53}
54 54
55static inline unsigned int hweight32(unsigned int w) 55static inline unsigned int __arch_hweight32(unsigned int w)
56{ 56{
57 unsigned int res; 57 unsigned int res;
58 58
@@ -60,7 +60,7 @@ static inline unsigned int hweight32(unsigned int w)
60 return res; 60 return res;
61} 61}
62 62
63static inline unsigned int hweight16(unsigned int w) 63static inline unsigned int __arch_hweight16(unsigned int w)
64{ 64{
65 unsigned int res; 65 unsigned int res;
66 66
@@ -68,7 +68,7 @@ static inline unsigned int hweight16(unsigned int w)
68 return res; 68 return res;
69} 69}
70 70
71static inline unsigned int hweight8(unsigned int w) 71static inline unsigned int __arch_hweight8(unsigned int w)
72{ 72{
73 unsigned int res; 73 unsigned int res;
74 74
@@ -78,9 +78,10 @@ static inline unsigned int hweight8(unsigned int w)
78 78
79#else 79#else
80 80
81#include <asm-generic/bitops/hweight.h> 81#include <asm-generic/bitops/arch_hweight.h>
82 82
83#endif 83#endif
84#include <asm-generic/bitops/const_hweight.h>
84#include <asm-generic/bitops/lock.h> 85#include <asm-generic/bitops/lock.h>
85#endif /* __KERNEL__ */ 86#endif /* __KERNEL__ */
86 87
diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h
index 41f85ae4bd4a..78b07009f60a 100644
--- a/arch/sparc/include/asm/cache.h
+++ b/arch/sparc/include/asm/cache.h
@@ -7,6 +7,8 @@
7#ifndef _SPARC_CACHE_H 7#ifndef _SPARC_CACHE_H
8#define _SPARC_CACHE_H 8#define _SPARC_CACHE_H
9 9
10#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
11
10#define L1_CACHE_SHIFT 5 12#define L1_CACHE_SHIFT 5
11#define L1_CACHE_BYTES 32 13#define L1_CACHE_BYTES 32
12#define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))) 14#define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)))
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index 844d73a0340c..9dd0318d3ddf 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -132,7 +132,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
132 * this quantum (SMP) */ 132 * this quantum (SMP) */
133#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling 133#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling
134 * TIF_NEED_RESCHED */ 134 * TIF_NEED_RESCHED */
135#define TIF_MEMDIE 10 135#define TIF_MEMDIE 10 /* is terminating due to OOM killer */
136#define TIF_FREEZE 11 /* is freezing for suspend */ 136#define TIF_FREEZE 11 /* is freezing for suspend */
137 137
138/* as above, but as bit values */ 138/* as above, but as bit values */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index 9e2d9447f2ad..fb2ea7705a46 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -111,7 +111,7 @@ struct thread_info {
111#define THREAD_SHIFT PAGE_SHIFT 111#define THREAD_SHIFT PAGE_SHIFT
112#endif /* PAGE_SHIFT == 13 */ 112#endif /* PAGE_SHIFT == 13 */
113 113
114#define PREEMPT_ACTIVE 0x4000000 114#define PREEMPT_ACTIVE 0x10000000
115 115
116/* 116/*
117 * macros/functions for gaining access to the thread information structure 117 * macros/functions for gaining access to the thread information structure
@@ -223,7 +223,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
223 * an immediate value in instructions such as andcc. 223 * an immediate value in instructions such as andcc.
224 */ 224 */
225/* flag bit 12 is available */ 225/* flag bit 12 is available */
226#define TIF_MEMDIE 13 226#define TIF_MEMDIE 13 /* is terminating due to OOM killer */
227#define TIF_POLLING_NRFLAG 14 227#define TIF_POLLING_NRFLAG 14
228#define TIF_FREEZE 15 /* is freezing for suspend */ 228#define TIF_FREEZE 15 /* is freezing for suspend */
229 229
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 454ce3a25273..830d70a3e20b 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -22,6 +22,7 @@
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/ftrace.h> 23#include <linux/ftrace.h>
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/kmemleak.h>
25 26
26#include <asm/ptrace.h> 27#include <asm/ptrace.h>
27#include <asm/processor.h> 28#include <asm/processor.h>
@@ -46,6 +47,7 @@
46 47
47#include "entry.h" 48#include "entry.h"
48#include "cpumap.h" 49#include "cpumap.h"
50#include "kstack.h"
49 51
50#define NUM_IVECS (IMAP_INR + 1) 52#define NUM_IVECS (IMAP_INR + 1)
51 53
@@ -712,24 +714,6 @@ void ack_bad_irq(unsigned int virt_irq)
712void *hardirq_stack[NR_CPUS]; 714void *hardirq_stack[NR_CPUS];
713void *softirq_stack[NR_CPUS]; 715void *softirq_stack[NR_CPUS];
714 716
715static __attribute__((always_inline)) void *set_hardirq_stack(void)
716{
717 void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
718
719 __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
720 if (orig_sp < sp ||
721 orig_sp > (sp + THREAD_SIZE)) {
722 sp += THREAD_SIZE - 192 - STACK_BIAS;
723 __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
724 }
725
726 return orig_sp;
727}
728static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
729{
730 __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
731}
732
733void __irq_entry handler_irq(int irq, struct pt_regs *regs) 717void __irq_entry handler_irq(int irq, struct pt_regs *regs)
734{ 718{
735 unsigned long pstate, bucket_pa; 719 unsigned long pstate, bucket_pa;
diff --git a/arch/sparc/kernel/kgdb_32.c b/arch/sparc/kernel/kgdb_32.c
index 04df4edc0073..539243b236fa 100644
--- a/arch/sparc/kernel/kgdb_32.c
+++ b/arch/sparc/kernel/kgdb_32.c
@@ -158,6 +158,12 @@ void kgdb_arch_exit(void)
158{ 158{
159} 159}
160 160
161void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
162{
163 regs->pc = ip;
164 regs->npc = regs->pc + 4;
165}
166
161struct kgdb_arch arch_kgdb_ops = { 167struct kgdb_arch arch_kgdb_ops = {
162 /* Breakpoint instruction: ta 0x7d */ 168 /* Breakpoint instruction: ta 0x7d */
163 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x7d }, 169 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x7d },
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c
index 0a2bd0f99fc1..768290a6c028 100644
--- a/arch/sparc/kernel/kgdb_64.c
+++ b/arch/sparc/kernel/kgdb_64.c
@@ -181,6 +181,12 @@ void kgdb_arch_exit(void)
181{ 181{
182} 182}
183 183
184void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
185{
186 regs->tpc = ip;
187 regs->tnpc = regs->tpc + 4;
188}
189
184struct kgdb_arch arch_kgdb_ops = { 190struct kgdb_arch arch_kgdb_ops = {
185 /* Breakpoint instruction: ta 0x72 */ 191 /* Breakpoint instruction: ta 0x72 */
186 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x72 }, 192 .gdb_bpt_instr = { 0x91, 0xd0, 0x20, 0x72 },
diff --git a/arch/sparc/kernel/kstack.h b/arch/sparc/kernel/kstack.h
index 5247283d1c03..53dfb92e09fb 100644
--- a/arch/sparc/kernel/kstack.h
+++ b/arch/sparc/kernel/kstack.h
@@ -61,4 +61,23 @@ check_magic:
61 61
62} 62}
63 63
64static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
65{
66 void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
67
68 __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
69 if (orig_sp < sp ||
70 orig_sp > (sp + THREAD_SIZE)) {
71 sp += THREAD_SIZE - 192 - STACK_BIAS;
72 __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
73 }
74
75 return orig_sp;
76}
77
78static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
79{
80 __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
81}
82
64#endif /* _KSTACK_H */ 83#endif /* _KSTACK_H */
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index 75a3d1a25356..a4bd7ba74c89 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -23,6 +23,8 @@
23#include <asm/ptrace.h> 23#include <asm/ptrace.h>
24#include <asm/pcr.h> 24#include <asm/pcr.h>
25 25
26#include "kstack.h"
27
26/* We don't have a real NMI on sparc64, but we can fake one 28/* We don't have a real NMI on sparc64, but we can fake one
27 * up using profiling counter overflow interrupts and interrupt 29 * up using profiling counter overflow interrupts and interrupt
28 * levels. 30 * levels.
@@ -92,6 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
92notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) 94notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
93{ 95{
94 unsigned int sum, touched = 0; 96 unsigned int sum, touched = 0;
97 void *orig_sp;
95 98
96 clear_softint(1 << irq); 99 clear_softint(1 << irq);
97 100
@@ -99,6 +102,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
99 102
100 nmi_enter(); 103 nmi_enter();
101 104
105 orig_sp = set_hardirq_stack();
106
102 if (notify_die(DIE_NMI, "nmi", regs, 0, 107 if (notify_die(DIE_NMI, "nmi", regs, 0,
103 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) 108 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
104 touched = 1; 109 touched = 1;
@@ -124,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
124 pcr_ops->write(pcr_enable); 129 pcr_ops->write(pcr_enable);
125 } 130 }
126 131
132 restore_hardirq_stack(orig_sp);
133
127 nmi_exit(); 134 nmi_exit();
128} 135}
129 136
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index e2771939341d..34ce49f80eac 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/perf_event.h> 15#include <linux/perf_event.h>
16#include <linux/kprobes.h> 16#include <linux/kprobes.h>
17#include <linux/ftrace.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/kdebug.h> 19#include <linux/kdebug.h>
19#include <linux/mutex.h> 20#include <linux/mutex.h>
@@ -1276,6 +1277,9 @@ static void perf_callchain_kernel(struct pt_regs *regs,
1276 struct perf_callchain_entry *entry) 1277 struct perf_callchain_entry *entry)
1277{ 1278{
1278 unsigned long ksp, fp; 1279 unsigned long ksp, fp;
1280#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1281 int graph = 0;
1282#endif
1279 1283
1280 callchain_store(entry, PERF_CONTEXT_KERNEL); 1284 callchain_store(entry, PERF_CONTEXT_KERNEL);
1281 callchain_store(entry, regs->tpc); 1285 callchain_store(entry, regs->tpc);
@@ -1303,6 +1307,16 @@ static void perf_callchain_kernel(struct pt_regs *regs,
1303 fp = (unsigned long)sf->fp + STACK_BIAS; 1307 fp = (unsigned long)sf->fp + STACK_BIAS;
1304 } 1308 }
1305 callchain_store(entry, pc); 1309 callchain_store(entry, pc);
1310#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1311 if ((pc + 8UL) == (unsigned long) &return_to_handler) {
1312 int index = current->curr_ret_stack;
1313 if (current->ret_stack && index >= graph) {
1314 pc = current->ret_stack[index - graph].ret;
1315 callchain_store(entry, pc);
1316 graph++;
1317 }
1318 }
1319#endif
1306 } while (entry->nr < PERF_MAX_STACK_DEPTH); 1320 } while (entry->nr < PERF_MAX_STACK_DEPTH);
1307} 1321}
1308 1322
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index a5cf3864b31f..dbe81a368b45 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -202,6 +202,7 @@ void show_regs(struct pt_regs *regs)
202 regs->u_regs[15]); 202 regs->u_regs[15]);
203 printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); 203 printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
204 show_regwindow(regs); 204 show_regwindow(regs);
205 show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]);
205} 206}
206 207
207struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; 208struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
index 83f1873c6c13..090b9e9ad5e3 100644
--- a/arch/sparc/kernel/rtrap_64.S
+++ b/arch/sparc/kernel/rtrap_64.S
@@ -130,7 +130,17 @@ rtrap_xcall:
130 nop 130 nop
131 call trace_hardirqs_on 131 call trace_hardirqs_on
132 nop 132 nop
133 wrpr %l4, %pil 133 /* Do not actually set the %pil here. We will do that
134 * below after we clear PSTATE_IE in the %pstate register.
135 * If we re-enable interrupts here, we can recurse down
136 * the hardirq stack potentially endlessly, causing a
137 * stack overflow.
138 *
139 * It is tempting to put this test and trace_hardirqs_on
140 * call at the 'rt_continue' label, but that will not work
141 * as that path hits unconditionally and we do not want to
142 * execute this in NMI return paths, for example.
143 */
134#endif 144#endif
135rtrap_no_irq_enable: 145rtrap_no_irq_enable:
136 andcc %l1, TSTATE_PRIV, %l3 146 andcc %l1, TSTATE_PRIV, %l3
diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c
index acb12f673757..3e0815349630 100644
--- a/arch/sparc/kernel/stacktrace.c
+++ b/arch/sparc/kernel/stacktrace.c
@@ -1,6 +1,7 @@
1#include <linux/sched.h> 1#include <linux/sched.h>
2#include <linux/stacktrace.h> 2#include <linux/stacktrace.h>
3#include <linux/thread_info.h> 3#include <linux/thread_info.h>
4#include <linux/ftrace.h>
4#include <linux/module.h> 5#include <linux/module.h>
5#include <asm/ptrace.h> 6#include <asm/ptrace.h>
6#include <asm/stacktrace.h> 7#include <asm/stacktrace.h>
@@ -12,6 +13,10 @@ static void __save_stack_trace(struct thread_info *tp,
12 bool skip_sched) 13 bool skip_sched)
13{ 14{
14 unsigned long ksp, fp; 15 unsigned long ksp, fp;
16#ifdef CONFIG_FUNCTION_GRAPH_TRACER
17 struct task_struct *t;
18 int graph = 0;
19#endif
15 20
16 if (tp == current_thread_info()) { 21 if (tp == current_thread_info()) {
17 stack_trace_flush(); 22 stack_trace_flush();
@@ -21,6 +26,9 @@ static void __save_stack_trace(struct thread_info *tp,
21 } 26 }
22 27
23 fp = ksp + STACK_BIAS; 28 fp = ksp + STACK_BIAS;
29#ifdef CONFIG_FUNCTION_GRAPH_TRACER
30 t = tp->task;
31#endif
24 do { 32 do {
25 struct sparc_stackf *sf; 33 struct sparc_stackf *sf;
26 struct pt_regs *regs; 34 struct pt_regs *regs;
@@ -44,8 +52,21 @@ static void __save_stack_trace(struct thread_info *tp,
44 52
45 if (trace->skip > 0) 53 if (trace->skip > 0)
46 trace->skip--; 54 trace->skip--;
47 else if (!skip_sched || !in_sched_functions(pc)) 55 else if (!skip_sched || !in_sched_functions(pc)) {
48 trace->entries[trace->nr_entries++] = pc; 56 trace->entries[trace->nr_entries++] = pc;
57#ifdef CONFIG_FUNCTION_GRAPH_TRACER
58 if ((pc + 8UL) == (unsigned long) &return_to_handler) {
59 int index = t->curr_ret_stack;
60 if (t->ret_stack && index >= graph) {
61 pc = t->ret_stack[index - graph].ret;
62 if (trace->nr_entries <
63 trace->max_entries)
64 trace->entries[trace->nr_entries++] = pc;
65 graph++;
66 }
67 }
68#endif
69 }
49 } while (trace->nr_entries < trace->max_entries); 70 } while (trace->nr_entries < trace->max_entries);
50} 71}
51 72
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 217ba275cabf..e404b063be2c 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -78,6 +78,11 @@ __volatile__ unsigned int *master_l10_counter;
78 78
79u32 (*do_arch_gettimeoffset)(void); 79u32 (*do_arch_gettimeoffset)(void);
80 80
81int update_persistent_clock(struct timespec now)
82{
83 return set_rtc_mmss(now.tv_sec);
84}
85
81/* 86/*
82 * timer_interrupt() needs to keep up the real-time clock, 87 * timer_interrupt() needs to keep up the real-time clock,
83 * as well as call the "do_timer()" routine every clocktick 88 * as well as call the "do_timer()" routine every clocktick
@@ -87,9 +92,6 @@ u32 (*do_arch_gettimeoffset)(void);
87 92
88static irqreturn_t timer_interrupt(int dummy, void *dev_id) 93static irqreturn_t timer_interrupt(int dummy, void *dev_id)
89{ 94{
90 /* last time the cmos clock got updated */
91 static long last_rtc_update;
92
93#ifndef CONFIG_SMP 95#ifndef CONFIG_SMP
94 profile_tick(CPU_PROFILING); 96 profile_tick(CPU_PROFILING);
95#endif 97#endif
@@ -101,16 +103,6 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id)
101 103
102 do_timer(1); 104 do_timer(1);
103 105
104 /* Determine when to update the Mostek clock. */
105 if (ntp_synced() &&
106 xtime.tv_sec > last_rtc_update + 660 &&
107 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
108 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
109 if (set_rtc_mmss(xtime.tv_sec) == 0)
110 last_rtc_update = xtime.tv_sec;
111 else
112 last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
113 }
114 write_sequnlock(&xtime_lock); 106 write_sequnlock(&xtime_lock);
115 107
116#ifndef CONFIG_SMP 108#ifndef CONFIG_SMP
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 9da57f032983..42ad2ba85010 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -17,6 +17,7 @@
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/kdebug.h> 19#include <linux/kdebug.h>
20#include <linux/ftrace.h>
20#include <linux/gfp.h> 21#include <linux/gfp.h>
21 22
22#include <asm/smp.h> 23#include <asm/smp.h>
@@ -2154,6 +2155,9 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
2154 unsigned long fp, thread_base, ksp; 2155 unsigned long fp, thread_base, ksp;
2155 struct thread_info *tp; 2156 struct thread_info *tp;
2156 int count = 0; 2157 int count = 0;
2158#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2159 int graph = 0;
2160#endif
2157 2161
2158 ksp = (unsigned long) _ksp; 2162 ksp = (unsigned long) _ksp;
2159 if (!tsk) 2163 if (!tsk)
@@ -2193,6 +2197,16 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
2193 } 2197 }
2194 2198
2195 printk(" [%016lx] %pS\n", pc, (void *) pc); 2199 printk(" [%016lx] %pS\n", pc, (void *) pc);
2200#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2201 if ((pc + 8UL) == (unsigned long) &return_to_handler) {
2202 int index = tsk->curr_ret_stack;
2203 if (tsk->ret_stack && index >= graph) {
2204 pc = tsk->ret_stack[index - graph].ret;
2205 printk(" [%016lx] %pS\n", pc, (void *) pc);
2206 graph++;
2207 }
2208 }
2209#endif
2196 } while (++count < 16); 2210 } while (++count < 16);
2197} 2211}
2198 2212
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index ebce43018c49..c752c4c479bd 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn)
50} 50}
51 51
52/* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */ 52/* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */
53static inline int decode_access_size(unsigned int insn) 53static inline int decode_access_size(struct pt_regs *regs, unsigned int insn)
54{ 54{
55 unsigned int tmp; 55 unsigned int tmp;
56 56
@@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn)
66 return 2; 66 return 2;
67 else { 67 else {
68 printk("Impossible unaligned trap. insn=%08x\n", insn); 68 printk("Impossible unaligned trap. insn=%08x\n", insn);
69 die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs); 69 die_if_kernel("Byte sized unaligned access?!?!", regs);
70 70
71 /* GCC should never warn that control reaches the end 71 /* GCC should never warn that control reaches the end
72 * of this function without returning a value because 72 * of this function without returning a value because
@@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs)
286asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) 286asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
287{ 287{
288 enum direction dir = decode_direction(insn); 288 enum direction dir = decode_direction(insn);
289 int size = decode_access_size(insn); 289 int size = decode_access_size(regs, insn);
290 int orig_asi, asi; 290 int orig_asi, asi;
291 291
292 current_thread_info()->kern_una_regs = regs; 292 current_thread_info()->kern_una_regs = regs;
diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S
index 3753e3c6e176..3ad6cbdc2163 100644
--- a/arch/sparc/lib/mcount.S
+++ b/arch/sparc/lib/mcount.S
@@ -34,7 +34,7 @@ mcount:
34 cmp %g1, %g2 34 cmp %g1, %g2
35 be,pn %icc, 1f 35 be,pn %icc, 1f
36 mov %i7, %g3 36 mov %i7, %g3
37 save %sp, -128, %sp 37 save %sp, -176, %sp
38 mov %g3, %o1 38 mov %g3, %o1
39 jmpl %g1, %o7 39 jmpl %g1, %o7
40 mov %i7, %o0 40 mov %i7, %o0
@@ -56,7 +56,7 @@ mcount:
56 nop 56 nop
575: mov %i7, %g2 575: mov %i7, %g2
58 mov %fp, %g3 58 mov %fp, %g3
59 save %sp, -128, %sp 59 save %sp, -176, %sp
60 mov %g2, %l0 60 mov %g2, %l0
61 ba,pt %xcc, ftrace_graph_caller 61 ba,pt %xcc, ftrace_graph_caller
62 mov %g3, %l1 62 mov %g3, %l1
@@ -85,7 +85,7 @@ ftrace_caller:
85 lduw [%g1 + %lo(function_trace_stop)], %g1 85 lduw [%g1 + %lo(function_trace_stop)], %g1
86 brnz,pn %g1, ftrace_stub 86 brnz,pn %g1, ftrace_stub
87 mov %fp, %g3 87 mov %fp, %g3
88 save %sp, -128, %sp 88 save %sp, -176, %sp
89 mov %g2, %o1 89 mov %g2, %o1
90 mov %g2, %l0 90 mov %g2, %l0
91 mov %g3, %l1 91 mov %g3, %l1
@@ -120,7 +120,7 @@ ENTRY(ftrace_graph_caller)
120END(ftrace_graph_caller) 120END(ftrace_graph_caller)
121 121
122ENTRY(return_to_handler) 122ENTRY(return_to_handler)
123 save %sp, -128, %sp 123 save %sp, -176, %sp
124 call ftrace_return_to_handler 124 call ftrace_return_to_handler
125 mov %fp, %o0 125 mov %fp, %o0
126 jmpl %o0 + 8, %g0 126 jmpl %o0 + 8, %g0