Commit d7b250e2a2d7f3cd23cf8d8d6689285e6f51a98d
1 parent
df7997ab1c
Exists in
master
and in
39 other branches
[S390] irq: merge irq.c and s390_ext.c
Merge irq.c and s390_ext.c into irq.c. That way all external interrupt related functions are together. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Showing 17 changed files with 147 additions and 174 deletions Side-by-side Diff
- arch/s390/include/asm/irq.h
- arch/s390/include/asm/s390_ext.h
- arch/s390/kernel/Makefile
- arch/s390/kernel/dis.c
- arch/s390/kernel/irq.c
- arch/s390/kernel/s390_ext.c
- arch/s390/kernel/smp.c
- arch/s390/kernel/time.c
- arch/s390/kernel/topology.c
- arch/s390/kernel/traps.c
- arch/s390/kernel/vtime.c
- arch/s390/mm/fault.c
- arch/s390/oprofile/hwsampler.c
- drivers/s390/block/dasd_diag.c
- drivers/s390/char/sclp.c
- drivers/s390/kvm/kvm_virtio.c
- net/iucv/iucv.c
arch/s390/include/asm/irq.h
... | ... | @@ -2,6 +2,7 @@ |
2 | 2 | #define _ASM_IRQ_H |
3 | 3 | |
4 | 4 | #include <linux/hardirq.h> |
5 | +#include <linux/types.h> | |
5 | 6 | |
6 | 7 | enum interruption_class { |
7 | 8 | EXTERNAL_INTERRUPT, |
... | ... | @@ -30,6 +31,13 @@ |
30 | 31 | NMI_NMI, |
31 | 32 | NR_IRQS, |
32 | 33 | }; |
34 | + | |
35 | +typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long); | |
36 | + | |
37 | +int register_external_interrupt(u16 code, ext_int_handler_t handler); | |
38 | +int unregister_external_interrupt(u16 code, ext_int_handler_t handler); | |
39 | +void service_subclass_irq_register(void); | |
40 | +void service_subclass_irq_unregister(void); | |
33 | 41 | |
34 | 42 | #endif /* _ASM_IRQ_H */ |
arch/s390/include/asm/s390_ext.h
1 | -/* | |
2 | - * Copyright IBM Corp. 1999,2010 | |
3 | - * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>, | |
4 | - * Martin Schwidefsky <schwidefsky@de.ibm.com>, | |
5 | - */ | |
6 | - | |
7 | -#ifndef _S390_EXTINT_H | |
8 | -#define _S390_EXTINT_H | |
9 | - | |
10 | -#include <linux/types.h> | |
11 | - | |
12 | -typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long); | |
13 | - | |
14 | -int register_external_interrupt(__u16 code, ext_int_handler_t handler); | |
15 | -int unregister_external_interrupt(__u16 code, ext_int_handler_t handler); | |
16 | -void service_subclass_irq_register(void); | |
17 | -void service_subclass_irq_unregister(void); | |
18 | - | |
19 | -#endif /* _S390_EXTINT_H */ |
arch/s390/kernel/Makefile
... | ... | @@ -20,10 +20,10 @@ |
20 | 20 | |
21 | 21 | CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w |
22 | 22 | |
23 | -obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o \ | |
24 | - processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ | |
25 | - s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \ | |
26 | - vdso.o vtime.o sysinfo.o nmi.o sclp.o jump_label.o | |
23 | +obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \ | |
24 | + processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \ | |
25 | + debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \ | |
26 | + sysinfo.o jump_label.o | |
27 | 27 | |
28 | 28 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) |
29 | 29 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) |
arch/s390/kernel/dis.c
arch/s390/kernel/irq.c
1 | 1 | /* |
2 | - * Copyright IBM Corp. 2004,2010 | |
3 | - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | |
4 | - * Thomas Spatzier (tspat@de.ibm.com) | |
2 | + * Copyright IBM Corp. 2004,2011 | |
3 | + * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, | |
4 | + * Holger Smolinski <Holger.Smolinski@de.ibm.com>, | |
5 | + * Thomas Spatzier <tspat@de.ibm.com>, | |
5 | 6 | * |
6 | 7 | * This file contains interrupt related functions. |
7 | 8 | */ |
8 | 9 | |
9 | -#include <linux/module.h> | |
10 | -#include <linux/kernel.h> | |
11 | 10 | #include <linux/kernel_stat.h> |
12 | 11 | #include <linux/interrupt.h> |
13 | 12 | #include <linux/seq_file.h> |
14 | -#include <linux/cpu.h> | |
15 | 13 | #include <linux/proc_fs.h> |
16 | 14 | #include <linux/profile.h> |
15 | +#include <linux/module.h> | |
16 | +#include <linux/kernel.h> | |
17 | +#include <linux/ftrace.h> | |
18 | +#include <linux/errno.h> | |
19 | +#include <linux/slab.h> | |
20 | +#include <linux/cpu.h> | |
21 | +#include <asm/irq_regs.h> | |
22 | +#include <asm/cputime.h> | |
23 | +#include <asm/lowcore.h> | |
24 | +#include <asm/irq.h> | |
25 | +#include "entry.h" | |
17 | 26 | |
18 | 27 | struct irq_class { |
19 | 28 | char *name; |
... | ... | @@ -82,8 +91,7 @@ |
82 | 91 | * For compatibilty only. S/390 specific setup of interrupts et al. is done |
83 | 92 | * much later in init_channel_subsystem(). |
84 | 93 | */ |
85 | -void __init | |
86 | -init_IRQ(void) | |
94 | +void __init init_IRQ(void) | |
87 | 95 | { |
88 | 96 | /* nothing... */ |
89 | 97 | } |
... | ... | @@ -134,4 +142,117 @@ |
134 | 142 | create_prof_cpu_mask(root_irq_dir); |
135 | 143 | } |
136 | 144 | #endif |
145 | + | |
146 | +/* | |
147 | + * ext_int_hash[index] is the start of the list for all external interrupts | |
148 | + * that hash to this index. With the current set of external interrupts | |
149 | + * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000 | |
150 | + * iucv and 0x2603 pfault) this is always the first element. | |
151 | + */ | |
152 | + | |
153 | +struct ext_int_info { | |
154 | + struct ext_int_info *next; | |
155 | + ext_int_handler_t handler; | |
156 | + u16 code; | |
157 | +}; | |
158 | + | |
159 | +static struct ext_int_info *ext_int_hash[256]; | |
160 | + | |
161 | +static inline int ext_hash(u16 code) | |
162 | +{ | |
163 | + return (code + (code >> 9)) & 0xff; | |
164 | +} | |
165 | + | |
166 | +int register_external_interrupt(u16 code, ext_int_handler_t handler) | |
167 | +{ | |
168 | + struct ext_int_info *p; | |
169 | + int index; | |
170 | + | |
171 | + p = kmalloc(sizeof(*p), GFP_ATOMIC); | |
172 | + if (!p) | |
173 | + return -ENOMEM; | |
174 | + p->code = code; | |
175 | + p->handler = handler; | |
176 | + index = ext_hash(code); | |
177 | + p->next = ext_int_hash[index]; | |
178 | + ext_int_hash[index] = p; | |
179 | + return 0; | |
180 | +} | |
181 | +EXPORT_SYMBOL(register_external_interrupt); | |
182 | + | |
183 | +int unregister_external_interrupt(u16 code, ext_int_handler_t handler) | |
184 | +{ | |
185 | + struct ext_int_info *p, *q; | |
186 | + int index; | |
187 | + | |
188 | + index = ext_hash(code); | |
189 | + q = NULL; | |
190 | + p = ext_int_hash[index]; | |
191 | + while (p) { | |
192 | + if (p->code == code && p->handler == handler) | |
193 | + break; | |
194 | + q = p; | |
195 | + p = p->next; | |
196 | + } | |
197 | + if (!p) | |
198 | + return -ENOENT; | |
199 | + if (q) | |
200 | + q->next = p->next; | |
201 | + else | |
202 | + ext_int_hash[index] = p->next; | |
203 | + kfree(p); | |
204 | + return 0; | |
205 | +} | |
206 | +EXPORT_SYMBOL(unregister_external_interrupt); | |
207 | + | |
208 | +void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code, | |
209 | + unsigned int param32, unsigned long param64) | |
210 | +{ | |
211 | + struct pt_regs *old_regs; | |
212 | + unsigned short code; | |
213 | + struct ext_int_info *p; | |
214 | + int index; | |
215 | + | |
216 | + code = (unsigned short) ext_int_code; | |
217 | + old_regs = set_irq_regs(regs); | |
218 | + s390_idle_check(regs, S390_lowcore.int_clock, | |
219 | + S390_lowcore.async_enter_timer); | |
220 | + irq_enter(); | |
221 | + if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) | |
222 | + /* Serve timer interrupts first. */ | |
223 | + clock_comparator_work(); | |
224 | + kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; | |
225 | + if (code != 0x1004) | |
226 | + __get_cpu_var(s390_idle).nohz_delay = 1; | |
227 | + index = ext_hash(code); | |
228 | + for (p = ext_int_hash[index]; p; p = p->next) { | |
229 | + if (likely(p->code == code)) | |
230 | + p->handler(ext_int_code, param32, param64); | |
231 | + } | |
232 | + irq_exit(); | |
233 | + set_irq_regs(old_regs); | |
234 | +} | |
235 | + | |
236 | +static DEFINE_SPINLOCK(sc_irq_lock); | |
237 | +static int sc_irq_refcount; | |
238 | + | |
239 | +void service_subclass_irq_register(void) | |
240 | +{ | |
241 | + spin_lock(&sc_irq_lock); | |
242 | + if (!sc_irq_refcount) | |
243 | + ctl_set_bit(0, 9); | |
244 | + sc_irq_refcount++; | |
245 | + spin_unlock(&sc_irq_lock); | |
246 | +} | |
247 | +EXPORT_SYMBOL(service_subclass_irq_register); | |
248 | + | |
249 | +void service_subclass_irq_unregister(void) | |
250 | +{ | |
251 | + spin_lock(&sc_irq_lock); | |
252 | + sc_irq_refcount--; | |
253 | + if (!sc_irq_refcount) | |
254 | + ctl_clear_bit(0, 9); | |
255 | + spin_unlock(&sc_irq_lock); | |
256 | +} | |
257 | +EXPORT_SYMBOL(service_subclass_irq_unregister); |
arch/s390/kernel/s390_ext.c
1 | -/* | |
2 | - * Copyright IBM Corp. 1999,2010 | |
3 | - * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>, | |
4 | - * Martin Schwidefsky <schwidefsky@de.ibm.com>, | |
5 | - */ | |
6 | - | |
7 | -#include <linux/kernel_stat.h> | |
8 | -#include <linux/interrupt.h> | |
9 | -#include <linux/module.h> | |
10 | -#include <linux/kernel.h> | |
11 | -#include <linux/ftrace.h> | |
12 | -#include <linux/errno.h> | |
13 | -#include <linux/slab.h> | |
14 | -#include <asm/s390_ext.h> | |
15 | -#include <asm/irq_regs.h> | |
16 | -#include <asm/cputime.h> | |
17 | -#include <asm/lowcore.h> | |
18 | -#include <asm/irq.h> | |
19 | -#include "entry.h" | |
20 | - | |
21 | -struct ext_int_info { | |
22 | - struct ext_int_info *next; | |
23 | - ext_int_handler_t handler; | |
24 | - __u16 code; | |
25 | -}; | |
26 | - | |
27 | -/* | |
28 | - * ext_int_hash[index] is the start of the list for all external interrupts | |
29 | - * that hash to this index. With the current set of external interrupts | |
30 | - * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000 | |
31 | - * iucv and 0x2603 pfault) this is always the first element. | |
32 | - */ | |
33 | -static struct ext_int_info *ext_int_hash[256]; | |
34 | - | |
35 | -static inline int ext_hash(__u16 code) | |
36 | -{ | |
37 | - return (code + (code >> 9)) & 0xff; | |
38 | -} | |
39 | - | |
40 | -int register_external_interrupt(__u16 code, ext_int_handler_t handler) | |
41 | -{ | |
42 | - struct ext_int_info *p; | |
43 | - int index; | |
44 | - | |
45 | - p = kmalloc(sizeof(*p), GFP_ATOMIC); | |
46 | - if (!p) | |
47 | - return -ENOMEM; | |
48 | - p->code = code; | |
49 | - p->handler = handler; | |
50 | - index = ext_hash(code); | |
51 | - p->next = ext_int_hash[index]; | |
52 | - ext_int_hash[index] = p; | |
53 | - return 0; | |
54 | -} | |
55 | -EXPORT_SYMBOL(register_external_interrupt); | |
56 | - | |
57 | -int unregister_external_interrupt(__u16 code, ext_int_handler_t handler) | |
58 | -{ | |
59 | - struct ext_int_info *p, *q; | |
60 | - int index; | |
61 | - | |
62 | - index = ext_hash(code); | |
63 | - q = NULL; | |
64 | - p = ext_int_hash[index]; | |
65 | - while (p) { | |
66 | - if (p->code == code && p->handler == handler) | |
67 | - break; | |
68 | - q = p; | |
69 | - p = p->next; | |
70 | - } | |
71 | - if (!p) | |
72 | - return -ENOENT; | |
73 | - if (q) | |
74 | - q->next = p->next; | |
75 | - else | |
76 | - ext_int_hash[index] = p->next; | |
77 | - kfree(p); | |
78 | - return 0; | |
79 | -} | |
80 | -EXPORT_SYMBOL(unregister_external_interrupt); | |
81 | - | |
82 | -void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code, | |
83 | - unsigned int param32, unsigned long param64) | |
84 | -{ | |
85 | - struct pt_regs *old_regs; | |
86 | - unsigned short code; | |
87 | - struct ext_int_info *p; | |
88 | - int index; | |
89 | - | |
90 | - code = (unsigned short) ext_int_code; | |
91 | - old_regs = set_irq_regs(regs); | |
92 | - s390_idle_check(regs, S390_lowcore.int_clock, | |
93 | - S390_lowcore.async_enter_timer); | |
94 | - irq_enter(); | |
95 | - if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) | |
96 | - /* Serve timer interrupts first. */ | |
97 | - clock_comparator_work(); | |
98 | - kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; | |
99 | - if (code != 0x1004) | |
100 | - __get_cpu_var(s390_idle).nohz_delay = 1; | |
101 | - index = ext_hash(code); | |
102 | - for (p = ext_int_hash[index]; p; p = p->next) { | |
103 | - if (likely(p->code == code)) | |
104 | - p->handler(ext_int_code, param32, param64); | |
105 | - } | |
106 | - irq_exit(); | |
107 | - set_irq_regs(old_regs); | |
108 | -} | |
109 | - | |
110 | -static DEFINE_SPINLOCK(sc_irq_lock); | |
111 | -static int sc_irq_refcount; | |
112 | - | |
113 | -void service_subclass_irq_register(void) | |
114 | -{ | |
115 | - spin_lock(&sc_irq_lock); | |
116 | - if (!sc_irq_refcount) | |
117 | - ctl_set_bit(0, 9); | |
118 | - sc_irq_refcount++; | |
119 | - spin_unlock(&sc_irq_lock); | |
120 | -} | |
121 | -EXPORT_SYMBOL(service_subclass_irq_register); | |
122 | - | |
123 | -void service_subclass_irq_unregister(void) | |
124 | -{ | |
125 | - spin_lock(&sc_irq_lock); | |
126 | - sc_irq_refcount--; | |
127 | - if (!sc_irq_refcount) | |
128 | - ctl_clear_bit(0, 9); | |
129 | - spin_unlock(&sc_irq_lock); | |
130 | -} | |
131 | -EXPORT_SYMBOL(service_subclass_irq_unregister); |
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/s390/kernel/topology.c
arch/s390/kernel/traps.c
arch/s390/kernel/vtime.c
... | ... | @@ -22,10 +22,10 @@ |
22 | 22 | #include <linux/cpu.h> |
23 | 23 | #include <linux/kprobes.h> |
24 | 24 | |
25 | -#include <asm/s390_ext.h> | |
26 | 25 | #include <asm/timer.h> |
27 | 26 | #include <asm/irq_regs.h> |
28 | 27 | #include <asm/cputime.h> |
28 | +#include <asm/irq.h> | |
29 | 29 | |
30 | 30 | static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); |
31 | 31 |
arch/s390/mm/fault.c
arch/s390/oprofile/hwsampler.c
drivers/s390/block/dasd_diag.c
drivers/s390/char/sclp.c
drivers/s390/kvm/kvm_virtio.c