aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio_main.c
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.vnet.ibm.com>2018-03-21 17:14:00 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-04-10 07:38:58 +0200
commit89286320a236d245834075fa13adb0bdd827ecaa (patch)
treeeac0fb567adcdc5da8d6e86d2afee4fa49e0b7c3 /drivers/s390/cio/qdio_main.c
parents390/ccwgroup: require at least one ccw device (diff)
downloadlinux-dev-89286320a236d245834075fa13adb0bdd827ecaa.tar.xz
linux-dev-89286320a236d245834075fa13adb0bdd827ecaa.zip
s390/qdio: clear intparm during shutdown
During shutdown, qdio returns its ccw device back to control by the upper-layer driver. But there is a remote chance that by the time where the IRQ handler gets switched back, the interrupt for the preceding ccw_device_{clear,halt} hasn't been presented yet. Upper-layer drivers would then need to handle this IRQ - and since the IO is issued with an intparm, it could very well be confused with whatever intparm mechanism the driver uses itself (eg intparm == request address). So when switching over the IRQ handler, also clear the intparm and have upper-layer drivers deal with any such delayed interrupt as if it was unsolicited. Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to '')
-rw-r--r--drivers/s390/cio/qdio_main.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index a337281337a7..f4ca72dd862f 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -1207,8 +1207,10 @@ no_cleanup:
qdio_shutdown_thinint(irq_ptr);
/* restore interrupt handler */
- if ((void *)cdev->handler == (void *)qdio_int_handler)
+ if ((void *)cdev->handler == (void *)qdio_int_handler) {
cdev->handler = irq_ptr->orig_handler;
+ cdev->private->intparm = 0;
+ }
spin_unlock_irq(get_ccwdev_lock(cdev));
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);