aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device.c
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-04-13 12:53:21 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-04-17 14:07:30 +0200
commit188561a462d3b82451d6ba09e2e32c9ba2c9938c (patch)
treeced10861aad02cad5cac0e232c8c85964dd2dc1f /drivers/s390/cio/device.c
parents390/hibernate: Save and restore absolute zero pages (diff)
downloadlinux-dev-188561a462d3b82451d6ba09e2e32c9ba2c9938c.tar.xz
linux-dev-188561a462d3b82451d6ba09e2e32c9ba2c9938c.zip
s390/cio: wait_cons_dev don't use static variable
wait_cons_dev is used to busy wait for an interrupt on the console ccw device. Stop using the static console_subchannel and add a parameter to this function to specify on which ccw device/subchannel we have to do the polling. While at it rename the function to ccw_device_wait_idle and move it to device.c Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r--drivers/s390/cio/device.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index c6767f5a58b2..2e1e9086e916 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -19,6 +19,7 @@
#include <linux/list.h>
#include <linux/device.h>
#include <linux/workqueue.h>
+#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/kernel_stat.h>
@@ -1612,13 +1613,15 @@ static int ccw_device_console_enable(struct ccw_device *cdev,
/* Now wait for the async. recognition to come to an end. */
spin_lock_irq(cdev->ccwlock);
while (!dev_fsm_final_state(cdev))
- wait_cons_dev();
+ ccw_device_wait_idle(cdev);
+
rc = -EIO;
if (cdev->private->state != DEV_STATE_OFFLINE)
goto out_unlock;
ccw_device_online(cdev);
while (!dev_fsm_final_state(cdev))
- wait_cons_dev();
+ ccw_device_wait_idle(cdev);
+
if (cdev->private->state != DEV_STATE_ONLINE)
goto out_unlock;
rc = 0;
@@ -1655,6 +1658,26 @@ ccw_device_probe_console(void)
return &console_cdev;
}
+/**
+ * ccw_device_wait_idle() - busy wait for device to become idle
+ * @cdev: ccw device
+ *
+ * Poll until activity control is zero, that is, no function or data
+ * transfer is pending/active.
+ * Called with device lock being held.
+ */
+void ccw_device_wait_idle(struct ccw_device *cdev)
+{
+ struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
+ while (1) {
+ cio_tsch(sch);
+ if (sch->schib.scsw.cmd.actl == 0)
+ break;
+ udelay_simple(100);
+ }
+}
+
static int ccw_device_pm_restore(struct device *dev);
int ccw_device_force_console(void)