diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-04-13 06:53:21 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-04-17 08:07:30 -0400 |
commit | 188561a462d3b82451d6ba09e2e32c9ba2c9938c (patch) | |
tree | ced10861aad02cad5cac0e232c8c85964dd2dc1f | |
parent | 91c15a951091a64a5f048ff93292057e3b590b6f (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.h | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/cio.h | 2 | ||||
-rw-r--r-- | drivers/s390/char/con3215.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 4 | ||||
-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 |
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 | ||
222 | extern struct ccw_device *ccw_device_probe_console(void); | 222 | extern struct ccw_device *ccw_device_probe_console(void); |
223 | extern void ccw_device_wait_idle(struct ccw_device *); | ||
223 | extern int ccw_device_force_console(void); | 224 | extern int ccw_device_force_console(void); |
224 | 225 | ||
225 | int ccw_device_siosl(struct ccw_device *); | 226 | int 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 | ||
299 | extern void wait_cons_dev(void); | ||
300 | |||
301 | extern void css_schedule_reprobe(void); | 299 | extern void css_schedule_reprobe(void); |
302 | 300 | ||
303 | extern void reipl_ccw_dev(struct ccw_dev_id *id); | 301 | extern 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 | */ |
661 | static void cio_tsch(struct subchannel *sch) | 661 | void 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 | */ | ||
696 | void 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 | |||
709 | static int | 693 | static int |
710 | cio_test_for_console(struct subchannel_id schid, void *data) | 694 | cio_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); | |||
133 | extern struct subchannel *cio_get_console_subchannel(void); | 133 | extern struct subchannel *cio_get_console_subchannel(void); |
134 | extern spinlock_t * cio_get_console_lock(void); | 134 | extern spinlock_t * cio_get_console_lock(void); |
135 | extern void *cio_get_console_priv(void); | 135 | extern void *cio_get_console_priv(void); |
136 | extern 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 | */ | ||
1669 | void 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 | |||
1658 | static int ccw_device_pm_restore(struct device *dev); | 1681 | static int ccw_device_pm_restore(struct device *dev); |
1659 | 1682 | ||
1660 | int ccw_device_force_console(void) | 1683 | int ccw_device_force_console(void) |