aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/irq.c')
-rw-r--r--arch/sh/kernel/irq.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index c7ebd6aec951..acf2602569c4 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -11,12 +11,15 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/kernel_stat.h> 12#include <linux/kernel_stat.h>
13#include <linux/seq_file.h> 13#include <linux/seq_file.h>
14#include <linux/io.h>
14#include <asm/irq.h> 15#include <asm/irq.h>
15#include <asm/processor.h> 16#include <asm/processor.h>
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
17#include <asm/thread_info.h> 18#include <asm/thread_info.h>
18#include <asm/cpu/mmu_context.h> 19#include <asm/cpu/mmu_context.h>
19 20
21atomic_t irq_err_count;
22
20/* 23/*
21 * 'what should we do if we get a hw irq event on an illegal vector'. 24 * 'what should we do if we get a hw irq event on an illegal vector'.
22 * each architecture has to answer this themselves, it doesn't deserve 25 * each architecture has to answer this themselves, it doesn't deserve
@@ -24,6 +27,7 @@
24 */ 27 */
25void ack_bad_irq(unsigned int irq) 28void ack_bad_irq(unsigned int irq)
26{ 29{
30 atomic_inc(&irq_err_count);
27 printk("unexpected IRQ trap at vector %02x\n", irq); 31 printk("unexpected IRQ trap at vector %02x\n", irq);
28} 32}
29 33
@@ -47,8 +51,10 @@ int show_interrupts(struct seq_file *p, void *v)
47 if (!action) 51 if (!action)
48 goto unlock; 52 goto unlock;
49 seq_printf(p, "%3d: ",i); 53 seq_printf(p, "%3d: ",i);
50 seq_printf(p, "%10u ", kstat_irqs(i)); 54 for_each_online_cpu(j)
51 seq_printf(p, " %14s", irq_desc[i].chip->typename); 55 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
56 seq_printf(p, " %14s", irq_desc[i].chip->name);
57 seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
52 seq_printf(p, " %s", action->name); 58 seq_printf(p, " %s", action->name);
53 59
54 for (action=action->next; action; action = action->next) 60 for (action=action->next; action; action = action->next)
@@ -56,7 +62,9 @@ int show_interrupts(struct seq_file *p, void *v)
56 seq_putc(p, '\n'); 62 seq_putc(p, '\n');
57unlock: 63unlock:
58 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 64 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
59 } 65 } else if (i == NR_IRQS)
66 seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
67
60 return 0; 68 return 0;
61} 69}
62#endif 70#endif
@@ -78,7 +86,8 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
78 unsigned long r6, unsigned long r7, 86 unsigned long r6, unsigned long r7,
79 struct pt_regs regs) 87 struct pt_regs regs)
80{ 88{
81 int irq = r4; 89 struct pt_regs *old_regs = set_irq_regs(&regs);
90 int irq;
82#ifdef CONFIG_4KSTACKS 91#ifdef CONFIG_4KSTACKS
83 union irq_ctx *curctx, *irqctx; 92 union irq_ctx *curctx, *irqctx;
84#endif 93#endif
@@ -102,20 +111,9 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
102#endif 111#endif
103 112
104#ifdef CONFIG_CPU_HAS_INTEVT 113#ifdef CONFIG_CPU_HAS_INTEVT
105 __asm__ __volatile__ ( 114 irq = (ctrl_inl(INTEVT) >> 5) - 16;
106#ifdef CONFIG_CPU_HAS_SR_RB
107 "stc r2_bank, %0\n\t"
108#else 115#else
109 "mov.l @%1, %0\n\t" 116 irq = r4;
110#endif
111 "shlr2 %0\n\t"
112 "shlr2 %0\n\t"
113 "shlr %0\n\t"
114 "add #-16, %0\n\t"
115 : "=z" (irq), "=r" (r4)
116 : "1" (INTEVT)
117 : "memory"
118 );
119#endif 117#endif
120 118
121 irq = irq_demux(irq); 119 irq = irq_demux(irq);
@@ -139,25 +137,25 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
139 137
140 __asm__ __volatile__ ( 138 __asm__ __volatile__ (
141 "mov %0, r4 \n" 139 "mov %0, r4 \n"
142 "mov %1, r5 \n"
143 "mov r15, r9 \n" 140 "mov r15, r9 \n"
144 "jsr @%2 \n" 141 "jsr @%1 \n"
145 /* swith to the irq stack */ 142 /* swith to the irq stack */
146 " mov %3, r15 \n" 143 " mov %2, r15 \n"
147 /* restore the stack (ring zero) */ 144 /* restore the stack (ring zero) */
148 "mov r9, r15 \n" 145 "mov r9, r15 \n"
149 : /* no outputs */ 146 : /* no outputs */
150 : "r" (irq), "r" (&regs), "r" (__do_IRQ), "r" (isp) 147 : "r" (irq), "r" (generic_handle_irq), "r" (isp)
151 /* XXX: A somewhat excessive clobber list? -PFM */ 148 /* XXX: A somewhat excessive clobber list? -PFM */
152 : "memory", "r0", "r1", "r2", "r3", "r4", 149 : "memory", "r0", "r1", "r2", "r3", "r4",
153 "r5", "r6", "r7", "r8", "t", "pr" 150 "r5", "r6", "r7", "r8", "t", "pr"
154 ); 151 );
155 } else 152 } else
156#endif 153#endif
157 __do_IRQ(irq, &regs); 154 generic_handle_irq(irq);
158 155
159 irq_exit(); 156 irq_exit();
160 157
158 set_irq_regs(old_regs);
161 return 1; 159 return 1;
162} 160}
163 161