aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-04-13 06:53:21 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-04-17 08:07:30 -0400
commit188561a462d3b82451d6ba09e2e32c9ba2c9938c (patch)
treeced10861aad02cad5cac0e232c8c85964dd2dc1f
parent91c15a951091a64a5f048ff93292057e3b590b6f (diff)
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>
-rw-r--r--arch/s390/include/asm/ccwdev.h1
-rw-r--r--arch/s390/include/asm/cio.h2
-rw-r--r--drivers/s390/char/con3215.c2
-rw-r--r--drivers/s390/char/raw3270.c4
-rw-r--r--drivers/s390/cio/cio.c20
-rw-r--r--drivers/s390/cio/cio.h1
-rw-r--r--drivers/s390/cio/device.c27
7 files changed, 32 insertions, 25 deletions
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index e6061617a50b..cb56fb6cff7e 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -220,6 +220,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
220#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) 220#define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
221 221
222extern struct ccw_device *ccw_device_probe_console(void); 222extern struct ccw_device *ccw_device_probe_console(void);
223extern void ccw_device_wait_idle(struct ccw_device *);
223extern int ccw_device_force_console(void); 224extern int ccw_device_force_console(void);
224 225
225int ccw_device_siosl(struct ccw_device *); 226int ccw_device_siosl(struct ccw_device *);
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index ad2b924167d7..ffb898961c8d 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -296,8 +296,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1,
296 return 0; 296 return 0;
297} 297}
298 298
299extern void wait_cons_dev(void);
300
301extern void css_schedule_reprobe(void); 299extern void css_schedule_reprobe(void);
302 300
303extern void reipl_ccw_dev(struct ccw_dev_id *id); 301extern void reipl_ccw_dev(struct ccw_dev_id *id);
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 7b00fa634d40..0d79eec799f1 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -502,7 +502,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
502 raw3215_try_io(raw); 502 raw3215_try_io(raw);
503 raw->flags &= ~RAW3215_FLUSHING; 503 raw->flags &= ~RAW3215_FLUSHING;
504#ifdef CONFIG_TN3215_CONSOLE 504#ifdef CONFIG_TN3215_CONSOLE
505 wait_cons_dev(); 505 ccw_device_wait_idle(raw->cdev);
506#endif 506#endif
507 /* Enough room freed up ? */ 507 /* Enough room freed up ? */
508 if (RAW3215_BUFFER_SIZE - raw->count >= length) 508 if (RAW3215_BUFFER_SIZE - raw->count >= length)
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 4c9030a5b9f2..383d6432a1a8 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -796,7 +796,7 @@ struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev)
796 do { 796 do {
797 __raw3270_reset_device(rp); 797 __raw3270_reset_device(rp);
798 while (!raw3270_state_final(rp)) { 798 while (!raw3270_state_final(rp)) {
799 wait_cons_dev(); 799 ccw_device_wait_idle(rp->cdev);
800 barrier(); 800 barrier();
801 } 801 }
802 } while (rp->state != RAW3270_STATE_READY); 802 } while (rp->state != RAW3270_STATE_READY);
@@ -810,7 +810,7 @@ raw3270_wait_cons_dev(struct raw3270 *rp)
810 unsigned long flags; 810 unsigned long flags;
811 811
812 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags); 812 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
813 wait_cons_dev(); 813 ccw_device_wait_idle(rp->cdev);
814 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); 814 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
815} 815}
816 816
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;
656 656
657/* 657/*
658 * Use cio_tsch to update the subchannel status and call the interrupt handler 658 * Use cio_tsch to update the subchannel status and call the interrupt handler
659 * if status had been pending. Called with the console_subchannel lock. 659 * if status had been pending. Called with the subchannel's lock held.
660 */ 660 */
661static void cio_tsch(struct subchannel *sch) 661void cio_tsch(struct subchannel *sch)
662{ 662{
663 struct irb *irb; 663 struct irb *irb;
664 int irq_context; 664 int irq_context;
@@ -690,22 +690,6 @@ void *cio_get_console_priv(void)
690 return &console_priv; 690 return &console_priv;
691} 691}
692 692
693/*
694 * busy wait for the next interrupt on the console
695 */
696void wait_cons_dev(void)
697{
698 if (!console_subchannel_in_use)
699 return;
700
701 while (1) {
702 cio_tsch(&console_subchannel);
703 if (console_subchannel.schib.scsw.cmd.actl == 0)
704 break;
705 udelay_simple(100);
706 }
707}
708
709static int 693static int
710cio_test_for_console(struct subchannel_id schid, void *data) 694cio_test_for_console(struct subchannel_id schid, void *data)
711{ 695{
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);
133extern struct subchannel *cio_get_console_subchannel(void); 133extern struct subchannel *cio_get_console_subchannel(void);
134extern spinlock_t * cio_get_console_lock(void); 134extern spinlock_t * cio_get_console_lock(void);
135extern void *cio_get_console_priv(void); 135extern void *cio_get_console_priv(void);
136extern void cio_tsch(struct subchannel *sch);
136#else 137#else
137#define cio_is_console(schid) 0 138#define cio_is_console(schid) 0
138#define cio_get_console_subchannel() NULL 139#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 @@
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/workqueue.h> 21#include <linux/workqueue.h>
22#include <linux/delay.h>
22#include <linux/timer.h> 23#include <linux/timer.h>
23#include <linux/kernel_stat.h> 24#include <linux/kernel_stat.h>
24 25
@@ -1612,13 +1613,15 @@ static int ccw_device_console_enable(struct ccw_device *cdev,
1612 /* Now wait for the async. recognition to come to an end. */ 1613 /* Now wait for the async. recognition to come to an end. */
1613 spin_lock_irq(cdev->ccwlock); 1614 spin_lock_irq(cdev->ccwlock);
1614 while (!dev_fsm_final_state(cdev)) 1615 while (!dev_fsm_final_state(cdev))
1615 wait_cons_dev(); 1616 ccw_device_wait_idle(cdev);
1617
1616 rc = -EIO; 1618 rc = -EIO;
1617 if (cdev->private->state != DEV_STATE_OFFLINE) 1619 if (cdev->private->state != DEV_STATE_OFFLINE)
1618 goto out_unlock; 1620 goto out_unlock;
1619 ccw_device_online(cdev); 1621 ccw_device_online(cdev);
1620 while (!dev_fsm_final_state(cdev)) 1622 while (!dev_fsm_final_state(cdev))
1621 wait_cons_dev(); 1623 ccw_device_wait_idle(cdev);
1624
1622 if (cdev->private->state != DEV_STATE_ONLINE) 1625 if (cdev->private->state != DEV_STATE_ONLINE)
1623 goto out_unlock; 1626 goto out_unlock;
1624 rc = 0; 1627 rc = 0;
@@ -1655,6 +1658,26 @@ ccw_device_probe_console(void)
1655 return &console_cdev; 1658 return &console_cdev;
1656} 1659}
1657 1660
1661/**
1662 * ccw_device_wait_idle() - busy wait for device to become idle
1663 * @cdev: ccw device
1664 *
1665 * Poll until activity control is zero, that is, no function or data
1666 * transfer is pending/active.
1667 * Called with device lock being held.
1668 */
1669void ccw_device_wait_idle(struct ccw_device *cdev)
1670{
1671 struct subchannel *sch = to_subchannel(cdev->dev.parent);
1672
1673 while (1) {
1674 cio_tsch(sch);
1675 if (sch->schib.scsw.cmd.actl == 0)
1676 break;
1677 udelay_simple(100);
1678 }
1679}
1680
1658static int ccw_device_pm_restore(struct device *dev); 1681static int ccw_device_pm_restore(struct device *dev);
1659 1682
1660int ccw_device_force_console(void) 1683int ccw_device_force_console(void)