aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2006-10-08 09:30:44 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-08 15:32:35 -0400
commit0d84438d98777b0f9425d39121c42f47a06878ca (patch)
tree9d3486664ecf836183f982f7011c5b8b37c4091e /arch/sparc
parent7ff3e52cf2947ebd38c84159af68e5a29d228f6c (diff)
[PATCH] sparc32 pt_regs fixes
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/irq.c23
-rw-r--r--arch/sparc/kernel/pcic.c4
-rw-r--r--arch/sparc/kernel/sun4c_irq.c2
-rw-r--r--arch/sparc/kernel/sun4d_irq.c12
-rw-r--r--arch/sparc/kernel/sun4d_smp.c6
-rw-r--r--arch/sparc/kernel/sun4m_irq.c2
-rw-r--r--arch/sparc/kernel/sun4m_smp.c7
-rw-r--r--arch/sparc/kernel/tick14.c2
-rw-r--r--arch/sparc/kernel/time.c7
9 files changed, 43 insertions, 22 deletions
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 72f0201051a0..ae4dfc89ca52 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -46,6 +46,7 @@
46#include <asm/pgtable.h> 46#include <asm/pgtable.h>
47#include <asm/pcic.h> 47#include <asm/pcic.h>
48#include <asm/cacheflush.h> 48#include <asm/cacheflush.h>
49#include <asm/irq_regs.h>
49 50
50#ifdef CONFIG_SMP 51#ifdef CONFIG_SMP
51#define SMP_NOP2 "nop; nop;\n\t" 52#define SMP_NOP2 "nop; nop;\n\t"
@@ -133,8 +134,8 @@ static void irq_panic(void)
133 prom_halt(); 134 prom_halt();
134} 135}
135 136
136void (*sparc_init_timers)(irqreturn_t (*)(int, void *,struct pt_regs *)) = 137void (*sparc_init_timers)(irqreturn_t (*)(int, void *)) =
137 (void (*)(irqreturn_t (*)(int, void *,struct pt_regs *))) irq_panic; 138 (void (*)(irqreturn_t (*)(int, void *))) irq_panic;
138 139
139/* 140/*
140 * Dave Redman (djhr@tadpole.co.uk) 141 * Dave Redman (djhr@tadpole.co.uk)
@@ -319,12 +320,14 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
319 320
320void handler_irq(int irq, struct pt_regs * regs) 321void handler_irq(int irq, struct pt_regs * regs)
321{ 322{
323 struct pt_regs *old_regs;
322 struct irqaction * action; 324 struct irqaction * action;
323 int cpu = smp_processor_id(); 325 int cpu = smp_processor_id();
324#ifdef CONFIG_SMP 326#ifdef CONFIG_SMP
325 extern void smp4m_irq_rotate(int cpu); 327 extern void smp4m_irq_rotate(int cpu);
326#endif 328#endif
327 329
330 old_regs = set_irq_regs(regs);
328 irq_enter(); 331 irq_enter();
329 disable_pil_irq(irq); 332 disable_pil_irq(irq);
330#ifdef CONFIG_SMP 333#ifdef CONFIG_SMP
@@ -338,27 +341,31 @@ void handler_irq(int irq, struct pt_regs * regs)
338 do { 341 do {
339 if (!action || !action->handler) 342 if (!action || !action->handler)
340 unexpected_irq(irq, NULL, regs); 343 unexpected_irq(irq, NULL, regs);
341 action->handler(irq, action->dev_id, regs); 344 action->handler(irq, action->dev_id);
342 action = action->next; 345 action = action->next;
343 } while (action); 346 } while (action);
344 sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS; 347 sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS;
345 enable_pil_irq(irq); 348 enable_pil_irq(irq);
346 irq_exit(); 349 irq_exit();
350 set_irq_regs(old_regs);
347} 351}
348 352
349#ifdef CONFIG_BLK_DEV_FD 353#ifdef CONFIG_BLK_DEV_FD
350extern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs); 354extern void floppy_interrupt(int irq, void *dev_id)
351 355
352void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) 356void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
353{ 357{
358 struct pt_regs *old_regs;
354 int cpu = smp_processor_id(); 359 int cpu = smp_processor_id();
355 360
361 old_regs = set_irq_regs(regs);
356 disable_pil_irq(irq); 362 disable_pil_irq(irq);
357 irq_enter(); 363 irq_enter();
358 kstat_cpu(cpu).irqs[irq]++; 364 kstat_cpu(cpu).irqs[irq]++;
359 floppy_interrupt(irq, dev_id, regs); 365 floppy_interrupt(irq, dev_id);
360 irq_exit(); 366 irq_exit();
361 enable_pil_irq(irq); 367 enable_pil_irq(irq);
368 set_irq_regs(old_regs);
362 // XXX Eek, it's totally changed with preempt_count() and such 369 // XXX Eek, it's totally changed with preempt_count() and such
363 // if (softirq_pending(cpu)) 370 // if (softirq_pending(cpu))
364 // do_softirq(); 371 // do_softirq();
@@ -369,7 +376,7 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
369 * thus no sharing possible. 376 * thus no sharing possible.
370 */ 377 */
371int request_fast_irq(unsigned int irq, 378int request_fast_irq(unsigned int irq,
372 irqreturn_t (*handler)(int, void *, struct pt_regs *), 379 irqreturn_t (*handler)(int, void *),
373 unsigned long irqflags, const char *devname) 380 unsigned long irqflags, const char *devname)
374{ 381{
375 struct irqaction *action; 382 struct irqaction *action;
@@ -468,7 +475,7 @@ out:
468} 475}
469 476
470int request_irq(unsigned int irq, 477int request_irq(unsigned int irq,
471 irqreturn_t (*handler)(int, void *, struct pt_regs *), 478 irqreturn_t (*handler)(int, void *),
472 unsigned long irqflags, const char * devname, void *dev_id) 479 unsigned long irqflags, const char * devname, void *dev_id)
473{ 480{
474 struct irqaction * action, **actionp; 481 struct irqaction * action, **actionp;
@@ -478,7 +485,7 @@ int request_irq(unsigned int irq,
478 485
479 if (sparc_cpu_model == sun4d) { 486 if (sparc_cpu_model == sun4d) {
480 extern int sun4d_request_irq(unsigned int, 487 extern int sun4d_request_irq(unsigned int,
481 irqreturn_t (*)(int, void *, struct pt_regs *), 488 irqreturn_t (*)(int, void *),
482 unsigned long, const char *, void *); 489 unsigned long, const char *, void *);
483 return sun4d_request_irq(irq, handler, irqflags, devname, dev_id); 490 return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
484 } 491 }
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index edb6cc665f56..b4e50ae323bf 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -708,13 +708,13 @@ static void pcic_clear_clock_irq(void)
708 pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT); 708 pcic_timer_dummy = readl(pcic0.pcic_regs+PCI_SYS_LIMIT);
709} 709}
710 710
711static irqreturn_t pcic_timer_handler (int irq, void *h, struct pt_regs *regs) 711static irqreturn_t pcic_timer_handler (int irq, void *h)
712{ 712{
713 write_seqlock(&xtime_lock); /* Dummy, to show that we remember */ 713 write_seqlock(&xtime_lock); /* Dummy, to show that we remember */
714 pcic_clear_clock_irq(); 714 pcic_clear_clock_irq();
715 do_timer(1); 715 do_timer(1);
716#ifndef CONFIG_SMP 716#ifndef CONFIG_SMP
717 update_process_times(user_mode(regs)); 717 update_process_times(user_mode(get_irq_regs()));
718#endif 718#endif
719 write_sequnlock(&xtime_lock); 719 write_sequnlock(&xtime_lock);
720 return IRQ_HANDLED; 720 return IRQ_HANDLED;
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c
index 4be2c86ea540..2eaa0d085e19 100644
--- a/arch/sparc/kernel/sun4c_irq.c
+++ b/arch/sparc/kernel/sun4c_irq.c
@@ -154,7 +154,7 @@ static void sun4c_load_profile_irq(int cpu, unsigned int limit)
154 /* Errm.. not sure how to do this.. */ 154 /* Errm.. not sure how to do this.. */
155} 155}
156 156
157static void __init sun4c_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *)) 157static void __init sun4c_init_timers(irqreturn_t (*counter_fn)(int, void *))
158{ 158{
159 int irq; 159 int irq;
160 160
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 74eed9775ac0..836d1562787a 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -38,6 +38,7 @@
38#include <asm/sbus.h> 38#include <asm/sbus.h>
39#include <asm/sbi.h> 39#include <asm/sbi.h>
40#include <asm/cacheflush.h> 40#include <asm/cacheflush.h>
41#include <asm/irq_regs.h>
41 42
42/* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ 43/* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */
43/* #define DISTRIBUTE_IRQS */ 44/* #define DISTRIBUTE_IRQS */
@@ -198,6 +199,7 @@ extern void unexpected_irq(int, void *, struct pt_regs *);
198 199
199void sun4d_handler_irq(int irq, struct pt_regs * regs) 200void sun4d_handler_irq(int irq, struct pt_regs * regs)
200{ 201{
202 struct pt_regs *old_regs;
201 struct irqaction * action; 203 struct irqaction * action;
202 int cpu = smp_processor_id(); 204 int cpu = smp_processor_id();
203 /* SBUS IRQ level (1 - 7) */ 205 /* SBUS IRQ level (1 - 7) */
@@ -208,6 +210,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
208 210
209 cc_set_iclr(1 << irq); 211 cc_set_iclr(1 << irq);
210 212
213 old_regs = set_irq_regs(regs);
211 irq_enter(); 214 irq_enter();
212 kstat_cpu(cpu).irqs[irq]++; 215 kstat_cpu(cpu).irqs[irq]++;
213 if (!sbusl) { 216 if (!sbusl) {
@@ -215,7 +218,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
215 if (!action) 218 if (!action)
216 unexpected_irq(irq, NULL, regs); 219 unexpected_irq(irq, NULL, regs);
217 do { 220 do {
218 action->handler(irq, action->dev_id, regs); 221 action->handler(irq, action->dev_id);
219 action = action->next; 222 action = action->next;
220 } while (action); 223 } while (action);
221 } else { 224 } else {
@@ -242,7 +245,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
242 if (!action) 245 if (!action)
243 unexpected_irq(irq, NULL, regs); 246 unexpected_irq(irq, NULL, regs);
244 do { 247 do {
245 action->handler(irq, action->dev_id, regs); 248 action->handler(irq, action->dev_id);
246 action = action->next; 249 action = action->next;
247 } while (action); 250 } while (action);
248 release_sbi(SBI2DEVID(sbino), slot); 251 release_sbi(SBI2DEVID(sbino), slot);
@@ -250,6 +253,7 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
250 } 253 }
251 } 254 }
252 irq_exit(); 255 irq_exit();
256 set_irq_regs(old_regs);
253} 257}
254 258
255unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq) 259unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq)
@@ -272,7 +276,7 @@ unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev, unsigned int sbint)
272} 276}
273 277
274int sun4d_request_irq(unsigned int irq, 278int sun4d_request_irq(unsigned int irq,
275 irqreturn_t (*handler)(int, void *, struct pt_regs *), 279 irqreturn_t (*handler)(int, void *),
276 unsigned long irqflags, const char * devname, void *dev_id) 280 unsigned long irqflags, const char * devname, void *dev_id)
277{ 281{
278 struct irqaction *action, *tmp = NULL, **actionp; 282 struct irqaction *action, *tmp = NULL, **actionp;
@@ -466,7 +470,7 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit)
466 bw_set_prof_limit(cpu, limit); 470 bw_set_prof_limit(cpu, limit);
467} 471}
468 472
469static void __init sun4d_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *)) 473static void __init sun4d_init_timers(irqreturn_t (*counter_fn)(int, void *))
470{ 474{
471 int irq; 475 int irq;
472 int cpu; 476 int cpu;
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 3ff4edd32815..c80ea61e8ba0 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -23,6 +23,7 @@
23 23
24#include <asm/ptrace.h> 24#include <asm/ptrace.h>
25#include <asm/atomic.h> 25#include <asm/atomic.h>
26#include <asm/irq_regs.h>
26 27
27#include <asm/delay.h> 28#include <asm/delay.h>
28#include <asm/irq.h> 29#include <asm/irq.h>
@@ -369,10 +370,12 @@ void smp4d_message_pass(int target, int msg, unsigned long data, int wait)
369 370
370void smp4d_percpu_timer_interrupt(struct pt_regs *regs) 371void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
371{ 372{
373 struct pt_regs *old_regs;
372 int cpu = hard_smp4d_processor_id(); 374 int cpu = hard_smp4d_processor_id();
373 static int cpu_tick[NR_CPUS]; 375 static int cpu_tick[NR_CPUS];
374 static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd }; 376 static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd };
375 377
378 old_regs = set_irq_regs(regs);
376 bw_get_prof_limit(cpu); 379 bw_get_prof_limit(cpu);
377 bw_clear_intr_mask(0, 1); /* INTR_TABLE[0] & 1 is Profile IRQ */ 380 bw_clear_intr_mask(0, 1); /* INTR_TABLE[0] & 1 is Profile IRQ */
378 381
@@ -384,7 +387,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
384 show_leds(cpu); 387 show_leds(cpu);
385 } 388 }
386 389
387 profile_tick(CPU_PROFILING, regs); 390 profile_tick(CPU_PROFILING);
388 391
389 if(!--prof_counter(cpu)) { 392 if(!--prof_counter(cpu)) {
390 int user = user_mode(regs); 393 int user = user_mode(regs);
@@ -395,6 +398,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
395 398
396 prof_counter(cpu) = prof_multiplier(cpu); 399 prof_counter(cpu) = prof_multiplier(cpu);
397 } 400 }
401 set_irq_regs(old_regs);
398} 402}
399 403
400extern unsigned int lvl14_resolution; 404extern unsigned int lvl14_resolution;
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index 7cefa301efea..28bcf8e2c5b3 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -228,7 +228,7 @@ static void sun4m_load_profile_irq(int cpu, unsigned int limit)
228 sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit; 228 sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit;
229} 229}
230 230
231static void __init sun4m_init_timers(irqreturn_t (*counter_fn)(int, void *, struct pt_regs *)) 231static void __init sun4m_init_timers(irqreturn_t (*counter_fn)(int, void *))
232{ 232{
233 int reg_count, irq, cpu; 233 int reg_count, irq, cpu;
234 struct linux_prom_registers cnt_regs[PROMREG_MAX]; 234 struct linux_prom_registers cnt_regs[PROMREG_MAX];
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 7d4a649138f6..e2d9c018bd56 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -19,6 +19,7 @@
19#include <linux/profile.h> 19#include <linux/profile.h>
20#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
21#include <asm/tlbflush.h> 21#include <asm/tlbflush.h>
22#include <asm/irq_regs.h>
22 23
23#include <asm/ptrace.h> 24#include <asm/ptrace.h>
24#include <asm/atomic.h> 25#include <asm/atomic.h>
@@ -353,11 +354,14 @@ void smp4m_cross_call_irq(void)
353 354
354void smp4m_percpu_timer_interrupt(struct pt_regs *regs) 355void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
355{ 356{
357 struct pt_regs *old_regs;
356 int cpu = smp_processor_id(); 358 int cpu = smp_processor_id();
357 359
360 old_regs = set_irq_regs(regs);
361
358 clear_profile_irq(cpu); 362 clear_profile_irq(cpu);
359 363
360 profile_tick(CPU_PROFILING, regs); 364 profile_tick(CPU_PROFILING);
361 365
362 if(!--prof_counter(cpu)) { 366 if(!--prof_counter(cpu)) {
363 int user = user_mode(regs); 367 int user = user_mode(regs);
@@ -368,6 +372,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
368 372
369 prof_counter(cpu) = prof_multiplier(cpu); 373 prof_counter(cpu) = prof_multiplier(cpu);
370 } 374 }
375 set_irq_regs(old_regs);
371} 376}
372 377
373extern unsigned int lvl14_resolution; 378extern unsigned int lvl14_resolution;
diff --git a/arch/sparc/kernel/tick14.c b/arch/sparc/kernel/tick14.c
index d3b4daac705f..7107d2f0625d 100644
--- a/arch/sparc/kernel/tick14.c
+++ b/arch/sparc/kernel/tick14.c
@@ -55,7 +55,7 @@ void install_obp_ticker(void)
55 linux_lvl14[3] = obp_lvl14[3]; 55 linux_lvl14[3] = obp_lvl14[3];
56} 56}
57 57
58void claim_ticker14(irqreturn_t (*handler)(int, void *, struct pt_regs *), 58void claim_ticker14(irqreturn_t (*handler)(int, void *),
59 int irq_nr, unsigned int timeout ) 59 int irq_nr, unsigned int timeout )
60{ 60{
61 int cpu = smp_processor_id(); 61 int cpu = smp_processor_id();
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index e10dc831944d..7dcd1a16c6e4 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -42,6 +42,7 @@
42#include <asm/page.h> 42#include <asm/page.h>
43#include <asm/pcic.h> 43#include <asm/pcic.h>
44#include <asm/of_device.h> 44#include <asm/of_device.h>
45#include <asm/irq_regs.h>
45 46
46DEFINE_SPINLOCK(rtc_lock); 47DEFINE_SPINLOCK(rtc_lock);
47enum sparc_clock_type sp_clock_typ; 48enum sparc_clock_type sp_clock_typ;
@@ -104,13 +105,13 @@ __volatile__ unsigned int *master_l10_limit;
104 105
105#define TICK_SIZE (tick_nsec / 1000) 106#define TICK_SIZE (tick_nsec / 1000)
106 107
107irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) 108irqreturn_t timer_interrupt(int irq, void *dev_id)
108{ 109{
109 /* last time the cmos clock got updated */ 110 /* last time the cmos clock got updated */
110 static long last_rtc_update; 111 static long last_rtc_update;
111 112
112#ifndef CONFIG_SMP 113#ifndef CONFIG_SMP
113 profile_tick(CPU_PROFILING, regs); 114 profile_tick(CPU_PROFILING);
114#endif 115#endif
115 116
116 /* Protect counter clear so that do_gettimeoffset works */ 117 /* Protect counter clear so that do_gettimeoffset works */
@@ -128,7 +129,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
128 129
129 do_timer(1); 130 do_timer(1);
130#ifndef CONFIG_SMP 131#ifndef CONFIG_SMP
131 update_process_times(user_mode(regs)); 132 update_process_times(user_mode(get_irq_regs()));
132#endif 133#endif
133 134
134 135