[S390] irq: external interrupt code passing
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Sun, 11 Mar 2012 15:59:31 +0000 (11:59 -0400)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Sun, 11 Mar 2012 15:59:29 +0000 (11:59 -0400)
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>
12 files changed:
arch/s390/include/asm/irq.h
arch/s390/kernel/entry.h
arch/s390/kernel/irq.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.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

index ba6d85f88d50018798b95c697ed5cf75d67b0183..acee1806f61e2b29d9eb138b28c29310cf1d2b93 100644 (file)
@@ -34,7 +34,12 @@ enum interruption_class {
        NR_IRQS,
 };
 
-typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
+struct ext_code {
+       unsigned short subcode;
+       unsigned short code;
+};
+
+typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long);
 
 int register_external_interrupt(u16 code, ext_int_handler_t handler);
 int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
index 4984785e3078938da4096bd99c71b3a7a3007b63..6cdddac93a2e48ed47f58d74648c5d858c7d8557 100644 (file)
@@ -35,7 +35,8 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
                    siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
 void do_notify_resume(struct pt_regs *regs);
 
-void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
+struct ext_code;
+void do_extint(struct pt_regs *regs, struct ext_code, unsigned int, unsigned long);
 void do_restart(void);
 void __init startup_init(void);
 void die(struct pt_regs *regs, const char *str);
index 09a014c6253710a38f5311dcbbd2c68fde783bb8..7a97d57f707392749bf08331603c3a7ef13a5b89 100644 (file)
@@ -209,29 +209,27 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
 }
 EXPORT_SYMBOL(unregister_external_interrupt);
 
-void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
+void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
                           unsigned int param32, unsigned long param64)
 {
        struct pt_regs *old_regs;
-       unsigned short code;
        struct ext_int_info *p;
        int index;
 
-       code = (unsigned short) ext_int_code;
        old_regs = set_irq_regs(regs);
        irq_enter();
        if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
                /* Serve timer interrupts first. */
                clock_comparator_work();
        kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
-       if (code != 0x1004)
+       if (ext_code.code != 0x1004)
                __get_cpu_var(s390_idle).nohz_delay = 1;
 
-       index = ext_hash(code);
+       index = ext_hash(ext_code.code);
        rcu_read_lock();
        list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
-               if (likely(p->code == code))
-                       p->handler(ext_int_code, param32, param64);
+               if (likely(p->code == ext_code.code))
+                       p->handler(ext_code, param32, param64);
        rcu_read_unlock();
        irq_exit();
        set_irq_regs(old_regs);
index afd6e5113a90dee922debfa8f20b25a817cc5101..734e644972ab488d1b289b730295819006d17076 100644 (file)
@@ -434,14 +434,14 @@ void smp_stop_cpu(void)
  * This is the main routine where commands issued by other
  * cpus are handled.
  */
-static void do_ext_call_interrupt(unsigned int ext_int_code,
+static void do_ext_call_interrupt(struct ext_code ext_code,
                                  unsigned int param32, unsigned long param64)
 {
        unsigned long bits;
        int cpu;
 
        cpu = smp_processor_id();
-       if ((ext_int_code & 0xffff) == 0x1202)
+       if (ext_code.code == 0x1202)
                kstat_cpu(cpu).irqs[EXTINT_EXC]++;
        else
                kstat_cpu(cpu).irqs[EXTINT_EMS]++;
index 14da278febbfa89c2a20ea797fa9a4c6ff1a1de1..d4e1cb1dbcd1a409af059d413bcef525f84cce52 100644 (file)
@@ -165,7 +165,7 @@ void init_cpu_timer(void)
        __ctl_set_bit(0, 4);
 }
 
-static void clock_comparator_interrupt(unsigned int ext_int_code,
+static void clock_comparator_interrupt(struct ext_code ext_code,
                                       unsigned int param32,
                                       unsigned long param64)
 {
@@ -177,7 +177,7 @@ static void clock_comparator_interrupt(unsigned int ext_int_code,
 static void etr_timing_alert(struct etr_irq_parm *);
 static void stp_timing_alert(struct stp_irq_parm *);
 
-static void timing_alert_interrupt(unsigned int ext_int_code,
+static void timing_alert_interrupt(struct ext_code ext_code,
                                   unsigned int param32, unsigned long param64)
 {
        kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++;
index 277ea712b2320a037265ed24023e0fd3e480f906..39ebff506946ef158d97604da5c87d41e312d81c 100644 (file)
@@ -220,7 +220,7 @@ static void do_callbacks(struct list_head *cb_list)
 /*
  * Handler for the virtual CPU timer.
  */
-static void do_cpu_timer_interrupt(unsigned int ext_int_code,
+static void do_cpu_timer_interrupt(struct ext_code ext_code,
                                   unsigned int param32, unsigned long param64)
 {
        struct vtimer_queue *vq;
index e8fcd928dc78005599f0b07aad6142052193f16d..b17c42df61c9f9b8ee29c8c452e42bc317fe8f25 100644 (file)
@@ -532,7 +532,7 @@ void pfault_fini(void)
 static DEFINE_SPINLOCK(pfault_lock);
 static LIST_HEAD(pfault_list);
 
-static void pfault_interrupt(unsigned int ext_int_code,
+static void pfault_interrupt(struct ext_code ext_code,
                             unsigned int param32, unsigned long param64)
 {
        struct task_struct *tsk;
@@ -545,7 +545,7 @@ static void pfault_interrupt(unsigned int ext_int_code,
         * in the 'cpu address' field associated with the
          * external interrupt. 
         */
-       subcode = ext_int_code >> 16;
+       subcode = ext_code.subcode;
        if ((subcode & 0xff00) != __SUBCODE_MASK)
                return;
        kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
index 9daee91e6c3fc20f8668a1797a8d388c102b62aa..12bea05a0fc18b6e70124510bc2d772fd87cbc71 100644 (file)
@@ -233,8 +233,8 @@ static inline unsigned long *trailer_entry_ptr(unsigned long v)
 }
 
 /* prototypes for external interrupt handler and worker */
-static void hws_ext_handler(unsigned int ext_int_code,
-                               unsigned int param32, unsigned long param64);
+static void hws_ext_handler(struct ext_code ext_code,
+                           unsigned int param32, unsigned long param64);
 
 static void worker(struct work_struct *work);
 
@@ -673,7 +673,7 @@ int hwsampler_activate(unsigned int cpu)
        return rc;
 }
 
-static void hws_ext_handler(unsigned int ext_int_code,
+static void hws_ext_handler(struct ext_code ext_code,
                            unsigned int param32, unsigned long param64)
 {
        struct hws_cpu_buffer *cb;
index 46784b83c5c4e1a4fcac2184dcebd6e37d014da3..0cea7e98f464bd30d54556675b7a5174ab420b15 100644 (file)
@@ -229,7 +229,7 @@ dasd_diag_term_IO(struct dasd_ccw_req * cqr)
 }
 
 /* Handle external interruption. */
-static void dasd_ext_handler(unsigned int ext_int_code,
+static void dasd_ext_handler(struct ext_code ext_code,
                             unsigned int param32, unsigned long param64)
 {
        struct dasd_ccw_req *cqr, *next;
@@ -239,7 +239,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
        addr_t ip;
        int rc;
 
-       switch (ext_int_code >> 24) {
+       switch (ext_code.subcode >> 8) {
        case DASD_DIAG_CODE_31BIT:
                ip = (addr_t) param32;
                break;
@@ -280,7 +280,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
        cqr->stopclk = get_clock();
 
        expires = 0;
-       if ((ext_int_code & 0xff0000) == 0) {
+       if ((ext_code.subcode & 0xff) == 0) {
                cqr->status = DASD_CQR_SUCCESS;
                /* Start first request on queue if possible -> fast_io. */
                if (!list_empty(&device->ccw_queue)) {
@@ -296,7 +296,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
                cqr->status = DASD_CQR_QUEUED;
                DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
                              "request %p was %d (%d retries left)", cqr,
-                             (ext_int_code >> 16) & 0xff, cqr->retries);
+                             ext_code.subcode & 0xff, cqr->retries);
                dasd_diag_erp(device);
        }
 
index eaa7e78186f969f0176a4c9f067688e1bf981bab..30f29a0020a12db90f944ec93f75fef4b241cf73 100644 (file)
@@ -393,7 +393,7 @@ __sclp_find_req(u32 sccb)
 /* Handler for external interruption. Perform request post-processing.
  * Prepare read event data request if necessary. Start processing of next
  * request on queue. */
-static void sclp_interrupt_handler(unsigned int ext_int_code,
+static void sclp_interrupt_handler(struct ext_code ext_code,
                                   unsigned int param32, unsigned long param64)
 {
        struct sclp_req *req;
@@ -818,7 +818,7 @@ EXPORT_SYMBOL(sclp_reactivate);
 
 /* Handler for external interruption used during initialization. Modify
  * request state to done. */
-static void sclp_check_handler(unsigned int ext_int_code,
+static void sclp_check_handler(struct ext_code ext_code,
                               unsigned int param32, unsigned long param64)
 {
        u32 finished_sccb;
index 7bc1955337ead5eecac17adc14021f9f5f843cd6..d74e9ae6dfb3e55407e27bfb5d6d997da1c845f1 100644 (file)
@@ -380,15 +380,13 @@ static void hotplug_devices(struct work_struct *dummy)
 /*
  * we emulate the request_irq behaviour on top of s390 extints
  */
-static void kvm_extint_handler(unsigned int ext_int_code,
+static void kvm_extint_handler(struct ext_code ext_code,
                               unsigned int param32, unsigned long param64)
 {
        struct virtqueue *vq;
-       u16 subcode;
        u32 param;
 
-       subcode = ext_int_code >> 16;
-       if ((subcode & 0xff00) != VIRTIO_SUBCODE_64)
+       if ((ext_code.subcode & 0xff00) != VIRTIO_SUBCODE_64)
                return;
        kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++;
 
index 403be43b793d737a73cf68a3eee8222fb996c535..3ad1f9db5f8b697167c8ed1ed249567f36ccf008 100644 (file)
@@ -1800,7 +1800,7 @@ static void iucv_work_fn(struct work_struct *work)
  * Handles external interrupts coming in from CP.
  * Places the interrupt buffer on a queue and schedules iucv_tasklet_fn().
  */
-static void iucv_external_interrupt(unsigned int ext_int_code,
+static void iucv_external_interrupt(struct ext_code ext_code,
                                    unsigned int param32, unsigned long param64)
 {
        struct iucv_irq_data *p;