TTY: isdn/gigaset, use tty_port
Let us port the code to use tty_port. We now use open_count and tty from there. This allows us also to use tty_port_tty_set with tty refcounting instead of hand-written locking and logic. Note that tty and open_count are no longer protected by cs->lock. It is protected by tty_port->lock. But since all the places where they were used are now switched to the helpers, we are fine. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Hansjoerg Lipp <hjlipp@web.de> Acked-by: Tilman Schmidt <tilman@imap.cc> Cc: <gigaset307x-common@lists.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
fc258f8940
commit
48a7466f4d
@ -720,12 +720,11 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
|
|||||||
|
|
||||||
tasklet_init(&cs->event_tasklet, gigaset_handle_event,
|
tasklet_init(&cs->event_tasklet, gigaset_handle_event,
|
||||||
(unsigned long) cs);
|
(unsigned long) cs);
|
||||||
|
tty_port_init(&cs->port);
|
||||||
cs->commands_pending = 0;
|
cs->commands_pending = 0;
|
||||||
cs->cur_at_seq = 0;
|
cs->cur_at_seq = 0;
|
||||||
cs->gotfwver = -1;
|
cs->gotfwver = -1;
|
||||||
cs->open_count = 0;
|
|
||||||
cs->dev = NULL;
|
cs->dev = NULL;
|
||||||
cs->tty = NULL;
|
|
||||||
cs->tty_dev = NULL;
|
cs->tty_dev = NULL;
|
||||||
cs->cidmode = cidmode != 0;
|
cs->cidmode = cidmode != 0;
|
||||||
cs->tabnocid = gigaset_tab_nocid;
|
cs->tabnocid = gigaset_tab_nocid;
|
||||||
|
@ -433,8 +433,7 @@ struct cardstate {
|
|||||||
spinlock_t cmdlock;
|
spinlock_t cmdlock;
|
||||||
unsigned curlen, cmdbytes;
|
unsigned curlen, cmdbytes;
|
||||||
|
|
||||||
unsigned open_count;
|
struct tty_port port;
|
||||||
struct tty_struct *tty;
|
|
||||||
struct tasklet_struct if_wake_tasklet;
|
struct tasklet_struct if_wake_tasklet;
|
||||||
unsigned control_state;
|
unsigned control_state;
|
||||||
|
|
||||||
|
@ -146,7 +146,6 @@ static const struct tty_operations if_ops = {
|
|||||||
static int if_open(struct tty_struct *tty, struct file *filp)
|
static int if_open(struct tty_struct *tty, struct file *filp)
|
||||||
{
|
{
|
||||||
struct cardstate *cs;
|
struct cardstate *cs;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
gig_dbg(DEBUG_IF, "%d+%d: %s()",
|
gig_dbg(DEBUG_IF, "%d+%d: %s()",
|
||||||
tty->driver->minor_start, tty->index, __func__);
|
tty->driver->minor_start, tty->index, __func__);
|
||||||
@ -161,12 +160,10 @@ static int if_open(struct tty_struct *tty, struct file *filp)
|
|||||||
}
|
}
|
||||||
tty->driver_data = cs;
|
tty->driver_data = cs;
|
||||||
|
|
||||||
++cs->open_count;
|
++cs->port.count;
|
||||||
|
|
||||||
if (cs->open_count == 1) {
|
if (cs->port.count == 1) {
|
||||||
spin_lock_irqsave(&cs->lock, flags);
|
tty_port_tty_set(&cs->port, tty);
|
||||||
cs->tty = tty;
|
|
||||||
spin_unlock_irqrestore(&cs->lock, flags);
|
|
||||||
tty->low_latency = 1;
|
tty->low_latency = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +174,6 @@ static int if_open(struct tty_struct *tty, struct file *filp)
|
|||||||
static void if_close(struct tty_struct *tty, struct file *filp)
|
static void if_close(struct tty_struct *tty, struct file *filp)
|
||||||
{
|
{
|
||||||
struct cardstate *cs = tty->driver_data;
|
struct cardstate *cs = tty->driver_data;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
if (!cs) { /* happens if we didn't find cs in open */
|
if (!cs) { /* happens if we didn't find cs in open */
|
||||||
printk(KERN_DEBUG "%s: no cardstate\n", __func__);
|
printk(KERN_DEBUG "%s: no cardstate\n", __func__);
|
||||||
@ -190,15 +186,10 @@ static void if_close(struct tty_struct *tty, struct file *filp)
|
|||||||
|
|
||||||
if (!cs->connected)
|
if (!cs->connected)
|
||||||
gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
|
gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
|
||||||
else if (!cs->open_count)
|
else if (!cs->port.count)
|
||||||
dev_warn(cs->dev, "%s: device not opened\n", __func__);
|
dev_warn(cs->dev, "%s: device not opened\n", __func__);
|
||||||
else {
|
else if (!--cs->port.count)
|
||||||
if (!--cs->open_count) {
|
tty_port_tty_set(&cs->port, NULL);
|
||||||
spin_lock_irqsave(&cs->lock, flags);
|
|
||||||
cs->tty = NULL;
|
|
||||||
spin_unlock_irqrestore(&cs->lock, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&cs->mutex);
|
mutex_unlock(&cs->mutex);
|
||||||
|
|
||||||
@ -511,10 +502,13 @@ out:
|
|||||||
/* wakeup tasklet for the write operation */
|
/* wakeup tasklet for the write operation */
|
||||||
static void if_wake(unsigned long data)
|
static void if_wake(unsigned long data)
|
||||||
{
|
{
|
||||||
struct cardstate *cs = (struct cardstate *) data;
|
struct cardstate *cs = (struct cardstate *)data;
|
||||||
|
struct tty_struct *tty = tty_port_tty_get(&cs->port);
|
||||||
|
|
||||||
if (cs->tty)
|
if (tty) {
|
||||||
tty_wakeup(cs->tty);
|
tty_wakeup(tty);
|
||||||
|
tty_kref_put(tty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** interface to common ***/
|
/*** interface to common ***/
|
||||||
@ -567,18 +561,16 @@ void gigaset_if_free(struct cardstate *cs)
|
|||||||
void gigaset_if_receive(struct cardstate *cs,
|
void gigaset_if_receive(struct cardstate *cs,
|
||||||
unsigned char *buffer, size_t len)
|
unsigned char *buffer, size_t len)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
struct tty_struct *tty = tty_port_tty_get(&cs->port);
|
||||||
struct tty_struct *tty;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&cs->lock, flags);
|
if (tty == NULL) {
|
||||||
tty = cs->tty;
|
|
||||||
if (tty == NULL)
|
|
||||||
gig_dbg(DEBUG_IF, "receive on closed device");
|
gig_dbg(DEBUG_IF, "receive on closed device");
|
||||||
else {
|
return;
|
||||||
tty_insert_flip_string(tty, buffer, len);
|
|
||||||
tty_flip_buffer_push(tty);
|
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&cs->lock, flags);
|
|
||||||
|
tty_insert_flip_string(tty, buffer, len);
|
||||||
|
tty_flip_buffer_push(tty);
|
||||||
|
tty_kref_put(tty);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(gigaset_if_receive);
|
EXPORT_SYMBOL_GPL(gigaset_if_receive);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user