aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-08-17 02:31:59 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-19 02:26:19 -0400
commitce4a925c29208cf48084d9fa174d965a65246a8d (patch)
tree9b99aafebe393782e602d6960da416dd36bb89e8 /arch
parent73a6b0538c131d489fe7a2581deddb72faca496b (diff)
sparc64: Abstract away the %pcr values used to enable/disable NMI
We assumed PCR_PIC_PRIV can always be used to disable it, but that won't be true for SPARC-T4. This allows us also to get rid of some messy defines used in only one location. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/include/asm/pcr.h4
-rw-r--r--arch/sparc/kernel/nmi.c14
-rw-r--r--arch/sparc/kernel/pcr.c37
3 files changed, 26 insertions, 29 deletions
diff --git a/arch/sparc/include/asm/pcr.h b/arch/sparc/include/asm/pcr.h
index 4c71bec20659..9ebc7f3840d1 100644
--- a/arch/sparc/include/asm/pcr.h
+++ b/arch/sparc/include/asm/pcr.h
@@ -7,6 +7,8 @@ struct pcr_ops {
7 u64 (*read_pic)(unsigned long); 7 u64 (*read_pic)(unsigned long);
8 void (*write_pic)(unsigned long, u64); 8 void (*write_pic)(unsigned long, u64);
9 u64 (*nmi_picl_value)(unsigned int nmi_hz); 9 u64 (*nmi_picl_value)(unsigned int nmi_hz);
10 u64 pcr_nmi_enable;
11 u64 pcr_nmi_disable;
10}; 12};
11extern const struct pcr_ops *pcr_ops; 13extern const struct pcr_ops *pcr_ops;
12 14
@@ -30,8 +32,6 @@ extern void schedule_deferred_pcr_work(void);
30#define PCR_N2_SL1_SHIFT 27 32#define PCR_N2_SL1_SHIFT 27
31#define PCR_N2_OV1 0x80000000 33#define PCR_N2_OV1 0x80000000
32 34
33extern u64 pcr_enable;
34
35extern int pcr_arch_init(void); 35extern int pcr_arch_init(void);
36 36
37#endif /* __PCR_H */ 37#endif /* __PCR_H */
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index 4c45158d4c88..6479256fd5a4 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -108,7 +108,7 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
108 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) 108 pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
109 touched = 1; 109 touched = 1;
110 else 110 else
111 pcr_ops->write_pcr(0, PCR_PIC_PRIV); 111 pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable);
112 112
113 sum = local_cpu_data().irq0_irqs; 113 sum = local_cpu_data().irq0_irqs;
114 if (__get_cpu_var(nmi_touch)) { 114 if (__get_cpu_var(nmi_touch)) {
@@ -126,7 +126,7 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
126 } 126 }
127 if (__get_cpu_var(wd_enabled)) { 127 if (__get_cpu_var(wd_enabled)) {
128 pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz)); 128 pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz));
129 pcr_ops->write_pcr(0, pcr_enable); 129 pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_enable);
130 } 130 }
131 131
132 restore_hardirq_stack(orig_sp); 132 restore_hardirq_stack(orig_sp);
@@ -165,7 +165,7 @@ static void report_broken_nmi(int cpu, int *prev_nmi_count)
165 165
166void stop_nmi_watchdog(void *unused) 166void stop_nmi_watchdog(void *unused)
167{ 167{
168 pcr_ops->write_pcr(0, PCR_PIC_PRIV); 168 pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable);
169 __get_cpu_var(wd_enabled) = 0; 169 __get_cpu_var(wd_enabled) = 0;
170 atomic_dec(&nmi_active); 170 atomic_dec(&nmi_active);
171} 171}
@@ -222,10 +222,10 @@ void start_nmi_watchdog(void *unused)
222 __get_cpu_var(wd_enabled) = 1; 222 __get_cpu_var(wd_enabled) = 1;
223 atomic_inc(&nmi_active); 223 atomic_inc(&nmi_active);
224 224
225 pcr_ops->write_pcr(0, PCR_PIC_PRIV); 225 pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable);
226 pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz)); 226 pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz));
227 227
228 pcr_ops->write_pcr(0, pcr_enable); 228 pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_enable);
229} 229}
230 230
231static void nmi_adjust_hz_one(void *unused) 231static void nmi_adjust_hz_one(void *unused)
@@ -233,10 +233,10 @@ static void nmi_adjust_hz_one(void *unused)
233 if (!__get_cpu_var(wd_enabled)) 233 if (!__get_cpu_var(wd_enabled))
234 return; 234 return;
235 235
236 pcr_ops->write_pcr(0, PCR_PIC_PRIV); 236 pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable);
237 pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz)); 237 pcr_ops->write_pic(0, pcr_ops->nmi_picl_value(nmi_hz));
238 238
239 pcr_ops->write_pcr(0, pcr_enable); 239 pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_enable);
240} 240}
241 241
242void nmi_adjust_hz(unsigned int new_hz) 242void nmi_adjust_hz(unsigned int new_hz)
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
index 494af3227f3b..e408fc5d0c18 100644
--- a/arch/sparc/kernel/pcr.c
+++ b/arch/sparc/kernel/pcr.c
@@ -20,14 +20,6 @@
20 * perf_event support layer. 20 * perf_event support layer.
21 */ 21 */
22 22
23#define PCR_SUN4U_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE)
24#define PCR_N2_ENABLE (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE | \
25 PCR_N2_TOE_OV1 | \
26 (2 << PCR_N2_SL1_SHIFT) | \
27 (0xff << PCR_N2_MASK1_SHIFT))
28
29u64 pcr_enable;
30
31/* Performance counter interrupts run unmasked at PIL level 15. 23/* Performance counter interrupts run unmasked at PIL level 15.
32 * Therefore we can't do things like wakeups and other work 24 * Therefore we can't do things like wakeups and other work
33 * that expects IRQ disabling to be adhered to in locking etc. 25 * that expects IRQ disabling to be adhered to in locking etc.
@@ -105,11 +97,13 @@ static u64 direct_picl_value(unsigned int nmi_hz)
105} 97}
106 98
107static const struct pcr_ops direct_pcr_ops = { 99static const struct pcr_ops direct_pcr_ops = {
108 .read_pcr = direct_pcr_read, 100 .read_pcr = direct_pcr_read,
109 .write_pcr = direct_pcr_write, 101 .write_pcr = direct_pcr_write,
110 .read_pic = direct_pic_read, 102 .read_pic = direct_pic_read,
111 .write_pic = direct_pic_write, 103 .write_pic = direct_pic_write,
112 .nmi_picl_value = direct_picl_value, 104 .nmi_picl_value = direct_picl_value,
105 .pcr_nmi_enable = (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE),
106 .pcr_nmi_disable = PCR_PIC_PRIV,
113}; 107};
114 108
115static void n2_pcr_write(unsigned long reg_num, u64 val) 109static void n2_pcr_write(unsigned long reg_num, u64 val)
@@ -133,11 +127,16 @@ static u64 n2_picl_value(unsigned int nmi_hz)
133} 127}
134 128
135static const struct pcr_ops n2_pcr_ops = { 129static const struct pcr_ops n2_pcr_ops = {
136 .read_pcr = direct_pcr_read, 130 .read_pcr = direct_pcr_read,
137 .write_pcr = n2_pcr_write, 131 .write_pcr = n2_pcr_write,
138 .read_pic = direct_pic_read, 132 .read_pic = direct_pic_read,
139 .write_pic = direct_pic_write, 133 .write_pic = direct_pic_write,
140 .nmi_picl_value = n2_picl_value, 134 .nmi_picl_value = n2_picl_value,
135 .pcr_nmi_enable = (PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE |
136 PCR_N2_TOE_OV1 |
137 (2 << PCR_N2_SL1_SHIFT) |
138 (0xff << PCR_N2_MASK1_SHIFT)),
139 .pcr_nmi_disable = PCR_PIC_PRIV,
141}; 140};
142 141
143static unsigned long perf_hsvc_group; 142static unsigned long perf_hsvc_group;
@@ -194,13 +193,11 @@ int __init pcr_arch_init(void)
194 switch (tlb_type) { 193 switch (tlb_type) {
195 case hypervisor: 194 case hypervisor:
196 pcr_ops = &n2_pcr_ops; 195 pcr_ops = &n2_pcr_ops;
197 pcr_enable = PCR_N2_ENABLE;
198 break; 196 break;
199 197
200 case cheetah: 198 case cheetah:
201 case cheetah_plus: 199 case cheetah_plus:
202 pcr_ops = &direct_pcr_ops; 200 pcr_ops = &direct_pcr_ops;
203 pcr_enable = PCR_SUN4U_ENABLE;
204 break; 201 break;
205 202
206 case spitfire: 203 case spitfire: