Merge 3.9-rc5 into tty-next
Greg Kroah-Hartman [Mon, 1 Apr 2013 19:01:10 +0000 (12:01 -0700)]
We need the fixes here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

1  2 
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/xilinx_uartps.c
drivers/usb/class/cdc-acm.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/quatech2.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c

@@@ -2755,7 -2755,7 +2755,7 @@@ static void __init serial8250_isa_init_
        if (nr_uarts > UART_NR)
                nr_uarts = UART_NR;
  
 -      for (i = 0; i < nr_uarts; i++) {
 +      for (i = 0; i < UART_NR; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
                struct uart_port *port = &up->port;
  
@@@ -2916,7 -2916,7 +2916,7 @@@ static int __init serial8250_console_se
         * if so, search for the first available port that does have
         * console support.
         */
 -      if (co->index >= nr_uarts)
 +      if (co->index >= UART_NR)
                co->index = 0;
        port = &serial8250_ports[co->index].port;
        if (!port->iobase && !port->membase)
@@@ -2957,7 -2957,7 +2957,7 @@@ int serial8250_find_port(struct uart_po
        int line;
        struct uart_port *port;
  
 -      for (line = 0; line < nr_uarts; line++) {
 +      for (line = 0; line < UART_NR; line++) {
                port = &serial8250_ports[line].port;
                if (uart_match_port(p, port))
                        return line;
@@@ -3110,7 -3110,7 +3110,7 @@@ static int serial8250_remove(struct pla
  {
        int i;
  
 -      for (i = 0; i < nr_uarts; i++) {
 +      for (i = 0; i < UART_NR; i++) {
                struct uart_8250_port *up = &serial8250_ports[i];
  
                if (up->port.dev == &dev->dev)
@@@ -3178,7 -3178,7 +3178,7 @@@ static struct uart_8250_port *serial825
        /*
         * First, find a port entry which matches.
         */
 -      for (i = 0; i < nr_uarts; i++)
 +      for (i = 0; i < UART_NR; i++)
                if (uart_match_port(&serial8250_ports[i].port, port))
                        return &serial8250_ports[i];
  
         * free entry.  We look for one which hasn't been previously
         * used (indicated by zero iobase).
         */
 -      for (i = 0; i < nr_uarts; i++)
 +      for (i = 0; i < UART_NR; i++)
                if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
                    serial8250_ports[i].port.iobase == 0)
                        return &serial8250_ports[i];
         * That also failed.  Last resort is to find any entry which
         * doesn't have a real port associated with it.
         */
 -      for (i = 0; i < nr_uarts; i++)
 +      for (i = 0; i < UART_NR; i++)
                if (serial8250_ports[i].port.type == PORT_UNKNOWN)
                        return &serial8250_ports[i];
  
@@@ -3247,10 -3247,6 +3247,10 @@@ int serial8250_register_8250_port(struc
                uart->tx_loadsz         = up->tx_loadsz;
                uart->capabilities      = up->capabilities;
  
 +              /* Take tx_loadsz from fifosize if it wasn't set separately */
 +              if (uart->port.fifosize && !uart->tx_loadsz)
 +                      uart->tx_loadsz = uart->port.fifosize;
 +
                if (up->port.dev)
                        uart->port.dev = up->port.dev;
  
@@@ -3422,6 -3418,7 +3422,7 @@@ MODULE_PARM_DESC(probe_rsa, "Probe I/O 
  #endif
  MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
  
+ #ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
  #ifndef MODULE
  /* This module was renamed to 8250_core in 3.7.  Keep the old "8250" name
   * working as well for the module options so we don't break people.  We
  static void __used s8250_options(void)
  {
  #undef MODULE_PARAM_PREFIX
- #define MODULE_PARAM_PREFIX "8250."
+ #define MODULE_PARAM_PREFIX "8250_core."
  
        module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
        module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
  #endif
  }
  #else
- MODULE_ALIAS("8250");
+ MODULE_ALIAS("8250_core");
+ #endif
  #endif
@@@ -578,11 -578,16 +578,13 @@@ static int xuartps_startup(struct uart_
        /* Receive Timeout register is enabled with value of 10 */
        xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
  
+       /* Clear out any pending interrupts before enabling them */
+       xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET);
  
        /* Set the Interrupt Registers with desired interrupts */
        xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY |
                XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN |
                XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT, XUARTPS_IER_OFFSET);
 -      xuartps_writel(~(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY |
 -              XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN |
 -              XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT), XUARTPS_IDR_OFFSET);
  
        return retval;
  }
@@@ -292,6 -292,7 +292,6 @@@ static void acm_ctrl_irq(struct urb *ur
  {
        struct acm *acm = urb->context;
        struct usb_cdc_notification *dr = urb->transfer_buffer;
 -      struct tty_struct *tty;
        unsigned char *data;
        int newctrl;
        int retval;
                break;
  
        case USB_CDC_NOTIFY_SERIAL_STATE:
 -              tty = tty_port_tty_get(&acm->port);
                newctrl = get_unaligned_le16(data);
  
 -              if (tty) {
 -                      if (!acm->clocal &&
 -                              (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
 -                              dev_dbg(&acm->control->dev,
 -                                      "%s - calling hangup\n", __func__);
 -                              tty_hangup(tty);
 -                      }
 -                      tty_kref_put(tty);
 +              if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
 +                      dev_dbg(&acm->control->dev, "%s - calling hangup\n",
 +                                      __func__);
 +                      tty_port_tty_hangup(&acm->port, false);
                }
  
                acm->ctrlin = newctrl;
@@@ -469,10 -475,15 +469,10 @@@ static void acm_write_bulk(struct urb *
  static void acm_softint(struct work_struct *work)
  {
        struct acm *acm = container_of(work, struct acm, work);
  
        dev_vdbg(&acm->data->dev, "%s\n", __func__);
  
 -      tty = tty_port_tty_get(&acm->port);
 -      if (!tty)
 -              return;
 -      tty_wakeup(tty);
 -      tty_kref_put(tty);
 +      tty_port_tty_wakeup(&acm->port);
  }
  
  /*
@@@ -582,7 -593,6 +582,6 @@@ static void acm_port_destruct(struct tt
  
        dev_dbg(&acm->control->dev, "%s\n", __func__);
  
-       tty_unregister_device(acm_tty_driver, acm->minor);
        acm_release_minor(acm);
        usb_put_intf(acm->control);
        kfree(acm->country_codes);
@@@ -966,6 -976,8 +965,8 @@@ static int acm_probe(struct usb_interfa
        int num_rx_buf;
        int i;
        int combined_interfaces = 0;
+       struct device *tty_dev;
+       int rv = -ENOMEM;
  
        /* normal quirks */
        quirks = (unsigned long)id->driver_info;
@@@ -1328,11 -1340,24 +1329,24 @@@ skip_countries
        usb_set_intfdata(data_interface, acm);
  
        usb_get_intf(control_interface);
-       tty_port_register_device(&acm->port, acm_tty_driver, minor,
+       tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
                        &control_interface->dev);
+       if (IS_ERR(tty_dev)) {
+               rv = PTR_ERR(tty_dev);
+               goto alloc_fail8;
+       }
  
        return 0;
+ alloc_fail8:
+       if (acm->country_codes) {
+               device_remove_file(&acm->control->dev,
+                               &dev_attr_wCountryCodes);
+               device_remove_file(&acm->control->dev,
+                               &dev_attr_iCountryCodeRelDate);
+       }
+       device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
  alloc_fail7:
+       usb_set_intfdata(intf, NULL);
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
  alloc_fail6:
@@@ -1348,7 -1373,7 +1362,7 @@@ alloc_fail2
        acm_release_minor(acm);
        kfree(acm);
  alloc_fail:
-       return -ENOMEM;
+       return rv;
  }
  
  static void stop_data_traffic(struct acm *acm)
@@@ -1400,6 -1425,8 +1414,8 @@@ static void acm_disconnect(struct usb_i
  
        stop_data_traffic(acm);
  
+       tty_unregister_device(acm_tty_driver, acm->minor);
        usb_free_urb(acm->ctrlurb);
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
@@@ -1492,9 -1519,15 +1508,9 @@@ err_out
  static int acm_reset_resume(struct usb_interface *intf)
  {
        struct acm *acm = usb_get_intfdata(intf);
 -      struct tty_struct *tty;
  
 -      if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
 -              tty = tty_port_tty_get(&acm->port);
 -              if (tty) {
 -                      tty_hangup(tty);
 -                      tty_kref_put(tty);
 -              }
 -      }
 +      if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
 +              tty_port_tty_hangup(&acm->port, false);
  
        return acm_resume(intf);
  }
@@@ -110,7 -110,6 +110,6 @@@ struct edgeport_port 
        wait_queue_head_t       wait_chase;             /* for handling sleeping while waiting for chase to finish */
        wait_queue_head_t       wait_open;              /* for handling sleeping while waiting for open to finish */
        wait_queue_head_t       wait_command;           /* for handling sleeping while waiting for command to finish */
-       wait_queue_head_t       delta_msr_wait;         /* for handling sleeping while waiting for msr change to happen */
  
        struct async_icount     icount;
        struct usb_serial_port  *port;                  /* loop back to the owner of this object */
@@@ -565,6 -564,7 +564,6 @@@ static void edge_interrupt_callback(str
        struct device *dev;
        struct edgeport_port *edge_port;
        struct usb_serial_port *port;
 -      struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int length = urb->actual_length;
        int bytes_avail;
  
                                        /* tell the tty driver that something
                                           has changed */
 -                                      tty = tty_port_tty_get(
 -                                              &edge_port->port->port);
 -                                      if (tty) {
 -                                              tty_wakeup(tty);
 -                                              tty_kref_put(tty);
 -                                      }
 +                                      tty_port_tty_wakeup(&edge_port->port->port);
                                        /* Since we have more credit, check
                                           if more data can be sent */
                                        send_more_port_data(edge_serial,
@@@ -732,6 -737,7 +731,6 @@@ static void edge_bulk_in_callback(struc
  static void edge_bulk_out_data_callback(struct urb *urb)
  {
        struct edgeport_port *edge_port = urb->context;
 -      struct tty_struct *tty;
        int status = urb->status;
  
        if (status) {
                        __func__, status);
        }
  
 -      tty = tty_port_tty_get(&edge_port->port->port);
 -
 -      if (tty && edge_port->open) {
 -              /* let the tty driver wakeup if it has a special
 -                 write_wakeup function */
 -              tty_wakeup(tty);
 -      }
 -      tty_kref_put(tty);
 +      if (edge_port->open)
 +              tty_port_tty_wakeup(&edge_port->port->port);
  
        /* Release the Write URB */
        edge_port->write_in_progress = false;
  static void edge_bulk_out_cmd_callback(struct urb *urb)
  {
        struct edgeport_port *edge_port = urb->context;
 -      struct tty_struct *tty;
        int status = urb->status;
  
        atomic_dec(&CmdUrbs);
                return;
        }
  
 -      /* Get pointer to tty */
 -      tty = tty_port_tty_get(&edge_port->port->port);
 -
        /* tell the tty driver that something has changed */
 -      if (tty && edge_port->open)
 -              tty_wakeup(tty);
 -      tty_kref_put(tty);
 +      if (edge_port->open)
 +              tty_port_tty_wakeup(&edge_port->port->port);
  
        /* we have completed the command */
        edge_port->commandPending = false;
@@@ -866,7 -883,6 +865,6 @@@ static int edge_open(struct tty_struct 
        /* initialize our wait queues */
        init_waitqueue_head(&edge_port->wait_open);
        init_waitqueue_head(&edge_port->wait_chase);
-       init_waitqueue_head(&edge_port->delta_msr_wait);
        init_waitqueue_head(&edge_port->wait_command);
  
        /* initialize our icount structure */
@@@ -1651,13 -1667,17 +1649,17 @@@ static int edge_ioctl(struct tty_struc
                dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__,  port->number);
                cprev = edge_port->icount;
                while (1) {
-                       prepare_to_wait(&edge_port->delta_msr_wait,
+                       prepare_to_wait(&port->delta_msr_wait,
                                                &wait, TASK_INTERRUPTIBLE);
                        schedule();
-                       finish_wait(&edge_port->delta_msr_wait, &wait);
+                       finish_wait(&port->delta_msr_wait, &wait);
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+                       if (port->serial->disconnected)
+                               return -EIO;
                        cnow = edge_port->icount;
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@@ -2033,7 -2053,7 +2035,7 @@@ static void handle_new_msr(struct edgep
                        icount->dcd++;
                if (newMsr & EDGEPORT_MSR_DELTA_RI)
                        icount->rng++;
-               wake_up_interruptible(&edge_port->delta_msr_wait);
+               wake_up_interruptible(&edge_port->port->delta_msr_wait);
        }
  
        /* Save the new modem status */
@@@ -219,7 -219,6 +219,6 @@@ struct moschip_port 
        char open;
        char open_ports;
        wait_queue_head_t wait_chase;   /* for handling sleeping while waiting for chase to finish */
-       wait_queue_head_t delta_msr_wait;       /* for handling sleeping while waiting for msr change to happen */
        int delta_msr_cond;
        struct async_icount icount;
        struct usb_serial_port *port;   /* loop back to the owner of this object */
@@@ -423,6 -422,9 +422,9 @@@ static void mos7840_handle_new_msr(stru
                        icount->rng++;
                        smp_wmb();
                }
+               mos7840_port->delta_msr_cond = 1;
+               wake_up_interruptible(&port->port->delta_msr_wait);
        }
  }
  
@@@ -814,6 -816,7 +816,6 @@@ static void mos7840_bulk_out_data_callb
  {
        struct moschip_port *mos7840_port;
        struct usb_serial_port *port;
 -      struct tty_struct *tty;
        int status = urb->status;
        int i;
  
        if (mos7840_port_paranoia_check(port, __func__))
                return;
  
 -      tty = tty_port_tty_get(&port->port);
 -      if (tty && mos7840_port->open)
 -              tty_wakeup(tty);
 -      tty_kref_put(tty);
 +      if (mos7840_port->open)
 +              tty_port_tty_wakeup(&port->port);
  
  }
  
@@@ -1124,7 -1129,6 +1126,6 @@@ static int mos7840_open(struct tty_stru
  
        /* initialize our wait queues */
        init_waitqueue_head(&mos7840_port->wait_chase);
-       init_waitqueue_head(&mos7840_port->delta_msr_wait);
  
        /* initialize our icount structure */
        memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
@@@ -2014,8 -2018,6 +2015,6 @@@ static void mos7840_change_port_setting
                        mos7840_port->read_urb_busy = false;
                }
        }
-       wake_up(&mos7840_port->delta_msr_wait);
-       mos7840_port->delta_msr_cond = 1;
        dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__,
                mos7840_port->shadowLCR);
  }
@@@ -2216,13 -2218,18 +2215,18 @@@ static int mos7840_ioctl(struct tty_str
                while (1) {
                        /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
                        mos7840_port->delta_msr_cond = 0;
-                       wait_event_interruptible(mos7840_port->delta_msr_wait,
-                                                (mos7840_port->
+                       wait_event_interruptible(port->delta_msr_wait,
+                                                (port->serial->disconnected ||
+                                                 mos7840_port->
                                                  delta_msr_cond == 1));
  
                        /* see if a signal did it */
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+                       if (port->serial->disconnected)
+                               return -EIO;
                        cnow = mos7840_port->icount;
                        smp_rmb();
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
@@@ -116,6 -116,7 +116,6 @@@ struct qt2_serial_private 
  };
  
  struct qt2_port_private {
 -      bool is_open;
        u8   device_port;
  
        spinlock_t urb_lock;
        u8          shadowLSR;
        u8          shadowMSR;
  
-       wait_queue_head_t   delta_msr_wait; /* Used for TIOCMIWAIT */
        struct async_icount icount;
  
        struct usb_serial_port *port;
@@@ -397,6 -397,7 +396,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 -417,8 +415,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;
@@@ -502,8 -505,9 +501,9 @@@ static int wait_modem_info(struct usb_s
        spin_unlock_irqrestore(&priv->lock, flags);
  
        while (1) {
-               wait_event_interruptible(priv->delta_msr_wait,
-                                        ((priv->icount.rng != prev.rng) ||
+               wait_event_interruptible(port->delta_msr_wait,
+                                        (port->serial->disconnected ||
+                                         (priv->icount.rng != prev.rng) ||
                                          (priv->icount.dsr != prev.dsr) ||
                                          (priv->icount.dcd != prev.dcd) ||
                                          (priv->icount.cts != prev.cts)));
                if (signal_pending(current))
                        return -ERESTARTSYS;
  
+               if (port->serial->disconnected)
+                       return -EIO;
                spin_lock_irqsave(&priv->lock, flags);
                cur = priv->icount;
                spin_unlock_irqrestore(&priv->lock, flags);
@@@ -657,7 -664,9 +660,7 @@@ void qt2_process_read_urb(struct urb *u
                                                 __func__);
                                        break;
                                }
 -
 -                              if (port_priv->is_open)
 -                                      tty_flip_buffer_push(&port->port);
 +                              tty_flip_buffer_push(&port->port);
  
                                newport = *(ch + 3);
  
                tty_insert_flip_string(&port->port, ch, 1);
        }
  
 -      if (port_priv->is_open)
 -              tty_flip_buffer_push(&port->port);
 +      tty_flip_buffer_push(&port->port);
  }
  
  static void qt2_write_bulk_callback(struct urb *urb)
@@@ -820,7 -830,6 +823,6 @@@ static int qt2_port_probe(struct usb_se
  
        spin_lock_init(&port_priv->lock);
        spin_lock_init(&port_priv->urb_lock);
-       init_waitqueue_head(&port_priv->delta_msr_wait);
        port_priv->port = port;
  
        port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
@@@ -901,6 -910,12 +903,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,
@@@ -957,7 -972,7 +959,7 @@@ static void qt2_update_msr(struct usb_s
                if (newMSR & UART_MSR_TERI)
                        port_priv->icount.rng++;
  
-               wake_up_interruptible(&port_priv->delta_msr_wait);
+               wake_up_interruptible(&port->delta_msr_wait);
        }
  }
  
@@@ -74,7 -74,6 +74,6 @@@ struct ti_port 
        int                     tp_flags;
        int                     tp_closing_wait;/* in .01 secs */
        struct async_icount     tp_icount;
-       wait_queue_head_t       tp_msr_wait;    /* wait for msr change */
        wait_queue_head_t       tp_write_wait;
        struct ti_device        *tp_tdev;
        struct usb_serial_port  *tp_port;
@@@ -432,7 -431,6 +431,6 @@@ static int ti_port_probe(struct usb_ser
        else
                tport->tp_uart_base_addr = TI_UART2_BASE_ADDR;
        tport->tp_closing_wait = closing_wait;
-       init_waitqueue_head(&tport->tp_msr_wait);
        init_waitqueue_head(&tport->tp_write_wait);
        if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) {
                kfree(tport);
@@@ -784,9 -782,13 +782,13 @@@ static int ti_ioctl(struct tty_struct *
                dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
                cprev = tport->tp_icount;
                while (1) {
-                       interruptible_sleep_on(&tport->tp_msr_wait);
+                       interruptible_sleep_on(&port->delta_msr_wait);
                        if (signal_pending(current))
                                return -ERESTARTSYS;
+                       if (port->serial->disconnected)
+                               return -EIO;
                        cnow = tport->tp_icount;
                        if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
                            cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
@@@ -1227,6 -1229,7 +1229,6 @@@ static void ti_send(struct ti_port *tpo
  {
        int count, result;
        struct usb_serial_port *port = tport->tp_port;
 -      struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */
        unsigned long flags;
  
        spin_lock_irqsave(&tport->tp_lock, flags);
        }
  
        /* more room in the buffer for new writes, wakeup */
 -      if (tty)
 -              tty_wakeup(tty);
 -      tty_kref_put(tty);
 +      tty_port_tty_wakeup(&port->port);
 +
        wake_up_interruptible(&tport->tp_write_wait);
        return;
  unlock:
        spin_unlock_irqrestore(&tport->tp_lock, flags);
 -      tty_kref_put(tty);
        return;
  }
  
@@@ -1389,7 -1394,7 +1391,7 @@@ static void ti_handle_new_msr(struct ti
                        icount->dcd++;
                if (msr & TI_MSR_DELTA_RI)
                        icount->rng++;
-               wake_up_interruptible(&tport->tp_msr_wait);
+               wake_up_interruptible(&tport->tp_port->delta_msr_wait);
                spin_unlock_irqrestore(&tport->tp_lock, flags);
        }
  
@@@ -151,6 -151,7 +151,7 @@@ static void destroy_serial(struct kref 
                }
        }
  
+       usb_put_intf(serial->interface);
        usb_put_dev(serial->dev);
        kfree(serial);
  }
@@@ -541,8 -542,16 +542,8 @@@ static void usb_serial_port_work(struc
  {
        struct usb_serial_port *port =
                container_of(work, struct usb_serial_port, work);
 -      struct tty_struct *tty;
  
 -      tty = tty_port_tty_get(&port->port);
 -      if (!tty)
 -              return;
 -
 -      dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number);
 -
 -      tty_wakeup(tty);
 -      tty_kref_put(tty);
 +      tty_port_tty_wakeup(&port->port);
  }
  
  static void kill_traffic(struct usb_serial_port *port)
@@@ -612,7 -621,7 +613,7 @@@ static struct usb_serial *create_serial
        }
        serial->dev = usb_get_dev(dev);
        serial->type = driver;
-       serial->interface = interface;
+       serial->interface = usb_get_intf(interface);
        kref_init(&serial->kref);
        mutex_init(&serial->disc_mutex);
        serial->minor = SERIAL_TTY_NO_MINOR;
@@@ -894,6 -903,7 +895,7 @@@ static int usb_serial_probe(struct usb_
                port->port.ops = &serial_port_ops;
                port->serial = serial;
                spin_lock_init(&port->lock);
+               init_waitqueue_head(&port->delta_msr_wait);
                /* Keep this for private driver use for the moment but
                   should probably go away */
                INIT_WORK(&port->work, usb_serial_port_work);