aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/sclp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char/sclp.c')
-rw-r--r--drivers/s390/char/sclp.c39
1 files changed, 18 insertions, 21 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index f6d72e1f2a38..eaa7e78186f9 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -7,6 +7,7 @@
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 */ 8 */
9 9
10#include <linux/kernel_stat.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/err.h> 12#include <linux/err.h>
12#include <linux/spinlock.h> 13#include <linux/spinlock.h>
@@ -19,15 +20,12 @@
19#include <linux/completion.h> 20#include <linux/completion.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <asm/types.h> 22#include <asm/types.h>
22#include <asm/s390_ext.h> 23#include <asm/irq.h>
23 24
24#include "sclp.h" 25#include "sclp.h"
25 26
26#define SCLP_HEADER "sclp: " 27#define SCLP_HEADER "sclp: "
27 28
28/* Structure for register_early_external_interrupt. */
29static ext_int_info_t ext_int_info_hwc;
30
31/* Lock to protect internal data consistency. */ 29/* Lock to protect internal data consistency. */
32static DEFINE_SPINLOCK(sclp_lock); 30static DEFINE_SPINLOCK(sclp_lock);
33 31
@@ -395,16 +393,17 @@ __sclp_find_req(u32 sccb)
395/* Handler for external interruption. Perform request post-processing. 393/* Handler for external interruption. Perform request post-processing.
396 * Prepare read event data request if necessary. Start processing of next 394 * Prepare read event data request if necessary. Start processing of next
397 * request on queue. */ 395 * request on queue. */
398static void 396static void sclp_interrupt_handler(unsigned int ext_int_code,
399sclp_interrupt_handler(__u16 code) 397 unsigned int param32, unsigned long param64)
400{ 398{
401 struct sclp_req *req; 399 struct sclp_req *req;
402 u32 finished_sccb; 400 u32 finished_sccb;
403 u32 evbuf_pending; 401 u32 evbuf_pending;
404 402
403 kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++;
405 spin_lock(&sclp_lock); 404 spin_lock(&sclp_lock);
406 finished_sccb = S390_lowcore.ext_params & 0xfffffff8; 405 finished_sccb = param32 & 0xfffffff8;
407 evbuf_pending = S390_lowcore.ext_params & 0x3; 406 evbuf_pending = param32 & 0x3;
408 if (finished_sccb) { 407 if (finished_sccb) {
409 del_timer(&sclp_request_timer); 408 del_timer(&sclp_request_timer);
410 sclp_running_state = sclp_running_state_reset_pending; 409 sclp_running_state = sclp_running_state_reset_pending;
@@ -468,7 +467,7 @@ sclp_sync_wait(void)
468 cr0_sync &= 0xffff00a0; 467 cr0_sync &= 0xffff00a0;
469 cr0_sync |= 0x00000200; 468 cr0_sync |= 0x00000200;
470 __ctl_load(cr0_sync, 0, 0); 469 __ctl_load(cr0_sync, 0, 0);
471 __raw_local_irq_stosm(0x01); 470 __arch_local_irq_stosm(0x01);
472 /* Loop until driver state indicates finished request */ 471 /* Loop until driver state indicates finished request */
473 while (sclp_running_state != sclp_running_state_idle) { 472 while (sclp_running_state != sclp_running_state_idle) {
474 /* Check for expired request timer */ 473 /* Check for expired request timer */
@@ -819,12 +818,13 @@ EXPORT_SYMBOL(sclp_reactivate);
819 818
820/* Handler for external interruption used during initialization. Modify 819/* Handler for external interruption used during initialization. Modify
821 * request state to done. */ 820 * request state to done. */
822static void 821static void sclp_check_handler(unsigned int ext_int_code,
823sclp_check_handler(__u16 code) 822 unsigned int param32, unsigned long param64)
824{ 823{
825 u32 finished_sccb; 824 u32 finished_sccb;
826 825
827 finished_sccb = S390_lowcore.ext_params & 0xfffffff8; 826 kstat_cpu(smp_processor_id()).irqs[EXTINT_SCP]++;
827 finished_sccb = param32 & 0xfffffff8;
828 /* Is this the interrupt we are waiting for? */ 828 /* Is this the interrupt we are waiting for? */
829 if (finished_sccb == 0) 829 if (finished_sccb == 0)
830 return; 830 return;
@@ -866,8 +866,7 @@ sclp_check_interface(void)
866 866
867 spin_lock_irqsave(&sclp_lock, flags); 867 spin_lock_irqsave(&sclp_lock, flags);
868 /* Prepare init mask command */ 868 /* Prepare init mask command */
869 rc = register_early_external_interrupt(0x2401, sclp_check_handler, 869 rc = register_external_interrupt(0x2401, sclp_check_handler);
870 &ext_int_info_hwc);
871 if (rc) { 870 if (rc) {
872 spin_unlock_irqrestore(&sclp_lock, flags); 871 spin_unlock_irqrestore(&sclp_lock, flags);
873 return rc; 872 return rc;
@@ -885,12 +884,12 @@ sclp_check_interface(void)
885 spin_unlock_irqrestore(&sclp_lock, flags); 884 spin_unlock_irqrestore(&sclp_lock, flags);
886 /* Enable service-signal interruption - needs to happen 885 /* Enable service-signal interruption - needs to happen
887 * with IRQs enabled. */ 886 * with IRQs enabled. */
888 ctl_set_bit(0, 9); 887 service_subclass_irq_register();
889 /* Wait for signal from interrupt or timeout */ 888 /* Wait for signal from interrupt or timeout */
890 sclp_sync_wait(); 889 sclp_sync_wait();
891 /* Disable service-signal interruption - needs to happen 890 /* Disable service-signal interruption - needs to happen
892 * with IRQs enabled. */ 891 * with IRQs enabled. */
893 ctl_clear_bit(0,9); 892 service_subclass_irq_unregister();
894 spin_lock_irqsave(&sclp_lock, flags); 893 spin_lock_irqsave(&sclp_lock, flags);
895 del_timer(&sclp_request_timer); 894 del_timer(&sclp_request_timer);
896 if (sclp_init_req.status == SCLP_REQ_DONE && 895 if (sclp_init_req.status == SCLP_REQ_DONE &&
@@ -900,8 +899,7 @@ sclp_check_interface(void)
900 } else 899 } else
901 rc = -EBUSY; 900 rc = -EBUSY;
902 } 901 }
903 unregister_early_external_interrupt(0x2401, sclp_check_handler, 902 unregister_external_interrupt(0x2401, sclp_check_handler);
904 &ext_int_info_hwc);
905 spin_unlock_irqrestore(&sclp_lock, flags); 903 spin_unlock_irqrestore(&sclp_lock, flags);
906 return rc; 904 return rc;
907} 905}
@@ -1064,15 +1062,14 @@ sclp_init(void)
1064 if (rc) 1062 if (rc)
1065 goto fail_init_state_uninitialized; 1063 goto fail_init_state_uninitialized;
1066 /* Register interrupt handler */ 1064 /* Register interrupt handler */
1067 rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler, 1065 rc = register_external_interrupt(0x2401, sclp_interrupt_handler);
1068 &ext_int_info_hwc);
1069 if (rc) 1066 if (rc)
1070 goto fail_unregister_reboot_notifier; 1067 goto fail_unregister_reboot_notifier;
1071 sclp_init_state = sclp_init_state_initialized; 1068 sclp_init_state = sclp_init_state_initialized;
1072 spin_unlock_irqrestore(&sclp_lock, flags); 1069 spin_unlock_irqrestore(&sclp_lock, flags);
1073 /* Enable service-signal external interruption - needs to happen with 1070 /* Enable service-signal external interruption - needs to happen with
1074 * IRQs enabled. */ 1071 * IRQs enabled. */
1075 ctl_set_bit(0, 9); 1072 service_subclass_irq_register();
1076 sclp_init_mask(1); 1073 sclp_init_mask(1);
1077 return 0; 1074 return 0;
1078 1075