Commit 188561a4 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

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: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 91c15a95
...@@ -220,6 +220,7 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); ...@@ -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) #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver)
extern struct ccw_device *ccw_device_probe_console(void); 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); extern int ccw_device_force_console(void);
int ccw_device_siosl(struct ccw_device *); int ccw_device_siosl(struct ccw_device *);
......
...@@ -296,8 +296,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, ...@@ -296,8 +296,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1,
return 0; return 0;
} }
extern void wait_cons_dev(void);
extern void css_schedule_reprobe(void); extern void css_schedule_reprobe(void);
extern void reipl_ccw_dev(struct ccw_dev_id *id); extern void reipl_ccw_dev(struct ccw_dev_id *id);
......
...@@ -502,7 +502,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length) ...@@ -502,7 +502,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
raw3215_try_io(raw); raw3215_try_io(raw);
raw->flags &= ~RAW3215_FLUSHING; raw->flags &= ~RAW3215_FLUSHING;
#ifdef CONFIG_TN3215_CONSOLE #ifdef CONFIG_TN3215_CONSOLE
wait_cons_dev(); ccw_device_wait_idle(raw->cdev);
#endif #endif
/* Enough room freed up ? */ /* Enough room freed up ? */
if (RAW3215_BUFFER_SIZE - raw->count >= length) if (RAW3215_BUFFER_SIZE - raw->count >= length)
......
...@@ -796,7 +796,7 @@ struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev) ...@@ -796,7 +796,7 @@ struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev)
do { do {
__raw3270_reset_device(rp); __raw3270_reset_device(rp);
while (!raw3270_state_final(rp)) { while (!raw3270_state_final(rp)) {
wait_cons_dev(); ccw_device_wait_idle(rp->cdev);
barrier(); barrier();
} }
} while (rp->state != RAW3270_STATE_READY); } while (rp->state != RAW3270_STATE_READY);
...@@ -810,7 +810,7 @@ raw3270_wait_cons_dev(struct raw3270 *rp) ...@@ -810,7 +810,7 @@ raw3270_wait_cons_dev(struct raw3270 *rp)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(get_ccwdev_lock(rp->cdev), 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); spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
} }
......
...@@ -656,9 +656,9 @@ static int console_subchannel_in_use; ...@@ -656,9 +656,9 @@ static int console_subchannel_in_use;
/* /*
* Use cio_tsch to update the subchannel status and call the interrupt handler * 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; struct irb *irb;
int irq_context; int irq_context;
...@@ -690,22 +690,6 @@ void *cio_get_console_priv(void) ...@@ -690,22 +690,6 @@ void *cio_get_console_priv(void)
return &console_priv; 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 static int
cio_test_for_console(struct subchannel_id schid, void *data) cio_test_for_console(struct subchannel_id schid, void *data)
{ {
......
...@@ -133,6 +133,7 @@ extern int cio_is_console(struct subchannel_id); ...@@ -133,6 +133,7 @@ extern int cio_is_console(struct subchannel_id);
extern struct subchannel *cio_get_console_subchannel(void); extern struct subchannel *cio_get_console_subchannel(void);
extern spinlock_t * cio_get_console_lock(void); extern spinlock_t * cio_get_console_lock(void);
extern void *cio_get_console_priv(void); extern void *cio_get_console_priv(void);
extern void cio_tsch(struct subchannel *sch);
#else #else
#define cio_is_console(schid) 0 #define cio_is_console(schid) 0
#define cio_get_console_subchannel() NULL #define cio_get_console_subchannel() NULL
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
...@@ -1612,13 +1613,15 @@ static int ccw_device_console_enable(struct ccw_device *cdev, ...@@ -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. */ /* Now wait for the async. recognition to come to an end. */
spin_lock_irq(cdev->ccwlock); spin_lock_irq(cdev->ccwlock);
while (!dev_fsm_final_state(cdev)) while (!dev_fsm_final_state(cdev))
wait_cons_dev(); ccw_device_wait_idle(cdev);
rc = -EIO; rc = -EIO;
if (cdev->private->state != DEV_STATE_OFFLINE) if (cdev->private->state != DEV_STATE_OFFLINE)
goto out_unlock; goto out_unlock;
ccw_device_online(cdev); ccw_device_online(cdev);
while (!dev_fsm_final_state(cdev)) while (!dev_fsm_final_state(cdev))
wait_cons_dev(); ccw_device_wait_idle(cdev);
if (cdev->private->state != DEV_STATE_ONLINE) if (cdev->private->state != DEV_STATE_ONLINE)
goto out_unlock; goto out_unlock;
rc = 0; rc = 0;
...@@ -1655,6 +1658,26 @@ ccw_device_probe_console(void) ...@@ -1655,6 +1658,26 @@ ccw_device_probe_console(void)
return &console_cdev; 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); static int ccw_device_pm_restore(struct device *dev);
int ccw_device_force_console(void) int ccw_device_force_console(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment