Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751483AbbEZCUp (ORCPT ); Mon, 25 May 2015 22:20:45 -0400 Received: from mga02.intel.com ([134.134.136.20]:49884 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751046AbbEZCUk (ORCPT ); Mon, 25 May 2015 22:20:40 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,495,1427785200"; d="scan'208";a="731556971" Message-ID: <5563D872.2040705@linux.intel.com> Date: Tue, 26 May 2015 10:20:34 +0800 From: "Zhang, Yanmin" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: linux-kernel@vger.kernel.org, xinhuix.pan@intel.com, Greg Kroah-Hartman , Alan Cox Subject: [PATCH 3/3] n_gsm: wake up ldisc tty before using it Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4481 Lines: 258 Wake up ldisc device before calling its driver to access the device. Signed-off-by: Zhang Yanmin --- drivers/tty/n_gsm.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 2c34c32..40671fa 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -62,6 +62,7 @@ #include #include #include +#include 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; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/