n_gsm: wake up ldisc tty before using it
PATCH v3 3/3 n_gsm: wake up ldisc tty before using it
From: Zhang Yanmin <[email protected]>
Wake up ldisc device before calling its driver to access the device.
Signed-off-by Zhang Yanmin <[email protected]>
--- drivers/tty/n_gsm.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-)
drivers/tty/n_gsm.c +39 -1
@@ -62,6 +62,7 @@#include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/gsmmux.h> +#include <linux/pm_runtime.h> static int debug;module_param (debug, int,0600 );
@@ -555,6 +556,27 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len)return olen; } +static int pm_runtime_get_sync_tty (struct tty_struct *tty) +{ +int ret =0 ; + +/* Wakeup parent as tty itself doesn't enable runtime */ +if (tty->dev->parent) + ret =pm_runtime_get_sync (tty->dev->parent); + +return ret; +} + +static int pm_runtime_put_tty (struct tty_struct *tty) +{ +int ret =0 ; + +if (tty->dev->parent) + ret =pm_runtime_put (tty->dev->parent); + +return ret; +} +/** * gsm_send - send a control frame * @gsm: our GSM mux
@@ -1511,7 +1533,9 @@ static void gsm_dlci_begin_open(struct gsm_dlci *dlci)return ; dlci->retries = gsm->n2; dlci->state =DLCI_OPENING ; +pm_runtime_get_sync_tty (gsm->tty);gsm_command (dlci->gsm, dlci->addr,SABM |PF ); +pm_runtime_put_tty (gsm->tty);mod_timer (&dlci->t1, jiffies + gsm->t1 *HZ /100 ); }
@@ -1533,7 +1557,9 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci)return ; dlci->retries = gsm->n2; dlci->state =DLCI_CLOSING ; +pm_runtime_get_sync_tty (gsm->tty);gsm_command (dlci->gsm, dlci->addr,DISC |PF ); +pm_runtime_put_tty (gsm->tty);mod_timer (&dlci->t1, jiffies + gsm->t1 *HZ /100 ); }
@@ -2286,7 +2312,9 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, flags = *f++;switch (flags) {case TTY_NORMAL : +pm_runtime_get_sync_tty (gsm->tty); gsm->receive (gsm, *dp); +pm_runtime_put_tty (gsm->tty);break ;case TTY_OVERRUN :case TTY_BREAK :
@@ -2957,6 +2985,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) {struct gsm_dlci *dlci = tty->driver_data;struct tty_port *port = &dlci->port; +int ret; port->count++;tty_port_tty_set (port, tty);
@@ -2968,7 +2997,11 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)/* Start sending off SABM messages */ gsm_dlci_begin_open (dlci);/* And wait for virtual carrier */ -return tty_port_block_til_ready (port, tty, filp); +pm_runtime_get_sync_tty (dlci->gsm->tty); + ret =tty_port_block_til_ready (port, tty, filp); +pm_runtime_put_tty (dlci->gsm->tty); + +return ret; }static void gsmtty_close (struct tty_struct *tty,struct file *filp)
@@ -2986,11 +3019,14 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) gsm = dlci->gsm;if (tty_port_close_start (&dlci->port, tty, filp) ==0 )return ; +pm_runtime_get_sync_tty (gsm->tty);gsm_dlci_begin_close (dlci);if (test_bit (ASYNCB_INITIALIZED , &dlci->port.flags)) {if (C_HUPCL (tty))tty_port_lower_dtr_rts (&dlci->port); } +pm_runtime_put_tty (gsm->tty); +tty_port_close_end (&dlci->port, tty);tty_port_tty_set (&dlci->port,NULL );return ;
@@ -3012,10 +3048,12 @@ static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf,struct gsm_dlci *dlci = tty->driver_data;if (dlci->state ==DLCI_CLOSED )return -EINVAL ; +pm_runtime_get_sync_tty (dlci->gsm->tty);/* Stuff the bytes into the fifo queue */ sent =kfifo_in_locked (dlci->fifo, buf, len, &dlci->lock);/* Need to kick the channel */ gsm_dlci_data_kick (dlci); +pm_runtime_put_tty (dlci->gsm->tty);return sent; }
Signature · 1 line
1.9.1