diff options
Diffstat (limited to 'arch/sh/kernel/irq.c')
-rw-r--r-- | arch/sh/kernel/irq.c | 42 |
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 | ||
21 | atomic_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 | */ |
25 | void ack_bad_irq(unsigned int irq) | 28 | void 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'); |
57 | unlock: | 63 | unlock: |
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(®s); |
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" (®s), "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, ®s); | 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 | ||