diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-04-13 12:53:21 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-04-17 14:07:30 +0200 |
commit | 188561a462d3b82451d6ba09e2e32c9ba2c9938c (patch) | |
tree | ced10861aad02cad5cac0e232c8c85964dd2dc1f /drivers/s390/cio | |
parent | s390/hibernate: Save and restore absolute zero pages (diff) | |
download | linux-188561a462d3b82451d6ba09e2e32c9ba2c9938c.tar.xz linux-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')
-rw-r--r-- | drivers/s390/cio/cio.c | 20 | ||||
-rw-r--r-- | drivers/s390/cio/cio.h | 1 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 27 |
3 files changed, 28 insertions, 20 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 986ef6a92a41..2c1d53fb2fab 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -656,9 +656,9 @@ static int console_subchannel_in_use; /* * Use cio_tsch to update the subchannel status and call the interrupt handler - * if status had been pending. Called with the console_subchannel lock. + * if status had been pending. Called with the subchannel's lock held. */ -static void cio_tsch(struct subchannel *sch) +void cio_tsch(struct subchannel *sch) { struct irb *irb; int irq_context; @@ -690,22 +690,6 @@ void *cio_get_console_priv(void) return &console_priv; } -/* - * busy wait for the next interrupt on the console - */ -void wait_cons_dev(void) -{ - if (!console_subchannel_in_use) - return; - - while (1) { - cio_tsch(&console_subchannel); - if (console_subchannel.schib.scsw.cmd.actl == 0) - break; - udelay_simple(100); - } -} - static int cio_test_for_console(struct subchannel_id schid, void *data) { diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 4a1ff5c2eb88..3b97c8bb30e5 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h @@ -133,6 +133,7 @@ extern int cio_is_console(struct subchannel_id); extern struct subchannel *cio_get_console_subchannel(void); extern spinlock_t * cio_get_console_lock(void); extern void *cio_get_console_priv(void); +extern void cio_tsch(struct subchannel *sch); #else #define cio_is_console(schid) 0 #define cio_get_console_subchannel() NULL 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) |