aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/ftdi_sio.c94
1 files changed, 60 insertions, 34 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index d9d87111f9a..21c053c31b9 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -89,6 +89,7 @@ struct ftdi_private {
89 int force_rtscts; /* if non-zero, force RTS-CTS to always 89 int force_rtscts; /* if non-zero, force RTS-CTS to always
90 be enabled */ 90 be enabled */
91 91
92 unsigned int latency; /* latency setting in use */
92 spinlock_t tx_lock; /* spinlock for transmit state */ 93 spinlock_t tx_lock; /* spinlock for transmit state */
93 unsigned long tx_bytes; 94 unsigned long tx_bytes;
94 unsigned long tx_outstanding_bytes; 95 unsigned long tx_outstanding_bytes;
@@ -1038,7 +1039,54 @@ static int change_speed(struct tty_struct *tty, struct usb_serial_port *port)
1038 return rv; 1039 return rv;
1039} 1040}
1040 1041
1042static int write_latency_timer(struct usb_serial_port *port)
1043{
1044 struct ftdi_private *priv = usb_get_serial_port_data(port);
1045 struct usb_device *udev = port->serial->dev;
1046 char buf[1];
1047 int rv = 0;
1048 int l = priv->latency;
1049
1050 if (priv->flags & ASYNC_LOW_LATENCY)
1051 l = 1;
1052
1053 dbg("%s: setting latency timer = %i", __func__, l);
1054
1055 rv = usb_control_msg(udev,
1056 usb_sndctrlpipe(udev, 0),
1057 FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
1058 FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
1059 l, priv->interface,
1060 buf, 0, WDR_TIMEOUT);
1041 1061
1062 if (rv < 0)
1063 dev_err(&port->dev, "Unable to write latency timer: %i\n", rv);
1064 return rv;
1065}
1066
1067static int read_latency_timer(struct usb_serial_port *port)
1068{
1069 struct ftdi_private *priv = usb_get_serial_port_data(port);
1070 struct usb_device *udev = port->serial->dev;
1071 unsigned short latency = 0;
1072 int rv = 0;
1073
1074
1075 dbg("%s", __func__);
1076
1077 rv = usb_control_msg(udev,
1078 usb_rcvctrlpipe(udev, 0),
1079 FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
1080 FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
1081 0, priv->interface,
1082 (char *) &latency, 1, WDR_TIMEOUT);
1083
1084 if (rv < 0) {
1085 dev_err(&port->dev, "Unable to read latency timer: %i\n", rv);
1086 return -EIO;
1087 }
1088 return latency;
1089}
1042 1090
1043static int get_serial_info(struct usb_serial_port *port, 1091static int get_serial_info(struct usb_serial_port *port,
1044 struct serial_struct __user *retinfo) 1092 struct serial_struct __user *retinfo)
@@ -1098,6 +1146,7 @@ static int set_serial_info(struct tty_struct *tty,
1098 priv->custom_divisor = new_serial.custom_divisor; 1146 priv->custom_divisor = new_serial.custom_divisor;
1099 1147
1100 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1148 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1149 write_latency_timer(port);
1101 1150
1102check_and_exit: 1151check_and_exit:
1103 if ((old_priv.flags & ASYNC_SPD_MASK) != 1152 if ((old_priv.flags & ASYNC_SPD_MASK) !=
@@ -1193,27 +1242,13 @@ static ssize_t show_latency_timer(struct device *dev,
1193{ 1242{
1194 struct usb_serial_port *port = to_usb_serial_port(dev); 1243 struct usb_serial_port *port = to_usb_serial_port(dev);
1195 struct ftdi_private *priv = usb_get_serial_port_data(port); 1244 struct ftdi_private *priv = usb_get_serial_port_data(port);
1196 struct usb_device *udev = port->serial->dev; 1245 if (priv->flags & ASYNC_LOW_LATENCY)
1197 unsigned short latency = 0; 1246 return sprintf(buf, "1\n");
1198 int rv = 0; 1247 else
1199 1248 return sprintf(buf, "%i\n", priv->latency);
1200
1201 dbg("%s", __func__);
1202
1203 rv = usb_control_msg(udev,
1204 usb_rcvctrlpipe(udev, 0),
1205 FTDI_SIO_GET_LATENCY_TIMER_REQUEST,
1206 FTDI_SIO_GET_LATENCY_TIMER_REQUEST_TYPE,
1207 0, priv->interface,
1208 (char *) &latency, 1, WDR_TIMEOUT);
1209
1210 if (rv < 0) {
1211 dev_err(dev, "Unable to read latency timer: %i\n", rv);
1212 return -EIO;
1213 }
1214 return sprintf(buf, "%i\n", latency);
1215} 1249}
1216 1250
1251
1217/* Write a new value of the latency timer, in units of milliseconds. */ 1252/* Write a new value of the latency timer, in units of milliseconds. */
1218static ssize_t store_latency_timer(struct device *dev, 1253static ssize_t store_latency_timer(struct device *dev,
1219 struct device_attribute *attr, const char *valbuf, 1254 struct device_attribute *attr, const char *valbuf,
@@ -1221,25 +1256,13 @@ static ssize_t store_latency_timer(struct device *dev,
1221{ 1256{
1222 struct usb_serial_port *port = to_usb_serial_port(dev); 1257 struct usb_serial_port *port = to_usb_serial_port(dev);
1223 struct ftdi_private *priv = usb_get_serial_port_data(port); 1258 struct ftdi_private *priv = usb_get_serial_port_data(port);
1224 struct usb_device *udev = port->serial->dev;
1225 char buf[1];
1226 int v = simple_strtoul(valbuf, NULL, 10); 1259 int v = simple_strtoul(valbuf, NULL, 10);
1227 int rv = 0; 1260 int rv = 0;
1228 1261
1229 dbg("%s: setting latency timer = %i", __func__, v); 1262 priv->latency = v;
1230 1263 rv = write_latency_timer(port);
1231 rv = usb_control_msg(udev, 1264 if (rv < 0)
1232 usb_sndctrlpipe(udev, 0),
1233 FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
1234 FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
1235 v, priv->interface,
1236 buf, 0, WDR_TIMEOUT);
1237
1238 if (rv < 0) {
1239 dev_err(dev, "Unable to write latency timer: %i\n", rv);
1240 return -EIO; 1265 return -EIO;
1241 }
1242
1243 return count; 1266 return count;
1244} 1267}
1245 1268
@@ -1393,6 +1416,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1393 usb_set_serial_port_data(port, priv); 1416 usb_set_serial_port_data(port, priv);
1394 1417
1395 ftdi_determine_type(port); 1418 ftdi_determine_type(port);
1419 read_latency_timer(port);
1396 create_sysfs_attrs(port); 1420 create_sysfs_attrs(port);
1397 return 0; 1421 return 0;
1398} 1422}
@@ -1515,6 +1539,8 @@ static int ftdi_open(struct tty_struct *tty,
1515 if (tty) 1539 if (tty)
1516 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1540 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1517 1541
1542 write_latency_timer(port);
1543
1518 /* No error checking for this (will get errors later anyway) */ 1544 /* No error checking for this (will get errors later anyway) */
1519 /* See ftdi_sio.h for description of what is reset */ 1545 /* See ftdi_sio.h for description of what is reset */
1520 usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1546 usb_control_msg(dev, usb_sndctrlpipe(dev, 0),