aboutsummaryrefslogtreecommitdiff
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 128c20a043c..2353679f601 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -273,12 +273,18 @@ static __u16 product;
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
struct ftdi_sio_quirk {
+ int (*probe)(struct usb_serial *);
void (*setup)(struct usb_serial *); /* Special settings during startup. */
};
+static int ftdi_olimex_probe (struct usb_serial *serial);
static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
+static struct ftdi_sio_quirk ftdi_olimex_quirk = {
+ .probe = ftdi_olimex_probe,
+};
+
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
.setup = ftdi_USB_UIRT_setup,
};
@@ -527,6 +533,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -671,7 +679,7 @@ static struct usb_serial_driver ftdi_sio_device = {
/*
* ***************************************************************************
- * Utlity functions
+ * Utility functions
* ***************************************************************************
*/
@@ -1173,9 +1181,17 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
/* Probe function to check for special devices */
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
{
+ struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
+
+ if (quirk && quirk->probe) {
+ int ret = quirk->probe(serial);
+ if (ret != 0)
+ return ret;
+ }
+
usb_set_serial_data(serial, (void *)id->driver_info);
- return (0);
+ return 0;
}
static int ftdi_sio_port_probe(struct usb_serial_port *port)
@@ -1270,6 +1286,24 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
priv->force_rtscts = 1;
} /* ftdi_HE_TIRA1_setup */
+/*
+ * First port on Olimex arm-usb-ocd is reserved for JTAG interface
+ * and can be accessed from userspace using openocd.
+ */
+static int ftdi_olimex_probe(struct usb_serial *serial)
+{
+ struct usb_device *udev = serial->dev;
+ struct usb_interface *interface = serial->interface;
+
+ dbg("%s",__FUNCTION__);
+
+ if (interface == udev->actconfig->interface[0]) {
+ info("Ignoring reserved serial port on Olimex arm-usb-ocd\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
* it is called when the usb device is disconnected