commit:     557a0c081003662fedb1e21ff88bad89f2a69a13
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Apr  7 10:30:01 2025 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Apr  7 10:30:01 2025 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=557a0c08

Linux patch 6.12.22

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |   4 +
 1021_linux-6.12.22.patch | 916 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 920 insertions(+)

diff --git a/0000_README b/0000_README
index 6196ef75..696eb7c9 100644
--- a/0000_README
+++ b/0000_README
@@ -127,6 +127,10 @@ Patch:  1020_linux-6.12.21.patch
 From:   https://www.kernel.org
 Desc:   Linux 6.12.21
 
+Patch:  1021_linux-6.12.22.patch
+From:   https://www.kernel.org
+Desc:   Linux 6.12.22
+
 Patch:  1500_fortify-copy-size-value-range-tracking-fix.patch
 From:   https://git.kernel.org/
 Desc:   fortify: Hide run-time copy size from value range tracking

diff --git a/1021_linux-6.12.22.patch b/1021_linux-6.12.22.patch
new file mode 100644
index 00000000..dd1e3934
--- /dev/null
+++ b/1021_linux-6.12.22.patch
@@ -0,0 +1,916 @@
+diff --git a/Makefile b/Makefile
+index a646151342b832..f380005d1600ad 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 12
+-SUBLEVEL = 21
++SUBLEVEL = 22
+ EXTRAVERSION =
+ NAME = Baby Opossum Posse
+ 
+diff --git a/drivers/counter/microchip-tcb-capture.c 
b/drivers/counter/microchip-tcb-capture.c
+index b3e615cbd2caa6..461f57f66631c3 100644
+--- a/drivers/counter/microchip-tcb-capture.c
++++ b/drivers/counter/microchip-tcb-capture.c
+@@ -368,6 +368,25 @@ static int mchp_tc_probe(struct platform_device *pdev)
+                       channel);
+       }
+ 
++      /* Disable Quadrature Decoder and position measure */
++      ret = regmap_update_bits(regmap, ATMEL_TC_BMR, ATMEL_TC_QDEN | 
ATMEL_TC_POSEN, 0);
++      if (ret)
++              return ret;
++
++      /* Setup the period capture mode */
++      ret = regmap_update_bits(regmap, ATMEL_TC_REG(priv->channel[0], CMR),
++                               ATMEL_TC_WAVE | ATMEL_TC_ABETRG | 
ATMEL_TC_CMR_MASK |
++                               ATMEL_TC_TCCLKS,
++                               ATMEL_TC_CMR_MASK);
++      if (ret)
++              return ret;
++
++      /* Enable clock and trigger counter */
++      ret = regmap_write(regmap, ATMEL_TC_REG(priv->channel[0], CCR),
++                         ATMEL_TC_CLKEN | ATMEL_TC_SWTRG);
++      if (ret)
++              return ret;
++
+       priv->tc_cfg = tcb_config;
+       priv->regmap = regmap;
+       counter->name = dev_name(&pdev->dev);
+diff --git a/drivers/counter/stm32-lptimer-cnt.c 
b/drivers/counter/stm32-lptimer-cnt.c
+index 8439755559b219..537fe9b669f352 100644
+--- a/drivers/counter/stm32-lptimer-cnt.c
++++ b/drivers/counter/stm32-lptimer-cnt.c
+@@ -58,37 +58,43 @@ static int stm32_lptim_set_enable_state(struct 
stm32_lptim_cnt *priv,
+               return 0;
+       }
+ 
++      ret = clk_enable(priv->clk);
++      if (ret)
++              goto disable_cnt;
++
+       /* LP timer must be enabled before writing CMP & ARR */
+       ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling);
+       if (ret)
+-              return ret;
++              goto disable_clk;
+ 
+       ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
+       if (ret)
+-              return ret;
++              goto disable_clk;
+ 
+       /* ensure CMP & ARR registers are properly written */
+       ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
+                                      (val & STM32_LPTIM_CMPOK_ARROK) == 
STM32_LPTIM_CMPOK_ARROK,
+                                      100, 1000);
+       if (ret)
+-              return ret;
++              goto disable_clk;
+ 
+       ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
+                          STM32_LPTIM_CMPOKCF_ARROKCF);
+       if (ret)
+-              return ret;
++              goto disable_clk;
+ 
+-      ret = clk_enable(priv->clk);
+-      if (ret) {
+-              regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
+-              return ret;
+-      }
+       priv->enabled = true;
+ 
+       /* Start LP timer in continuous mode */
+       return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
+                                 STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
++
++disable_clk:
++      clk_disable(priv->clk);
++disable_cnt:
++      regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
++
++      return ret;
+ }
+ 
+ static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index d9a3917d207e93..c4c6538eabae6d 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -3231,8 +3231,7 @@ static int dm_resume(void *handle)
+       struct dm_atomic_state *dm_state = 
to_dm_atomic_state(dm->atomic_obj.state);
+       enum dc_connection_type new_connection_type = dc_connection_none;
+       struct dc_state *dc_state;
+-      int i, r, j, ret;
+-      bool need_hotplug = false;
++      int i, r, j;
+       struct dc_commit_streams_params commit_params = {};
+ 
+       if (dm->dc->caps.ips_support) {
+@@ -3427,23 +3426,16 @@ static int dm_resume(void *handle)
+                   aconnector->mst_root)
+                       continue;
+ 
+-              ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, 
true);
+-
+-              if (ret < 0) {
+-                      dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx,
+-                                      aconnector->dc_link);
+-                      need_hotplug = true;
+-              }
++              drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr);
+       }
+       drm_connector_list_iter_end(&iter);
+ 
+-      if (need_hotplug)
+-              drm_kms_helper_hotplug_event(ddev);
+-
+       amdgpu_dm_irq_resume_late(adev);
+ 
+       amdgpu_dm_smu_write_watermarks_table(adev);
+ 
++      drm_kms_helper_hotplug_event(ddev);
++
+       return 0;
+ }
+ 
+diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
+index 25cfd964dc25d9..acb9eb18f7ccfe 100644
+--- a/drivers/hid/hid-plantronics.c
++++ b/drivers/hid/hid-plantronics.c
+@@ -6,9 +6,6 @@
+  *  Copyright (c) 2015-2018 Terry Junge <[email protected]>
+  */
+ 
+-/*
+- */
+-
+ #include "hid-ids.h"
+ 
+ #include <linux/hid.h>
+@@ -23,30 +20,28 @@
+ 
+ #define PLT_VOL_UP            0x00b1
+ #define PLT_VOL_DOWN          0x00b2
++#define PLT_MIC_MUTE          0x00b5
+ 
+ #define PLT1_VOL_UP           (PLT_HID_1_0_PAGE | PLT_VOL_UP)
+ #define PLT1_VOL_DOWN         (PLT_HID_1_0_PAGE | PLT_VOL_DOWN)
++#define PLT1_MIC_MUTE         (PLT_HID_1_0_PAGE | PLT_MIC_MUTE)
+ #define PLT2_VOL_UP           (PLT_HID_2_0_PAGE | PLT_VOL_UP)
+ #define PLT2_VOL_DOWN         (PLT_HID_2_0_PAGE | PLT_VOL_DOWN)
++#define PLT2_MIC_MUTE         (PLT_HID_2_0_PAGE | PLT_MIC_MUTE)
++#define HID_TELEPHONY_MUTE    (HID_UP_TELEPHONY | 0x2f)
++#define HID_CONSUMER_MUTE     (HID_UP_CONSUMER | 0xe2)
+ 
+ #define PLT_DA60              0xda60
+ #define PLT_BT300_MIN         0x0413
+ #define PLT_BT300_MAX         0x0418
+ 
+-
+-#define PLT_ALLOW_CONSUMER (field->application == HID_CP_CONSUMERCONTROL && \
+-                          (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
+-
+-#define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
+-#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
+-
+ #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
+-#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
+ 
+ struct plt_drv_data {
+       unsigned long device_type;
+-      unsigned long last_volume_key_ts;
+-      u32 quirks;
++      unsigned long last_key_ts;
++      unsigned long double_key_to;
++      __u16 last_key;
+ };
+ 
+ static int plantronics_input_mapping(struct hid_device *hdev,
+@@ -58,34 +53,43 @@ static int plantronics_input_mapping(struct hid_device 
*hdev,
+       unsigned short mapped_key;
+       struct plt_drv_data *drv_data = hid_get_drvdata(hdev);
+       unsigned long plt_type = drv_data->device_type;
++      int allow_mute = usage->hid == HID_TELEPHONY_MUTE;
++      int allow_consumer = field->application == HID_CP_CONSUMERCONTROL &&
++                      (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER &&
++                      usage->hid != HID_CONSUMER_MUTE;
+ 
+       /* special case for PTT products */
+       if (field->application == HID_GD_JOYSTICK)
+               goto defaulted;
+ 
+-      /* handle volume up/down mapping */
+       /* non-standard types or multi-HID interfaces - plt_type is PID */
+       if (!(plt_type & HID_USAGE_PAGE)) {
+               switch (plt_type) {
+               case PLT_DA60:
+-                      if (PLT_ALLOW_CONSUMER)
++                      if (allow_consumer)
+                               goto defaulted;
+-                      goto ignored;
++                      if (usage->hid == HID_CONSUMER_MUTE) {
++                              mapped_key = KEY_MICMUTE;
++                              goto mapped;
++                      }
++                      break;
+               default:
+-                      if (PLT_ALLOW_CONSUMER)
++                      if (allow_consumer || allow_mute)
+                               goto defaulted;
+               }
++              goto ignored;
+       }
+-      /* handle standard types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
+-      /* 'basic telephony compliant' - allow default consumer page map */
+-      else if ((plt_type & HID_USAGE) >= PLT_BASIC_TELEPHONY &&
+-               (plt_type & HID_USAGE) != PLT_BASIC_EXCEPTION) {
+-              if (PLT_ALLOW_CONSUMER)
+-                      goto defaulted;
+-      }
+-      /* not 'basic telephony' - apply legacy mapping */
+-      /* only map if the field is in the device's primary vendor page */
+-      else if (!((field->application ^ plt_type) & HID_USAGE_PAGE)) {
++
++      /* handle standard consumer control mapping */
++      /* and standard telephony mic mute mapping */
++      if (allow_consumer || allow_mute)
++              goto defaulted;
++
++      /* handle vendor unique types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
++      /* if not 'basic telephony compliant' - map vendor unique controls */
++      if (!((plt_type & HID_USAGE) >= PLT_BASIC_TELEPHONY &&
++            (plt_type & HID_USAGE) != PLT_BASIC_EXCEPTION) &&
++            !((field->application ^ plt_type) & HID_USAGE_PAGE))
+               switch (usage->hid) {
+               case PLT1_VOL_UP:
+               case PLT2_VOL_UP:
+@@ -95,8 +99,11 @@ static int plantronics_input_mapping(struct hid_device 
*hdev,
+               case PLT2_VOL_DOWN:
+                       mapped_key = KEY_VOLUMEDOWN;
+                       goto mapped;
++              case PLT1_MIC_MUTE:
++              case PLT2_MIC_MUTE:
++                      mapped_key = KEY_MICMUTE;
++                      goto mapped;
+               }
+-      }
+ 
+ /*
+  * Future mapping of call control or other usages,
+@@ -105,6 +112,8 @@ static int plantronics_input_mapping(struct hid_device 
*hdev,
+  */
+ 
+ ignored:
++      hid_dbg(hdev, "usage: %08x (appl: %08x) - ignored\n",
++              usage->hid, field->application);
+       return -1;
+ 
+ defaulted:
+@@ -123,38 +132,26 @@ static int plantronics_event(struct hid_device *hdev, 
struct hid_field *field,
+                            struct hid_usage *usage, __s32 value)
+ {
+       struct plt_drv_data *drv_data = hid_get_drvdata(hdev);
++      unsigned long prev_tsto, cur_ts;
++      __u16 prev_key, cur_key;
+ 
+-      if (drv_data->quirks & PLT_QUIRK_DOUBLE_VOLUME_KEYS) {
+-              unsigned long prev_ts, cur_ts;
++      /* Usages are filtered in plantronics_usages. */
+ 
+-              /* Usages are filtered in plantronics_usages. */
++      /* HZ too low for ms resolution - double key detection disabled */
++      /* or it is a key release - handle key presses only. */
++      if (!drv_data->double_key_to || !value)
++              return 0;
+ 
+-              if (!value) /* Handle key presses only. */
+-                      return 0;
++      prev_tsto = drv_data->last_key_ts + drv_data->double_key_to;
++      cur_ts = drv_data->last_key_ts = jiffies;
++      prev_key = drv_data->last_key;
++      cur_key = drv_data->last_key = usage->code;
+ 
+-              prev_ts = drv_data->last_volume_key_ts;
+-              cur_ts = jiffies;
+-              if (jiffies_to_msecs(cur_ts - prev_ts) <= 
PLT_DOUBLE_KEY_TIMEOUT)
+-                      return 1; /* Ignore the repeated key. */
+-
+-              drv_data->last_volume_key_ts = cur_ts;
++      /* If the same key occurs in <= double_key_to -- ignore it */
++      if (prev_key == cur_key && time_before_eq(cur_ts, prev_tsto)) {
++              hid_dbg(hdev, "double key %d ignored\n", cur_key);
++              return 1; /* Ignore the repeated key. */
+       }
+-      if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) {
+-              unsigned long prev_ts, cur_ts;
+-
+-              /* Usages are filtered in plantronics_usages. */
+-
+-              if (!value) /* Handle key presses only. */
+-                      return 0;
+-
+-              prev_ts = drv_data->last_volume_key_ts;
+-              cur_ts = jiffies;
+-              if (jiffies_to_msecs(cur_ts - prev_ts) <= 
PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT)
+-                      return 1; /* Ignore the followed opposite volume key. */
+-
+-              drv_data->last_volume_key_ts = cur_ts;
+-      }
+-
+       return 0;
+ }
+ 
+@@ -196,12 +193,16 @@ static int plantronics_probe(struct hid_device *hdev,
+       ret = hid_parse(hdev);
+       if (ret) {
+               hid_err(hdev, "parse failed\n");
+-              goto err;
++              return ret;
+       }
+ 
+       drv_data->device_type = plantronics_device_type(hdev);
+-      drv_data->quirks = id->driver_data;
+-      drv_data->last_volume_key_ts = jiffies - 
msecs_to_jiffies(PLT_DOUBLE_KEY_TIMEOUT);
++      drv_data->double_key_to = msecs_to_jiffies(PLT_DOUBLE_KEY_TIMEOUT);
++      drv_data->last_key_ts = jiffies - drv_data->double_key_to;
++
++      /* if HZ does not allow ms resolution - disable double key detection */
++      if (drv_data->double_key_to < PLT_DOUBLE_KEY_TIMEOUT)
++              drv_data->double_key_to = 0;
+ 
+       hid_set_drvdata(hdev, drv_data);
+ 
+@@ -210,29 +211,10 @@ static int plantronics_probe(struct hid_device *hdev,
+       if (ret)
+               hid_err(hdev, "hw start failed\n");
+ 
+-err:
+       return ret;
+ }
+ 
+ static const struct hid_device_id plantronics_devices[] = {
+-      { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+-                                       
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
+-              .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+-      { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+-                                       
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
+-              .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+-      { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+-                                       
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
+-              .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+-      { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+-                                       
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
+-              .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+-      { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+-                                       
USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES),
+-              .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
+-      { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+-                                       
USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES),
+-              .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
+       { }
+ };
+@@ -241,6 +223,14 @@ MODULE_DEVICE_TABLE(hid, plantronics_devices);
+ static const struct hid_usage_id plantronics_usages[] = {
+       { HID_CP_VOLUMEUP, EV_KEY, HID_ANY_ID },
+       { HID_CP_VOLUMEDOWN, EV_KEY, HID_ANY_ID },
++      { HID_TELEPHONY_MUTE, EV_KEY, HID_ANY_ID },
++      { HID_CONSUMER_MUTE, EV_KEY, HID_ANY_ID },
++      { PLT2_VOL_UP, EV_KEY, HID_ANY_ID },
++      { PLT2_VOL_DOWN, EV_KEY, HID_ANY_ID },
++      { PLT2_MIC_MUTE, EV_KEY, HID_ANY_ID },
++      { PLT1_VOL_UP, EV_KEY, HID_ANY_ID },
++      { PLT1_VOL_DOWN, EV_KEY, HID_ANY_ID },
++      { PLT1_MIC_MUTE, EV_KEY, HID_ANY_ID },
+       { HID_TERMINATOR, HID_TERMINATOR, HID_TERMINATOR }
+ };
+ 
+diff --git a/drivers/memstick/host/rtsx_usb_ms.c 
b/drivers/memstick/host/rtsx_usb_ms.c
+index ffdd8de9ec5d79..d99f8922d4ad04 100644
+--- a/drivers/memstick/host/rtsx_usb_ms.c
++++ b/drivers/memstick/host/rtsx_usb_ms.c
+@@ -813,6 +813,7 @@ static void rtsx_usb_ms_drv_remove(struct platform_device 
*pdev)
+ 
+       host->eject = true;
+       cancel_work_sync(&host->handle_req);
++      cancel_delayed_work_sync(&host->poll_card);
+ 
+       mutex_lock(&host->host_mutex);
+       if (host->req) {
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 9fe7f704a2f7b8..944a33361dae59 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1365,9 +1365,11 @@ static const struct usb_device_id products[] = {
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */
++      {QMI_QUIRK_SET_DTR(0x1bc7, 0x10b0, 0)}, /* Telit FE990B */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c0, 0)}, /* Telit FE910C04 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c4, 0)}, /* Telit FE910C04 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c8, 0)}, /* Telit FE910C04 */
++      {QMI_QUIRK_SET_DTR(0x1bc7, 0x10d0, 0)}, /* Telit FN990B */
+       {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},    /* Telit ME910 */
+       {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},    /* Telit ME910 dual modem */
+       {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
+diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
+index 44179f4e807fc3..aeab2308b15008 100644
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -178,6 +178,17 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int 
iMACAddress)
+ }
+ EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
+ 
++static bool usbnet_needs_usb_name_format(struct usbnet *dev, struct 
net_device *net)
++{
++      /* Point to point devices which don't have a real MAC address
++       * (or report a fake local one) have historically used the usb%d
++       * naming. Preserve this..
++       */
++      return (dev->driver_info->flags & FLAG_POINTTOPOINT) != 0 &&
++              (is_zero_ether_addr(net->dev_addr) ||
++               is_local_ether_addr(net->dev_addr));
++}
++
+ static void intr_complete (struct urb *urb)
+ {
+       struct usbnet   *dev = urb->context;
+@@ -1762,13 +1773,11 @@ usbnet_probe (struct usb_interface *udev, const struct 
usb_device_id *prod)
+               if (status < 0)
+                       goto out1;
+ 
+-              // heuristic:  "usb%d" for links we know are two-host,
+-              // else "eth%d" when there's reasonable doubt.  userspace
+-              // can rename the link if it knows better.
++              /* heuristic: rename to "eth%d" if we are not sure this link
++               * is two-host (these links keep "usb%d")
++               */
+               if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
+-                  ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
+-                   /* somebody touched it*/
+-                   !is_zero_ether_addr(net->dev_addr)))
++                  !usbnet_needs_usb_name_format(dev, net))
+                       strscpy(net->name, "eth%d", sizeof(net->name));
+               /* WLAN devices should always be named "wlan%d" */
+               if ((dev->driver_info->flags & FLAG_WLAN) != 0)
+diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
+index f245a84f4a508d..bdd26c9f34bdf2 100644
+--- a/drivers/tty/serial/8250/8250_dma.c
++++ b/drivers/tty/serial/8250/8250_dma.c
+@@ -162,7 +162,7 @@ void serial8250_tx_dma_flush(struct uart_8250_port *p)
+        */
+       dma->tx_size = 0;
+ 
+-      dmaengine_terminate_async(dma->rxchan);
++      dmaengine_terminate_async(dma->txchan);
+ }
+ 
+ int serial8250_rx_dma(struct uart_8250_port *p)
+diff --git a/drivers/tty/serial/8250/8250_pci.c 
b/drivers/tty/serial/8250/8250_pci.c
+index de6d90bf0d70a2..b3c19ba777c68d 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -2687,6 +2687,22 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
+               .init           = pci_oxsemi_tornado_init,
+               .setup          = pci_oxsemi_tornado_setup,
+       },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4026,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4021,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = 0x8811,
+@@ -5213,6 +5229,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0BA2,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0BA3,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
+       /*
+        * Brainboxes UC-235/246
+        */
+@@ -5333,6 +5357,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_b2_4_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C42,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_4_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C43,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_4_115200 },
+       /*
+        * Brainboxes UC-420
+        */
+@@ -5559,6 +5591,20 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_oxsemi_1_15625000 },
++      /*
++       * Brainboxes XC-235
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4026,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_1_15625000 },
++      /*
++       * Brainboxes XC-475
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4021,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_1_15625000 },
+ 
+       /*
+        * Perle PCI-RAS cards
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 77efa7ee6eda29..9f9fc733eb2c1f 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -1483,6 +1483,19 @@ static int lpuart32_config_rs485(struct uart_port 
*port, struct ktermios *termio
+ 
+       unsigned long modem = lpuart32_read(&sport->port, UARTMODIR)
+                               & ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE);
++      u32 ctrl;
++
++      /* TXRTSE and TXRTSPOL only can be changed when transmitter is 
disabled. */
++      ctrl = lpuart32_read(&sport->port, UARTCTRL);
++      if (ctrl & UARTCTRL_TE) {
++              /* wait for the transmit engine to complete */
++              lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
++              lpuart32_write(&sport->port, ctrl & ~UARTCTRL_TE, UARTCTRL);
++
++              while (lpuart32_read(&sport->port, UARTCTRL) & UARTCTRL_TE)
++                      cpu_relax();
++      }
++
+       lpuart32_write(&sport->port, modem, UARTMODIR);
+ 
+       if (rs485->flags & SER_RS485_ENABLED) {
+@@ -1502,6 +1515,10 @@ static int lpuart32_config_rs485(struct uart_port 
*port, struct ktermios *termio
+       }
+ 
+       lpuart32_write(&sport->port, modem, UARTMODIR);
++
++      if (ctrl & UARTCTRL_TE)
++              lpuart32_write(&sport->port, ctrl, UARTCTRL);
++
+       return 0;
+ }
+ 
+diff --git a/drivers/tty/serial/stm32-usart.c 
b/drivers/tty/serial/stm32-usart.c
+index f5199fdecff278..9b9981352b1e1a 100644
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -965,10 +965,8 @@ static void stm32_usart_start_tx(struct uart_port *port)
+ {
+       struct tty_port *tport = &port->state->port;
+ 
+-      if (kfifo_is_empty(&tport->xmit_fifo) && !port->x_char) {
+-              stm32_usart_rs485_rts_disable(port);
++      if (kfifo_is_empty(&tport->xmit_fifo) && !port->x_char)
+               return;
+-      }
+ 
+       stm32_usart_rs485_rts_enable(port);
+ 
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 4384b86ea7b66c..2fad9563dca40b 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2866,6 +2866,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+               if (!ep_seg) {
+ 
+                       if (ep->skip && 
usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
++                              /* this event is unlikely to match any TD, 
don't skip them all */
++                              if (trb_comp_code == 
COMP_STOPPED_LENGTH_INVALID)
++                                      return 0;
++
+                               skip_isoc_td(xhci, td, ep, status);
+                               if (!list_empty(&ep_ring->td_list))
+                                       continue;
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 439767d242fa9c..71588e4db0e34b 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1748,11 +1748,20 @@ static inline void xhci_write_64(struct xhci_hcd *xhci,
+ }
+ 
+ 
+-/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings 
*/
++/*
++ * Reportedly, some chapters of v0.95 spec said that Link TRB always has its 
chain bit set.
++ * Other chapters and later specs say that it should only be set if the link 
is inside a TD
++ * which continues from the end of one segment to the next segment.
++ *
++ * Some 0.95 hardware was found to misbehave if any link TRB doesn't have the 
chain bit set.
++ *
++ * 0.96 hardware from AMD and NEC was found to ignore unchained isochronous 
link TRBs when
++ * "resynchronizing the pipe" after a Missed Service Error.
++ */
+ static inline bool xhci_link_chain_quirk(struct xhci_hcd *xhci, enum 
xhci_ring_type type)
+ {
+       return (xhci->quirks & XHCI_LINK_TRB_QUIRK) ||
+-             (type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST));
++             (type == TYPE_ISOC && (xhci->quirks & (XHCI_AMD_0x96_HOST | 
XHCI_NEC_HOST)));
+ }
+ 
+ /* xHCI debugging */
+diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c
+index 405cf08bda3473..e599d5ac6e4d2a 100644
+--- a/fs/bcachefs/fs-ioctl.c
++++ b/fs/bcachefs/fs-ioctl.c
+@@ -520,10 +520,12 @@ static long bch2_ioctl_subvolume_destroy(struct bch_fs 
*c, struct file *filp,
+               ret = -ENOENT;
+               goto err;
+       }
+-      ret = __bch2_unlink(dir, victim, true);
++
++      ret =   inode_permission(file_mnt_idmap(filp), d_inode(victim), 
MAY_WRITE) ?:
++              __bch2_unlink(dir, victim, true);
+       if (!ret) {
+               fsnotify_rmdir(dir, victim);
+-              d_delete(victim);
++              d_invalidate(victim);
+       }
+ err:
+       inode_unlock(dir);
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index 4a765555bf8459..1c8fcb04b3cdeb 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -2052,7 +2052,6 @@ static inline int check_for_legacy_methods(int status, 
struct net *net)
+               path_put(&path);
+               if (status)
+                       return -ENOTDIR;
+-              status = nn->client_tracking_ops->init(net);
+       }
+       return status;
+ }
+diff --git a/net/atm/mpc.c b/net/atm/mpc.c
+index 324e3ab96bb393..12da0269275c54 100644
+--- a/net/atm/mpc.c
++++ b/net/atm/mpc.c
+@@ -1314,6 +1314,8 @@ static void MPOA_cache_impos_rcvd(struct k_message *msg,
+       holding_time = msg->content.eg_info.holding_time;
+       dprintk("(%s) entry = %p, holding_time = %u\n",
+               mpc->dev->name, entry, holding_time);
++      if (entry == NULL && !holding_time)
++              return;
+       if (entry == NULL && holding_time) {
+               entry = mpc->eg_ops->add_entry(msg, mpc);
+               mpc->eg_ops->put(entry);
+diff --git a/net/ipv6/netfilter/nf_socket_ipv6.c 
b/net/ipv6/netfilter/nf_socket_ipv6.c
+index a7690ec6232596..9ea5ef56cb2704 100644
+--- a/net/ipv6/netfilter/nf_socket_ipv6.c
++++ b/net/ipv6/netfilter/nf_socket_ipv6.c
+@@ -103,6 +103,10 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const 
struct sk_buff *skb,
+       struct sk_buff *data_skb = NULL;
+       int doff = 0;
+       int thoff = 0, tproto;
++#if IS_ENABLED(CONFIG_NF_CONNTRACK)
++      enum ip_conntrack_info ctinfo;
++      struct nf_conn const *ct;
++#endif
+ 
+       tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
+       if (tproto < 0) {
+@@ -136,6 +140,25 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const 
struct sk_buff *skb,
+               return NULL;
+       }
+ 
++#if IS_ENABLED(CONFIG_NF_CONNTRACK)
++      /* Do the lookup with the original socket address in
++       * case this is a reply packet of an established
++       * SNAT-ted connection.
++       */
++      ct = nf_ct_get(skb, &ctinfo);
++      if (ct &&
++          ((tproto != IPPROTO_ICMPV6 &&
++            ctinfo == IP_CT_ESTABLISHED_REPLY) ||
++           (tproto == IPPROTO_ICMPV6 &&
++            ctinfo == IP_CT_RELATED_REPLY)) &&
++          (ct->status & IPS_SRC_NAT_DONE)) {
++              daddr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in6;
++              dport = (tproto == IPPROTO_TCP) ?
++                      ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port :
++                      ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
++      }
++#endif
++
+       return nf_socket_get_sock_v6(net, data_skb, doff, tproto, saddr, daddr,
+                                    sport, dport, indev);
+ }
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 3949e2614a6638..8c7da13a804c04 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10441,6 +10441,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x103c, 0x8811, "HP Spectre x360 15-eb1xxx", 
ALC285_FIXUP_HP_SPECTRE_X360_EB1),
+       SND_PCI_QUIRK(0x103c, 0x8812, "HP Spectre x360 15-eb1xxx", 
ALC285_FIXUP_HP_SPECTRE_X360_EB1),
+       SND_PCI_QUIRK(0x103c, 0x881d, "HP 250 G8 Notebook PC", 
ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
++      SND_PCI_QUIRK(0x103c, 0x881e, "HP Laptop 15s-du3xxx", 
ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
+       SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", 
ALC285_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8847, "HP EliteBook x360 830 G8 Notebook PC", 
ALC285_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", 
ALC285_FIXUP_HP_GPIO_LED),
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index a95ebcf4e46e76..1e7192cb4693c0 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -4156,6 +4156,52 @@ static void snd_dragonfly_quirk_db_scale(struct 
usb_mixer_interface *mixer,
+       }
+ }
+ 
++/*
++ * Some Plantronics headsets have control names that don't meet ALSA naming
++ * standards. This function fixes nonstandard source names. By the time
++ * this function is called the control name should look like one of these:
++ * "source names Playback Volume"
++ * "source names Playback Switch"
++ * "source names Capture Volume"
++ * "source names Capture Switch"
++ * If any of the trigger words are found in the name then the name will
++ * be changed to:
++ * "Headset Playback Volume"
++ * "Headset Playback Switch"
++ * "Headset Capture Volume"
++ * "Headset Capture Switch"
++ * depending on the current suffix.
++ */
++static void snd_fix_plt_name(struct snd_usb_audio *chip,
++                           struct snd_ctl_elem_id *id)
++{
++      /* no variant of "Sidetone" should be added to this list */
++      static const char * const trigger[] = {
++              "Earphone", "Microphone", "Receive", "Transmit"
++      };
++      static const char * const suffix[] = {
++              " Playback Volume", " Playback Switch",
++              " Capture Volume", " Capture Switch"
++      };
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(trigger); i++)
++              if (strstr(id->name, trigger[i]))
++                      goto triggered;
++      usb_audio_dbg(chip, "no change in %s\n", id->name);
++      return;
++
++triggered:
++      for (i = 0; i < ARRAY_SIZE(suffix); i++)
++              if (strstr(id->name, suffix[i])) {
++                      usb_audio_dbg(chip, "fixing kctl name %s\n", id->name);
++                      snprintf(id->name, sizeof(id->name), "Headset%s",
++                               suffix[i]);
++                      return;
++              }
++      usb_audio_dbg(chip, "something wrong in kctl name %s\n", id->name);
++}
++
+ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+                                 struct usb_mixer_elem_info *cval, int unitid,
+                                 struct snd_kcontrol *kctl)
+@@ -4173,5 +4219,10 @@ void snd_usb_mixer_fu_apply_quirk(struct 
usb_mixer_interface *mixer,
+                       cval->min_mute = 1;
+               break;
+       }
++
++      /* ALSA-ify some Plantronics headset control names */
++      if (USB_ID_VENDOR(mixer->chip->usb_id) == 0x047f &&
++          (cval->control == UAC_FU_MUTE || cval->control == UAC_FU_VOLUME))
++              snd_fix_plt_name(mixer->chip, &kctl->id);
+ }
+ 
+diff --git a/tools/perf/Documentation/intel-hybrid.txt 
b/tools/perf/Documentation/intel-hybrid.txt
+index e7a776ad25d719..0379903673a4ac 100644
+--- a/tools/perf/Documentation/intel-hybrid.txt
++++ b/tools/perf/Documentation/intel-hybrid.txt
+@@ -8,15 +8,15 @@ Part of events are available on core cpu, part of events are 
available
+ on atom cpu and even part of events are available on both.
+ 
+ Kernel exports two new cpu pmus via sysfs:
+-/sys/devices/cpu_core
+-/sys/devices/cpu_atom
++/sys/bus/event_source/devices/cpu_core
++/sys/bus/event_source/devices/cpu_atom
+ 
+ The 'cpus' files are created under the directories. For example,
+ 
+-cat /sys/devices/cpu_core/cpus
++cat /sys/bus/event_source/devices/cpu_core/cpus
+ 0-15
+ 
+-cat /sys/devices/cpu_atom/cpus
++cat /sys/bus/event_source/devices/cpu_atom/cpus
+ 16-23
+ 
+ It indicates cpu0-cpu15 are core cpus and cpu16-cpu23 are atom cpus.
+@@ -60,8 +60,8 @@ can't carry pmu information. So now this type is extended to 
be PMU aware
+ type. The PMU type ID is stored at attr.config[63:32].
+ 
+ PMU type ID is retrieved from sysfs.
+-/sys/devices/cpu_atom/type
+-/sys/devices/cpu_core/type
++/sys/bus/event_source/devices/cpu_atom/type
++/sys/bus/event_source/devices/cpu_core/type
+ 
+ The new attr.config layout for PERF_TYPE_HARDWARE:
+ 
+diff --git a/tools/perf/Documentation/perf-list.txt 
b/tools/perf/Documentation/perf-list.txt
+index dea005410ec02f..ee5d333e2ca964 100644
+--- a/tools/perf/Documentation/perf-list.txt
++++ b/tools/perf/Documentation/perf-list.txt
+@@ -188,7 +188,7 @@ in the CPU vendor specific documentation.
+ 
+ The available PMUs and their raw parameters can be listed with
+ 
+-  ls /sys/devices/*/format
++  ls /sys/bus/event_source/devices/*/format
+ 
+ For example the raw event "LSD.UOPS" core pmu event above could
+ be specified as
+diff --git a/tools/perf/arch/x86/util/iostat.c 
b/tools/perf/arch/x86/util/iostat.c
+index df7b5dfcc26a51..7ea882ef293a18 100644
+--- a/tools/perf/arch/x86/util/iostat.c
++++ b/tools/perf/arch/x86/util/iostat.c
+@@ -32,7 +32,7 @@
+ #define MAX_PATH 1024
+ #endif
+ 
+-#define UNCORE_IIO_PMU_PATH   "devices/uncore_iio_%d"
++#define UNCORE_IIO_PMU_PATH   "bus/event_source/devices/uncore_iio_%d"
+ #define SYSFS_UNCORE_PMU_PATH "%s/"UNCORE_IIO_PMU_PATH
+ #define PLATFORM_MAPPING_PATH UNCORE_IIO_PMU_PATH"/die%d"
+ 
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index 4933efdfee76fb..628c61397d2d38 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -96,7 +96,7 @@
+ #include <internal/threadmap.h>
+ 
+ #define DEFAULT_SEPARATOR     " "
+-#define FREEZE_ON_SMI_PATH    "devices/cpu/freeze_on_smi"
++#define FREEZE_ON_SMI_PATH    "bus/event_source/devices/cpu/freeze_on_smi"
+ 
+ static void print_counters(struct timespec *ts, int argc, const char **argv);
+ 
+diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c
+index bf5090f5220bbd..9c4adfb45f62ba 100644
+--- a/tools/perf/util/mem-events.c
++++ b/tools/perf/util/mem-events.c
+@@ -189,7 +189,7 @@ static bool perf_pmu__mem_events_supported(const char 
*mnt, struct perf_pmu *pmu
+       if (!e->event_name)
+               return true;
+ 
+-      scnprintf(path, PATH_MAX, "%s/devices/%s/events/%s", mnt, pmu->name, 
e->event_name);
++      scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/events/%s", 
mnt, pmu->name, e->event_name);
+ 
+       return !stat(path, &st);
+ }
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index 61bdda01a05aca..ed893c3c6ad938 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -33,12 +33,12 @@
+ #define UNIT_MAX_LEN  31 /* max length for event unit name */
+ 
+ enum event_source {
+-      /* An event loaded from /sys/devices/<pmu>/events. */
++      /* An event loaded from /sys/bus/event_source/devices/<pmu>/events. */
+       EVENT_SRC_SYSFS,
+       /* An event loaded from a CPUID matched json file. */
+       EVENT_SRC_CPU_JSON,
+       /*
+-       * An event loaded from a /sys/devices/<pmu>/identifier matched json
++       * An event loaded from a 
/sys/bus/event_source/devices/<pmu>/identifier matched json
+        * file.
+        */
+       EVENT_SRC_SYS_JSON,

Reply via email to