]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/serial/metro-usb.c
Merge remote-tracking branch 'asoc/topic/wm0010' into asoc-next
[~andy/linux] / drivers / usb / serial / metro-usb.c
index 0b257ddffbdbd903da48db51746bee3da9ebe4d6..6f29c74eb76925098a9cab841142c955c6d3a725 100644 (file)
@@ -179,16 +179,13 @@ static void metrousb_cleanup(struct usb_serial_port *port)
 {
        dev_dbg(&port->dev, "%s\n", __func__);
 
-       if (port->serial->dev) {
-               /* Shutdown any interrupt in urbs. */
-               if (port->interrupt_in_urb) {
-                       usb_unlink_urb(port->interrupt_in_urb);
-                       usb_kill_urb(port->interrupt_in_urb);
-               }
-
-               /* Send deactivate cmd to device */
+       usb_unlink_urb(port->interrupt_in_urb);
+       usb_kill_urb(port->interrupt_in_urb);
+
+       mutex_lock(&port->serial->disc_mutex);
+       if (!port->serial->disconnected)
                metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
-       }
+       mutex_unlock(&port->serial->disc_mutex);
 }
 
 static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
@@ -271,51 +268,27 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr
        return retval;
 }
 
-static void metrousb_shutdown(struct usb_serial *serial)
+static int metrousb_port_probe(struct usb_serial_port *port)
 {
-       int i = 0;
+       struct metrousb_private *metro_priv;
 
-       dev_dbg(&serial->dev->dev, "%s\n", __func__);
+       metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL);
+       if (!metro_priv)
+               return -ENOMEM;
 
-       /* Stop reading and writing on all ports. */
-       for (i = 0; i < serial->num_ports; ++i) {
-               /* Close any open urbs. */
-               metrousb_cleanup(serial->port[i]);
+       spin_lock_init(&metro_priv->lock);
 
-               /* Free memory. */
-               kfree(usb_get_serial_port_data(serial->port[i]));
-               usb_set_serial_port_data(serial->port[i], NULL);
+       usb_set_serial_port_data(port, metro_priv);
 
-               dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n",
-                       __func__, serial->port[i]->number);
-       }
+       return 0;
 }
 
-static int metrousb_startup(struct usb_serial *serial)
+static int metrousb_port_remove(struct usb_serial_port *port)
 {
        struct metrousb_private *metro_priv;
-       struct usb_serial_port *port;
-       int i = 0;
 
-       dev_dbg(&serial->dev->dev, "%s\n", __func__);
-
-       /* Loop through the serial ports setting up the private structures.
-        * Currently we only use one port. */
-       for (i = 0; i < serial->num_ports; ++i) {
-               port = serial->port[i];
-
-               /* Declare memory. */
-               metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL);
-               if (!metro_priv)
-                       return -ENOMEM;
-
-               /* Initialize memory. */
-               spin_lock_init(&metro_priv->lock);
-               usb_set_serial_port_data(port, metro_priv);
-
-               dev_dbg(&serial->dev->dev, "%s - port number=%d\n ",
-                       __func__, port->number);
-       }
+       metro_priv = usb_get_serial_port_data(port);
+       kfree(metro_priv);
 
        return 0;
 }
@@ -414,8 +387,8 @@ static struct usb_serial_driver metrousb_device = {
        .close                  = metrousb_cleanup,
        .read_int_callback      = metrousb_read_int_callback,
        .write_int_callback     = metrousb_write_int_callback,
-       .attach                 = metrousb_startup,
-       .release                = metrousb_shutdown,
+       .port_probe             = metrousb_port_probe,
+       .port_remove            = metrousb_port_remove,
        .throttle               = metrousb_throttle,
        .unthrottle             = metrousb_unthrottle,
        .tiocmget               = metrousb_tiocmget,