--- /dev/null
+From 284f52ac1c6cfa1b2e5c11b84653dd90e4e91de7 Mon Sep 17 00:00:00 2001
+From: Christian Eggers <ceggers@arri.de>
+Date: Tue, 28 Jul 2020 11:29:59 +0200
+Subject: eeprom: at25: set minimum read/write access stride to 1
+
+From: Christian Eggers <ceggers@arri.de>
+
+commit 284f52ac1c6cfa1b2e5c11b84653dd90e4e91de7 upstream.
+
+SPI eeproms are addressed by byte.
+
+Signed-off-by: Christian Eggers <ceggers@arri.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200728092959.24600-1-ceggers@arri.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/eeprom/at25.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/eeprom/at25.c
++++ b/drivers/misc/eeprom/at25.c
+@@ -358,7 +358,7 @@ static int at25_probe(struct spi_device
+ at25->nvmem_config.reg_read = at25_ee_read;
+ at25->nvmem_config.reg_write = at25_ee_write;
+ at25->nvmem_config.priv = at25;
+- at25->nvmem_config.stride = 4;
++ at25->nvmem_config.stride = 1;
+ at25->nvmem_config.word_size = 1;
+ at25->nvmem_config.size = chip.byte_len;
+
ath10k-check-idx-validity-in-__ath10k_htt_rx_ring_fi.patch
net-korina-cast-kseg0-address-to-pointer-in-kfree.patch
s390-qeth-don-t-let-hw-override-the-configured-port-.patch
+tty-serial-lpuart-fix-lpuart32_write-usage.patch
+tty-serial-fsl_lpuart-fix-lpuart32_poll_get_char.patch
+usb-cdc-acm-add-quirk-to-blacklist-etas-es58x-devices.patch
+usb-cdc-wdm-make-wdm_flush-interruptible-and-add-wdm_fsync.patch
+usb-cdns3-gadget-free-interrupt-after-gadget-has-deleted.patch
+eeprom-at25-set-minimum-read-write-access-stride-to-1.patch
--- /dev/null
+From 29788ab1d2bf26c130de8f44f9553ee78a27e8d5 Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Tue, 29 Sep 2020 17:55:09 +0800
+Subject: tty: serial: fsl_lpuart: fix lpuart32_poll_get_char
+
+From: Peng Fan <peng.fan@nxp.com>
+
+commit 29788ab1d2bf26c130de8f44f9553ee78a27e8d5 upstream.
+
+The watermark is set to 1, so we need to input two chars to trigger RDRF
+using the original logic. With the new logic, we could always get the
+char when there is data in FIFO.
+
+Suggested-by: Fugang Duan <fugang.duan@nxp.com>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20200929095509.21680-1-peng.fan@nxp.com
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/fsl_lpuart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -666,7 +666,7 @@ static void lpuart32_poll_put_char(struc
+
+ static int lpuart32_poll_get_char(struct uart_port *port)
+ {
+- if (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF))
++ if (!(lpuart32_read(port, UARTWATER) >> UARTWATER_RXCNT_OFF))
+ return NO_POLL_CHAR;
+
+ return lpuart32_read(port, UARTDATA);
--- /dev/null
+From 9ea40db477c024dcb87321b7f32bd6ea12130ac2 Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Tue, 29 Sep 2020 17:19:20 +0800
+Subject: tty: serial: lpuart: fix lpuart32_write usage
+
+From: Peng Fan <peng.fan@nxp.com>
+
+commit 9ea40db477c024dcb87321b7f32bd6ea12130ac2 upstream.
+
+The 2nd and 3rd parameter were wrongly used, and cause kernel abort when
+doing kgdb debug.
+
+Fixes: 1da17d7cf8e2 ("tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs")
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Link: https://lore.kernel.org/r/20200929091920.22612-1-peng.fan@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/fsl_lpuart.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -635,26 +635,24 @@ static int lpuart32_poll_init(struct uar
+ spin_lock_irqsave(&sport->port.lock, flags);
+
+ /* Disable Rx & Tx */
+- lpuart32_write(&sport->port, UARTCTRL, 0);
++ lpuart32_write(&sport->port, 0, UARTCTRL);
+
+ temp = lpuart32_read(&sport->port, UARTFIFO);
+
+ /* Enable Rx and Tx FIFO */
+- lpuart32_write(&sport->port, UARTFIFO,
+- temp | UARTFIFO_RXFE | UARTFIFO_TXFE);
++ lpuart32_write(&sport->port, temp | UARTFIFO_RXFE | UARTFIFO_TXFE, UARTFIFO);
+
+ /* flush Tx and Rx FIFO */
+- lpuart32_write(&sport->port, UARTFIFO,
+- UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH);
++ lpuart32_write(&sport->port, UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, UARTFIFO);
+
+ /* explicitly clear RDRF */
+ if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) {
+ lpuart32_read(&sport->port, UARTDATA);
+- lpuart32_write(&sport->port, UARTFIFO, UARTFIFO_RXUF);
++ lpuart32_write(&sport->port, UARTFIFO_RXUF, UARTFIFO);
+ }
+
+ /* Enable Rx and Tx */
+- lpuart32_write(&sport->port, UARTCTRL, UARTCTRL_RE | UARTCTRL_TE);
++ lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ return 0;
+@@ -663,7 +661,7 @@ static int lpuart32_poll_init(struct uar
+ static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c)
+ {
+ lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TDRE);
+- lpuart32_write(port, UARTDATA, c);
++ lpuart32_write(port, c, UARTDATA);
+ }
+
+ static int lpuart32_poll_get_char(struct uart_port *port)
--- /dev/null
+From a4f88430af896bf34ec25a7a5f0e053fb3d928e0 Mon Sep 17 00:00:00 2001
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Date: Sat, 3 Oct 2020 00:41:51 +0900
+Subject: usb: cdc-acm: add quirk to blacklist ETAS ES58X devices
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+commit a4f88430af896bf34ec25a7a5f0e053fb3d928e0 upstream.
+
+The ES58X devices has a CDC ACM interface (used for debug
+purpose). During probing, the device is thus recognized as USB Modem
+(CDC ACM), preventing the etas-es58x module to load:
+ usbcore: registered new interface driver etas_es58x
+ usb 1-1.1: new full-speed USB device number 14 using xhci_hcd
+ usb 1-1.1: New USB device found, idVendor=108c, idProduct=0159, bcdDevice= 1.00
+ usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
+ usb 1-1.1: Product: ES581.4
+ usb 1-1.1: Manufacturer: ETAS GmbH
+ usb 1-1.1: SerialNumber: 2204355
+ cdc_acm 1-1.1:1.0: No union descriptor, testing for castrated device
+ cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device
+
+Thus, these have been added to the ignore list in
+drivers/usb/class/cdc-acm.c
+
+N.B. Future firmware release of the ES58X will remove the CDC-ACM
+interface.
+
+`lsusb -v` of the three devices variant (ES581.4, ES582.1 and
+ES584.1):
+
+ Bus 001 Device 011: ID 108c:0159 Robert Bosch GmbH ES581.4
+ Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 1.10
+ bDeviceClass 2 Communications
+ bDeviceSubClass 0
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ idVendor 0x108c Robert Bosch GmbH
+ idProduct 0x0159
+ bcdDevice 1.00
+ iManufacturer 1 ETAS GmbH
+ iProduct 2 ES581.4
+ iSerial 3 2204355
+ bNumConfigurations 1
+ Configuration Descriptor:
+ bLength 9
+ bDescriptorType 2
+ wTotalLength 0x0035
+ bNumInterfaces 1
+ bConfigurationValue 1
+ iConfiguration 5 Bus Powered Configuration
+ bmAttributes 0x80
+ (Bus Powered)
+ MaxPower 100mA
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 0
+ bAlternateSetting 0
+ bNumEndpoints 3
+ bInterfaceClass 2 Communications
+ bInterfaceSubClass 2 Abstract (modem)
+ bInterfaceProtocol 0
+ iInterface 4 ACM Control Interface
+ CDC Header:
+ bcdCDC 1.10
+ CDC Call Management:
+ bmCapabilities 0x01
+ call management
+ bDataInterface 0
+ CDC ACM:
+ bmCapabilities 0x06
+ sends break
+ line coding and serial state
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x81 EP 1 IN
+ bmAttributes 3
+ Transfer Type Interrupt
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0010 1x 16 bytes
+ bInterval 10
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x82 EP 2 IN
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x03 EP 3 OUT
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 0
+ Device Status: 0x0000
+ (Bus Powered)
+
+ Bus 001 Device 012: ID 108c:0168 Robert Bosch GmbH ES582
+ Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 2.00
+ bDeviceClass 2 Communications
+ bDeviceSubClass 0
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ idVendor 0x108c Robert Bosch GmbH
+ idProduct 0x0168
+ bcdDevice 1.00
+ iManufacturer 1 ETAS GmbH
+ iProduct 2 ES582
+ iSerial 3 0108933
+ bNumConfigurations 1
+ Configuration Descriptor:
+ bLength 9
+ bDescriptorType 2
+ wTotalLength 0x0043
+ bNumInterfaces 2
+ bConfigurationValue 1
+ iConfiguration 0
+ bmAttributes 0x80
+ (Bus Powered)
+ MaxPower 500mA
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 0
+ bAlternateSetting 0
+ bNumEndpoints 1
+ bInterfaceClass 2 Communications
+ bInterfaceSubClass 2 Abstract (modem)
+ bInterfaceProtocol 1 AT-commands (v.25ter)
+ iInterface 0
+ CDC Header:
+ bcdCDC 1.10
+ CDC ACM:
+ bmCapabilities 0x02
+ line coding and serial state
+ CDC Union:
+ bMasterInterface 0
+ bSlaveInterface 1
+ CDC Call Management:
+ bmCapabilities 0x03
+ call management
+ use DataInterface
+ bDataInterface 1
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x83 EP 3 IN
+ bmAttributes 3
+ Transfer Type Interrupt
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 16
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 1
+ bAlternateSetting 0
+ bNumEndpoints 2
+ bInterfaceClass 10 CDC Data
+ bInterfaceSubClass 0
+ bInterfaceProtocol 0
+ iInterface 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x81 EP 1 IN
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0200 1x 512 bytes
+ bInterval 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x02 EP 2 OUT
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0200 1x 512 bytes
+ bInterval 0
+ Device Qualifier (for other device speed):
+ bLength 10
+ bDescriptorType 6
+ bcdUSB 2.00
+ bDeviceClass 2 Communications
+ bDeviceSubClass 0
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ bNumConfigurations 1
+ Device Status: 0x0000
+ (Bus Powered)
+
+ Bus 001 Device 013: ID 108c:0169 Robert Bosch GmbH ES584.1
+ Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 2.00
+ bDeviceClass 2 Communications
+ bDeviceSubClass 0
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ idVendor 0x108c Robert Bosch GmbH
+ idProduct 0x0169
+ bcdDevice 1.00
+ iManufacturer 1 ETAS GmbH
+ iProduct 2 ES584.1
+ iSerial 3 0100320
+ bNumConfigurations 1
+ Configuration Descriptor:
+ bLength 9
+ bDescriptorType 2
+ wTotalLength 0x0043
+ bNumInterfaces 2
+ bConfigurationValue 1
+ iConfiguration 0
+ bmAttributes 0x80
+ (Bus Powered)
+ MaxPower 500mA
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 0
+ bAlternateSetting 0
+ bNumEndpoints 1
+ bInterfaceClass 2 Communications
+ bInterfaceSubClass 2 Abstract (modem)
+ bInterfaceProtocol 1 AT-commands (v.25ter)
+ iInterface 0
+ CDC Header:
+ bcdCDC 1.10
+ CDC ACM:
+ bmCapabilities 0x02
+ line coding and serial state
+ CDC Union:
+ bMasterInterface 0
+ bSlaveInterface 1
+ CDC Call Management:
+ bmCapabilities 0x03
+ call management
+ use DataInterface
+ bDataInterface 1
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x83 EP 3 IN
+ bmAttributes 3
+ Transfer Type Interrupt
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0040 1x 64 bytes
+ bInterval 16
+ Interface Descriptor:
+ bLength 9
+ bDescriptorType 4
+ bInterfaceNumber 1
+ bAlternateSetting 0
+ bNumEndpoints 2
+ bInterfaceClass 10 CDC Data
+ bInterfaceSubClass 0
+ bInterfaceProtocol 0
+ iInterface 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x81 EP 1 IN
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0200 1x 512 bytes
+ bInterval 0
+ Endpoint Descriptor:
+ bLength 7
+ bDescriptorType 5
+ bEndpointAddress 0x02 EP 2 OUT
+ bmAttributes 2
+ Transfer Type Bulk
+ Synch Type None
+ Usage Type Data
+ wMaxPacketSize 0x0200 1x 512 bytes
+ bInterval 0
+ Device Qualifier (for other device speed):
+ bLength 10
+ bDescriptorType 6
+ bcdUSB 2.00
+ bDeviceClass 2 Communications
+ bDeviceSubClass 0
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ bNumConfigurations 1
+ Device Status: 0x0000
+ (Bus Powered)
+
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20201002154219.4887-8-mailhol.vincent@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/class/cdc-acm.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1912,6 +1912,17 @@ static const struct usb_device_id acm_id
+ .driver_info = IGNORE_DEVICE,
+ },
+
++ /* Exclude ETAS ES58x */
++ { USB_DEVICE(0x108c, 0x0159), /* ES581.4 */
++ .driver_info = IGNORE_DEVICE,
++ },
++ { USB_DEVICE(0x108c, 0x0168), /* ES582.1 */
++ .driver_info = IGNORE_DEVICE,
++ },
++ { USB_DEVICE(0x108c, 0x0169), /* ES584.1 */
++ .driver_info = IGNORE_DEVICE,
++ },
++
+ { USB_DEVICE(0x1bc7, 0x0021), /* Telit 3G ACM only composition */
+ .driver_info = SEND_ZERO_PACKET,
+ },
--- /dev/null
+From 37d2a36394d954413a495da61da1b2a51ecd28ab Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Mon, 28 Sep 2020 23:17:55 +0900
+Subject: USB: cdc-wdm: Make wdm_flush() interruptible and add wdm_fsync().
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 37d2a36394d954413a495da61da1b2a51ecd28ab upstream.
+
+syzbot is reporting hung task at wdm_flush() [1], for there is a circular
+dependency that wdm_flush() from flip_close() for /dev/cdc-wdm0 forever
+waits for /dev/raw-gadget to be closed while close() for /dev/raw-gadget
+cannot be called unless close() for /dev/cdc-wdm0 completes.
+
+Tetsuo Handa considered that such circular dependency is an usage error [2]
+which corresponds to an unresponding broken hardware [3]. But Alan Stern
+responded that we should be prepared for such hardware [4]. Therefore,
+this patch changes wdm_flush() to use wait_event_interruptible_timeout()
+which gives up after 30 seconds, for hardware that remains silent must be
+ignored. The 30 seconds are coming out of thin air.
+
+Changing wait_event() to wait_event_interruptible_timeout() makes error
+reporting from close() syscall less reliable. To compensate it, this patch
+also implements wdm_fsync() which does not use timeout. Those who want to
+be very sure that data has gone out to the device are now advised to call
+fsync(), with a caveat that fsync() can return -EINVAL when running on
+older kernels which do not implement wdm_fsync().
+
+This patch also fixes three more problems (listed below) found during
+exhaustive discussion and testing.
+
+ Since multiple threads can concurrently call wdm_write()/wdm_flush(),
+ we need to use wake_up_all() whenever clearing WDM_IN_USE in order to
+ make sure that all waiters are woken up. Also, error reporting needs
+ to use fetch-and-clear approach in order not to report same error for
+ multiple times.
+
+ Since wdm_flush() checks WDM_DISCONNECTING, wdm_write() should as well
+ check WDM_DISCONNECTING.
+
+ In wdm_flush(), since locks are not held, it is not safe to dereference
+ desc->intf after checking that WDM_DISCONNECTING is not set [5]. Thus,
+ remove dev_err() from wdm_flush().
+
+[1] https://syzkaller.appspot.com/bug?id=e7b761593b23eb50855b9ea31e3be5472b711186
+[2] https://lkml.kernel.org/r/27b7545e-8f41-10b8-7c02-e35a08eb1611@i-love.sakura.ne.jp
+[3] https://lkml.kernel.org/r/79ba410f-e0ef-2465-b94f-6b9a4a82adf5@i-love.sakura.ne.jp
+[4] https://lkml.kernel.org/r/20200530011040.GB12419@rowland.harvard.edu
+[5] https://lkml.kernel.org/r/c85331fc-874c-6e46-a77f-0ef1dc075308@i-love.sakura.ne.jp
+
+Reported-by: syzbot <syzbot+854768b99f19e89d7f81@syzkaller.appspotmail.com>
+Cc: stable <stable@vger.kernel.org>
+Co-developed-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200928141755.3476-1-penguin-kernel@I-love.SAKURA.ne.jp
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-wdm.c | 70 +++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 54 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -58,6 +58,9 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
+
+ #define WDM_MAX 16
+
++/* we cannot wait forever at flush() */
++#define WDM_FLUSH_TIMEOUT (30 * HZ)
++
+ /* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */
+ #define WDM_DEFAULT_BUFSIZE 256
+
+@@ -151,7 +154,7 @@ static void wdm_out_callback(struct urb
+ kfree(desc->outbuf);
+ desc->outbuf = NULL;
+ clear_bit(WDM_IN_USE, &desc->flags);
+- wake_up(&desc->wait);
++ wake_up_all(&desc->wait);
+ }
+
+ static void wdm_in_callback(struct urb *urb)
+@@ -393,6 +396,9 @@ static ssize_t wdm_write
+ if (test_bit(WDM_RESETTING, &desc->flags))
+ r = -EIO;
+
++ if (test_bit(WDM_DISCONNECTING, &desc->flags))
++ r = -ENODEV;
++
+ if (r < 0) {
+ rv = r;
+ goto out_free_mem_pm;
+@@ -424,6 +430,7 @@ static ssize_t wdm_write
+ if (rv < 0) {
+ desc->outbuf = NULL;
+ clear_bit(WDM_IN_USE, &desc->flags);
++ wake_up_all(&desc->wait); /* for wdm_wait_for_response() */
+ dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
+ rv = usb_translate_errors(rv);
+ goto out_free_mem_pm;
+@@ -583,28 +590,58 @@ err:
+ return rv;
+ }
+
+-static int wdm_flush(struct file *file, fl_owner_t id)
++static int wdm_wait_for_response(struct file *file, long timeout)
+ {
+ struct wdm_device *desc = file->private_data;
++ long rv; /* Use long here because (int) MAX_SCHEDULE_TIMEOUT < 0. */
+
+- wait_event(desc->wait,
+- /*
+- * needs both flags. We cannot do with one
+- * because resetting it would cause a race
+- * with write() yet we need to signal
+- * a disconnect
+- */
+- !test_bit(WDM_IN_USE, &desc->flags) ||
+- test_bit(WDM_DISCONNECTING, &desc->flags));
++ /*
++ * Needs both flags. We cannot do with one because resetting it would
++ * cause a race with write() yet we need to signal a disconnect.
++ */
++ rv = wait_event_interruptible_timeout(desc->wait,
++ !test_bit(WDM_IN_USE, &desc->flags) ||
++ test_bit(WDM_DISCONNECTING, &desc->flags),
++ timeout);
+
+- /* cannot dereference desc->intf if WDM_DISCONNECTING */
++ /*
++ * To report the correct error. This is best effort.
++ * We are inevitably racing with the hardware.
++ */
+ if (test_bit(WDM_DISCONNECTING, &desc->flags))
+ return -ENODEV;
+- if (desc->werr < 0)
+- dev_err(&desc->intf->dev, "Error in flush path: %d\n",
+- desc->werr);
++ if (!rv)
++ return -EIO;
++ if (rv < 0)
++ return -EINTR;
++
++ spin_lock_irq(&desc->iuspin);
++ rv = desc->werr;
++ desc->werr = 0;
++ spin_unlock_irq(&desc->iuspin);
+
+- return usb_translate_errors(desc->werr);
++ return usb_translate_errors(rv);
++
++}
++
++/*
++ * You need to send a signal when you react to malicious or defective hardware.
++ * Also, don't abort when fsync() returned -EINVAL, for older kernels which do
++ * not implement wdm_flush() will return -EINVAL.
++ */
++static int wdm_fsync(struct file *file, loff_t start, loff_t end, int datasync)
++{
++ return wdm_wait_for_response(file, MAX_SCHEDULE_TIMEOUT);
++}
++
++/*
++ * Same with wdm_fsync(), except it uses finite timeout in order to react to
++ * malicious or defective hardware which ceased communication after close() was
++ * implicitly called due to process termination.
++ */
++static int wdm_flush(struct file *file, fl_owner_t id)
++{
++ return wdm_wait_for_response(file, WDM_FLUSH_TIMEOUT);
+ }
+
+ static __poll_t wdm_poll(struct file *file, struct poll_table_struct *wait)
+@@ -729,6 +766,7 @@ static const struct file_operations wdm_
+ .owner = THIS_MODULE,
+ .read = wdm_read,
+ .write = wdm_write,
++ .fsync = wdm_fsync,
+ .open = wdm_open,
+ .flush = wdm_flush,
+ .release = wdm_release,
--- /dev/null
+From 98df91f8840cf750a0bc7c4c5d6b6085bac945b3 Mon Sep 17 00:00:00 2001
+From: Peter Chen <peter.chen@nxp.com>
+Date: Tue, 1 Sep 2020 10:35:49 +0800
+Subject: usb: cdns3: gadget: free interrupt after gadget has deleted
+
+From: Peter Chen <peter.chen@nxp.com>
+
+commit 98df91f8840cf750a0bc7c4c5d6b6085bac945b3 upstream.
+
+The interrupt may occur during the gadget deletion, it fixes the
+below oops.
+
+[ 2394.974604] configfs-gadget gadget: suspend
+[ 2395.042578] configfs-gadget 5b130000.usb: unregistering UDC driver [g1]
+[ 2395.382562] irq 229: nobody cared (try booting with the "irqpoll" option)
+[ 2395.389362] CPU: 0 PID: 301 Comm: kworker/u12:6 Not tainted 5.8.0-rc3-next-20200703-00060-g2f13b83cbf30-dirty #456
+[ 2395.399712] Hardware name: Freescale i.MX8QM MEK (DT)
+[ 2395.404782] Workqueue: 2-0051 tcpm_state_machine_work
+[ 2395.409832] Call trace:
+[ 2395.412289] dump_backtrace+0x0/0x1d0
+[ 2395.415950] show_stack+0x1c/0x28
+[ 2395.419271] dump_stack+0xbc/0x118
+[ 2395.422678] __report_bad_irq+0x50/0xe0
+[ 2395.426513] note_interrupt+0x2cc/0x38c
+[ 2395.430355] handle_irq_event_percpu+0x88/0x90
+[ 2395.434800] handle_irq_event+0x4c/0xe8
+[ 2395.438640] handle_fasteoi_irq+0xbc/0x168
+[ 2395.442740] generic_handle_irq+0x34/0x48
+[ 2395.446752] __handle_domain_irq+0x68/0xc0
+[ 2395.450846] gic_handle_irq+0x64/0x150
+[ 2395.454596] el1_irq+0xb8/0x180
+[ 2395.457733] __do_softirq+0xac/0x3b8
+[ 2395.461310] irq_exit+0xc0/0xe0
+[ 2395.464448] __handle_domain_irq+0x6c/0xc0
+[ 2395.468540] gic_handle_irq+0x64/0x150
+[ 2395.472295] el1_irq+0xb8/0x180
+[ 2395.475436] _raw_spin_unlock_irqrestore+0x14/0x48
+[ 2395.480232] usb_gadget_disconnect+0x120/0x140
+[ 2395.484678] usb_gadget_remove_driver+0xb4/0xd0
+[ 2395.489208] usb_del_gadget+0x6c/0xc8
+[ 2395.492872] cdns3_gadget_exit+0x5c/0x120
+[ 2395.496882] cdns3_role_stop+0x60/0x90
+[ 2395.500634] cdns3_role_set+0x64/0xd8
+[ 2395.504301] usb_role_switch_set_role.part.0+0x3c/0x90
+[ 2395.509444] usb_role_switch_set_role+0x20/0x30
+[ 2395.513978] tcpm_mux_set+0x60/0xf8
+[ 2395.517470] tcpm_reset_port+0xa4/0xf0
+[ 2395.521222] tcpm_detach.part.0+0x44/0x50
+[ 2395.525227] tcpm_state_machine_work+0x8b0/0x2360
+[ 2395.529932] process_one_work+0x1c8/0x470
+[ 2395.533939] worker_thread+0x50/0x420
+[ 2395.537603] kthread+0x148/0x168
+[ 2395.540830] ret_from_fork+0x10/0x18
+[ 2395.544399] handlers:
+[ 2395.546671] [<000000008dea28da>] cdns3_wakeup_irq
+[ 2395.551375] [<000000009fee5c61>] cdns3_drd_irq threaded [<000000005148eaec>] cdns3_drd_thread_irq
+[ 2395.560255] Disabling IRQ #229
+[ 2395.563454] configfs-gadget gadget: unbind function 'Mass Storage Function'/000000000132f835
+[ 2395.563657] configfs-gadget gadget: unbind
+[ 2395.563917] udc 5b130000.usb: releasing '5b130000.usb'
+
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Cc: <stable@vger.kernel.org>
+Acked-by: Roger Quadros <rogerq@ti.com>
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/cdns3/gadget.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -2545,12 +2545,12 @@ void cdns3_gadget_exit(struct cdns3 *cdn
+
+ priv_dev = cdns->gadget_dev;
+
+- devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);
+
+ pm_runtime_mark_last_busy(cdns->dev);
+ pm_runtime_put_autosuspend(cdns->dev);
+
+ usb_del_gadget_udc(&priv_dev->gadget);
++ devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);
+
+ cdns3_free_all_eps(priv_dev);
+