15 #include <linux/module.h>
16 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/slab.h>
21 #include <asm/irq_regs.h>
22 #include <asm/cputime.h>
32 static const struct irq_class intrclass_names[] = {
35 [
EXTINT_CLK] = {.name =
"CLK", .desc =
"[EXT] Clock Comparator"},
36 [
EXTINT_EXC] = {.name =
"EXC", .desc =
"[EXT] External Call"},
37 [
EXTINT_EMS] = {.name =
"EMS", .desc =
"[EXT] Emergency Signal"},
38 [
EXTINT_TMR] = {.name =
"TMR", .desc =
"[EXT] CPU Timer"},
39 [
EXTINT_TLA] = {.name =
"TAL", .desc =
"[EXT] Timing Alert"},
40 [
EXTINT_PFL] = {.name =
"PFL", .desc =
"[EXT] Pseudo Page Fault"},
41 [
EXTINT_DSD] = {.name =
"DSD", .desc =
"[EXT] DASD Diag"},
42 [
EXTINT_VRT] = {.name =
"VRT", .desc =
"[EXT] Virtio"},
43 [
EXTINT_SCP] = {.name =
"SCP", .desc =
"[EXT] Service Call"},
44 [
EXTINT_IUC] = {.name =
"IUC", .desc =
"[EXT] IUCV"},
45 [
EXTINT_CMS] = {.name =
"CMS", .desc =
"[EXT] CPU-Measurement: Sampling"},
46 [
EXTINT_CMC] = {.name =
"CMC", .desc =
"[EXT] CPU-Measurement: Counter"},
47 [
EXTINT_CMR] = {.name =
"CMR", .desc =
"[EXT] CPU-Measurement: RI"},
48 [
IOINT_CIO] = {.name =
"CIO", .desc =
"[I/O] Common I/O Layer Interrupt"},
49 [
IOINT_QAI] = {.name =
"QAI", .desc =
"[I/O] QDIO Adapter Interrupt"},
50 [
IOINT_DAS] = {.name =
"DAS", .desc =
"[I/O] DASD"},
51 [
IOINT_C15] = {.name =
"C15", .desc =
"[I/O] 3215"},
52 [
IOINT_C70] = {.name =
"C70", .desc =
"[I/O] 3270"},
53 [
IOINT_TAP] = {.name =
"TAP", .desc =
"[I/O] Tape"},
54 [
IOINT_VMR] = {.name =
"VMR", .desc =
"[I/O] Unit Record Devices"},
55 [
IOINT_LCS] = {.name =
"LCS", .desc =
"[I/O] LCS"},
56 [
IOINT_CLW] = {.name =
"CLW", .desc =
"[I/O] CLAW"},
57 [
IOINT_CTC] = {.name =
"CTC", .desc =
"[I/O] CTC"},
58 [
IOINT_APB] = {.name =
"APB", .desc =
"[I/O] AP Bus"},
59 [
IOINT_ADM] = {.name =
"ADM", .desc =
"[I/O] EADM Subchannel"},
60 [
IOINT_CSC] = {.name =
"CSC", .desc =
"[I/O] CHSC Subchannel"},
61 [
NMI_NMI] = {.name =
"NMI", .desc =
"[NMI] Machine Check"},
69 int i = *(loff_t *) v,
j;
87 if (intrclass_names[i].
desc)
100 unsigned long flags, old,
new;
109 asm volatile(
"la %0,0(15)" :
"=a" (old));
117 asm volatile(
" la 15,0(%0)\n"
120 : :
"a" (
new),
"a" (old),
122 :
"0",
"1",
"2",
"3",
"4",
"5",
"14",
133 #ifdef CONFIG_PROC_FS
139 create_prof_cpu_mask(root_irq_dir);
147 static struct list_head ext_int_hash[256];
159 static void __init init_external_interrupts(
void)
163 for (idx = 0; idx <
ARRAY_SIZE(ext_int_hash); idx++)
164 INIT_LIST_HEAD(&ext_int_hash[idx]);
167 static inline int ext_hash(
u16 code)
169 return (code + (code >> 9)) & 0xff;
183 index = ext_hash(code);
186 list_add_rcu(&p->
entry, &ext_int_hash[index]);
187 spin_unlock_irqrestore(&ext_int_hash_lock, flags);
196 int index = ext_hash(code);
199 list_for_each_entry_rcu(p, &ext_int_hash[index],
entry) {
201 list_del_rcu(&p->
entry);
205 spin_unlock_irqrestore(&ext_int_hash_lock, flags);
211 unsigned int param32,
unsigned long param64)
217 old_regs = set_irq_regs(regs);
224 if (ext_code.
code != 0x1004)
227 index = ext_hash(ext_code.
code);
229 list_for_each_entry_rcu(p, &ext_int_hash[index],
entry)
231 p->
handler(ext_code, param32, param64);
234 set_irq_regs(old_regs);
239 init_external_interrupts();
243 static int sc_irq_refcount;
247 spin_lock(&sc_irq_lock);
248 if (!sc_irq_refcount)
251 spin_unlock(&sc_irq_lock);
257 spin_lock(&sc_irq_lock);
259 if (!sc_irq_refcount)
261 spin_unlock(&sc_irq_lock);
266 static int ma_subclass_refcount;
270 spin_lock(&ma_subclass_lock);
271 if (!ma_subclass_refcount)
273 ma_subclass_refcount++;
274 spin_unlock(&ma_subclass_lock);
280 spin_lock(&ma_subclass_lock);
281 ma_subclass_refcount--;
282 if (!ma_subclass_refcount)
284 spin_unlock(&ma_subclass_lock);