public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/3] n_gsm: wake up ldisc tty before using it
@ 2015-05-26  2:20 Zhang, Yanmin
  0 siblings, 0 replies; only message in thread
From: Zhang, Yanmin @ 2015-05-26  2:20 UTC (permalink / raw)
  To: linux-kernel, xinhuix.pan, Greg Kroah-Hartman, Alan Cox

Wake up ldisc device before calling its driver to access the device.

Signed-off-by: Zhang Yanmin <yanmin.zhang@intel.com>

---

  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 <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;

  }

  

-- 

1.9.1



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-05-26  2:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-26  2:20 [PATCH 3/3] n_gsm: wake up ldisc tty before using it Zhang, Yanmin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox