aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 128c20a043c9..2353679f601e 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -273,12 +273,18 @@ static __u16 product;
273 273
274/* struct ftdi_sio_quirk is used by devices requiring special attention. */ 274/* struct ftdi_sio_quirk is used by devices requiring special attention. */
275struct ftdi_sio_quirk { 275struct ftdi_sio_quirk {
276 int (*probe)(struct usb_serial *);
276 void (*setup)(struct usb_serial *); /* Special settings during startup. */ 277 void (*setup)(struct usb_serial *); /* Special settings during startup. */
277}; 278};
278 279
280static int ftdi_olimex_probe (struct usb_serial *serial);
279static void ftdi_USB_UIRT_setup (struct usb_serial *serial); 281static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
280static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); 282static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
281 283
284static struct ftdi_sio_quirk ftdi_olimex_quirk = {
285 .probe = ftdi_olimex_probe,
286};
287
282static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { 288static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
283 .setup = ftdi_USB_UIRT_setup, 289 .setup = ftdi_USB_UIRT_setup,
284}; 290};
@@ -527,6 +533,8 @@ static struct usb_device_id id_table_combined [] = {
527 { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, 533 { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
528 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, 534 { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
529 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, 535 { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
536 { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
537 .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
530 { }, /* Optional parameter entry */ 538 { }, /* Optional parameter entry */
531 { } /* Terminating entry */ 539 { } /* Terminating entry */
532}; 540};
@@ -671,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = {
671 679
672/* 680/*
673 * *************************************************************************** 681 * ***************************************************************************
674 * Utlity functions 682 * Utility functions
675 * *************************************************************************** 683 * ***************************************************************************
676 */ 684 */
677 685
@@ -1173,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
1173/* Probe function to check for special devices */ 1181/* Probe function to check for special devices */
1174static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id) 1182static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
1175{ 1183{
1184 struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
1185
1186 if (quirk && quirk->probe) {
1187 int ret = quirk->probe(serial);
1188 if (ret != 0)
1189 return ret;
1190 }
1191
1176 usb_set_serial_data(serial, (void *)id->driver_info); 1192 usb_set_serial_data(serial, (void *)id->driver_info);
1177 1193
1178 return (0); 1194 return 0;
1179} 1195}
1180 1196
1181static int ftdi_sio_port_probe(struct usb_serial_port *port) 1197static int ftdi_sio_port_probe(struct usb_serial_port *port)
@@ -1270,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
1270 priv->force_rtscts = 1; 1286 priv->force_rtscts = 1;
1271} /* ftdi_HE_TIRA1_setup */ 1287} /* ftdi_HE_TIRA1_setup */
1272 1288
1289/*
1290 * First port on Olimex arm-usb-ocd is reserved for JTAG interface
1291 * and can be accessed from userspace using openocd.
1292 */
1293static int ftdi_olimex_probe(struct usb_serial *serial)
1294{
1295 struct usb_device *udev = serial->dev;
1296 struct usb_interface *interface = serial->interface;
1297
1298 dbg("%s",__FUNCTION__);
1299
1300 if (interface == udev->actconfig->interface[0]) {
1301 info("Ignoring reserved serial port on Olimex arm-usb-ocd\n");
1302 return -ENODEV;
1303 }
1304
1305 return 0;
1306}
1273 1307
1274/* ftdi_shutdown is called from usbserial:usb_serial_disconnect 1308/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
1275 * it is called when the usb device is disconnected 1309 * it is called when the usb device is disconnected