aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2012-03-11 11:59:31 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-03-11 11:59:29 -0400
commitfde15c3a3adc7b65cd0610dd6bca4804ee7ffd38 (patch)
tree62c1f93d33a7449fb07250993e4cf4086d5aa273
parent2215011dd9c1b01f1fc430620ed31f2baad267c3 (diff)
[S390] irq: external interrupt code passing
The external interrupt handlers have a parameter called ext_int_code. Besides the name this paramter does not only contain the ext_int_code but in addition also the "cpu address" (POP) which caused the external interrupt. To make the code a bit more obvious pass a struct instead so the called function can easily distinguish between external interrupt code and cpu address. The cpu address field however is named "subcode" since some external interrupt sources do not pass a cpu address but a different parameter (or none at all). 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/irq.h7
-rw-r--r--arch/s390/kernel/entry.h3
-rw-r--r--arch/s390/kernel/irq.c12
-rw-r--r--arch/s390/kernel/smp.c4
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vtime.c2
-rw-r--r--arch/s390/mm/fault.c4
-rw-r--r--arch/s390/oprofile/hwsampler.c6
-rw-r--r--drivers/s390/block/dasd_diag.c8
-rw-r--r--drivers/s390/char/sclp.c4
-rw-r--r--drivers/s390/kvm/kvm_virtio.c6
-rw-r--r--net/iucv/iucv.c2
12 files changed, 32 insertions, 30 deletions
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index ba6d85f88d50..acee1806f61e 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -34,7 +34,12 @@ enum interruption_class {
34 NR_IRQS, 34 NR_IRQS,
35}; 35};
36 36
37typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long); 37struct ext_code {
38 unsigned short subcode;
39 unsigned short code;
40};
41
42typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long);
38 43
39int register_external_interrupt(u16 code, ext_int_handler_t handler); 44int register_external_interrupt(u16 code, ext_int_handler_t handler);
40int unregister_external_interrupt(u16 code, ext_int_handler_t handler); 45int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 4984785e3078..6cdddac93a2e 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -35,7 +35,8 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
35 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs); 35 siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
36void do_notify_resume(struct pt_regs *regs); 36void do_notify_resume(struct pt_regs *regs);
37 37
38void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long); 38struct ext_code;
39void do_extint(struct pt_regs *regs, struct ext_code, unsigned int, unsigned long);
39void do_restart(void); 40void do_restart(void);
40void __init startup_init(void); 41void __init startup_init(void);
41void die(struct pt_regs *regs, const char *str); 42void die(struct pt_regs *regs, const char *str);
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 09a014c62537..7a97d57f7073 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -209,29 +209,27 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
209} 209}
210EXPORT_SYMBOL(unregister_external_interrupt); 210EXPORT_SYMBOL(unregister_external_interrupt);
211 211
212void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code, 212void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
213 unsigned int param32, unsigned long param64) 213 unsigned int param32, unsigned long param64)
214{ 214{
215 struct pt_regs *old_regs; 215 struct pt_regs *old_regs;
216 unsigned short code;
217 struct ext_int_info *p; 216 struct ext_int_info *p;
218 int index; 217 int index;
219 218
220 code = (unsigned short) ext_int_code;
221 old_regs = set_irq_regs(regs); 219 old_regs = set_irq_regs(regs);
222 irq_enter(); 220 irq_enter();
223 if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) 221 if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
224 /* Serve timer interrupts first. */ 222 /* Serve timer interrupts first. */
225 clock_comparator_work(); 223 clock_comparator_work();
226 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; 224 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
227 if (code != 0x1004) 225 if (ext_code.code != 0x1004)
228 __get_cpu_var(s390_idle).nohz_delay = 1; 226 __get_cpu_var(s390_idle).nohz_delay = 1;
229 227
230 index = ext_hash(code); 228 index = ext_hash(ext_code.code);
231 rcu_read_lock(); 229 rcu_read_lock();
232 list_for_each_entry_rcu(p, &ext_int_hash[index], entry) 230 list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
233 if (likely(p->code == code)) 231 if (likely(p->code == ext_code.code))
234 p->handler(ext_int_code, param32, param64); 232 p->handler(ext_code, param32, param64);
235 rcu_read_unlock(); 233 rcu_read_unlock();
236 irq_exit(); 234 irq_exit();
237 set_irq_regs(old_regs); 235 set_irq_regs(old_regs);
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index afd6e5113a90..734e644972ab 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -434,14 +434,14 @@ void smp_stop_cpu(void)
434 * This is the main routine where commands issued by other 434 * This is the main routine where commands issued by other
435 * cpus are handled. 435 * cpus are handled.
436 */ 436 */
437static void do_ext_call_interrupt(unsigned int ext_int_code, 437static void do_ext_call_interrupt(struct ext_code ext_code,
438 unsigned int param32, unsigned long param64) 438 unsigned int param32, unsigned long param64)
439{ 439{
440 unsigned long bits; 440 unsigned long bits;
441 int cpu; 441 int cpu;
442 442
443 cpu = smp_processor_id(); 443 cpu = smp_processor_id();
444 if ((ext_int_code & 0xffff) == 0x1202) 444 if (ext_code.code == 0x1202)
445 kstat_cpu(cpu).irqs[EXTINT_EXC]++; 445 kstat_cpu(cpu).irqs[EXTINT_EXC]++;
446 else 446 else
447 kstat_cpu(cpu).irqs[EXTINT_EMS]++; 447 kstat_cpu(cpu).irqs[EXTINT_EMS]++;
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 14da278febbf..d4e1cb1dbcd1 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -165,7 +165,7 @@ void init_cpu_timer(void)
165 __ctl_set_bit(0, 4); 165 __ctl_set_bit(0, 4);
166} 166}
167 167
168static void clock_comparator_interrupt(unsigned int ext_int_code, 168static void clock_comparator_interrupt(struct ext_code ext_code,
169 unsigned int param32, 169 unsigned int param32,
170 unsigned long param64) 170 unsigned long param64)
171{ 171{
@@ -177,7 +177,7 @@ static void clock_comparator_interrupt(unsigned int ext_int_code,
177static void etr_timing_alert(struct etr_irq_parm *); 177static void etr_timing_alert(struct etr_irq_parm *);
178static void stp_timing_alert(struct stp_irq_parm *); 178static void stp_timing_alert(struct stp_irq_parm *);
179 179
180static void timing_alert_interrupt(unsigned int ext_int_code, 180static void timing_alert_interrupt(struct ext_code ext_code,
181 unsigned int param32, unsigned long param64) 181 unsigned int param32, unsigned long param64)
182{ 182{
183 kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++; 183 kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++;
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 277ea712b232..39ebff506946 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -220,7 +220,7 @@ static void do_callbacks(struct list_head *cb_list)
220/* 220/*
221 * Handler for the virtual CPU timer. 221 * Handler for the virtual CPU timer.
222 */ 222 */
223static void do_cpu_timer_interrupt(unsigned int ext_int_code, 223static void do_cpu_timer_interrupt(struct ext_code ext_code,
224 unsigned int param32, unsigned long param64) 224 unsigned int param32, unsigned long param64)
225{ 225{
226 struct vtimer_queue *vq; 226 struct vtimer_queue *vq;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index e8fcd928dc78..b17c42df61c9 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -532,7 +532,7 @@ void pfault_fini(void)
532static DEFINE_SPINLOCK(pfault_lock); 532static DEFINE_SPINLOCK(pfault_lock);
533static LIST_HEAD(pfault_list); 533static LIST_HEAD(pfault_list);
534 534
535static void pfault_interrupt(unsigned int ext_int_code, 535static void pfault_interrupt(struct ext_code ext_code,
536 unsigned int param32, unsigned long param64) 536 unsigned int param32, unsigned long param64)
537{ 537{
538 struct task_struct *tsk; 538 struct task_struct *tsk;
@@ -545,7 +545,7 @@ static void pfault_interrupt(unsigned int ext_int_code,
545 * in the 'cpu address' field associated with the 545 * in the 'cpu address' field associated with the
546 * external interrupt. 546 * external interrupt.
547 */ 547 */
548 subcode = ext_int_code >> 16; 548 subcode = ext_code.subcode;
549 if ((subcode & 0xff00) != __SUBCODE_MASK) 549 if ((subcode & 0xff00) != __SUBCODE_MASK)
550 return; 550 return;
551 kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; 551 kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c
index 9daee91e6c3f..12bea05a0fc1 100644
--- a/arch/s390/oprofile/hwsampler.c
+++ b/arch/s390/oprofile/hwsampler.c
@@ -233,8 +233,8 @@ static inline unsigned long *trailer_entry_ptr(unsigned long v)
233} 233}
234 234
235/* prototypes for external interrupt handler and worker */ 235/* prototypes for external interrupt handler and worker */
236static void hws_ext_handler(unsigned int ext_int_code, 236static void hws_ext_handler(struct ext_code ext_code,
237 unsigned int param32, unsigned long param64); 237 unsigned int param32, unsigned long param64);
238 238
239static void worker(struct work_struct *work); 239static void worker(struct work_struct *work);
240 240
@@ -673,7 +673,7 @@ int hwsampler_activate(unsigned int cpu)
673 return rc; 673 return rc;
674} 674}
675 675
676static void hws_ext_handler(unsigned int ext_int_code, 676static void hws_ext_handler(struct ext_code ext_code,
677 unsigned int param32, unsigned long param64) 677 unsigned int param32, unsigned long param64)
678{ 678{
679 struct hws_cpu_buffer *cb; 679 struct hws_cpu_buffer *cb;
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 46784b83c5c4..0cea7e98f464 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -229,7 +229,7 @@ dasd_diag_term_IO(struct dasd_ccw_req * cqr)
229} 229}
230 230
231/* Handle external interruption. */ 231/* Handle external interruption. */
232static void dasd_ext_handler(unsigned int ext_int_code, 232static void dasd_ext_handler(struct ext_code ext_code,
233 unsigned int param32, unsigned long param64) 233 unsigned int param32, unsigned long param64)
234{ 234{
235 struct dasd_ccw_req *cqr, *next; 235 struct dasd_ccw_req *cqr, *next;
@@ -239,7 +239,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
239 addr_t ip; 239 addr_t ip;
240 int rc; 240 int rc;
241 241
242 switch (ext_int_code >> 24) { 242 switch (ext_code.subcode >> 8) {
243 case DASD_DIAG_CODE_31BIT: 243 case DASD_DIAG_CODE_31BIT:
244 ip = (addr_t) param32; 244 ip = (addr_t) param32;
245 break; 245 break;
@@ -280,7 +280,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
280 cqr->stopclk = get_clock(); 280 cqr->stopclk = get_clock();
281 281
282 expires = 0; 282 expires = 0;
283 if ((ext_int_code & 0xff0000) == 0) { 283 if ((ext_code.subcode & 0xff) == 0) {
284 cqr->status = DASD_CQR_SUCCESS; 284 cqr->status = DASD_CQR_SUCCESS;
285 /* Start first request on queue if possible -> fast_io. */ 285 /* Start first request on queue if possible -> fast_io. */
286 if (!list_empty(&device->ccw_queue)) { 286 if (!list_empty(&device->ccw_queue)) {
@@ -296,7 +296,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
296 cqr->status = DASD_CQR_QUEUED; 296 cqr->status = DASD_CQR_QUEUED;
297 DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for " 297 DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
298 "request %p was %d (%d retries left)", cqr, 298 "request %p was %d (%d retries left)", cqr,
299 (ext_int_code >> 16) & 0xff, cqr->retries); 299 ext_code.subcode & 0xff, cqr->retries);
300 dasd_diag_erp(device); 300 dasd_diag_erp(device);
301 } 301 }
302 302
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index eaa7e78186f9..30f29a0020a1 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -393,7 +393,7 @@ __sclp_find_req(u32 sccb)
393/* Handler for external interruption. Perform request post-processing. 393/* Handler for external interruption. Perform request post-processing.
394 * Prepare read event data request if necessary. Start processing of next 394 * Prepare read event data request if necessary. Start processing of next
395 * request on queue. */ 395 * request on queue. */
396static void sclp_interrupt_handler(unsigned int ext_int_code, 396static void sclp_interrupt_handler(struct ext_code ext_code,
397 unsigned int param32, unsigned long param64) 397 unsigned int param32, unsigned long param64)
398{ 398{
399 struct sclp_req *req; 399 struct sclp_req *req;
@@ -818,7 +818,7 @@ EXPORT_SYMBOL(sclp_reactivate);
818 818
819/* Handler for external interruption used during initialization. Modify 819/* Handler for external interruption used during initialization. Modify
820 * request state to done. */ 820 * request state to done. */
821static void sclp_check_handler(unsigned int ext_int_code, 821static void sclp_check_handler(struct ext_code ext_code,
822 unsigned int param32, unsigned long param64) 822 unsigned int param32, unsigned long param64)
823{ 823{
824 u32 finished_sccb; 824 u32 finished_sccb;
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 7bc1955337ea..d74e9ae6dfb3 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -380,15 +380,13 @@ static void hotplug_devices(struct work_struct *dummy)
380/* 380/*
381 * we emulate the request_irq behaviour on top of s390 extints 381 * we emulate the request_irq behaviour on top of s390 extints
382 */ 382 */
383static void kvm_extint_handler(unsigned int ext_int_code, 383static void kvm_extint_handler(struct ext_code ext_code,
384 unsigned int param32, unsigned long param64) 384 unsigned int param32, unsigned long param64)
385{ 385{
386 struct virtqueue *vq; 386 struct virtqueue *vq;
387 u16 subcode;
388 u32 param; 387 u32 param;
389 388
390 subcode = ext_int_code >> 16; 389 if ((ext_code.subcode & 0xff00) != VIRTIO_SUBCODE_64)
391 if ((subcode & 0xff00) != VIRTIO_SUBCODE_64)
392 return; 390 return;
393 kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; 391 kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++;
394 392
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 403be43b793d..3ad1f9db5f8b 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -1800,7 +1800,7 @@ static void iucv_work_fn(struct work_struct *work)
1800 * Handles external interrupts coming in from CP. 1800 * Handles external interrupts coming in from CP.
1801 * Places the interrupt buffer on a queue and schedules iucv_tasklet_fn(). 1801 * Places the interrupt buffer on a queue and schedules iucv_tasklet_fn().
1802 */ 1802 */
1803static void iucv_external_interrupt(unsigned int ext_int_code, 1803static void iucv_external_interrupt(struct ext_code ext_code,
1804 unsigned int param32, unsigned long param64) 1804 unsigned int param32, unsigned long param64)
1805{ 1805{
1806 struct iucv_irq_data *p; 1806 struct iucv_irq_data *p;