aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/s390_ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/s390_ext.c')
-rw-r--r--arch/s390/kernel/s390_ext.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 3bdd38ec71da..207bc511a6e3 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -19,7 +19,6 @@
19#include <asm/irq.h> 19#include <asm/irq.h>
20 20
21/* 21/*
22 * Simple hash strategy: index = code & 0xff;
23 * ext_int_hash[index] is the start of the list for all external interrupts 22 * ext_int_hash[index] is the start of the list for all external interrupts
24 * that hash to this index. With the current set of external interrupts 23 * that hash to this index. With the current set of external interrupts
25 * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000 24 * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
@@ -27,6 +26,11 @@
27 */ 26 */
28ext_int_info_t *ext_int_hash[256] = { 0, }; 27ext_int_info_t *ext_int_hash[256] = { 0, };
29 28
29static inline int ext_hash(__u16 code)
30{
31 return (code + (code >> 9)) & 0xff;
32}
33
30int register_external_interrupt(__u16 code, ext_int_handler_t handler) 34int register_external_interrupt(__u16 code, ext_int_handler_t handler)
31{ 35{
32 ext_int_info_t *p; 36 ext_int_info_t *p;
@@ -37,7 +41,7 @@ int register_external_interrupt(__u16 code, ext_int_handler_t handler)
37 return -ENOMEM; 41 return -ENOMEM;
38 p->code = code; 42 p->code = code;
39 p->handler = handler; 43 p->handler = handler;
40 index = code & 0xff; 44 index = ext_hash(code);
41 p->next = ext_int_hash[index]; 45 p->next = ext_int_hash[index];
42 ext_int_hash[index] = p; 46 ext_int_hash[index] = p;
43 return 0; 47 return 0;
@@ -52,7 +56,7 @@ int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
52 return -EINVAL; 56 return -EINVAL;
53 p->code = code; 57 p->code = code;
54 p->handler = handler; 58 p->handler = handler;
55 index = code & 0xff; 59 index = ext_hash(code);
56 p->next = ext_int_hash[index]; 60 p->next = ext_int_hash[index];
57 ext_int_hash[index] = p; 61 ext_int_hash[index] = p;
58 return 0; 62 return 0;
@@ -63,7 +67,7 @@ int unregister_external_interrupt(__u16 code, ext_int_handler_t handler)
63 ext_int_info_t *p, *q; 67 ext_int_info_t *p, *q;
64 int index; 68 int index;
65 69
66 index = code & 0xff; 70 index = ext_hash(code);
67 q = NULL; 71 q = NULL;
68 p = ext_int_hash[index]; 72 p = ext_int_hash[index];
69 while (p != NULL) { 73 while (p != NULL) {
@@ -90,7 +94,7 @@ int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
90 94
91 if (p == NULL || p->code != code || p->handler != handler) 95 if (p == NULL || p->code != code || p->handler != handler)
92 return -EINVAL; 96 return -EINVAL;
93 index = code & 0xff; 97 index = ext_hash(code);
94 q = ext_int_hash[index]; 98 q = ext_int_hash[index];
95 if (p != q) { 99 if (p != q) {
96 while (q != NULL) { 100 while (q != NULL) {
@@ -120,7 +124,7 @@ void do_extint(struct pt_regs *regs, unsigned short code)
120 */ 124 */
121 account_ticks(regs); 125 account_ticks(regs);
122 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; 126 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
123 index = code & 0xff; 127 index = ext_hash(code);
124 for (p = ext_int_hash[index]; p; p = p->next) { 128 for (p = ext_int_hash[index]; p; p = p->next) {
125 if (likely(p->code == code)) { 129 if (likely(p->code == code)) {
126 if (likely(p->handler)) 130 if (likely(p->handler))