diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/ata/ahci.c linux-libre-5.6.2-gnu/drivers/ata/ahci.c
--- linux-libre-5.6-gnu/drivers/ata/ahci.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/ata/ahci.c	2020-04-02 02:02:32.000000000 -0400
@@ -401,6 +401,7 @@ static const struct pci_device_id ahci_p
 	{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
 	{ PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */
+	{ PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */
 	{ PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */
 	{ PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */
 	{ PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/b2c2/flexcop-usb.c linux-libre-5.6.2-gnu/drivers/media/usb/b2c2/flexcop-usb.c
--- linux-libre-5.6-gnu/drivers/media/usb/b2c2/flexcop-usb.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/b2c2/flexcop-usb.c	2020-04-02 02:02:32.000000000 -0400
@@ -511,6 +511,9 @@ static int flexcop_usb_init(struct flexc
 		return ret;
 	}
 
+	if (fc_usb->uintf->cur_altsetting->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	switch (fc_usb->udev->speed) {
 	case USB_SPEED_LOW:
 		err("cannot handle USB speed because it is too slow.");
@@ -544,9 +547,6 @@ static int flexcop_usb_probe(struct usb_
 	struct flexcop_device *fc = NULL;
 	int ret;
 
-	if (intf->cur_altsetting->desc.bNumEndpoints < 1)
-		return -ENODEV;
-
 	if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
 		err("out of memory\n");
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/dvb-usb/dib0700_core.c linux-libre-5.6.2-gnu/drivers/media/usb/dvb-usb/dib0700_core.c
--- linux-libre-5.6-gnu/drivers/media/usb/dvb-usb/dib0700_core.c	2020-03-29 20:42:33.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/dvb-usb/dib0700_core.c	2020-04-02 02:40:27.000000000 -0400
@@ -818,7 +818,7 @@ int dib0700_rc_setup(struct dvb_usb_devi
 
 	/* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
 
-	if (intf->altsetting[0].desc.bNumEndpoints < rc_ep + 1)
+	if (intf->cur_altsetting->desc.bNumEndpoints < rc_ep + 1)
 		return -ENODEV;
 
 	purb = usb_alloc_urb(0, GFP_KERNEL);
@@ -838,7 +838,7 @@ int dib0700_rc_setup(struct dvb_usb_devi
 	 * Some devices like the Hauppauge NovaTD model 52009 use an interrupt
 	 * endpoint, while others use a bulk one.
 	 */
-	e = &intf->altsetting[0].endpoint[rc_ep].desc;
+	e = &intf->cur_altsetting->endpoint[rc_ep].desc;
 	if (usb_endpoint_dir_in(e)) {
 		if (usb_endpoint_xfer_bulk(e)) {
 			pipe = usb_rcvbulkpipe(d->udev, rc_ep);
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/gspca/ov519.c linux-libre-5.6.2-gnu/drivers/media/usb/gspca/ov519.c
--- linux-libre-5.6-gnu/drivers/media/usb/gspca/ov519.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/gspca/ov519.c	2020-04-02 02:02:32.000000000 -0400
@@ -3477,6 +3477,11 @@ static void ov511_mode_init_regs(struct
 		return;
 	}
 
+	if (alt->desc.bNumEndpoints < 1) {
+		sd->gspca_dev.usb_err = -ENODEV;
+		return;
+	}
+
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 	reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
 
@@ -3603,6 +3608,11 @@ static void ov518_mode_init_regs(struct
 		return;
 	}
 
+	if (alt->desc.bNumEndpoints < 1) {
+		sd->gspca_dev.usb_err = -ENODEV;
+		return;
+	}
+
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 	ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
 
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/gspca/stv06xx/stv06xx.c linux-libre-5.6.2-gnu/drivers/media/usb/gspca/stv06xx/stv06xx.c
--- linux-libre-5.6-gnu/drivers/media/usb/gspca/stv06xx/stv06xx.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/gspca/stv06xx/stv06xx.c	2020-04-02 02:02:32.000000000 -0400
@@ -282,6 +282,9 @@ static int stv06xx_start(struct gspca_de
 		return -EIO;
 	}
 
+	if (alt->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 	err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);
 	if (err < 0)
@@ -306,11 +309,21 @@ out:
 
 static int stv06xx_isoc_init(struct gspca_dev *gspca_dev)
 {
+	struct usb_interface_cache *intfc;
 	struct usb_host_interface *alt;
 	struct sd *sd = (struct sd *) gspca_dev;
 
+	intfc = gspca_dev->dev->actconfig->intf_cache[0];
+
+	if (intfc->num_altsetting < 2)
+		return -ENODEV;
+
+	alt = &intfc->altsetting[1];
+
+	if (alt->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
-	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
 	alt->endpoint[0].desc.wMaxPacketSize =
 		cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);
 
@@ -323,6 +336,10 @@ static int stv06xx_isoc_nego(struct gspc
 	struct usb_host_interface *alt;
 	struct sd *sd = (struct sd *) gspca_dev;
 
+	/*
+	 * Existence of altsetting and endpoint was verified in
+	 * stv06xx_isoc_init()
+	 */
 	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 	min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c linux-libre-5.6.2-gnu/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
--- linux-libre-5.6-gnu/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c	2020-04-02 02:02:32.000000000 -0400
@@ -185,6 +185,10 @@ static int pb0100_start(struct sd *sd)
 	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
 	if (!alt)
 		return -ENODEV;
+
+	if (alt->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 
 	/* If we don't have enough bandwidth use a lower framerate */
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/gspca/xirlink_cit.c linux-libre-5.6.2-gnu/drivers/media/usb/gspca/xirlink_cit.c
--- linux-libre-5.6-gnu/drivers/media/usb/gspca/xirlink_cit.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/gspca/xirlink_cit.c	2020-04-02 02:02:32.000000000 -0400
@@ -1442,6 +1442,9 @@ static int cit_get_packet_size(struct gs
 		return -EIO;
 	}
 
+	if (alt->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 }
 
@@ -2626,6 +2629,7 @@ static int sd_start(struct gspca_dev *gs
 
 static int sd_isoc_init(struct gspca_dev *gspca_dev)
 {
+	struct usb_interface_cache *intfc;
 	struct usb_host_interface *alt;
 	int max_packet_size;
 
@@ -2641,8 +2645,17 @@ static int sd_isoc_init(struct gspca_dev
 		break;
 	}
 
+	intfc = gspca_dev->dev->actconfig->intf_cache[0];
+
+	if (intfc->num_altsetting < 2)
+		return -ENODEV;
+
+	alt = &intfc->altsetting[1];
+
+	if (alt->desc.bNumEndpoints < 1)
+		return -ENODEV;
+
 	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
-	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
 	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size);
 
 	return 0;
@@ -2665,6 +2678,9 @@ static int sd_isoc_nego(struct gspca_dev
 		break;
 	}
 
+	/*
+	 * Existence of altsetting and endpoint was verified in sd_isoc_init()
+	 */
 	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 	if (packet_size <= min_packet_size)
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/usbtv/usbtv-core.c linux-libre-5.6.2-gnu/drivers/media/usb/usbtv/usbtv-core.c
--- linux-libre-5.6-gnu/drivers/media/usb/usbtv/usbtv-core.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/usbtv/usbtv-core.c	2020-04-02 02:02:32.000000000 -0400
@@ -56,7 +56,7 @@ int usbtv_set_regs(struct usbtv *usbtv,
 
 		ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			value, index, NULL, 0, 0);
+			value, index, NULL, 0, USB_CTRL_GET_TIMEOUT);
 		if (ret < 0)
 			return ret;
 	}
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/usb/usbtv/usbtv-video.c linux-libre-5.6.2-gnu/drivers/media/usb/usbtv/usbtv-video.c
--- linux-libre-5.6-gnu/drivers/media/usb/usbtv/usbtv-video.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/usb/usbtv/usbtv-video.c	2020-04-02 02:02:32.000000000 -0400
@@ -800,7 +800,8 @@ static int usbtv_s_ctrl(struct v4l2_ctrl
 		ret = usb_control_msg(usbtv->udev,
 			usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			0, USBTV_BASE + 0x0244, (void *)data, 3, 0);
+			0, USBTV_BASE + 0x0244, (void *)data, 3,
+			USB_CTRL_GET_TIMEOUT);
 		if (ret < 0)
 			goto error;
 	}
@@ -851,7 +852,7 @@ static int usbtv_s_ctrl(struct v4l2_ctrl
 	ret = usb_control_msg(usbtv->udev, usb_sndctrlpipe(usbtv->udev, 0),
 			USBTV_CONTROL_REG,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			0, index, (void *)data, size, 0);
+			0, index, (void *)data, size, USB_CTRL_SET_TIMEOUT);
 
 error:
 	if (ret < 0)
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/media/v4l2-core/v4l2-device.c linux-libre-5.6.2-gnu/drivers/media/v4l2-core/v4l2-device.c
--- linux-libre-5.6-gnu/drivers/media/v4l2-core/v4l2-device.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/media/v4l2-core/v4l2-device.c	2020-04-02 02:02:32.000000000 -0400
@@ -179,6 +179,7 @@ static void v4l2_subdev_release(struct v
 
 	if (sd->internal_ops && sd->internal_ops->release)
 		sd->internal_ops->release(sd);
+	sd->devnode = NULL;
 	module_put(owner);
 }
 
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/platform/x86/pmc_atom.c linux-libre-5.6.2-gnu/drivers/platform/x86/pmc_atom.c
--- linux-libre-5.6-gnu/drivers/platform/x86/pmc_atom.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/platform/x86/pmc_atom.c	2020-04-02 02:02:32.000000000 -0400
@@ -385,6 +385,14 @@ static const struct dmi_system_id critcl
 	},
 	{
 		/* pmc_plt_clk* - are used for ethernet controllers */
+		.ident = "Lex 2I385SW",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "2I385SW"),
+		},
+	},
+	{
+		/* pmc_plt_clk* - are used for ethernet controllers */
 		.ident = "Beckhoff CB3163",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"),
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/kpc2000/kpc2000/core.c linux-libre-5.6.2-gnu/drivers/staging/kpc2000/kpc2000/core.c
--- linux-libre-5.6-gnu/drivers/staging/kpc2000/kpc2000/core.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/kpc2000/kpc2000/core.c	2020-04-02 02:02:32.000000000 -0400
@@ -110,10 +110,10 @@ static ssize_t cpld_reconfigure(struct d
 				const char *buf, size_t count)
 {
 	struct kp2000_device *pcard = dev_get_drvdata(dev);
-	long wr_val;
+	unsigned long wr_val;
 	int rv;
 
-	rv = kstrtol(buf, 0, &wr_val);
+	rv = kstrtoul(buf, 0, &wr_val);
 	if (rv < 0)
 		return rv;
 	if (wr_val > 7)
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c linux-libre-5.6.2-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c
--- linux-libre-5.6-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/rtl8188eu/os_dep/usb_intf.c	2020-04-02 02:02:32.000000000 -0400
@@ -32,6 +32,7 @@ static const struct usb_device_id rtw_us
 	/****** 8188EUS ********/
 	{USB_DEVICE(0x056e, 0x4008)}, /* Elecom WDC-150SU2M */
 	{USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */
+	{USB_DEVICE(0x0B05, 0x18F0)}, /* ASUS USB-N10 Nano B1 */
 	{USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
 	{USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
 	{USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wfx/bus_sdio.c linux-libre-5.6.2-gnu/drivers/staging/wfx/bus_sdio.c
--- linux-libre-5.6-gnu/drivers/staging/wfx/bus_sdio.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wfx/bus_sdio.c	2020-04-02 02:02:32.000000000 -0400
@@ -200,25 +200,23 @@ static int wfx_sdio_probe(struct sdio_fu
 	if (ret)
 		goto err0;
 
-	ret = wfx_sdio_irq_subscribe(bus);
-	if (ret)
-		goto err1;
-
 	bus->core = wfx_init_common(&func->dev, &wfx_sdio_pdata,
 				    &wfx_sdio_hwbus_ops, bus);
 	if (!bus->core) {
 		ret = -EIO;
-		goto err2;
+		goto err1;
 	}
 
+	ret = wfx_sdio_irq_subscribe(bus);
+	if (ret)
+		goto err1;
+
 	ret = wfx_probe(bus->core);
 	if (ret)
-		goto err3;
+		goto err2;
 
 	return 0;
 
-err3:
-	wfx_free_common(bus->core);
 err2:
 	wfx_sdio_irq_unsubscribe(bus);
 err1:
@@ -234,7 +232,6 @@ static void wfx_sdio_remove(struct sdio_
 	struct wfx_sdio_priv *bus = sdio_get_drvdata(func);
 
 	wfx_release(bus->core);
-	wfx_free_common(bus->core);
 	wfx_sdio_irq_unsubscribe(bus);
 	sdio_claim_host(func);
 	sdio_disable_func(func);
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wfx/bus_spi.c linux-libre-5.6.2-gnu/drivers/staging/wfx/bus_spi.c
--- linux-libre-5.6-gnu/drivers/staging/wfx/bus_spi.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wfx/bus_spi.c	2020-04-02 02:02:32.000000000 -0400
@@ -27,6 +27,8 @@ MODULE_PARM_DESC(gpio_reset, "gpio numbe
 #define SET_WRITE 0x7FFF        /* usage: and operation */
 #define SET_READ 0x8000         /* usage: or operation */
 
+#define WFX_RESET_INVERTED 1
+
 static const struct wfx_platform_data wfx_spi_pdata = {
 	.file_fw = "wfm_wf200",
 	.file_pds = "wf200.pds",
@@ -154,6 +156,11 @@ static void wfx_spi_request_rx(struct wo
 	wfx_bh_request_rx(bus->core);
 }
 
+static void wfx_flush_irq_work(void *w)
+{
+	flush_work(w);
+}
+
 static size_t wfx_spi_align_size(void *priv, size_t size)
 {
 	// Most of SPI controllers avoid DMA if buffer size is not 32bit aligned
@@ -201,28 +208,31 @@ static int wfx_spi_probe(struct spi_devi
 	if (!bus->gpio_reset) {
 		dev_warn(&func->dev, "try to load firmware anyway\n");
 	} else {
-		gpiod_set_value(bus->gpio_reset, 0);
-		udelay(100);
+		if (spi_get_device_id(func)->driver_data & WFX_RESET_INVERTED)
+			gpiod_toggle_active_low(bus->gpio_reset);
 		gpiod_set_value(bus->gpio_reset, 1);
+		udelay(100);
+		gpiod_set_value(bus->gpio_reset, 0);
 		udelay(2000);
 	}
 
-	ret = devm_request_irq(&func->dev, func->irq, wfx_spi_irq_handler,
-			       IRQF_TRIGGER_RISING, "wfx", bus);
-	if (ret)
-		return ret;
-
 	INIT_WORK(&bus->request_rx, wfx_spi_request_rx);
 	bus->core = wfx_init_common(&func->dev, &wfx_spi_pdata,
 				    &wfx_spi_hwbus_ops, bus);
 	if (!bus->core)
 		return -EIO;
 
-	ret = wfx_probe(bus->core);
+	ret = devm_add_action_or_reset(&func->dev, wfx_flush_irq_work,
+				       &bus->request_rx);
 	if (ret)
-		wfx_free_common(bus->core);
+		return ret;
 
-	return ret;
+	ret = devm_request_irq(&func->dev, func->irq, wfx_spi_irq_handler,
+			       IRQF_TRIGGER_RISING, "wfx", bus);
+	if (ret)
+		return ret;
+
+	return wfx_probe(bus->core);
 }
 
 static int wfx_spi_remove(struct spi_device *func)
@@ -230,11 +240,6 @@ static int wfx_spi_remove(struct spi_dev
 	struct wfx_spi_priv *bus = spi_get_drvdata(func);
 
 	wfx_release(bus->core);
-	wfx_free_common(bus->core);
-	// A few IRQ will be sent during device release. Hopefully, no IRQ
-	// should happen after wdev/wvif are released.
-	devm_free_irq(&func->dev, func->irq, bus);
-	flush_work(&bus->request_rx);
 	return 0;
 }
 
@@ -244,14 +249,16 @@ static int wfx_spi_remove(struct spi_dev
  * stripped.
  */
 static const struct spi_device_id wfx_spi_id[] = {
-	{ "wfx-spi", 0 },
+	{ "wfx-spi", WFX_RESET_INVERTED },
+	{ "wf200", 0 },
 	{ },
 };
 MODULE_DEVICE_TABLE(spi, wfx_spi_id);
 
 #ifdef CONFIG_OF
 static const struct of_device_id wfx_spi_of_match[] = {
-	{ .compatible = "silabs,wfx-spi" },
+	{ .compatible = "silabs,wfx-spi", .data = (void *)WFX_RESET_INVERTED },
+	{ .compatible = "silabs,wf200" },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, wfx_spi_of_match);
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt linux-libre-5.6.2-gnu/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt
--- linux-libre-5.6-gnu/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wfx/Documentation/devicetree/bindings/net/wireless/siliabs,wfx.txt	2020-04-02 02:02:32.000000000 -0400
@@ -6,7 +6,7 @@ SPI
 You have to declare the WFxxx chip in your device tree.
 
 Required properties:
- - compatible: Should be "silabs,wfx-spi"
+ - compatible: Should be "silabs,wf200"
  - reg: Chip select address of device
  - spi-max-frequency: Maximum SPI clocking speed of device in Hz
  - interrupts-extended: Should contain interrupt line (interrupt-parent +
@@ -15,6 +15,7 @@ Required properties:
 Optional properties:
  - reset-gpios: phandle of gpio that will be used to reset chip during probe.
    Without this property, you may encounter issues with warm boot.
+   (Legacy: when compatible == "silabs,wfx-spi", the gpio is inverted.)
 
 Please consult Documentation/devicetree/bindings/spi/spi-bus.txt for optional
 SPI connection related properties,
@@ -23,12 +24,12 @@ Example:
 
 &spi1 {
 	wfx {
-		compatible = "silabs,wfx-spi";
+		compatible = "silabs,wf200";
 		pinctrl-names = "default";
 		pinctrl-0 = <&wfx_irq &wfx_gpios>;
 		interrupts-extended = <&gpio 16 IRQ_TYPE_EDGE_RISING>;
 		wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
-		reset-gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
 		reg = <0>;
 		spi-max-frequency = <42000000>;
 	};
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wfx/main.c linux-libre-5.6.2-gnu/drivers/staging/wfx/main.c
--- linux-libre-5.6-gnu/drivers/staging/wfx/main.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wfx/main.c	2020-04-02 02:02:32.000000000 -0400
@@ -262,6 +262,16 @@ static int wfx_send_pdata_pds(struct wfx
 	return ret;
 }
 
+static void wfx_free_common(void *data)
+{
+	struct wfx_dev *wdev = data;
+
+	mutex_destroy(&wdev->rx_stats_lock);
+	mutex_destroy(&wdev->conf_mutex);
+	wfx_tx_queues_deinit(wdev);
+	ieee80211_free_hw(wdev->hw);
+}
+
 struct wfx_dev *wfx_init_common(struct device *dev,
 				const struct wfx_platform_data *pdata,
 				const struct hwbus_ops *hwbus_ops,
@@ -332,15 +342,10 @@ struct wfx_dev *wfx_init_common(struct d
 	wfx_init_hif_cmd(&wdev->hif_cmd);
 	wfx_tx_queues_init(wdev);
 
-	return wdev;
-}
+	if (devm_add_action_or_reset(dev, wfx_free_common, wdev))
+		return NULL;
 
-void wfx_free_common(struct wfx_dev *wdev)
-{
-	mutex_destroy(&wdev->rx_stats_lock);
-	mutex_destroy(&wdev->conf_mutex);
-	wfx_tx_queues_deinit(wdev);
-	ieee80211_free_hw(wdev->hw);
+	return wdev;
 }
 
 int wfx_probe(struct wfx_dev *wdev)
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wfx/main.h linux-libre-5.6.2-gnu/drivers/staging/wfx/main.h
--- linux-libre-5.6-gnu/drivers/staging/wfx/main.h	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wfx/main.h	2020-04-02 02:02:32.000000000 -0400
@@ -34,7 +34,6 @@ struct wfx_dev *wfx_init_common(struct d
 				const struct wfx_platform_data *pdata,
 				const struct hwbus_ops *hwbus_ops,
 				void *hwbus_priv);
-void wfx_free_common(struct wfx_dev *wdev);
 
 int wfx_probe(struct wfx_dev *wdev);
 void wfx_release(struct wfx_dev *wdev);
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wfx/queue.c linux-libre-5.6.2-gnu/drivers/staging/wfx/queue.c
--- linux-libre-5.6-gnu/drivers/staging/wfx/queue.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wfx/queue.c	2020-04-02 02:02:32.000000000 -0400
@@ -130,12 +130,12 @@ static void wfx_tx_queue_clear(struct wf
 	spin_lock_bh(&queue->queue.lock);
 	while ((item = __skb_dequeue(&queue->queue)) != NULL)
 		skb_queue_head(gc_list, item);
-	spin_lock_bh(&stats->pending.lock);
+	spin_lock_nested(&stats->pending.lock, 1);
 	for (i = 0; i < ARRAY_SIZE(stats->link_map_cache); ++i) {
 		stats->link_map_cache[i] -= queue->link_map_cache[i];
 		queue->link_map_cache[i] = 0;
 	}
-	spin_unlock_bh(&stats->pending.lock);
+	spin_unlock(&stats->pending.lock);
 	spin_unlock_bh(&queue->queue.lock);
 }
 
@@ -207,9 +207,9 @@ void wfx_tx_queue_put(struct wfx_dev *wd
 
 	++queue->link_map_cache[tx_priv->link_id];
 
-	spin_lock_bh(&stats->pending.lock);
+	spin_lock_nested(&stats->pending.lock, 1);
 	++stats->link_map_cache[tx_priv->link_id];
-	spin_unlock_bh(&stats->pending.lock);
+	spin_unlock(&stats->pending.lock);
 	spin_unlock_bh(&queue->queue.lock);
 }
 
@@ -237,11 +237,11 @@ static struct sk_buff *wfx_tx_queue_get(
 		__skb_unlink(skb, &queue->queue);
 		--queue->link_map_cache[tx_priv->link_id];
 
-		spin_lock_bh(&stats->pending.lock);
+		spin_lock_nested(&stats->pending.lock, 1);
 		__skb_queue_tail(&stats->pending, skb);
 		if (!--stats->link_map_cache[tx_priv->link_id])
 			wakeup_stats = true;
-		spin_unlock_bh(&stats->pending.lock);
+		spin_unlock(&stats->pending.lock);
 	}
 	spin_unlock_bh(&queue->queue.lock);
 	if (wakeup_stats)
@@ -259,10 +259,10 @@ int wfx_pending_requeue(struct wfx_dev *
 	spin_lock_bh(&queue->queue.lock);
 	++queue->link_map_cache[tx_priv->link_id];
 
-	spin_lock_bh(&stats->pending.lock);
+	spin_lock_nested(&stats->pending.lock, 1);
 	++stats->link_map_cache[tx_priv->link_id];
 	__skb_unlink(skb, &stats->pending);
-	spin_unlock_bh(&stats->pending.lock);
+	spin_unlock(&stats->pending.lock);
 	__skb_queue_tail(&queue->queue, skb);
 	spin_unlock_bh(&queue->queue.lock);
 	return 0;
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wlan-ng/hfa384x_usb.c linux-libre-5.6.2-gnu/drivers/staging/wlan-ng/hfa384x_usb.c
--- linux-libre-5.6-gnu/drivers/staging/wlan-ng/hfa384x_usb.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wlan-ng/hfa384x_usb.c	2020-04-02 02:02:32.000000000 -0400
@@ -3372,6 +3372,8 @@ static void hfa384x_int_rxmonitor(struct
 	     WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
 		pr_debug("overlen frm: len=%zd\n",
 			 skblen - sizeof(struct p80211_caphdr));
+
+		return;
 	}
 
 	skb = dev_alloc_skb(skblen);
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/staging/wlan-ng/prism2usb.c linux-libre-5.6.2-gnu/drivers/staging/wlan-ng/prism2usb.c
--- linux-libre-5.6-gnu/drivers/staging/wlan-ng/prism2usb.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/staging/wlan-ng/prism2usb.c	2020-04-02 02:02:32.000000000 -0400
@@ -180,6 +180,7 @@ static void prism2sta_disconnect_usb(str
 
 		cancel_work_sync(&hw->link_bh);
 		cancel_work_sync(&hw->commsqual_bh);
+		cancel_work_sync(&hw->usb_work);
 
 		/* Now we complete any outstanding commands
 		 * and tell everyone who is waiting for their
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/tty/serial/sprd_serial.c linux-libre-5.6.2-gnu/drivers/tty/serial/sprd_serial.c
--- linux-libre-5.6-gnu/drivers/tty/serial/sprd_serial.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/tty/serial/sprd_serial.c	2020-04-02 02:02:32.000000000 -0400
@@ -1132,14 +1132,13 @@ static int sprd_remove(struct platform_d
 	if (sup) {
 		uart_remove_one_port(&sprd_uart_driver, &sup->port);
 		sprd_port[sup->port.line] = NULL;
+		sprd_rx_free_buf(sup);
 		sprd_ports_num--;
 	}
 
 	if (!sprd_ports_num)
 		uart_unregister_driver(&sprd_uart_driver);
 
-	sprd_rx_free_buf(sup);
-
 	return 0;
 }
 
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/tty/vt/selection.c linux-libre-5.6.2-gnu/drivers/tty/vt/selection.c
--- linux-libre-5.6-gnu/drivers/tty/vt/selection.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/tty/vt/selection.c	2020-04-02 02:02:32.000000000 -0400
@@ -88,6 +88,11 @@ void clear_selection(void)
 }
 EXPORT_SYMBOL_GPL(clear_selection);
 
+bool vc_is_sel(struct vc_data *vc)
+{
+	return vc == sel_cons;
+}
+
 /*
  * User settable table: what characters are to be considered alphabetic?
  * 128 bits. Locked by the console lock.
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/tty/vt/vt.c linux-libre-5.6.2-gnu/drivers/tty/vt/vt.c
--- linux-libre-5.6-gnu/drivers/tty/vt/vt.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/tty/vt/vt.c	2020-04-02 02:02:32.000000000 -0400
@@ -890,8 +890,9 @@ static void hide_softcursor(struct vc_da
 
 static void hide_cursor(struct vc_data *vc)
 {
-	if (vc == sel_cons)
+	if (vc_is_sel(vc))
 		clear_selection();
+
 	vc->vc_sw->con_cursor(vc, CM_ERASE);
 	hide_softcursor(vc);
 }
@@ -901,7 +902,7 @@ static void set_cursor(struct vc_data *v
 	if (!con_is_fg(vc) || console_blanked || vc->vc_mode == KD_GRAPHICS)
 		return;
 	if (vc->vc_deccm) {
-		if (vc == sel_cons)
+		if (vc_is_sel(vc))
 			clear_selection();
 		add_softcursor(vc);
 		if ((vc->vc_cursor_type & 0x0f) != 1)
@@ -1074,6 +1075,17 @@ static void visual_deinit(struct vc_data
 	module_put(vc->vc_sw->owner);
 }
 
+static void vc_port_destruct(struct tty_port *port)
+{
+	struct vc_data *vc = container_of(port, struct vc_data, port);
+
+	kfree(vc);
+}
+
+static const struct tty_port_operations vc_port_ops = {
+	.destruct = vc_port_destruct,
+};
+
 int vc_allocate(unsigned int currcons)	/* return 0 on success */
 {
 	struct vt_notifier_param param;
@@ -1099,6 +1111,7 @@ int vc_allocate(unsigned int currcons)	/
 
 	vc_cons[currcons].d = vc;
 	tty_port_init(&vc->port);
+	vc->port.ops = &vc_port_ops;
 	INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
 
 	visual_init(vc, currcons, 1);
@@ -1207,7 +1220,7 @@ static int vc_do_resize(struct tty_struc
 		}
 	}
 
-	if (vc == sel_cons)
+	if (vc_is_sel(vc))
 		clear_selection();
 
 	old_rows = vc->vc_rows;
@@ -3253,6 +3266,7 @@ static int con_install(struct tty_driver
 
 	tty->driver_data = vc;
 	vc->port.tty = tty;
+	tty_port_get(&vc->port);
 
 	if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
 		tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
@@ -3288,6 +3302,13 @@ static void con_shutdown(struct tty_stru
 	console_unlock();
 }
 
+static void con_cleanup(struct tty_struct *tty)
+{
+	struct vc_data *vc = tty->driver_data;
+
+	tty_port_put(&vc->port);
+}
+
 static int default_color           = 7; /* white */
 static int default_italic_color    = 2; // green (ASCII)
 static int default_underline_color = 3; // cyan (ASCII)
@@ -3413,7 +3434,8 @@ static const struct tty_operations con_o
 	.throttle = con_throttle,
 	.unthrottle = con_unthrottle,
 	.resize = vt_resize,
-	.shutdown = con_shutdown
+	.shutdown = con_shutdown,
+	.cleanup = con_cleanup,
 };
 
 static struct cdev vc0_cdev;
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/tty/vt/vt_ioctl.c linux-libre-5.6.2-gnu/drivers/tty/vt/vt_ioctl.c
--- linux-libre-5.6-gnu/drivers/tty/vt/vt_ioctl.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/tty/vt/vt_ioctl.c	2020-04-02 02:02:32.000000000 -0400
@@ -39,11 +39,32 @@
 #include <linux/kbd_diacr.h>
 #include <linux/selection.h>
 
-char vt_dont_switch;
-extern struct tty_driver *console_driver;
+bool vt_dont_switch;
 
-#define VT_IS_IN_USE(i)	(console_driver->ttys[i] && console_driver->ttys[i]->count)
-#define VT_BUSY(i)	(VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
+static inline bool vt_in_use(unsigned int i)
+{
+	const struct vc_data *vc = vc_cons[i].d;
+
+	/*
+	 * console_lock must be held to prevent the vc from being deallocated
+	 * while we're checking whether it's in-use.
+	 */
+	WARN_CONSOLE_UNLOCKED();
+
+	return vc && kref_read(&vc->port.kref) > 1;
+}
+
+static inline bool vt_busy(int i)
+{
+	if (vt_in_use(i))
+		return true;
+	if (i == fg_console)
+		return true;
+	if (vc_is_sel(vc_cons[i].d))
+		return true;
+
+	return false;
+}
 
 /*
  * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
@@ -289,16 +310,14 @@ static int vt_disallocate(unsigned int v
 	int ret = 0;
 
 	console_lock();
-	if (VT_BUSY(vc_num))
+	if (vt_busy(vc_num))
 		ret = -EBUSY;
 	else if (vc_num)
 		vc = vc_deallocate(vc_num);
 	console_unlock();
 
-	if (vc && vc_num >= MIN_NR_CONSOLES) {
-		tty_port_destroy(&vc->port);
-		kfree(vc);
-	}
+	if (vc && vc_num >= MIN_NR_CONSOLES)
+		tty_port_put(&vc->port);
 
 	return ret;
 }
@@ -311,17 +330,15 @@ static void vt_disallocate_all(void)
 
 	console_lock();
 	for (i = 1; i < MAX_NR_CONSOLES; i++)
-		if (!VT_BUSY(i))
+		if (!vt_busy(i))
 			vc[i] = vc_deallocate(i);
 		else
 			vc[i] = NULL;
 	console_unlock();
 
 	for (i = 1; i < MAX_NR_CONSOLES; i++) {
-		if (vc[i] && i >= MIN_NR_CONSOLES) {
-			tty_port_destroy(&vc[i]->port);
-			kfree(vc[i]);
-		}
+		if (vc[i] && i >= MIN_NR_CONSOLES)
+			tty_port_put(&vc[i]->port);
 	}
 }
 
@@ -335,22 +352,13 @@ int vt_ioctl(struct tty_struct *tty,
 {
 	struct vc_data *vc = tty->driver_data;
 	struct console_font_op op;	/* used in multiple places here */
-	unsigned int console;
+	unsigned int console = vc->vc_num;
 	unsigned char ucval;
 	unsigned int uival;
 	void __user *up = (void __user *)arg;
 	int i, perm;
 	int ret = 0;
 
-	console = vc->vc_num;
-
-
-	if (!vc_cons_allocated(console)) { 	/* impossible? */
-		ret = -ENOIOCTLCMD;
-		goto out;
-	}
-
-
 	/*
 	 * To have permissions to do most of the vt ioctls, we either have
 	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
@@ -641,15 +649,16 @@ int vt_ioctl(struct tty_struct *tty,
 		struct vt_stat __user *vtstat = up;
 		unsigned short state, mask;
 
-		/* Review: FIXME: Console lock ? */
 		if (put_user(fg_console + 1, &vtstat->v_active))
 			ret = -EFAULT;
 		else {
 			state = 1;	/* /dev/tty0 is always open */
+			console_lock(); /* required by vt_in_use() */
 			for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
 							++i, mask <<= 1)
-				if (VT_IS_IN_USE(i))
+				if (vt_in_use(i))
 					state |= mask;
+			console_unlock();
 			ret = put_user(state, &vtstat->v_state);
 		}
 		break;
@@ -659,10 +668,11 @@ int vt_ioctl(struct tty_struct *tty,
 	 * Returns the first available (non-opened) console.
 	 */
 	case VT_OPENQRY:
-		/* FIXME: locking ? - but then this is a stupid API */
+		console_lock(); /* required by vt_in_use() */
 		for (i = 0; i < MAX_NR_CONSOLES; ++i)
-			if (! VT_IS_IN_USE(i))
+			if (!vt_in_use(i))
 				break;
+		console_unlock();
 		uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
 		goto setint;		 
 
@@ -1011,12 +1021,12 @@ int vt_ioctl(struct tty_struct *tty,
 	case VT_LOCKSWITCH:
 		if (!capable(CAP_SYS_TTY_CONFIG))
 			return -EPERM;
-		vt_dont_switch = 1;
+		vt_dont_switch = true;
 		break;
 	case VT_UNLOCKSWITCH:
 		if (!capable(CAP_SYS_TTY_CONFIG))
 			return -EPERM;
-		vt_dont_switch = 0;
+		vt_dont_switch = false;
 		break;
 	case VT_GETHIFONTMASK:
 		ret = put_user(vc->vc_hi_font_mask,
@@ -1180,14 +1190,9 @@ long vt_compat_ioctl(struct tty_struct *
 {
 	struct vc_data *vc = tty->driver_data;
 	struct console_font_op op;	/* used in multiple places here */
-	unsigned int console = vc->vc_num;
 	void __user *up = compat_ptr(arg);
 	int perm;
 
-
-	if (!vc_cons_allocated(console)) 	/* impossible? */
-		return -ENOIOCTLCMD;
-
 	/*
 	 * To have permissions to do most of the vt ioctls, we either have
 	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/usb/class/cdc-acm.c linux-libre-5.6.2-gnu/drivers/usb/class/cdc-acm.c
--- linux-libre-5.6-gnu/drivers/usb/class/cdc-acm.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/usb/class/cdc-acm.c	2020-04-02 02:02:32.000000000 -0400
@@ -923,16 +923,16 @@ static int set_serial_info(struct tty_st
 
 	mutex_lock(&acm->port.mutex);
 
-	if ((ss->close_delay != old_close_delay) ||
-            (ss->closing_wait != old_closing_wait)) {
-		if (!capable(CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN)) {
+		if ((ss->close_delay != old_close_delay) ||
+		    (ss->closing_wait != old_closing_wait))
 			retval = -EPERM;
-		else {
-			acm->port.close_delay  = close_delay;
-			acm->port.closing_wait = closing_wait;
-		}
-	} else
-		retval = -EOPNOTSUPP;
+		else
+			retval = -EOPNOTSUPP;
+	} else {
+		acm->port.close_delay  = close_delay;
+		acm->port.closing_wait = closing_wait;
+	}
 
 	mutex_unlock(&acm->port.mutex);
 	return retval;
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/usb/musb/musb_host.c linux-libre-5.6.2-gnu/drivers/usb/musb/musb_host.c
--- linux-libre-5.6-gnu/drivers/usb/musb/musb_host.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/usb/musb/musb_host.c	2020-04-02 02:02:32.000000000 -0400
@@ -1436,10 +1436,7 @@ done:
 	 * We need to map sg if the transfer_buffer is
 	 * NULL.
 	 */
-	if (!urb->transfer_buffer)
-		qh->use_sg = true;
-
-	if (qh->use_sg) {
+	if (!urb->transfer_buffer) {
 		/* sg_miter_start is already done in musb_ep_program */
 		if (!sg_miter_next(&qh->sg_miter)) {
 			dev_err(musb->controller, "error: sg list empty\n");
@@ -1447,9 +1444,8 @@ done:
 			status = -EINVAL;
 			goto done;
 		}
-		urb->transfer_buffer = qh->sg_miter.addr;
 		length = min_t(u32, length, qh->sg_miter.length);
-		musb_write_fifo(hw_ep, length, urb->transfer_buffer);
+		musb_write_fifo(hw_ep, length, qh->sg_miter.addr);
 		qh->sg_miter.consumed = length;
 		sg_miter_stop(&qh->sg_miter);
 	} else {
@@ -1458,11 +1454,6 @@ done:
 
 	qh->segsize = length;
 
-	if (qh->use_sg) {
-		if (offset + length >= urb->transfer_buffer_length)
-			qh->use_sg = false;
-	}
-
 	musb_ep_select(mbase, epnum);
 	musb_writew(epio, MUSB_TXCSR,
 			MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY);
@@ -1977,8 +1968,10 @@ finish:
 	urb->actual_length += xfer_len;
 	qh->offset += xfer_len;
 	if (done) {
-		if (qh->use_sg)
+		if (qh->use_sg) {
 			qh->use_sg = false;
+			urb->transfer_buffer = NULL;
+		}
 
 		if (urb->status == -EINPROGRESS)
 			urb->status = status;
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/usb/serial/io_edgeport.c linux-libre-5.6.2-gnu/drivers/usb/serial/io_edgeport.c
--- linux-libre-5.6-gnu/drivers/usb/serial/io_edgeport.c	2020-03-29 21:05:03.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/usb/serial/io_edgeport.c	2020-04-02 03:02:59.000000000 -0400
@@ -710,7 +710,7 @@ static void edge_interrupt_callback(stru
 		/* grab the txcredits for the ports if available */
 		position = 2;
 		portNumber = 0;
-		while ((position < length) &&
+		while ((position < length - 1) &&
 				(portNumber < edge_serial->serial->num_ports)) {
 			txCredits = data[position] | (data[position+1] << 8);
 			if (txCredits) {
diff -druNp --no-dereference linux-libre-5.6-gnu/drivers/usb/serial/option.c linux-libre-5.6.2-gnu/drivers/usb/serial/option.c
--- linux-libre-5.6-gnu/drivers/usb/serial/option.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/drivers/usb/serial/option.c	2020-04-02 02:02:32.000000000 -0400
@@ -1992,8 +1992,14 @@ static const struct usb_device_id option
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) },	/* D-Link DWM-152/C1 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) },	/* D-Link DWM-156/C1 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) },	/* D-Link DWM-156/A3 */
+	{ USB_DEVICE_INTERFACE_CLASS(0x1435, 0xd191, 0xff),			/* Wistron Neweb D19Q1 */
+	  .driver_info = RSVD(1) | RSVD(4) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x1690, 0x7588, 0xff),			/* ASKEY WWHC050 */
+	  .driver_info = RSVD(1) | RSVD(4) },
 	{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2031, 0xff),			/* Olicard 600 */
 	  .driver_info = RSVD(4) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2033, 0xff),			/* BroadMobi BM806U */
+	  .driver_info = RSVD(4) },
 	{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x2060, 0xff),			/* BroadMobi BM818 */
 	  .driver_info = RSVD(4) },
 	{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) },			/* OLICARD300 - MT6225 */
diff -druNp --no-dereference linux-libre-5.6-gnu/fs/libfs.c linux-libre-5.6.2-gnu/fs/libfs.c
--- linux-libre-5.6-gnu/fs/libfs.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/fs/libfs.c	2020-04-02 02:02:32.000000000 -0400
@@ -891,7 +891,7 @@ int simple_attr_open(struct inode *inode
 {
 	struct simple_attr *attr;
 
-	attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
 	if (!attr)
 		return -ENOMEM;
 
@@ -931,9 +931,11 @@ ssize_t simple_attr_read(struct file *fi
 	if (ret)
 		return ret;
 
-	if (*ppos) {		/* continued read */
+	if (*ppos && attr->get_buf[0]) {
+		/* continued read */
 		size = strlen(attr->get_buf);
-	} else {		/* first read */
+	} else {
+		/* first read */
 		u64 val;
 		ret = attr->get(attr->data, &val);
 		if (ret)
diff -druNp --no-dereference linux-libre-5.6-gnu/include/linux/selection.h linux-libre-5.6.2-gnu/include/linux/selection.h
--- linux-libre-5.6-gnu/include/linux/selection.h	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/include/linux/selection.h	2020-04-02 02:02:32.000000000 -0400
@@ -11,8 +11,8 @@
 #include <linux/tiocl.h>
 #include <linux/vt_buffer.h>
 
-extern struct vc_data *sel_cons;
 struct tty_struct;
+struct vc_data;
 
 extern void clear_selection(void);
 extern int set_selection_user(const struct tiocl_selection __user *sel,
@@ -24,6 +24,8 @@ extern int sel_loadlut(char __user *p);
 extern int mouse_reporting(void);
 extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
 
+bool vc_is_sel(struct vc_data *vc);
+
 extern int console_blanked;
 
 extern const unsigned char color_table[];
diff -druNp --no-dereference linux-libre-5.6-gnu/include/linux/vt_kern.h linux-libre-5.6.2-gnu/include/linux/vt_kern.h
--- linux-libre-5.6-gnu/include/linux/vt_kern.h	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/include/linux/vt_kern.h	2020-04-02 02:02:32.000000000 -0400
@@ -135,7 +135,7 @@ extern int do_unbind_con_driver(const st
 			     int deflt);
 int vty_init(const struct file_operations *console_fops);
 
-extern char vt_dont_switch;
+extern bool vt_dont_switch;
 extern int default_utf8;
 extern int global_cursor_default;
 
diff -druNp --no-dereference linux-libre-5.6-gnu/kernel/bpf/verifier.c linux-libre-5.6.2-gnu/kernel/bpf/verifier.c
--- linux-libre-5.6-gnu/kernel/bpf/verifier.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/kernel/bpf/verifier.c	2020-04-02 02:02:32.000000000 -0400
@@ -1034,17 +1034,6 @@ static void __reg_bound_offset(struct bp
 						 reg->umax_value));
 }
 
-static void __reg_bound_offset32(struct bpf_reg_state *reg)
-{
-	u64 mask = 0xffffFFFF;
-	struct tnum range = tnum_range(reg->umin_value & mask,
-				       reg->umax_value & mask);
-	struct tnum lo32 = tnum_cast(reg->var_off, 4);
-	struct tnum hi32 = tnum_lshift(tnum_rshift(reg->var_off, 32), 32);
-
-	reg->var_off = tnum_or(hi32, tnum_intersect(lo32, range));
-}
-
 /* Reset the min/max bounds of a register */
 static void __mark_reg_unbounded(struct bpf_reg_state *reg)
 {
@@ -5717,10 +5706,6 @@ static void reg_set_min_max(struct bpf_r
 	/* We might have learned some bits from the bounds. */
 	__reg_bound_offset(false_reg);
 	__reg_bound_offset(true_reg);
-	if (is_jmp32) {
-		__reg_bound_offset32(false_reg);
-		__reg_bound_offset32(true_reg);
-	}
 	/* Intersecting with the old var_off might have improved our bounds
 	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
 	 * then new var_off is (0; 0x7f...fc) which improves our umax.
@@ -5830,10 +5815,6 @@ static void reg_set_min_max_inv(struct b
 	/* We might have learned some bits from the bounds. */
 	__reg_bound_offset(false_reg);
 	__reg_bound_offset(true_reg);
-	if (is_jmp32) {
-		__reg_bound_offset32(false_reg);
-		__reg_bound_offset32(true_reg);
-	}
 	/* Intersecting with the old var_off might have improved our bounds
 	 * slightly.  e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc),
 	 * then new var_off is (0; 0x7f...fc) which improves our umax.
diff -druNp --no-dereference linux-libre-5.6-gnu/Makefile linux-libre-5.6.2-gnu/Makefile
--- linux-libre-5.6-gnu/Makefile	2020-03-29 20:30:15.000000000 -0400
+++ linux-libre-5.6.2-gnu/Makefile	2020-04-02 02:30:55.000000000 -0400
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
 PATCHLEVEL = 6
-SUBLEVEL = 0
+SUBLEVEL = 2
 EXTRAVERSION = -gnu
 NAME = Kleptomaniac Octopus
 
diff -druNp --no-dereference linux-libre-5.6-gnu/net/mac80211/tx.c linux-libre-5.6.2-gnu/net/mac80211/tx.c
--- linux-libre-5.6-gnu/net/mac80211/tx.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/net/mac80211/tx.c	2020-04-02 02:02:32.000000000 -0400
@@ -3610,7 +3610,8 @@ begin:
 		 * Drop unicast frames to unauthorised stations unless they are
 		 * EAPOL frames from the local station.
 		 */
-		if (unlikely(!ieee80211_vif_is_mesh(&tx.sdata->vif) &&
+		if (unlikely(ieee80211_is_data(hdr->frame_control) &&
+			     !ieee80211_vif_is_mesh(&tx.sdata->vif) &&
 			     tx.sdata->vif.type != NL80211_IFTYPE_OCB &&
 			     !is_multicast_ether_addr(hdr->addr1) &&
 			     !test_sta_flag(tx.sta, WLAN_STA_AUTHORIZED) &&
diff -druNp --no-dereference linux-libre-5.6-gnu/tools/testing/selftests/bpf/verifier/jmp32.c linux-libre-5.6.2-gnu/tools/testing/selftests/bpf/verifier/jmp32.c
--- linux-libre-5.6-gnu/tools/testing/selftests/bpf/verifier/jmp32.c	2020-03-29 18:25:41.000000000 -0400
+++ linux-libre-5.6.2-gnu/tools/testing/selftests/bpf/verifier/jmp32.c	2020-04-02 02:02:32.000000000 -0400
@@ -783,7 +783,8 @@
 	},
 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
 	.fixup_map_hash_48b = { 4 },
-	.result = ACCEPT,
+	.result = REJECT,
+	.errstr = "R8 unbounded memory access",
 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 },
 {
@@ -811,7 +812,8 @@
 	},
 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
 	.fixup_map_hash_48b = { 4 },
-	.result = ACCEPT,
+	.result = REJECT,
+	.errstr = "R8 unbounded memory access",
 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 },
 {
@@ -839,6 +841,7 @@
 	},
 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
 	.fixup_map_hash_48b = { 4 },
-	.result = ACCEPT,
+	.result = REJECT,
+	.errstr = "R8 unbounded memory access",
 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
 },
