diff options
Diffstat (limited to 'arch/sparc/kernel/irq_64.c')
-rw-r--r-- | arch/sparc/kernel/irq_64.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index e1cbdb94d97b..830d70a3e20b 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -20,7 +20,9 @@ | |||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/ftrace.h> | ||
23 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/kmemleak.h> | ||
24 | 26 | ||
25 | #include <asm/ptrace.h> | 27 | #include <asm/ptrace.h> |
26 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
@@ -45,6 +47,7 @@ | |||
45 | 47 | ||
46 | #include "entry.h" | 48 | #include "entry.h" |
47 | #include "cpumap.h" | 49 | #include "cpumap.h" |
50 | #include "kstack.h" | ||
48 | 51 | ||
49 | #define NUM_IVECS (IMAP_INR + 1) | 52 | #define NUM_IVECS (IMAP_INR + 1) |
50 | 53 | ||
@@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | |||
647 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); | 650 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); |
648 | if (unlikely(!bucket)) | 651 | if (unlikely(!bucket)) |
649 | return 0; | 652 | return 0; |
653 | |||
654 | /* The only reference we store to the IRQ bucket is | ||
655 | * by physical address which kmemleak can't see, tell | ||
656 | * it that this object explicitly is not a leak and | ||
657 | * should be scanned. | ||
658 | */ | ||
659 | kmemleak_not_leak(bucket); | ||
660 | |||
650 | __flush_dcache_range((unsigned long) bucket, | 661 | __flush_dcache_range((unsigned long) bucket, |
651 | ((unsigned long) bucket + | 662 | ((unsigned long) bucket + |
652 | sizeof(struct ino_bucket))); | 663 | sizeof(struct ino_bucket))); |
@@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq) | |||
703 | void *hardirq_stack[NR_CPUS]; | 714 | void *hardirq_stack[NR_CPUS]; |
704 | void *softirq_stack[NR_CPUS]; | 715 | void *softirq_stack[NR_CPUS]; |
705 | 716 | ||
706 | static __attribute__((always_inline)) void *set_hardirq_stack(void) | 717 | void __irq_entry handler_irq(int irq, struct pt_regs *regs) |
707 | { | ||
708 | void *orig_sp, *sp = hardirq_stack[smp_processor_id()]; | ||
709 | |||
710 | __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp)); | ||
711 | if (orig_sp < sp || | ||
712 | orig_sp > (sp + THREAD_SIZE)) { | ||
713 | sp += THREAD_SIZE - 192 - STACK_BIAS; | ||
714 | __asm__ __volatile__("mov %0, %%sp" : : "r" (sp)); | ||
715 | } | ||
716 | |||
717 | return orig_sp; | ||
718 | } | ||
719 | static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp) | ||
720 | { | ||
721 | __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp)); | ||
722 | } | ||
723 | |||
724 | void handler_irq(int irq, struct pt_regs *regs) | ||
725 | { | 718 | { |
726 | unsigned long pstate, bucket_pa; | 719 | unsigned long pstate, bucket_pa; |
727 | struct pt_regs *old_regs; | 720 | struct pt_regs *old_regs; |