changeset 83:d7a1e7a6d6ba

linux-patch: current best offering of minpatch-*
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 06 Dec 2020 02:55:40 +0000
parents e2161ac7d641
children 1d7d8615d628
files linux-patch/README linux-patch/minpatch-4.4.14/0001-USB-serial-ftdi_sio-add-support-for-FreeCalypso-JTAG.patch linux-patch/minpatch-4.4.14/0002-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch linux-patch/minpatch-4.4.14/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch linux-patch/minpatch-4.4.240/0002-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch linux-patch/minpatch-4.4.240/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch linux-patch/minpatch-4.9.240/0002-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch linux-patch/minpatch-4.9.240/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch
diffstat 8 files changed, 879 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/README	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,57 @@
+This directory contains several versions of the Linux kernel ftdi_sio driver
+patch that adds support for FreeCalypso DUART28C adapter, i.e., the optional
+configuration of DUART28 with boot control outputs.
+
+The version in the orig-202007 directory was produced at the end of 2020-07,
+when DUART28 hardware was still being designed; this original version of the
+patch was created to test the idea and to prove it working (using a generic
+FT2232D board and an oscilloscope), and it was created with the mindset of a
+hardware engineer, rather than that of Linux kernel maintainers.  This original
+patch version was made against kernel version 4.4.14 (the version used by the
+Mother), and it predates all later mainline submission and integration attempts.
+
+A patch series against then-current mainline was submitted to ftdi_sio driver
+maintainer Johan Hovold in 2020-09 for inclusion in mainline Linux.  The
+preliminary patch adding support for FreeCalypso JTAG+UART USB ID codes was
+readily accepted and has since been propagated to several stable kernel branches
+(4.4.240, 4.9.240, 4.14.202, 4.19.152, 5.4.72, 5.8.16, 5.9.1 and mainline 5.10),
+but this patch by itself does not help in any way with DUART28C support.  The
+remaining two patches from the original 2020-09 patch series (a preliminary
+patch fixing an oversight in the quirk interface and then the main patch of
+interest) were met with resistance, however, and the goal of bringing DUART28C
+support into mainline Linux is still in limbo as of 2020-12.
+
+Johan (the ftdi_sio driver maintainer who was the target of our initial pressure
+campaign to get the needed driver quirk accepted) has now proposed a generalized
+version of Mother Mychaela's original idea; this generalized version is just as
+good for our purposes because in the end it still recognizes our custom USB ID
+and sets the quirk flag which we require, but it also helps other potential
+users who may have similar needs, but who work with "any" serial port rather
+than a custom USB ID.  The current version as of this writing of Johan's patch
+series implementing his proposed generalized solution is this one:
+
+https://lore.kernel.org/linux-serial/X8iuCXYhOBVMGvXv@localhost/T/
+
+However, the comments in that thread indicate that the maintainers seem intent
+on delaying this integration until 5.12 merge window if not even later, thus we
+are still months away from any hope of resolution.  Because We The End Users
+cannot be expected to put our lives on hold and just sit and wait for kernel
+maintainers to get their act together, we need some immediate solution for our
+use right now - and the minpatch-* series presented here is our current best
+offering for end user purposes.
+
+3 end user patch series versions are presented in minpatch-4.4.14,
+minpatch-4.4.240 and minpatch-4.9.240.  4.4.240 and 4.9.240 already include the
+preliminary JTAG+UART USB ID code support patch (which serves mainly as an
+anchor marking the place where the new DUART28C USB ID code needs to go in
+ftdi_sio_ids.h and in the ftdi_sio.c ID code table), but 4.4.14 predates this
+patch by a few years, thus minpatch-4.4.14 includes a backport of this
+preliminary patch as well.  After this preliminary patch, each minpatch-*
+version includes the quirk port_probe patch and the main patch adding DUART28C
+support with the needed quirk.  These latter patches are the closest version we
+have to what we are hoping to see eventually merged into mainline, and they have
+already undergone rounds of revision in response to maintainer Johan's criticism
+- but this "minimal patch" version is limited to just the ftdi_sio driver, not
+extending into more generic layers, hence the actual quirk flag is implemented
+inside ftdi_sio, not fully generalized like it is in the version which we are
+hoping to see merged into mainline in future months/years.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/minpatch-4.4.14/0001-USB-serial-ftdi_sio-add-support-for-FreeCalypso-JTAG.patch	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,78 @@
+From 5af8e2ad7d0295d90cb2bc566f3d935668fb0535 Mon Sep 17 00:00:00 2001
+From: "Mychaela N. Falconia" <falcon@freecalypso.org>
+Date: Wed, 16 Sep 2020 01:56:29 +0000
+Subject: [PATCH 1/3] USB: serial: ftdi_sio: add support for FreeCalypso
+ JTAG+UART adapters
+
+commit 6cf87e5edd9944e1d3b6efd966ea401effc304ee upstream.
+
+There exist many FT2232-based JTAG+UART adapter designs in which
+FT2232 Channel A is used for JTAG and Channel B is used for UART.
+The best way to handle them in Linux is to have the ftdi_sio driver
+create a ttyUSB device only for Channel B and not for Channel A:
+a ttyUSB device for Channel A would be bogus and will disappear as
+soon as the user runs OpenOCD or other applications that access
+Channel A for JTAG from userspace, causing undesirable noise for
+users.  The ftdi_sio driver already has a dedicated quirk for such
+JTAG+UART FT2232 adapters, and it requires assigning custom USB IDs
+to such adapters and adding these IDs to the driver with the
+ftdi_jtag_quirk applied.
+
+Boutique hardware manufacturer Falconia Partners LLC has created a
+couple of JTAG+UART adapter designs (one buffered, one unbuffered)
+as part of FreeCalypso project, and this hardware is specifically made
+to be used with Linux hosts, with the intent that Channel A will be
+accessed only from userspace via appropriate applications, and that
+Channel B will be supported by the ftdi_sio kernel driver, presenting
+a standard ttyUSB device to userspace.  Toward this end the hardware
+manufacturer will be programming FT2232 EEPROMs with custom USB IDs,
+specifically with the intent that these IDs will be recognized by
+the ftdi_sio driver with the ftdi_jtag_quirk applied.
+
+Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
+[johan: insert in PID order and drop unused define]
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/serial/ftdi_sio.c     | 5 +++++
+ drivers/usb/serial/ftdi_sio_ids.h | 7 +++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index b61f12160d37..984a93c38365 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1008,6 +1008,11 @@ static const struct usb_device_id id_table_combined[] = {
+ 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
+ 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
+ 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
++	/* FreeCalypso USB adapters */
++	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_BUF_PID),
++		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
++		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ 	{ }					/* Terminating entry */
+ };
+ 
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index c5d6c1e73e8e..6218f9c45016 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -38,6 +38,13 @@
+ 
+ #define FTDI_LUMEL_PD12_PID	0x6002
+ 
++/*
++ * Custom USB adapters made by Falconia Partners LLC
++ * for FreeCalypso project, ID codes allocated to Falconia by FTDI.
++ */
++#define FTDI_FALCONIA_JTAG_BUF_PID	0x7150
++#define FTDI_FALCONIA_JTAG_UNBUF_PID	0x7151
++
+ /* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */
+ #define CYBER_CORTEX_AV_PID	0x8698
+ 
+-- 
+2.9.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/minpatch-4.4.14/0002-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,85 @@
+From 13701049a8f24450d69b6eeac6cfab5951abc604 Mon Sep 17 00:00:00 2001
+From: "Mychaela N. Falconia" <falcon@freecalypso.org>
+Date: Fri, 2 Oct 2020 17:38:56 +0000
+Subject: [PATCH 2/3] USB: serial: ftdi_sio: pass port to quirk port_probe
+ functions
+
+The original code passed only the pointer to the ftdi_private struct
+to quirk port_probe functions.  However, some quirks may need to be
+applied conditionally only to some channels of a multichannel FT2232x
+or FT4232H device, and if a given quirk's port_probe function needs
+to figure out which channel of a multichannel device is currently
+being considered, it needs access to the port pointer passed to the
+ftdi_sio_port_probe() function, so it can traverse USB data structures
+from there.
+
+Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
+---
+ drivers/usb/serial/ftdi_sio.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 984a93c38365..60d1831ee8c3 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -83,15 +83,15 @@ struct ftdi_private {
+ struct ftdi_sio_quirk {
+ 	int (*probe)(struct usb_serial *);
+ 	/* Special settings for probed ports. */
+-	void (*port_probe)(struct ftdi_private *);
++	void (*port_probe)(struct usb_serial_port *);
+ };
+ 
+ static int   ftdi_jtag_probe(struct usb_serial *serial);
+ static int   ftdi_NDI_device_setup(struct usb_serial *serial);
+ static int   ftdi_stmclite_probe(struct usb_serial *serial);
+ static int   ftdi_8u2232c_probe(struct usb_serial *serial);
+-static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
+-static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
++static void  ftdi_USB_UIRT_setup(struct usb_serial_port *port);
++static void  ftdi_HE_TIRA1_setup(struct usb_serial_port *port);
+ 
+ static struct ftdi_sio_quirk ftdi_jtag_quirk = {
+ 	.probe	= ftdi_jtag_probe,
+@@ -1808,11 +1808,11 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ 
+ 	priv->flags = ASYNC_LOW_LATENCY;
+ 
+-	if (quirk && quirk->port_probe)
+-		quirk->port_probe(priv);
+-
+ 	usb_set_serial_port_data(port, priv);
+ 
++	if (quirk && quirk->port_probe)
++		quirk->port_probe(port);
++
+ 	ftdi_determine_type(port);
+ 	ftdi_set_max_packet_size(port);
+ 	if (read_latency_timer(port) < 0)
+@@ -1825,8 +1825,10 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ /* Setup for the USB-UIRT device, which requires hardwired
+  * baudrate (38400 gets mapped to 312500) */
+ /* Called from usbserial:serial_probe */
+-static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
++static void ftdi_USB_UIRT_setup(struct usb_serial_port *port)
+ {
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++
+ 	priv->flags |= ASYNC_SPD_CUST;
+ 	priv->custom_divisor = 77;
+ 	priv->force_baud = 38400;
+@@ -1835,8 +1837,10 @@ static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
+ /* Setup for the HE-TIRA1 device, which requires hardwired
+  * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */
+ 
+-static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
++static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port)
+ {
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++
+ 	priv->flags |= ASYNC_SPD_CUST;
+ 	priv->custom_divisor = 240;
+ 	priv->force_baud = 38400;
+-- 
+2.9.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/minpatch-4.4.14/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,163 @@
+From 32c23625ab6e7cdc7da7849e866ccee66cbe2ee9 Mon Sep 17 00:00:00 2001
+From: "Mychaela N. Falconia" <falcon@freecalypso.org>
+Date: Sat, 5 Dec 2020 20:53:18 +0000
+Subject: [PATCH 3/3] USB: serial: ftdi_sio: add support for FreeCalypso
+ DUART28C adapter
+
+FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
+with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
+on the chip) have been repurposed to drive PWON and RESET controls
+on Calypso targets.  The circuit is wired such that BDBUS[24] high
+(RTS/DTR inactive) is the normal state with Iota VRPC controls
+NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
+the corresponding open drain control signal drivers.
+
+A special ftdi_sio driver quirk is needed in order to suppress
+automatic assertion of DTR & RTS on device open: this device's
+special PWON and RESET control drivers MUST NOT be activated
+when the port is ordinarily opened for plain serial communication,
+instead they must only be activated when a special userspace
+application explicitly requests such activation with a TIOCMBIS ioctl.
+These special userspace applications are responsible for making the
+needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
+
+The special quirk is conditionalized on the DUART28C adapter's custom
+USB ID, and is further limited to FT2232D Channel B only: Channel A
+is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
+actually being RTS and DTR rather than something else.
+
+Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
+---
+ drivers/usb/serial/ftdi_sio.c     | 61 +++++++++++++++++++++++++++++++++++----
+ drivers/usb/serial/ftdi_sio_ids.h |  1 +
+ 2 files changed, 57 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 60d1831ee8c3..b9abe8571aa1 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -73,6 +73,8 @@ struct ftdi_private {
+ 				   this value */
+ 	int force_rtscts;	/* if non-zero, force RTS-CTS to always
+ 				   be enabled */
++	int no_auto_dtr_rts;	/* if non-zero, suppress automatic assertion
++				   of DTR & RTS on device open */
+ 
+ 	unsigned int latency;		/* latency setting in use */
+ 	unsigned short max_packet_size;
+@@ -92,6 +94,7 @@ static int   ftdi_stmclite_probe(struct usb_serial *serial);
+ static int   ftdi_8u2232c_probe(struct usb_serial *serial);
+ static void  ftdi_USB_UIRT_setup(struct usb_serial_port *port);
+ static void  ftdi_HE_TIRA1_setup(struct usb_serial_port *port);
++static void  ftdi_duart28c_setup(struct usb_serial_port *port);
+ 
+ static struct ftdi_sio_quirk ftdi_jtag_quirk = {
+ 	.probe	= ftdi_jtag_probe,
+@@ -117,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
+ 	.probe	= ftdi_8u2232c_probe,
+ };
+ 
++static struct ftdi_sio_quirk ftdi_duart28c_quirk = {
++	.port_probe = ftdi_duart28c_setup,
++};
++
+ /*
+  * The 8U232AM has the same API as the sio except for:
+  * - it can support MUCH higher baudrates; up to:
+@@ -1013,6 +1020,8 @@ static const struct usb_device_id id_table_combined[] = {
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ 	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_DUART28C_PID),
++		.driver_info = (kernel_ulong_t)&ftdi_duart28c_quirk },
+ 	{ }					/* Terminating entry */
+ };
+ 
+@@ -1935,6 +1944,39 @@ static int ftdi_stmclite_probe(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
++/*
++ * FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
++ * with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
++ * on the chip) have been repurposed to drive PWON and RESET controls
++ * on Calypso targets.  The circuit is wired such that BDBUS[24] high
++ * (RTS/DTR inactive) is the normal state with Iota VRPC controls
++ * NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
++ * the corresponding open drain control signal drivers.
++ *
++ * A special ftdi_sio driver quirk is needed in order to suppress
++ * automatic assertion of DTR & RTS on device open: this device's
++ * special PWON and RESET control drivers MUST NOT be activated
++ * when the port is ordinarily opened for plain serial communication,
++ * instead they must only be activated when a special userspace
++ * application explicitly requests such activation with a TIOCMBIS ioctl.
++ * These special userspace applications are responsible for making the
++ * needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
++ *
++ * The special quirk must be applied only to FT2232D Channel B:
++ * Channel A is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
++ * actually being RTS and DTR rather than something else.
++ */
++static void ftdi_duart28c_setup(struct usb_serial_port *port)
++{
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++	struct usb_serial *serial = port->serial;
++	struct usb_interface *intf = serial->interface;
++	int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
++
++	if (ifnum == 1)
++		priv->no_auto_dtr_rts = 1;
++}
++
+ static int ftdi_sio_port_remove(struct usb_serial_port *port)
+ {
+ 	struct ftdi_private *priv = usb_get_serial_port_data(port);
+@@ -1984,10 +2026,18 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
+ 			dev_err(&port->dev, "error from flowcontrol urb\n");
+ 		}
+ 	}
+-	/* drop RTS and DTR */
+-	if (on)
+-		set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+-	else
++	/*
++	 * Assert or negate RTS and DTR as requested.  When DUART28C
++	 * quirk is applied, we suppress automatic assertion, but
++	 * automatic negation on device close is retained - these
++	 * special control signals are meant to be pulsed, and leaving
++	 * either of them stuck on when the responsible userspace
++	 * program has terminated unexpectedly is undesirable.
++	 */
++	if (on) {
++		if (!priv->no_auto_dtr_rts)
++			set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
++	} else
+ 		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ }
+ 
+@@ -2325,7 +2375,8 @@ no_data_parity_stop_changes:
+ 			dev_err(ddev, "%s urb failed to set baudrate\n", __func__);
+ 		mutex_unlock(&priv->cfg_lock);
+ 		/* Ensure RTS and DTR are raised when baudrate changed from 0 */
+-		if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
++		if (old_termios && (old_termios->c_cflag & CBAUD) == B0
++		    && !priv->no_auto_dtr_rts)
+ 			set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ 	}
+ 
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index 6218f9c45016..5720768859fe 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -44,6 +44,7 @@
+  */
+ #define FTDI_FALCONIA_JTAG_BUF_PID	0x7150
+ #define FTDI_FALCONIA_JTAG_UNBUF_PID	0x7151
++#define FTDI_FALCONIA_DUART28C_PID	0x7152
+ 
+ /* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */
+ #define CYBER_CORTEX_AV_PID	0x8698
+-- 
+2.9.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/minpatch-4.4.240/0002-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,85 @@
+From 269f94070f6ae14abbc47a36ec2556e977ea9bec Mon Sep 17 00:00:00 2001
+From: "Mychaela N. Falconia" <falcon@freecalypso.org>
+Date: Fri, 2 Oct 2020 17:38:56 +0000
+Subject: [PATCH 2/3] USB: serial: ftdi_sio: pass port to quirk port_probe
+ functions
+
+The original code passed only the pointer to the ftdi_private struct
+to quirk port_probe functions.  However, some quirks may need to be
+applied conditionally only to some channels of a multichannel FT2232x
+or FT4232H device, and if a given quirk's port_probe function needs
+to figure out which channel of a multichannel device is currently
+being considered, it needs access to the port pointer passed to the
+ftdi_sio_port_probe() function, so it can traverse USB data structures
+from there.
+
+Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
+---
+ drivers/usb/serial/ftdi_sio.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 5b42b8d760cb..2d23fd7b93cb 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -83,15 +83,15 @@ struct ftdi_private {
+ struct ftdi_sio_quirk {
+ 	int (*probe)(struct usb_serial *);
+ 	/* Special settings for probed ports. */
+-	void (*port_probe)(struct ftdi_private *);
++	void (*port_probe)(struct usb_serial_port *);
+ };
+ 
+ static int   ftdi_jtag_probe(struct usb_serial *serial);
+ static int   ftdi_NDI_device_setup(struct usb_serial *serial);
+ static int   ftdi_stmclite_probe(struct usb_serial *serial);
+ static int   ftdi_8u2232c_probe(struct usb_serial *serial);
+-static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
+-static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
++static void  ftdi_USB_UIRT_setup(struct usb_serial_port *port);
++static void  ftdi_HE_TIRA1_setup(struct usb_serial_port *port);
+ 
+ static struct ftdi_sio_quirk ftdi_jtag_quirk = {
+ 	.probe	= ftdi_jtag_probe,
+@@ -1833,11 +1833,11 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ 
+ 	mutex_init(&priv->cfg_lock);
+ 
+-	if (quirk && quirk->port_probe)
+-		quirk->port_probe(priv);
+-
+ 	usb_set_serial_port_data(port, priv);
+ 
++	if (quirk && quirk->port_probe)
++		quirk->port_probe(port);
++
+ 	ftdi_determine_type(port);
+ 	ftdi_set_max_packet_size(port);
+ 	if (read_latency_timer(port) < 0)
+@@ -1850,8 +1850,10 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ /* Setup for the USB-UIRT device, which requires hardwired
+  * baudrate (38400 gets mapped to 312500) */
+ /* Called from usbserial:serial_probe */
+-static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
++static void ftdi_USB_UIRT_setup(struct usb_serial_port *port)
+ {
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++
+ 	priv->flags |= ASYNC_SPD_CUST;
+ 	priv->custom_divisor = 77;
+ 	priv->force_baud = 38400;
+@@ -1860,8 +1862,10 @@ static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
+ /* Setup for the HE-TIRA1 device, which requires hardwired
+  * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */
+ 
+-static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
++static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port)
+ {
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++
+ 	priv->flags |= ASYNC_SPD_CUST;
+ 	priv->custom_divisor = 240;
+ 	priv->force_baud = 38400;
+-- 
+2.9.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/minpatch-4.4.240/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,163 @@
+From 6bfda041e99ef9f1175c0583f2f3c87b491e19b4 Mon Sep 17 00:00:00 2001
+From: "Mychaela N. Falconia" <falcon@freecalypso.org>
+Date: Sat, 5 Dec 2020 20:53:18 +0000
+Subject: [PATCH 3/3] USB: serial: ftdi_sio: add support for FreeCalypso
+ DUART28C adapter
+
+FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
+with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
+on the chip) have been repurposed to drive PWON and RESET controls
+on Calypso targets.  The circuit is wired such that BDBUS[24] high
+(RTS/DTR inactive) is the normal state with Iota VRPC controls
+NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
+the corresponding open drain control signal drivers.
+
+A special ftdi_sio driver quirk is needed in order to suppress
+automatic assertion of DTR & RTS on device open: this device's
+special PWON and RESET control drivers MUST NOT be activated
+when the port is ordinarily opened for plain serial communication,
+instead they must only be activated when a special userspace
+application explicitly requests such activation with a TIOCMBIS ioctl.
+These special userspace applications are responsible for making the
+needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
+
+The special quirk is conditionalized on the DUART28C adapter's custom
+USB ID, and is further limited to FT2232D Channel B only: Channel A
+is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
+actually being RTS and DTR rather than something else.
+
+Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
+---
+ drivers/usb/serial/ftdi_sio.c     | 61 +++++++++++++++++++++++++++++++++++----
+ drivers/usb/serial/ftdi_sio_ids.h |  1 +
+ 2 files changed, 57 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 2d23fd7b93cb..41f73b519023 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -73,6 +73,8 @@ struct ftdi_private {
+ 				   this value */
+ 	int force_rtscts;	/* if non-zero, force RTS-CTS to always
+ 				   be enabled */
++	int no_auto_dtr_rts;	/* if non-zero, suppress automatic assertion
++				   of DTR & RTS on device open */
+ 
+ 	unsigned int latency;		/* latency setting in use */
+ 	unsigned short max_packet_size;
+@@ -92,6 +94,7 @@ static int   ftdi_stmclite_probe(struct usb_serial *serial);
+ static int   ftdi_8u2232c_probe(struct usb_serial *serial);
+ static void  ftdi_USB_UIRT_setup(struct usb_serial_port *port);
+ static void  ftdi_HE_TIRA1_setup(struct usb_serial_port *port);
++static void  ftdi_duart28c_setup(struct usb_serial_port *port);
+ 
+ static struct ftdi_sio_quirk ftdi_jtag_quirk = {
+ 	.probe	= ftdi_jtag_probe,
+@@ -117,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
+ 	.probe	= ftdi_8u2232c_probe,
+ };
+ 
++static struct ftdi_sio_quirk ftdi_duart28c_quirk = {
++	.port_probe = ftdi_duart28c_setup,
++};
++
+ /*
+  * The 8U232AM has the same API as the sio except for:
+  * - it can support MUCH higher baudrates; up to:
+@@ -1037,6 +1044,8 @@ static const struct usb_device_id id_table_combined[] = {
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ 	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_DUART28C_PID),
++		.driver_info = (kernel_ulong_t)&ftdi_duart28c_quirk },
+ 	{ }					/* Terminating entry */
+ };
+ 
+@@ -1961,6 +1970,39 @@ static int ftdi_stmclite_probe(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
++/*
++ * FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
++ * with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
++ * on the chip) have been repurposed to drive PWON and RESET controls
++ * on Calypso targets.  The circuit is wired such that BDBUS[24] high
++ * (RTS/DTR inactive) is the normal state with Iota VRPC controls
++ * NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
++ * the corresponding open drain control signal drivers.
++ *
++ * A special ftdi_sio driver quirk is needed in order to suppress
++ * automatic assertion of DTR & RTS on device open: this device's
++ * special PWON and RESET control drivers MUST NOT be activated
++ * when the port is ordinarily opened for plain serial communication,
++ * instead they must only be activated when a special userspace
++ * application explicitly requests such activation with a TIOCMBIS ioctl.
++ * These special userspace applications are responsible for making the
++ * needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
++ *
++ * The special quirk must be applied only to FT2232D Channel B:
++ * Channel A is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
++ * actually being RTS and DTR rather than something else.
++ */
++static void ftdi_duart28c_setup(struct usb_serial_port *port)
++{
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++	struct usb_serial *serial = port->serial;
++	struct usb_interface *intf = serial->interface;
++	int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
++
++	if (ifnum == 1)
++		priv->no_auto_dtr_rts = 1;
++}
++
+ static int ftdi_sio_port_remove(struct usb_serial_port *port)
+ {
+ 	struct ftdi_private *priv = usb_get_serial_port_data(port);
+@@ -2010,10 +2052,18 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
+ 			dev_err(&port->dev, "error from flowcontrol urb\n");
+ 		}
+ 	}
+-	/* drop RTS and DTR */
+-	if (on)
+-		set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+-	else
++	/*
++	 * Assert or negate RTS and DTR as requested.  When DUART28C
++	 * quirk is applied, we suppress automatic assertion, but
++	 * automatic negation on device close is retained - these
++	 * special control signals are meant to be pulsed, and leaving
++	 * either of them stuck on when the responsible userspace
++	 * program has terminated unexpectedly is undesirable.
++	 */
++	if (on) {
++		if (!priv->no_auto_dtr_rts)
++			set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
++	} else
+ 		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ }
+ 
+@@ -2355,7 +2405,8 @@ no_data_parity_stop_changes:
+ 			dev_err(ddev, "%s urb failed to set baudrate\n", __func__);
+ 		mutex_unlock(&priv->cfg_lock);
+ 		/* Ensure RTS and DTR are raised when baudrate changed from 0 */
+-		if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
++		if (old_termios && (old_termios->c_cflag & CBAUD) == B0
++		    && !priv->no_auto_dtr_rts)
+ 			set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ 	}
+ 
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index f3302516a1e4..f756b80cb361 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -44,6 +44,7 @@
+  */
+ #define FTDI_FALCONIA_JTAG_BUF_PID	0x7150
+ #define FTDI_FALCONIA_JTAG_UNBUF_PID	0x7151
++#define FTDI_FALCONIA_DUART28C_PID	0x7152
+ 
+ /* Sienna Serial Interface by Secyourit GmbH */
+ #define FTDI_SIENNA_PID		0x8348
+-- 
+2.9.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/minpatch-4.9.240/0002-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,85 @@
+From 214b1d2da22e380b05ecf6e546962ca867e3a60e Mon Sep 17 00:00:00 2001
+From: "Mychaela N. Falconia" <falcon@freecalypso.org>
+Date: Fri, 2 Oct 2020 17:38:56 +0000
+Subject: [PATCH 2/3] USB: serial: ftdi_sio: pass port to quirk port_probe
+ functions
+
+The original code passed only the pointer to the ftdi_private struct
+to quirk port_probe functions.  However, some quirks may need to be
+applied conditionally only to some channels of a multichannel FT2232x
+or FT4232H device, and if a given quirk's port_probe function needs
+to figure out which channel of a multichannel device is currently
+being considered, it needs access to the port pointer passed to the
+ftdi_sio_port_probe() function, so it can traverse USB data structures
+from there.
+
+Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
+---
+ drivers/usb/serial/ftdi_sio.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index c9f979063af1..878ab4e5625c 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -83,15 +83,15 @@ struct ftdi_private {
+ struct ftdi_sio_quirk {
+ 	int (*probe)(struct usb_serial *);
+ 	/* Special settings for probed ports. */
+-	void (*port_probe)(struct ftdi_private *);
++	void (*port_probe)(struct usb_serial_port *);
+ };
+ 
+ static int   ftdi_jtag_probe(struct usb_serial *serial);
+ static int   ftdi_NDI_device_setup(struct usb_serial *serial);
+ static int   ftdi_stmclite_probe(struct usb_serial *serial);
+ static int   ftdi_8u2232c_probe(struct usb_serial *serial);
+-static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
+-static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
++static void  ftdi_USB_UIRT_setup(struct usb_serial_port *port);
++static void  ftdi_HE_TIRA1_setup(struct usb_serial_port *port);
+ 
+ static const struct ftdi_sio_quirk ftdi_jtag_quirk = {
+ 	.probe	= ftdi_jtag_probe,
+@@ -1833,11 +1833,11 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ 
+ 	mutex_init(&priv->cfg_lock);
+ 
+-	if (quirk && quirk->port_probe)
+-		quirk->port_probe(priv);
+-
+ 	usb_set_serial_port_data(port, priv);
+ 
++	if (quirk && quirk->port_probe)
++		quirk->port_probe(port);
++
+ 	ftdi_determine_type(port);
+ 	ftdi_set_max_packet_size(port);
+ 	if (read_latency_timer(port) < 0)
+@@ -1850,8 +1850,10 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
+ /* Setup for the USB-UIRT device, which requires hardwired
+  * baudrate (38400 gets mapped to 312500) */
+ /* Called from usbserial:serial_probe */
+-static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
++static void ftdi_USB_UIRT_setup(struct usb_serial_port *port)
+ {
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++
+ 	priv->flags |= ASYNC_SPD_CUST;
+ 	priv->custom_divisor = 77;
+ 	priv->force_baud = 38400;
+@@ -1860,8 +1862,10 @@ static void ftdi_USB_UIRT_setup(struct ftdi_private *priv)
+ /* Setup for the HE-TIRA1 device, which requires hardwired
+  * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */
+ 
+-static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
++static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port)
+ {
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++
+ 	priv->flags |= ASYNC_SPD_CUST;
+ 	priv->custom_divisor = 240;
+ 	priv->force_baud = 38400;
+-- 
+2.9.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-patch/minpatch-4.9.240/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch	Sun Dec 06 02:55:40 2020 +0000
@@ -0,0 +1,163 @@
+From 8edb5017764d4ad9d90a631c420caca41827cd6e Mon Sep 17 00:00:00 2001
+From: "Mychaela N. Falconia" <falcon@freecalypso.org>
+Date: Fri, 2 Oct 2020 18:01:12 +0000
+Subject: [PATCH 3/3] USB: serial: ftdi_sio: add support for FreeCalypso
+ DUART28C adapter
+
+FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
+with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
+on the chip) have been repurposed to drive PWON and RESET controls
+on Calypso targets.  The circuit is wired such that BDBUS[24] high
+(RTS/DTR inactive) is the normal state with Iota VRPC controls
+NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
+the corresponding open drain control signal drivers.
+
+A special ftdi_sio driver quirk is needed in order to suppress
+automatic assertion of DTR & RTS on device open: this device's
+special PWON and RESET control drivers MUST NOT be activated
+when the port is ordinarily opened for plain serial communication,
+instead they must only be activated when a special userspace
+application explicitly requests such activation with a TIOCMBIS ioctl.
+These special userspace applications are responsible for making the
+needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
+
+The special quirk is conditionalized on the DUART28C adapter's custom
+USB ID, and is further limited to FT2232D Channel B only: Channel A
+is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
+actually being RTS and DTR rather than something else.
+
+Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
+---
+ drivers/usb/serial/ftdi_sio.c     | 61 +++++++++++++++++++++++++++++++++++----
+ drivers/usb/serial/ftdi_sio_ids.h |  1 +
+ 2 files changed, 57 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 878ab4e5625c..443aee847556 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -73,6 +73,8 @@ struct ftdi_private {
+ 				   this value */
+ 	int force_rtscts;	/* if non-zero, force RTS-CTS to always
+ 				   be enabled */
++	int no_auto_dtr_rts;	/* if non-zero, suppress automatic assertion
++				   of DTR & RTS on device open */
+ 
+ 	unsigned int latency;		/* latency setting in use */
+ 	unsigned short max_packet_size;
+@@ -92,6 +94,7 @@ static int   ftdi_stmclite_probe(struct usb_serial *serial);
+ static int   ftdi_8u2232c_probe(struct usb_serial *serial);
+ static void  ftdi_USB_UIRT_setup(struct usb_serial_port *port);
+ static void  ftdi_HE_TIRA1_setup(struct usb_serial_port *port);
++static void  ftdi_duart28c_setup(struct usb_serial_port *port);
+ 
+ static const struct ftdi_sio_quirk ftdi_jtag_quirk = {
+ 	.probe	= ftdi_jtag_probe,
+@@ -117,6 +120,10 @@ static const struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
+ 	.probe	= ftdi_8u2232c_probe,
+ };
+ 
++static const struct ftdi_sio_quirk ftdi_duart28c_quirk = {
++	.port_probe = ftdi_duart28c_setup,
++};
++
+ /*
+  * The 8U232AM has the same API as the sio except for:
+  * - it can support MUCH higher baudrates; up to:
+@@ -1037,6 +1044,8 @@ static const struct usb_device_id id_table_combined[] = {
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ 	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
+ 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++	{ USB_DEVICE(FTDI_VID, FTDI_FALCONIA_DUART28C_PID),
++		.driver_info = (kernel_ulong_t)&ftdi_duart28c_quirk },
+ 	{ }					/* Terminating entry */
+ };
+ 
+@@ -1961,6 +1970,39 @@ static int ftdi_stmclite_probe(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
++/*
++ * FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
++ * with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
++ * on the chip) have been repurposed to drive PWON and RESET controls
++ * on Calypso targets.  The circuit is wired such that BDBUS[24] high
++ * (RTS/DTR inactive) is the normal state with Iota VRPC controls
++ * NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
++ * the corresponding open drain control signal drivers.
++ *
++ * A special ftdi_sio driver quirk is needed in order to suppress
++ * automatic assertion of DTR & RTS on device open: this device's
++ * special PWON and RESET control drivers MUST NOT be activated
++ * when the port is ordinarily opened for plain serial communication,
++ * instead they must only be activated when a special userspace
++ * application explicitly requests such activation with a TIOCMBIS ioctl.
++ * These special userspace applications are responsible for making the
++ * needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
++ *
++ * The special quirk must be applied only to FT2232D Channel B:
++ * Channel A is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
++ * actually being RTS and DTR rather than something else.
++ */
++static void ftdi_duart28c_setup(struct usb_serial_port *port)
++{
++	struct ftdi_private *priv = usb_get_serial_port_data(port);
++	struct usb_serial *serial = port->serial;
++	struct usb_interface *intf = serial->interface;
++	int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
++
++	if (ifnum == 1)
++		priv->no_auto_dtr_rts = 1;
++}
++
+ static int ftdi_sio_port_remove(struct usb_serial_port *port)
+ {
+ 	struct ftdi_private *priv = usb_get_serial_port_data(port);
+@@ -2010,10 +2052,18 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
+ 			dev_err(&port->dev, "error from flowcontrol urb\n");
+ 		}
+ 	}
+-	/* drop RTS and DTR */
+-	if (on)
+-		set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+-	else
++	/*
++	 * Assert or negate RTS and DTR as requested.  When DUART28C
++	 * quirk is applied, we suppress automatic assertion, but
++	 * automatic negation on device close is retained - these
++	 * special control signals are meant to be pulsed, and leaving
++	 * either of them stuck on when the responsible userspace
++	 * program has terminated unexpectedly is undesirable.
++	 */
++	if (on) {
++		if (!priv->no_auto_dtr_rts)
++			set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
++	} else
+ 		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ }
+ 
+@@ -2355,7 +2405,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
+ 			dev_err(ddev, "%s urb failed to set baudrate\n", __func__);
+ 		mutex_unlock(&priv->cfg_lock);
+ 		/* Ensure RTS and DTR are raised when baudrate changed from 0 */
+-		if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
++		if (old_termios && (old_termios->c_cflag & CBAUD) == B0
++		    && !priv->no_auto_dtr_rts)
+ 			set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ 	}
+ 
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index f3302516a1e4..f756b80cb361 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -44,6 +44,7 @@
+  */
+ #define FTDI_FALCONIA_JTAG_BUF_PID	0x7150
+ #define FTDI_FALCONIA_JTAG_UNBUF_PID	0x7151
++#define FTDI_FALCONIA_DUART28C_PID	0x7152
+ 
+ /* Sienna Serial Interface by Secyourit GmbH */
+ #define FTDI_SIENNA_PID		0x8348
+-- 
+2.9.0
+