diff options
Diffstat (limited to 'drivers/s390/char/sclp.c')
-rw-r--r-- | drivers/s390/char/sclp.c | 39 |
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. */ | ||
29 | static ext_int_info_t ext_int_info_hwc; | ||
30 | |||
31 | /* Lock to protect internal data consistency. */ | 29 | /* Lock to protect internal data consistency. */ |
32 | static DEFINE_SPINLOCK(sclp_lock); | 30 | static 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. */ |
398 | static void | 396 | static void sclp_interrupt_handler(unsigned int ext_int_code, |
399 | sclp_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. */ |
822 | static void | 821 | static void sclp_check_handler(unsigned int ext_int_code, |
823 | sclp_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 | ||