Merge 3.9-rc3 into tty-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 21 Mar 2013 23:07:34 +0000 (16:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 21 Mar 2013 23:07:34 +0000 (16:07 -0700)
1  2 
arch/um/drivers/chan_kern.c
arch/um/drivers/line.c
drivers/isdn/i4l/isdn_tty.c
drivers/tty/serial/vt8500_serial.c
drivers/usb/serial/option.c
drivers/usb/serial/quatech2.c

@@@ -122,10 -122,10 +122,10 @@@ static int open_chan(struct list_head *
        return err;
  }
  
- void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
+ void chan_enable_winch(struct chan *chan, struct tty_port *port)
  {
        if (chan && chan->primary && chan->ops->winch)
-               register_winch(chan->fd, tty);
+               register_winch(chan->fd, port);
  }
  
  static void line_timer_cb(struct work_struct *work)
@@@ -568,7 -568,11 +568,7 @@@ void chan_interrupt(struct line *line, 
                reactivate_fd(chan->fd, irq);
        if (err == -EIO) {
                if (chan->primary) {
 -                      struct tty_struct *tty = tty_port_tty_get(&line->port);
 -                      if (tty != NULL) {
 -                              tty_hangup(tty);
 -                              tty_kref_put(tty);
 -                      }
 +                      tty_port_tty_hangup(&line->port, false);
                        if (line->chan_out != chan)
                                close_one_chan(line->chan_out, 1);
                }
diff --combined arch/um/drivers/line.c
@@@ -248,6 -248,7 +248,6 @@@ static irqreturn_t line_write_interrupt
  {
        struct chan *chan = data;
        struct line *line = chan->line;
 -      struct tty_struct *tty;
        int err;
  
        /*
        }
        spin_unlock(&line->lock);
  
 -      tty = tty_port_tty_get(&line->port);
 -      if (tty == NULL)
 -              return IRQ_NONE;
 -
 -      tty_wakeup(tty);
 -      tty_kref_put(tty);
 +      tty_port_tty_wakeup(&line->port);
  
        return IRQ_HANDLED;
  }
@@@ -299,7 -305,7 +299,7 @@@ static int line_activate(struct tty_por
                return ret;
  
        if (!line->sigio) {
-               chan_enable_winch(line->chan_out, tty);
+               chan_enable_winch(line->chan_out, port);
                line->sigio = 1;
        }
  
        return 0;
  }
  
+ static void unregister_winch(struct tty_struct *tty);
+ static void line_destruct(struct tty_port *port)
+ {
+       struct tty_struct *tty = tty_port_tty_get(port);
+       struct line *line = tty->driver_data;
+       if (line->sigio) {
+               unregister_winch(tty);
+               line->sigio = 0;
+       }
+ }
  static const struct tty_port_operations line_port_ops = {
        .activate = line_activate,
+       .destruct = line_destruct,
  };
  
  int line_open(struct tty_struct *tty, struct file *filp)
@@@ -334,18 -354,6 +348,6 @@@ int line_install(struct tty_driver *dri
        return 0;
  }
  
- static void unregister_winch(struct tty_struct *tty);
- void line_cleanup(struct tty_struct *tty)
- {
-       struct line *line = tty->driver_data;
-       if (line->sigio) {
-               unregister_winch(tty);
-               line->sigio = 0;
-       }
- }
  void line_close(struct tty_struct *tty, struct file * filp)
  {
        struct line *line = tty->driver_data;
@@@ -595,7 -603,7 +597,7 @@@ struct winch 
        int fd;
        int tty_fd;
        int pid;
-       struct tty_struct *tty;
+       struct tty_port *port;
        unsigned long stack;
        struct work_struct work;
  };
@@@ -649,7 -657,7 +651,7 @@@ static irqreturn_t winch_interrupt(int 
                        goto out;
                }
        }
-       tty = winch->tty;
+       tty = tty_port_tty_get(winch->port);
        if (tty != NULL) {
                line = tty->driver_data;
                if (line != NULL) {
                                         &tty->winsize.ws_col);
                        kill_pgrp(tty->pgrp, SIGWINCH, 1);
                }
+               tty_kref_put(tty);
        }
   out:
        if (winch->fd != -1)
        return IRQ_HANDLED;
  }
  
- void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
+ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
                        unsigned long stack)
  {
        struct winch *winch;
                                   .fd          = fd,
                                   .tty_fd      = tty_fd,
                                   .pid         = pid,
-                                  .tty         = tty,
+                                  .port        = port,
                                   .stack       = stack });
  
        if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
@@@ -708,15 -717,18 +711,18 @@@ static void unregister_winch(struct tty
  {
        struct list_head *ele, *next;
        struct winch *winch;
+       struct tty_struct *wtty;
  
        spin_lock(&winch_handler_lock);
  
        list_for_each_safe(ele, next, &winch_handlers) {
                winch = list_entry(ele, struct winch, list);
-               if (winch->tty == tty) {
+               wtty = tty_port_tty_get(winch->port);
+               if (wtty == tty) {
                        free_winch(winch);
                        break;
                }
+               tty_kref_put(wtty);
        }
        spin_unlock(&winch_handler_lock);
  }
@@@ -902,7 -902,9 +902,9 @@@ isdn_tty_send_msg(modem_info *info, ate
        int j;
        int l;
  
-       l = strlen(msg);
+       l = min(strlen(msg), sizeof(cmd.parm) - sizeof(cmd.parm.cmsg)
+               + sizeof(cmd.parm.cmsg.para) - 2);
        if (!l) {
                isdn_tty_modem_result(RESULT_ERROR, info);
                return;
@@@ -1470,6 -1472,9 +1472,6 @@@ isdn_tty_set_termios(struct tty_struct 
                    tty->termios.c_ospeed == old_termios->c_ospeed)
                        return;
                isdn_tty_change_speed(info);
 -              if ((old_termios->c_cflag & CRTSCTS) &&
 -                  !(tty->termios.c_cflag & CRTSCTS))
 -                      tty->hw_stopped = 0;
        }
  }
  
@@@ -35,7 -35,6 +35,7 @@@
  #include <linux/clk.h>
  #include <linux/platform_device.h>
  #include <linux/of.h>
 +#include <linux/err.h>
  
  /*
   * UART Register offsets
@@@ -586,9 -585,9 +586,9 @@@ static int vt8500_serial_probe(struct p
        if (!vt8500_port)
                return -ENOMEM;
  
 -      vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres);
 -      if (!vt8500_port->uart.membase)
 -              return -EADDRNOTAVAIL;
 +      vt8500_port->uart.membase = devm_ioremap_resource(&pdev->dev, mmres);
 +      if (IS_ERR(vt8500_port->uart.membase))
 +              return PTR_ERR(vt8500_port->uart.membase);
  
        vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
        if (IS_ERR(vt8500_port->clk)) {
        vt8500_port->uart.dev = &pdev->dev;
        vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
  
-       vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
-       if (!IS_ERR(vt8500_port->clk)) {
-               vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
-       } else {
-               /* use the default of 24Mhz if not specified and warn */
-               pr_warn("%s: serial clock source not specified\n", __func__);
-               vt8500_port->uart.uartclk = 24000000;
-       }
+       vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
  
        snprintf(vt8500_port->name, sizeof(vt8500_port->name),
                 "VT8500 UART%d", pdev->id);
@@@ -341,6 -341,8 +341,8 @@@ static void option_instat_callback(stru
  #define CINTERION_PRODUCT_EU3_E                       0x0051
  #define CINTERION_PRODUCT_EU3_P                       0x0052
  #define CINTERION_PRODUCT_PH8                 0x0053
+ #define CINTERION_PRODUCT_AH6                 0x0055
+ #define CINTERION_PRODUCT_PLS8                        0x0060
  
  /* Olivetti products */
  #define OLIVETTI_VENDOR_ID                    0x0b3c
@@@ -579,6 -581,7 +581,7 @@@ static const struct usb_device_id optio
        { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42),
                .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
@@@ -1532,8 -1537,13 +1537,8 @@@ static void option_instat_callback(stru
                        portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
                        portdata->ri_state = ((signals & 0x08) ? 1 : 0);
  
 -                      if (old_dcd_state && !portdata->dcd_state) {
 -                              struct tty_struct *tty =
 -                                              tty_port_tty_get(&port->port);
 -                              if (tty && !C_CLOCAL(tty))
 -                                      tty_hangup(tty);
 -                              tty_kref_put(tty);
 -                      }
 +                      if (old_dcd_state && !portdata->dcd_state)
 +                              tty_port_tty_hangup(&port->port, true);
                } else {
                        dev_dbg(dev, "%s: type %x req %x\n", __func__,
                                req_pkt->bRequestType, req_pkt->bRequest);
@@@ -116,6 -116,7 +116,6 @@@ struct qt2_serial_private 
  };
  
  struct qt2_port_private {
 -      bool is_open;
        u8   device_port;
  
        spinlock_t urb_lock;
@@@ -397,6 -398,7 +397,6 @@@ static int qt2_open(struct tty_struct *
                return status;
        }
  
 -      port_priv->is_open = true;
        port_priv->device_port = (u8) device_port;
  
        if (tty)
@@@ -416,6 -418,8 +416,6 @@@ static void qt2_close(struct usb_serial
        serial = port->serial;
        port_priv = usb_get_serial_port_data(port);
  
 -      port_priv->is_open = false;
 -
        spin_lock_irqsave(&port_priv->urb_lock, flags);
        usb_kill_urb(port_priv->write_urb);
        port_priv->urb_in_use = false;
@@@ -657,7 -661,9 +657,9 @@@ void qt2_process_read_urb(struct urb *u
                                                 __func__);
                                        break;
                                }
-                               tty_flip_buffer_push(&port->port);
+                               if (port_priv->is_open)
+                                       tty_flip_buffer_push(&port->port);
  
                                newport = *(ch + 3);
  
                tty_insert_flip_string(&port->port, ch, 1);
        }
  
-       tty_flip_buffer_push(&port->port);
+       if (port_priv->is_open)
+               tty_flip_buffer_push(&port->port);
  }
  
  static void qt2_write_bulk_callback(struct urb *urb)
@@@ -901,6 -908,12 +904,6 @@@ static void qt2_break_ctl(struct tty_st
  
        port_priv = usb_get_serial_port_data(port);
  
 -      if (!port_priv->is_open) {
 -              dev_err(&port->dev,
 -                      "%s - port is not open\n", __func__);
 -              return;
 -      }
 -
        val = (break_state == -1) ? 1 : 0;
  
        status = qt2_control_msg(port->serial->dev, QT2_BREAK_CONTROL,