diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-05-22 14:25:34 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-05-22 14:25:34 -0400 |
commit | e4b636366c00738b9609cda307014d71b1225b7f (patch) | |
tree | 760b67b3624eda62e943e48ce93635c30a5b47bf /drivers/usb/serial/ftdi_sio.c | |
parent | b9ed7252d219c1c663944bf03846eabb515dbe75 (diff) | |
parent | 279e677faa775ad16e75c32e1bf4a37f8158bc61 (diff) |
Merge branch 'master' into for-2.6.31
Conflicts:
drivers/block/hd.c
drivers/block/mg_disk.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8100f1d25904..d9fcdaedf389 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -56,6 +56,7 @@ static __u16 vendor = FTDI_VID; | |||
56 | static __u16 product; | 56 | static __u16 product; |
57 | 57 | ||
58 | struct ftdi_private { | 58 | struct ftdi_private { |
59 | struct kref kref; | ||
59 | ftdi_chip_type_t chip_type; | 60 | ftdi_chip_type_t chip_type; |
60 | /* type of device, either SIO or FT8U232AM */ | 61 | /* type of device, either SIO or FT8U232AM */ |
61 | int baud_base; /* baud base clock for divisor setting */ | 62 | int baud_base; /* baud base clock for divisor setting */ |
@@ -669,6 +670,8 @@ static struct usb_device_id id_table_combined [] = { | |||
669 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), | 670 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), |
670 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 671 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
671 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 672 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
673 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | ||
674 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
672 | { }, /* Optional parameter entry */ | 675 | { }, /* Optional parameter entry */ |
673 | { } /* Terminating entry */ | 676 | { } /* Terminating entry */ |
674 | }; | 677 | }; |
@@ -1352,6 +1355,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) | |||
1352 | return -ENOMEM; | 1355 | return -ENOMEM; |
1353 | } | 1356 | } |
1354 | 1357 | ||
1358 | kref_init(&priv->kref); | ||
1355 | spin_lock_init(&priv->rx_lock); | 1359 | spin_lock_init(&priv->rx_lock); |
1356 | spin_lock_init(&priv->tx_lock); | 1360 | spin_lock_init(&priv->tx_lock); |
1357 | init_waitqueue_head(&priv->delta_msr_wait); | 1361 | init_waitqueue_head(&priv->delta_msr_wait); |
@@ -1468,6 +1472,13 @@ static void ftdi_shutdown(struct usb_serial *serial) | |||
1468 | dbg("%s", __func__); | 1472 | dbg("%s", __func__); |
1469 | } | 1473 | } |
1470 | 1474 | ||
1475 | static void ftdi_sio_priv_release(struct kref *k) | ||
1476 | { | ||
1477 | struct ftdi_private *priv = container_of(k, struct ftdi_private, kref); | ||
1478 | |||
1479 | kfree(priv); | ||
1480 | } | ||
1481 | |||
1471 | static int ftdi_sio_port_remove(struct usb_serial_port *port) | 1482 | static int ftdi_sio_port_remove(struct usb_serial_port *port) |
1472 | { | 1483 | { |
1473 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1484 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
@@ -1476,14 +1487,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) | |||
1476 | 1487 | ||
1477 | remove_sysfs_attrs(port); | 1488 | remove_sysfs_attrs(port); |
1478 | 1489 | ||
1479 | /* all open ports are closed at this point | 1490 | kref_put(&priv->kref, ftdi_sio_priv_release); |
1480 | * (by usbserial.c:__serial_close, which calls ftdi_close) | ||
1481 | */ | ||
1482 | |||
1483 | if (priv) { | ||
1484 | usb_set_serial_port_data(port, NULL); | ||
1485 | kfree(priv); | ||
1486 | } | ||
1487 | 1491 | ||
1488 | return 0; | 1492 | return 0; |
1489 | } | 1493 | } |
@@ -1547,7 +1551,8 @@ static int ftdi_open(struct tty_struct *tty, | |||
1547 | dev_err(&port->dev, | 1551 | dev_err(&port->dev, |
1548 | "%s - failed submitting read urb, error %d\n", | 1552 | "%s - failed submitting read urb, error %d\n", |
1549 | __func__, result); | 1553 | __func__, result); |
1550 | 1554 | else | |
1555 | kref_get(&priv->kref); | ||
1551 | 1556 | ||
1552 | return result; | 1557 | return result; |
1553 | } /* ftdi_open */ | 1558 | } /* ftdi_open */ |
@@ -1589,11 +1594,11 @@ static void ftdi_close(struct tty_struct *tty, | |||
1589 | mutex_unlock(&port->serial->disc_mutex); | 1594 | mutex_unlock(&port->serial->disc_mutex); |
1590 | 1595 | ||
1591 | /* cancel any scheduled reading */ | 1596 | /* cancel any scheduled reading */ |
1592 | cancel_delayed_work(&priv->rx_work); | 1597 | cancel_delayed_work_sync(&priv->rx_work); |
1593 | flush_scheduled_work(); | ||
1594 | 1598 | ||
1595 | /* shutdown our bulk read */ | 1599 | /* shutdown our bulk read */ |
1596 | usb_kill_urb(port->read_urb); | 1600 | usb_kill_urb(port->read_urb); |
1601 | kref_put(&priv->kref, ftdi_sio_priv_release); | ||
1597 | } /* ftdi_close */ | 1602 | } /* ftdi_close */ |
1598 | 1603 | ||
1599 | 1604 | ||