summary refs log tree commit diff
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2015-08-17 07:56:20 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2015-08-19 10:40:17 +0200
commite619cd3d618672bea8602d682ea63b42a1faf1bc (patch)
treeeb14d81bb7c0e8fdc8a550334c61860c73c0ddf4 /drivers/s390/char
parent89b1145e93771d727645c96e323539c029b63f1c (diff)
downloadlinux-e619cd3d618672bea8602d682ea63b42a1faf1bc.tar.gz
s390/hmcdrv: fix interrupt registration
The z/VM driver sets bit "63-22" in control register zero to one in order
to enable the CP Service interrupt (0x2603). However the irq subclass mask
that normally corresponds to the CP Service interrupt is
"63-54" (== "63-22-32").

So it looks like the author read the documentation with the 32 bit sized
cr0 register bit positions (== 22), but didn't realize that bit numbers
change, if applied to a 64 bit register (== 54) due to the numbering
scheme.

Also use irq_subclass_register() instead if ctl_set_bit() since multiple
services depend on the service signal subclass mask, which is the correct
bit. This also explains why nobody noticed the bug, since the bit is always
enabled anyway (e.g. pfault).

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/diag_ftp.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/s390/char/diag_ftp.c b/drivers/s390/char/diag_ftp.c
index 93889632fdf9..12db8db04cdd 100644
--- a/drivers/s390/char/diag_ftp.c
+++ b/drivers/s390/char/diag_ftp.c
@@ -223,7 +223,7 @@ int diag_ftp_startup(void)
 	if (rc)
 		return rc;
 
-	ctl_set_bit(0, 63 - 22);
+	irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
 	return 0;
 }
 
@@ -232,6 +232,6 @@ int diag_ftp_startup(void)
  */
 void diag_ftp_shutdown(void)
 {
-	ctl_clear_bit(0, 63 - 22);
+	irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
 	unregister_external_irq(EXT_IRQ_CP_SERVICE, diag_ftp_handler);
 }