aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2011-01-05 06:47:41 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-05 06:47:26 -0500
commitb1b750918566c6c4e8ed6c9b3c0f05b4c0a8805c (patch)
treea40f322d2b65f26e82d93139d0dc275543e08b27
parent98b799800c3e2f855ef2d2c6263e84fa5d1420a0 (diff)
[S390] extint: get rid of early code plus cleanup
Get rid of register/unregister_early_external_interrupt() and clean up the code while at it. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/s390_ext.h29
-rw-r--r--arch/s390/kernel/s390_ext.c125
2 files changed, 51 insertions, 103 deletions
diff --git a/arch/s390/include/asm/s390_ext.h b/arch/s390/include/asm/s390_ext.h
index 1a9307e70842..080876d5f196 100644
--- a/arch/s390/include/asm/s390_ext.h
+++ b/arch/s390/include/asm/s390_ext.h
@@ -1,32 +1,17 @@
1#ifndef _S390_EXTINT_H
2#define _S390_EXTINT_H
3
4/* 1/*
5 * include/asm-s390/s390_ext.h 2 * Copyright IBM Corp. 1999,2010
6 * 3 * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
7 * S390 version 4 * Martin Schwidefsky <schwidefsky@de.ibm.com>,
8 * Copyright IBM Corp. 1999,2007
9 * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com),
10 * Martin Schwidefsky (schwidefsky@de.ibm.com)
11 */ 5 */
12 6
7#ifndef _S390_EXTINT_H
8#define _S390_EXTINT_H
9
13#include <linux/types.h> 10#include <linux/types.h>
14 11
15typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long); 12typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
16 13
17typedef struct ext_int_info_t {
18 struct ext_int_info_t *next;
19 ext_int_handler_t handler;
20 __u16 code;
21} ext_int_info_t;
22
23extern ext_int_info_t *ext_int_hash[];
24
25int register_external_interrupt(__u16 code, ext_int_handler_t handler); 14int register_external_interrupt(__u16 code, ext_int_handler_t handler);
26int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
27 ext_int_info_t *info);
28int unregister_external_interrupt(__u16 code, ext_int_handler_t handler); 15int unregister_external_interrupt(__u16 code, ext_int_handler_t handler);
29int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
30 ext_int_info_t *info);
31 16
32#endif 17#endif /* _S390_EXTINT_H */
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index bd1db508e8af..185029919c4d 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -1,33 +1,36 @@
1/* 1/*
2 * arch/s390/kernel/s390_ext.c 2 * Copyright IBM Corp. 1999,2010
3 * 3 * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
4 * S390 version 4 * Martin Schwidefsky <schwidefsky@de.ibm.com>,
5 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com),
7 * Martin Schwidefsky (schwidefsky@de.ibm.com)
8 */ 5 */
9 6
7#include <linux/kernel_stat.h>
8#include <linux/interrupt.h>
10#include <linux/module.h> 9#include <linux/module.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/ftrace.h> 11#include <linux/ftrace.h>
14#include <linux/errno.h> 12#include <linux/errno.h>
15#include <linux/kernel_stat.h> 13#include <linux/slab.h>
16#include <linux/interrupt.h>
17#include <asm/cputime.h>
18#include <asm/lowcore.h>
19#include <asm/s390_ext.h> 14#include <asm/s390_ext.h>
20#include <asm/irq_regs.h> 15#include <asm/irq_regs.h>
16#include <asm/cputime.h>
17#include <asm/lowcore.h>
21#include <asm/irq.h> 18#include <asm/irq.h>
22#include "entry.h" 19#include "entry.h"
23 20
21struct ext_int_info {
22 struct ext_int_info *next;
23 ext_int_handler_t handler;
24 __u16 code;
25};
26
24/* 27/*
25 * ext_int_hash[index] is the start of the list for all external interrupts 28 * ext_int_hash[index] is the start of the list for all external interrupts
26 * that hash to this index. With the current set of external interrupts 29 * that hash to this index. With the current set of external interrupts
27 * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000 30 * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
28 * iucv and 0x2603 pfault) this is always the first element. 31 * iucv and 0x2603 pfault) this is always the first element.
29 */ 32 */
30ext_int_info_t *ext_int_hash[256] = { NULL, }; 33static struct ext_int_info *ext_int_hash[256];
31 34
32static inline int ext_hash(__u16 code) 35static inline int ext_hash(__u16 code)
33{ 36{
@@ -36,90 +39,53 @@ static inline int ext_hash(__u16 code)
36 39
37int register_external_interrupt(__u16 code, ext_int_handler_t handler) 40int register_external_interrupt(__u16 code, ext_int_handler_t handler)
38{ 41{
39 ext_int_info_t *p; 42 struct ext_int_info *p;
40 int index; 43 int index;
41
42 p = kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
43 if (p == NULL)
44 return -ENOMEM;
45 p->code = code;
46 p->handler = handler;
47 index = ext_hash(code);
48 p->next = ext_int_hash[index];
49 ext_int_hash[index] = p;
50 return 0;
51}
52
53int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
54 ext_int_info_t *p)
55{
56 int index;
57 44
58 if (p == NULL) 45 p = kmalloc(sizeof(*p), GFP_ATOMIC);
59 return -EINVAL; 46 if (!p)
60 p->code = code; 47 return -ENOMEM;
61 p->handler = handler; 48 p->code = code;
49 p->handler = handler;
62 index = ext_hash(code); 50 index = ext_hash(code);
63 p->next = ext_int_hash[index]; 51 p->next = ext_int_hash[index];
64 ext_int_hash[index] = p; 52 ext_int_hash[index] = p;
65 return 0; 53 return 0;
66} 54}
55EXPORT_SYMBOL(register_external_interrupt);
67 56
68int unregister_external_interrupt(__u16 code, ext_int_handler_t handler) 57int unregister_external_interrupt(__u16 code, ext_int_handler_t handler)
69{ 58{
70 ext_int_info_t *p, *q; 59 struct ext_int_info *p, *q;
71 int index;
72
73 index = ext_hash(code);
74 q = NULL;
75 p = ext_int_hash[index];
76 while (p != NULL) {
77 if (p->code == code && p->handler == handler)
78 break;
79 q = p;
80 p = p->next;
81 }
82 if (p == NULL)
83 return -ENOENT;
84 if (q != NULL)
85 q->next = p->next;
86 else
87 ext_int_hash[index] = p->next;
88 kfree(p);
89 return 0;
90}
91
92int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
93 ext_int_info_t *p)
94{
95 ext_int_info_t *q;
96 int index; 60 int index;
97 61
98 if (p == NULL || p->code != code || p->handler != handler)
99 return -EINVAL;
100 index = ext_hash(code); 62 index = ext_hash(code);
101 q = ext_int_hash[index]; 63 q = NULL;
102 if (p != q) { 64 p = ext_int_hash[index];
103 while (q != NULL) { 65 while (p) {
104 if (q->next == p) 66 if (p->code == code && p->handler == handler)
105 break; 67 break;
106 q = q->next; 68 q = p;
107 } 69 p = p->next;
108 if (q == NULL) 70 }
109 return -ENOENT; 71 if (!p)
72 return -ENOENT;
73 if (q)
110 q->next = p->next; 74 q->next = p->next;
111 } else 75 else
112 ext_int_hash[index] = p->next; 76 ext_int_hash[index] = p->next;
77 kfree(p);
113 return 0; 78 return 0;
114} 79}
80EXPORT_SYMBOL(unregister_external_interrupt);
115 81
116void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code, 82void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
117 unsigned int param32, unsigned long param64) 83 unsigned int param32, unsigned long param64)
118{ 84{
119 struct pt_regs *old_regs; 85 struct pt_regs *old_regs;
120 unsigned short code; 86 unsigned short code;
121 ext_int_info_t *p; 87 struct ext_int_info *p;
122 int index; 88 int index;
123 89
124 code = (unsigned short) ext_int_code; 90 code = (unsigned short) ext_int_code;
125 old_regs = set_irq_regs(regs); 91 old_regs = set_irq_regs(regs);
@@ -132,7 +98,7 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
132 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; 98 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
133 if (code != 0x1004) 99 if (code != 0x1004)
134 __get_cpu_var(s390_idle).nohz_delay = 1; 100 __get_cpu_var(s390_idle).nohz_delay = 1;
135 index = ext_hash(code); 101 index = ext_hash(code);
136 for (p = ext_int_hash[index]; p; p = p->next) { 102 for (p = ext_int_hash[index]; p; p = p->next) {
137 if (likely(p->code == code)) 103 if (likely(p->code == code))
138 p->handler(ext_int_code, param32, param64); 104 p->handler(ext_int_code, param32, param64);
@@ -140,6 +106,3 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
140 irq_exit(); 106 irq_exit();
141 set_irq_regs(old_regs); 107 set_irq_regs(old_regs);
142} 108}
143
144EXPORT_SYMBOL(register_external_interrupt);
145EXPORT_SYMBOL(unregister_external_interrupt);