s390/cio: wait_cons_dev don't use static variable
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Sat, 13 Apr 2013 10:53:21 +0000 (12:53 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 17 Apr 2013 12:07:30 +0000 (14:07 +0200)
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>
arch/s390/include/asm/ccwdev.h
arch/s390/include/asm/cio.h
drivers/s390/char/con3215.c
drivers/s390/char/raw3270.c
drivers/s390/cio/cio.c
drivers/s390/cio/cio.h
drivers/s390/cio/device.c

index e6061617a50b071ed2a8b4a8da01e562de49d836..cb56fb6cff7ef63d2efc824b93491a6ee734ba59 100644 (file)
@@ -220,6 +220,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
 #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
 
 extern struct ccw_device *ccw_device_probe_console(void);
+extern void ccw_device_wait_idle(struct ccw_device *);
 extern int ccw_device_force_console(void);
 
 int ccw_device_siosl(struct ccw_device *);
index ad2b924167d799f4b410a1bc38e4350656f3da4c..ffb898961c8d28ecdc385443a37d8f523cf72daf 100644 (file)
@@ -296,8 +296,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1,
        return 0;
 }
 
-extern void wait_cons_dev(void);
-
 extern void css_schedule_reprobe(void);
 
 extern void reipl_ccw_dev(struct ccw_dev_id *id);
index 7b00fa634d40bf96ac5fe119431a562871a92b57..0d79eec799f1c14b3f08f487f16fd04456913e70 100644 (file)
@@ -502,7 +502,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
                raw3215_try_io(raw);
                raw->flags &= ~RAW3215_FLUSHING;
 #ifdef CONFIG_TN3215_CONSOLE
-               wait_cons_dev();
+               ccw_device_wait_idle(raw->cdev);
 #endif
                /* Enough room freed up ? */
                if (RAW3215_BUFFER_SIZE - raw->count >= length)
index 4c9030a5b9f268b4a78f43688ada94a383315438..383d6432a1a87ddac74a94be16be8b120fea6dea 100644 (file)
@@ -796,7 +796,7 @@ struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev)
        do {
                __raw3270_reset_device(rp);
                while (!raw3270_state_final(rp)) {
-                       wait_cons_dev();
+                       ccw_device_wait_idle(rp->cdev);
                        barrier();
                }
        } while (rp->state != RAW3270_STATE_READY);
@@ -810,7 +810,7 @@ raw3270_wait_cons_dev(struct raw3270 *rp)
        unsigned long flags;
 
        spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
-       wait_cons_dev();
+       ccw_device_wait_idle(rp->cdev);
        spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 }
 
index 986ef6a92a410ad893127ff786fe43774d9e0daa..2c1d53fb2fabefe1c35b2724646b9340d24314de 100644 (file)
@@ -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)
 {
index 4a1ff5c2eb881355204ffe8e047cfbe3bb8e3706..3b97c8bb30e528a8803f404f0078023435be43c8 100644 (file)
@@ -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
index c6767f5a58b23f3202a52113bc67ee295ab174f6..2e1e9086e9167e46e03d2281e7fba4bd1c5225ec 100644 (file)
@@ -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)