commit:     e47454f1268c89d9232c88ae0fd9580e30e52ac1
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Nov  8 11:51:46 2023 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Nov  8 11:51:46 2023 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e47454f1

Linux patch 6.6.1

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

 0000_README            |    4 +
 1000_linux-6.6.1.patch | 1531 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1535 insertions(+)

diff --git a/0000_README b/0000_README
index aed4554c..bb74cf79 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,10 @@ EXPERIMENTAL
 Individual Patch Descriptions:
 --------------------------------------------------------------------------
 
+Patch:  1000_linux-6.6.1.patch
+From:   https://www.kernel.org
+Desc:   Linux 6.6.1
+
 Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
 From:   
http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
 Desc:   Enable link security restrictions by default.

diff --git a/1000_linux-6.6.1.patch b/1000_linux-6.6.1.patch
new file mode 100644
index 00000000..e487d1d9
--- /dev/null
+++ b/1000_linux-6.6.1.patch
@@ -0,0 +1,1531 @@
+diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml 
b/Documentation/devicetree/bindings/serial/rs485.yaml
+index 303a443d9e29b..9418fd66a8e95 100644
+--- a/Documentation/devicetree/bindings/serial/rs485.yaml
++++ b/Documentation/devicetree/bindings/serial/rs485.yaml
+@@ -29,6 +29,10 @@ properties:
+           default: 0
+           maximum: 100
+ 
++  rs485-rts-active-high:
++    description: drive RTS high when sending (this is the default).
++    $ref: /schemas/types.yaml#/definitions/flag
++
+   rs485-rts-active-low:
+     description: drive RTS low when sending (default is high).
+     $ref: /schemas/types.yaml#/definitions/flag
+diff --git a/Makefile b/Makefile
+index 5c418efbe89b6..f8c14da7c7bc7 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 6
+-SUBLEVEL = 0
++SUBLEVEL = 1
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/drivers/bluetooth/hci_bcm4377.c b/drivers/bluetooth/hci_bcm4377.c
+index 19ad0e7886462..a617578356953 100644
+--- a/drivers/bluetooth/hci_bcm4377.c
++++ b/drivers/bluetooth/hci_bcm4377.c
+@@ -512,6 +512,7 @@ struct bcm4377_hw {
+       unsigned long disable_aspm : 1;
+       unsigned long broken_ext_scan : 1;
+       unsigned long broken_mws_transport_config : 1;
++      unsigned long broken_le_coded : 1;
+ 
+       int (*send_calibration)(struct bcm4377_data *bcm4377);
+       int (*send_ptb)(struct bcm4377_data *bcm4377,
+@@ -2372,6 +2373,8 @@ static int bcm4377_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
+               set_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &hdev->quirks);
+       if (bcm4377->hw->broken_ext_scan)
+               set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
++      if (bcm4377->hw->broken_le_coded)
++              set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
+ 
+       pci_set_drvdata(pdev, bcm4377);
+       hci_set_drvdata(hdev, bcm4377);
+@@ -2461,6 +2464,7 @@ static const struct bcm4377_hw bcm4377_hw_variants[] = {
+               .bar0_core2_window2 = 0x18107000,
+               .has_bar0_core2_window2 = true,
+               .broken_mws_transport_config = true,
++              .broken_le_coded = true,
+               .send_calibration = bcm4378_send_calibration,
+               .send_ptb = bcm4378_send_ptb,
+       },
+@@ -2474,6 +2478,7 @@ static const struct bcm4377_hw bcm4377_hw_variants[] = {
+               .has_bar0_core2_window2 = true,
+               .clear_pciecfg_subsystem_ctrl_bit19 = true,
+               .broken_mws_transport_config = true,
++              .broken_le_coded = true,
+               .send_calibration = bcm4387_send_calibration,
+               .send_ptb = bcm4378_send_ptb,
+       },
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c 
b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+index b87bfecb7755a..a8e79104b684e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+@@ -586,7 +586,8 @@ static void dcn10_dmcu_set_psr_enable(struct dmcu *dmcu, 
bool enable, bool wait)
+                               if (state == PSR_STATE0)
+                                       break;
+                       }
+-                      fsleep(500);
++                      /* must *not* be fsleep - this can be called from high 
irq levels */
++                      udelay(500);
+               }
+ 
+               /* assert if max retry hit */
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c 
b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+index 0f24b6fbd2201..4704c9c85ee6f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
+@@ -216,7 +216,8 @@ static void dmub_psr_enable(struct dmub_psr *dmub, bool 
enable, bool wait, uint8
+                                       break;
+                       }
+ 
+-                      fsleep(500);
++                      /* must *not* be fsleep - this can be called from high 
irq levels */
++                      udelay(500);
+               }
+ 
+               /* assert if max retry hit */
+diff --git a/drivers/misc/pci_endpoint_test.c 
b/drivers/misc/pci_endpoint_test.c
+index ed4d0ef5e5c31..7e1acc68d4359 100644
+--- a/drivers/misc/pci_endpoint_test.c
++++ b/drivers/misc/pci_endpoint_test.c
+@@ -71,6 +71,7 @@
+ #define PCI_DEVICE_ID_TI_AM654                        0xb00c
+ #define PCI_DEVICE_ID_TI_J7200                        0xb00f
+ #define PCI_DEVICE_ID_TI_AM64                 0xb010
++#define PCI_DEVICE_ID_TI_J721S2               0xb013
+ #define PCI_DEVICE_ID_LS1088A                 0x80c0
+ #define PCI_DEVICE_ID_IMX8                    0x0808
+ 
+@@ -999,6 +1000,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] 
= {
+       { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM64),
+         .driver_data = (kernel_ulong_t)&j721e_data,
+       },
++      { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721S2),
++        .driver_data = (kernel_ulong_t)&j721e_data,
++      },
+       { }
+ };
+ MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index eeec1d6f90238..e3e915329510f 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -690,7 +690,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 
PCI_DEVICE_ID_ATI_RS100,   quirk_ati_
+ /*
+  * In the AMD NL platform, this device ([1022:7912]) has a class code of
+  * PCI_CLASS_SERIAL_USB_XHCI (0x0c0330), which means the xhci driver will
+- * claim it.
++ * claim it. The same applies on the VanGogh platform device ([1022:163a]).
+  *
+  * But the dwc3 driver is a more specific driver for this device, and we'd
+  * prefer to use it instead of xhci. To prevent xhci from claiming the
+@@ -698,7 +698,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 
PCI_DEVICE_ID_ATI_RS100,   quirk_ati_
+  * defines as "USB device (not host controller)". The dwc3 driver can then
+  * claim it based on its Vendor and Device ID.
+  */
+-static void quirk_amd_nl_class(struct pci_dev *pdev)
++static void quirk_amd_dwc_class(struct pci_dev *pdev)
+ {
+       u32 class = pdev->class;
+ 
+@@ -708,7 +708,9 @@ static void quirk_amd_nl_class(struct pci_dev *pdev)
+                class, pdev->class);
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB,
+-              quirk_amd_nl_class);
++              quirk_amd_dwc_class);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VANGOGH_USB,
++              quirk_amd_dwc_class);
+ 
+ /*
+  * Synopsys USB 3.x host HAPS platform has a class code of
+diff --git a/drivers/power/supply/power_supply_core.c 
b/drivers/power/supply/power_supply_core.c
+index 0b69fb7bafd85..416409e2fd6da 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -29,7 +29,7 @@
+ struct class *power_supply_class;
+ EXPORT_SYMBOL_GPL(power_supply_class);
+ 
+-ATOMIC_NOTIFIER_HEAD(power_supply_notifier);
++BLOCKING_NOTIFIER_HEAD(power_supply_notifier);
+ EXPORT_SYMBOL_GPL(power_supply_notifier);
+ 
+ static struct device_type power_supply_dev_type;
+@@ -97,7 +97,7 @@ static void power_supply_changed_work(struct work_struct 
*work)
+               class_for_each_device(power_supply_class, NULL, psy,
+                                     __power_supply_changed_work);
+               power_supply_update_leds(psy);
+-              atomic_notifier_call_chain(&power_supply_notifier,
++              blocking_notifier_call_chain(&power_supply_notifier,
+                               PSY_EVENT_PROP_CHANGED, psy);
+               kobject_uevent(&psy->dev.kobj, KOBJ_CHANGE);
+               spin_lock_irqsave(&psy->changed_lock, flags);
+@@ -1262,13 +1262,13 @@ static void power_supply_dev_release(struct device 
*dev)
+ 
+ int power_supply_reg_notifier(struct notifier_block *nb)
+ {
+-      return atomic_notifier_chain_register(&power_supply_notifier, nb);
++      return blocking_notifier_chain_register(&power_supply_notifier, nb);
+ }
+ EXPORT_SYMBOL_GPL(power_supply_reg_notifier);
+ 
+ void power_supply_unreg_notifier(struct notifier_block *nb)
+ {
+-      atomic_notifier_chain_unregister(&power_supply_notifier, nb);
++      blocking_notifier_chain_unregister(&power_supply_notifier, nb);
+ }
+ EXPORT_SYMBOL_GPL(power_supply_unreg_notifier);
+ 
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 1f3aba607cd51..0ee7531c92017 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -4108,6 +4108,8 @@ static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, 
u8 brk)
+ 
+ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk)
+ {
++      if (dlci->gsm->dead)
++              return -EL2HLT;
+       if (dlci->adaption == 2) {
+               /* Send convergence layer type 2 empty data frame. */
+               gsm_modem_upd_via_data(dlci, brk);
+diff --git a/drivers/tty/serial/8250/8250_pci.c 
b/drivers/tty/serial/8250/8250_pci.c
+index 62a9bd30b4db5..bbd7914ddc9ad 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -2429,6 +2429,153 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
+               .init                   = pci_oxsemi_tornado_init,
+               .setup          = pci_oxsemi_tornado_setup,
+       },
++      /*
++       * Brainboxes devices - all Oxsemi based
++       */
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4027,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4028,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4029,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4019,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4016,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4015,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x400A,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x400E,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x400C,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x400B,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x400F,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4010,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4011,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x401D,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x401E,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4013,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4017,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .init           = pci_oxsemi_tornado_init,
++              .setup          = pci_oxsemi_tornado_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTASHIELD,
++              .device         = 0x4018,
++              .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,
+@@ -4913,6 +5060,12 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               0, 0,
+               pbn_b1_bt_1_115200 },
+ 
++      /*
++       * IntaShield IS-100
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0D60,
++              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
++              pbn_b2_1_115200 },
+       /*
+        * IntaShield IS-200
+        */
+@@ -4925,6 +5078,27 @@ static const struct pci_device_id serial_pci_tbl[] = {
+       {       PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,    /* 135a.0dc0 */
+               pbn_b2_4_115200 },
++      /*
++       * IntaShield IX-100
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4027,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_1_15625000 },
++      /*
++       * IntaShield IX-200
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4028,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_2_15625000 },
++      /*
++       * IntaShield IX-400
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4029,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_4_15625000 },
+       /* Brainboxes Devices */
+       /*
+       * Brainboxes UC-101
+@@ -4940,10 +5114,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_b2_1_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0AA2,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_1_115200 },
+       /*
+-       * Brainboxes UC-257
++       * Brainboxes UC-253/UC-734
+        */
+-      {       PCI_VENDOR_ID_INTASHIELD, 0x0861,
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0CA1,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_b2_2_115200 },
+@@ -4979,6 +5157,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, 0x08E2,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x08E3,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
+       /*
+        * Brainboxes UC-310
+        */
+@@ -4989,6 +5175,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
+       /*
+        * Brainboxes UC-313
+        */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x08A1,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x08A2,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
+       {       PCI_VENDOR_ID_INTASHIELD, 0x08A3,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+@@ -5003,6 +5197,10 @@ static const struct pci_device_id serial_pci_tbl[] = {
+       /*
+        * Brainboxes UC-346
+        */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0B01,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_4_115200 },
+       {       PCI_VENDOR_ID_INTASHIELD, 0x0B02,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+@@ -5014,6 +5212,10 @@ 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, 0x0A82,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
+       {       PCI_VENDOR_ID_INTASHIELD, 0x0A83,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+@@ -5026,12 +5228,94 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               0, 0,
+               pbn_b2_4_115200 },
+       /*
+-       * Brainboxes UC-420/431
++       * Brainboxes UC-420
+        */
+       {       PCI_VENDOR_ID_INTASHIELD, 0x0921,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_b2_4_115200 },
++      /*
++       * Brainboxes UC-607
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x09A1,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x09A2,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x09A3,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      /*
++       * Brainboxes UC-836
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0D41,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_4_115200 },
++      /*
++       * Brainboxes UP-189
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0AC1,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0AC2,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0AC3,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      /*
++       * Brainboxes UP-200
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0B21,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0B22,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0B23,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      /*
++       * Brainboxes UP-869
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C01,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C02,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C03,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      /*
++       * Brainboxes UP-880
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C21,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C22,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0C23,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_2_115200 },
+       /*
+        * Brainboxes PX-101
+        */
+@@ -5064,7 +5348,7 @@ static const struct pci_device_id serial_pci_tbl[] = {
+       {       PCI_VENDOR_ID_INTASHIELD, 0x4015,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+-              pbn_oxsemi_4_15625000 },
++              pbn_oxsemi_2_15625000 },
+       /*
+        * Brainboxes PX-260/PX-701
+        */
+@@ -5072,6 +5356,13 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+               pbn_oxsemi_4_15625000 },
++      /*
++       * Brainboxes PX-275/279
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x0E41,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b2_8_115200 },
+       /*
+        * Brainboxes PX-310
+        */
+@@ -5119,16 +5410,38 @@ static const struct pci_device_id serial_pci_tbl[] = {
+               0, 0,
+               pbn_oxsemi_4_15625000 },
+       /*
+-       * Brainboxes PX-803
++       * Brainboxes PX-475
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x401D,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_1_15625000 },
++      /*
++       * Brainboxes PX-803/PX-857
+        */
+       {       PCI_VENDOR_ID_INTASHIELD, 0x4009,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+-              pbn_b0_1_115200 },
++              pbn_b0_2_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4018,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_2_15625000 },
+       {       PCI_VENDOR_ID_INTASHIELD, 0x401E,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0,
+-              pbn_oxsemi_1_15625000 },
++              pbn_oxsemi_2_15625000 },
++      /*
++       * Brainboxes PX-820
++       */
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4002,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_b0_4_115200 },
++      {       PCI_VENDOR_ID_INTASHIELD, 0x4013,
++              PCI_ANY_ID, PCI_ANY_ID,
++              0, 0,
++              pbn_oxsemi_4_15625000 },
+       /*
+        * Brainboxes PX-846
+        */
+diff --git a/drivers/tty/serial/serial_core.c 
b/drivers/tty/serial/serial_core.c
+index d5ba6e90bd95f..f912f8bf1e633 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -146,7 +146,7 @@ static void __uart_start(struct uart_state *state)
+ 
+       /* Increment the runtime PM usage count for the active check below */
+       err = pm_runtime_get(&port_dev->dev);
+-      if (err < 0) {
++      if (err < 0 && err != -EINPROGRESS) {
+               pm_runtime_put_noidle(&port_dev->dev);
+               return;
+       }
+diff --git a/drivers/usb/gadget/legacy/raw_gadget.c 
b/drivers/usb/gadget/legacy/raw_gadget.c
+index e549022642e56..ea106ad665a1f 100644
+--- a/drivers/usb/gadget/legacy/raw_gadget.c
++++ b/drivers/usb/gadget/legacy/raw_gadget.c
+@@ -663,12 +663,12 @@ static int raw_process_ep0_io(struct raw_dev *dev, 
struct usb_raw_ep_io *io,
+       if (WARN_ON(in && dev->ep0_out_pending)) {
+               ret = -ENODEV;
+               dev->state = STATE_DEV_FAILED;
+-              goto out_done;
++              goto out_unlock;
+       }
+       if (WARN_ON(!in && dev->ep0_in_pending)) {
+               ret = -ENODEV;
+               dev->state = STATE_DEV_FAILED;
+-              goto out_done;
++              goto out_unlock;
+       }
+ 
+       dev->req->buf = data;
+@@ -683,7 +683,7 @@ static int raw_process_ep0_io(struct raw_dev *dev, struct 
usb_raw_ep_io *io,
+                               "fail, usb_ep_queue returned %d\n", ret);
+               spin_lock_irqsave(&dev->lock, flags);
+               dev->state = STATE_DEV_FAILED;
+-              goto out_done;
++              goto out_queue_failed;
+       }
+ 
+       ret = wait_for_completion_interruptible(&dev->ep0_done);
+@@ -692,13 +692,16 @@ static int raw_process_ep0_io(struct raw_dev *dev, 
struct usb_raw_ep_io *io,
+               usb_ep_dequeue(dev->gadget->ep0, dev->req);
+               wait_for_completion(&dev->ep0_done);
+               spin_lock_irqsave(&dev->lock, flags);
+-              goto out_done;
++              if (dev->ep0_status == -ECONNRESET)
++                      dev->ep0_status = -EINTR;
++              goto out_interrupted;
+       }
+ 
+       spin_lock_irqsave(&dev->lock, flags);
+-      ret = dev->ep0_status;
+ 
+-out_done:
++out_interrupted:
++      ret = dev->ep0_status;
++out_queue_failed:
+       dev->ep0_urb_queued = false;
+ out_unlock:
+       spin_unlock_irqrestore(&dev->lock, flags);
+@@ -1067,7 +1070,7 @@ static int raw_process_ep_io(struct raw_dev *dev, struct 
usb_raw_ep_io *io,
+                               "fail, usb_ep_queue returned %d\n", ret);
+               spin_lock_irqsave(&dev->lock, flags);
+               dev->state = STATE_DEV_FAILED;
+-              goto out_done;
++              goto out_queue_failed;
+       }
+ 
+       ret = wait_for_completion_interruptible(&done);
+@@ -1076,13 +1079,16 @@ static int raw_process_ep_io(struct raw_dev *dev, 
struct usb_raw_ep_io *io,
+               usb_ep_dequeue(ep->ep, ep->req);
+               wait_for_completion(&done);
+               spin_lock_irqsave(&dev->lock, flags);
+-              goto out_done;
++              if (ep->status == -ECONNRESET)
++                      ep->status = -EINTR;
++              goto out_interrupted;
+       }
+ 
+       spin_lock_irqsave(&dev->lock, flags);
+-      ret = ep->status;
+ 
+-out_done:
++out_interrupted:
++      ret = ep->status;
++out_queue_failed:
+       ep->urb_queued = false;
+ out_unlock:
+       spin_unlock_irqrestore(&dev->lock, flags);
+diff --git a/drivers/usb/storage/unusual_cypress.h 
b/drivers/usb/storage/unusual_cypress.h
+index 0547daf116a26..5df40759d77ad 100644
+--- a/drivers/usb/storage/unusual_cypress.h
++++ b/drivers/usb/storage/unusual_cypress.h
+@@ -19,7 +19,7 @@ UNUSUAL_DEV(  0x04b4, 0x6831, 0x0000, 0x9999,
+               "Cypress ISD-300LP",
+               USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
+ 
+-UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160,
++UNUSUAL_DEV( 0x14cd, 0x6116, 0x0150, 0x0160,
+               "Super Top",
+               "USB 2.0  SATA BRIDGE",
+               USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
+diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
+index d962f67c95ae6..25e7e14da2a77 100644
+--- a/drivers/usb/typec/tcpm/tcpm.c
++++ b/drivers/usb/typec/tcpm/tcpm.c
+@@ -1625,6 +1625,9 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct 
typec_altmode *adev,
+                       if (PD_VDO_VID(p[0]) != USB_SID_PD)
+                               break;
+ 
++                      if (IS_ERR_OR_NULL(port->partner))
++                              break;
++
+                       if (PD_VDO_SVDM_VER(p[0]) < svdm_version) {
+                               typec_partner_set_svdm_version(port->partner,
+                                                              
PD_VDO_SVDM_VER(p[0]));
+@@ -3903,6 +3906,8 @@ static void run_state_machine(struct tcpm_port *port)
+               port->potential_contaminant = ((port->enter_state == 
SRC_ATTACH_WAIT &&
+                                               port->state == SRC_UNATTACHED) 
||
+                                              (port->enter_state == 
SNK_ATTACH_WAIT &&
++                                              port->state == SNK_UNATTACHED) 
||
++                                             (port->enter_state == 
SNK_DEBOUNCED &&
+                                               port->state == SNK_UNATTACHED));
+ 
+       port->enter_state = port->state;
+diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
+index 8c8d64e76103e..5fcfb634fec26 100644
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -38,7 +38,10 @@ struct eventfs_inode {
+  * @fop:      file_operations for file or directory
+  * @iop:      inode_operations for file or directory
+  * @data:     something that the caller will want to get to later on
++ * @is_freed: Flag set if the eventfs is on its way to be freed
+  * @mode:     the permission that the file or directory should have
++ * @uid:      saved uid if changed
++ * @gid:      saved gid if changed
+  */
+ struct eventfs_file {
+       const char                      *name;
+@@ -50,22 +53,32 @@ struct eventfs_file {
+       const struct inode_operations   *iop;
+       /*
+        * Union - used for deletion
+-       * @del_list:   list of eventfs_file to delete
++       * @llist:      for calling dput() if needed after RCU
+        * @rcu:        eventfs_file to delete in RCU
+-       * @is_freed:   node is freed if one of the above is set
+        */
+       union {
+-              struct list_head        del_list;
++              struct llist_node       llist;
+               struct rcu_head         rcu;
+-              unsigned long           is_freed;
+       };
+       void                            *data;
+-      umode_t                         mode;
++      unsigned int                    is_freed:1;
++      unsigned int                    mode:31;
++      kuid_t                          uid;
++      kgid_t                          gid;
+ };
+ 
+ static DEFINE_MUTEX(eventfs_mutex);
+ DEFINE_STATIC_SRCU(eventfs_srcu);
+ 
++/* Mode is unsigned short, use the upper bits for flags */
++enum {
++      EVENTFS_SAVE_MODE       = BIT(16),
++      EVENTFS_SAVE_UID        = BIT(17),
++      EVENTFS_SAVE_GID        = BIT(18),
++};
++
++#define EVENTFS_MODE_MASK     (EVENTFS_SAVE_MODE - 1)
++
+ static struct dentry *eventfs_root_lookup(struct inode *dir,
+                                         struct dentry *dentry,
+                                         unsigned int flags);
+@@ -73,8 +86,53 @@ static int dcache_dir_open_wrapper(struct inode *inode, 
struct file *file);
+ static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx);
+ static int eventfs_release(struct inode *inode, struct file *file);
+ 
++static void update_attr(struct eventfs_file *ef, struct iattr *iattr)
++{
++      unsigned int ia_valid = iattr->ia_valid;
++
++      if (ia_valid & ATTR_MODE) {
++              ef->mode = (ef->mode & ~EVENTFS_MODE_MASK) |
++                      (iattr->ia_mode & EVENTFS_MODE_MASK) |
++                      EVENTFS_SAVE_MODE;
++      }
++      if (ia_valid & ATTR_UID) {
++              ef->mode |= EVENTFS_SAVE_UID;
++              ef->uid = iattr->ia_uid;
++      }
++      if (ia_valid & ATTR_GID) {
++              ef->mode |= EVENTFS_SAVE_GID;
++              ef->gid = iattr->ia_gid;
++      }
++}
++
++static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
++                           struct iattr *iattr)
++{
++      struct eventfs_file *ef;
++      int ret;
++
++      mutex_lock(&eventfs_mutex);
++      ef = dentry->d_fsdata;
++      if (ef->is_freed) {
++              /* Do not allow changes if the event is about to be removed. */
++              mutex_unlock(&eventfs_mutex);
++              return -ENODEV;
++      }
++
++      ret = simple_setattr(idmap, dentry, iattr);
++      if (!ret)
++              update_attr(ef, iattr);
++      mutex_unlock(&eventfs_mutex);
++      return ret;
++}
++
+ static const struct inode_operations eventfs_root_dir_inode_operations = {
+       .lookup         = eventfs_root_lookup,
++      .setattr        = eventfs_set_attr,
++};
++
++static const struct inode_operations eventfs_file_inode_operations = {
++      .setattr        = eventfs_set_attr,
+ };
+ 
+ static const struct file_operations eventfs_file_operations = {
+@@ -85,10 +143,20 @@ static const struct file_operations 
eventfs_file_operations = {
+       .release        = eventfs_release,
+ };
+ 
++static void update_inode_attr(struct inode *inode, struct eventfs_file *ef)
++{
++      inode->i_mode = ef->mode & EVENTFS_MODE_MASK;
++
++      if (ef->mode & EVENTFS_SAVE_UID)
++              inode->i_uid = ef->uid;
++
++      if (ef->mode & EVENTFS_SAVE_GID)
++              inode->i_gid = ef->gid;
++}
++
+ /**
+  * create_file - create a file in the tracefs filesystem
+- * @name: the name of the file to create.
+- * @mode: the permission that the file should have.
++ * @ef: the eventfs_file
+  * @parent: parent dentry for this file.
+  * @data: something that the caller will want to get to later on.
+  * @fop: struct file_operations that should be used for this file.
+@@ -104,7 +172,7 @@ static const struct file_operations 
eventfs_file_operations = {
+  * If tracefs is not enabled in the kernel, the value -%ENODEV will be
+  * returned.
+  */
+-static struct dentry *create_file(const char *name, umode_t mode,
++static struct dentry *create_file(struct eventfs_file *ef,
+                                 struct dentry *parent, void *data,
+                                 const struct file_operations *fop)
+ {
+@@ -112,13 +180,13 @@ static struct dentry *create_file(const char *name, 
umode_t mode,
+       struct dentry *dentry;
+       struct inode *inode;
+ 
+-      if (!(mode & S_IFMT))
+-              mode |= S_IFREG;
++      if (!(ef->mode & S_IFMT))
++              ef->mode |= S_IFREG;
+ 
+-      if (WARN_ON_ONCE(!S_ISREG(mode)))
++      if (WARN_ON_ONCE(!S_ISREG(ef->mode)))
+               return NULL;
+ 
+-      dentry = eventfs_start_creating(name, parent);
++      dentry = eventfs_start_creating(ef->name, parent);
+ 
+       if (IS_ERR(dentry))
+               return dentry;
+@@ -127,7 +195,10 @@ static struct dentry *create_file(const char *name, 
umode_t mode,
+       if (unlikely(!inode))
+               return eventfs_failed_creating(dentry);
+ 
+-      inode->i_mode = mode;
++      /* If the user updated the directory's attributes, use them */
++      update_inode_attr(inode, ef);
++
++      inode->i_op = &eventfs_file_inode_operations;
+       inode->i_fop = fop;
+       inode->i_private = data;
+ 
+@@ -140,7 +211,7 @@ static struct dentry *create_file(const char *name, 
umode_t mode,
+ 
+ /**
+  * create_dir - create a dir in the tracefs filesystem
+- * @name: the name of the file to create.
++ * @ei: the eventfs_inode that represents the directory to create
+  * @parent: parent dentry for this file.
+  * @data: something that the caller will want to get to later on.
+  *
+@@ -155,13 +226,14 @@ static struct dentry *create_file(const char *name, 
umode_t mode,
+  * If tracefs is not enabled in the kernel, the value -%ENODEV will be
+  * returned.
+  */
+-static struct dentry *create_dir(const char *name, struct dentry *parent, 
void *data)
++static struct dentry *create_dir(struct eventfs_file *ef,
++                               struct dentry *parent, void *data)
+ {
+       struct tracefs_inode *ti;
+       struct dentry *dentry;
+       struct inode *inode;
+ 
+-      dentry = eventfs_start_creating(name, parent);
++      dentry = eventfs_start_creating(ef->name, parent);
+       if (IS_ERR(dentry))
+               return dentry;
+ 
+@@ -169,7 +241,8 @@ static struct dentry *create_dir(const char *name, struct 
dentry *parent, void *
+       if (unlikely(!inode))
+               return eventfs_failed_creating(dentry);
+ 
+-      inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
++      update_inode_attr(inode, ef);
++
+       inode->i_op = &eventfs_root_dir_inode_operations;
+       inode->i_fop = &eventfs_file_operations;
+       inode->i_private = data;
+@@ -184,6 +257,13 @@ static struct dentry *create_dir(const char *name, struct 
dentry *parent, void *
+       return eventfs_end_creating(dentry);
+ }
+ 
++static void free_ef(struct eventfs_file *ef)
++{
++      kfree(ef->name);
++      kfree(ef->ei);
++      kfree(ef);
++}
++
+ /**
+  * eventfs_set_ef_status_free - set the ef->status to free
+  * @ti: the tracefs_inode of the dentry
+@@ -194,59 +274,37 @@ static struct dentry *create_dir(const char *name, 
struct dentry *parent, void *
+  */
+ void eventfs_set_ef_status_free(struct tracefs_inode *ti, struct dentry 
*dentry)
+ {
+-      struct tracefs_inode *ti_parent;
+       struct eventfs_inode *ei;
+-      struct eventfs_file *ef, *tmp;
++      struct eventfs_file *ef;
+ 
+       /* The top level events directory may be freed by this */
+       if (unlikely(ti->flags & TRACEFS_EVENT_TOP_INODE)) {
+-              LIST_HEAD(ef_del_list);
+-
+               mutex_lock(&eventfs_mutex);
+-
+               ei = ti->private;
+ 
+-              /* Record all the top level files */
+-              list_for_each_entry_srcu(ef, &ei->e_top_files, list,
+-                                       lockdep_is_held(&eventfs_mutex)) {
+-                      list_add_tail(&ef->del_list, &ef_del_list);
+-              }
+-
+               /* Nothing should access this, but just in case! */
+               ti->private = NULL;
+-
+               mutex_unlock(&eventfs_mutex);
+ 
+-              /* Now safely free the top level files and their children */
+-              list_for_each_entry_safe(ef, tmp, &ef_del_list, del_list) {
+-                      list_del(&ef->del_list);
+-                      eventfs_remove(ef);
+-              }
+-
+-              kfree(ei);
++              ef = dentry->d_fsdata;
++              if (ef)
++                      free_ef(ef);
+               return;
+       }
+ 
+       mutex_lock(&eventfs_mutex);
+ 
+-      ti_parent = get_tracefs(dentry->d_parent->d_inode);
+-      if (!ti_parent || !(ti_parent->flags & TRACEFS_EVENT_INODE))
+-              goto out;
+-
+       ef = dentry->d_fsdata;
+       if (!ef)
+               goto out;
+ 
+-      /*
+-       * If ef was freed, then the LSB bit is set for d_fsdata.
+-       * But this should not happen, as it should still have a
+-       * ref count that prevents it. Warn in case it does.
+-       */
+-      if (WARN_ON_ONCE((unsigned long)ef & 1))
+-              goto out;
++      if (ef->is_freed) {
++              free_ef(ef);
++      } else {
++              ef->dentry = NULL;
++      }
+ 
+       dentry->d_fsdata = NULL;
+-      ef->dentry = NULL;
+ out:
+       mutex_unlock(&eventfs_mutex);
+ }
+@@ -306,10 +364,9 @@ create_dentry(struct eventfs_file *ef, struct dentry 
*parent, bool lookup)
+               inode_lock(parent->d_inode);
+ 
+       if (ef->ei)
+-              dentry = create_dir(ef->name, parent, ef->data);
++              dentry = create_dir(ef, parent, ef->data);
+       else
+-              dentry = create_file(ef->name, ef->mode, parent,
+-                                   ef->data, ef->fop);
++              dentry = create_file(ef, parent, ef->data, ef->fop);
+ 
+       if (!lookup)
+               inode_unlock(parent->d_inode);
+@@ -475,6 +532,7 @@ static int dcache_dir_open_wrapper(struct inode *inode, 
struct file *file)
+               if (d) {
+                       struct dentry **tmp;
+ 
++
+                       tmp = krealloc(dentries, sizeof(d) * (cnt + 2), 
GFP_KERNEL);
+                       if (!tmp)
+                               break;
+@@ -549,13 +607,14 @@ static struct eventfs_file *eventfs_prepare_ef(const 
char *name, umode_t mode,
+                       return ERR_PTR(-ENOMEM);
+               }
+               INIT_LIST_HEAD(&ef->ei->e_top_files);
++              ef->mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
+       } else {
+               ef->ei = NULL;
++              ef->mode = mode;
+       }
+ 
+       ef->iop = iop;
+       ef->fop = fop;
+-      ef->mode = mode;
+       ef->data = data;
+       return ef;
+ }
+@@ -772,25 +831,64 @@ int eventfs_add_file(const char *name, umode_t mode,
+       return 0;
+ }
+ 
+-static void free_ef(struct rcu_head *head)
++static LLIST_HEAD(free_list);
++
++static void eventfs_workfn(struct work_struct *work)
++{
++        struct eventfs_file *ef, *tmp;
++        struct llist_node *llnode;
++
++      llnode = llist_del_all(&free_list);
++        llist_for_each_entry_safe(ef, tmp, llnode, llist) {
++              /* This should only get here if it had a dentry */
++              if (!WARN_ON_ONCE(!ef->dentry))
++                      dput(ef->dentry);
++        }
++}
++
++static DECLARE_WORK(eventfs_work, eventfs_workfn);
++
++static void free_rcu_ef(struct rcu_head *head)
+ {
+       struct eventfs_file *ef = container_of(head, struct eventfs_file, rcu);
+ 
+-      kfree(ef->name);
+-      kfree(ef->ei);
+-      kfree(ef);
++      if (ef->dentry) {
++              /* Do not free the ef until all references of dentry are gone */
++              if (llist_add(&ef->llist, &free_list))
++                      queue_work(system_unbound_wq, &eventfs_work);
++              return;
++      }
++
++      free_ef(ef);
++}
++
++static void unhook_dentry(struct dentry *dentry)
++{
++      if (!dentry)
++              return;
++      /*
++       * Need to add a reference to the dentry that is expected by
++       * simple_recursive_removal(), which will include a dput().
++       */
++      dget(dentry);
++
++      /*
++       * Also add a reference for the dput() in eventfs_workfn().
++       * That is required as that dput() will free the ei after
++       * the SRCU grace period is over.
++       */
++      dget(dentry);
+ }
+ 
+ /**
+  * eventfs_remove_rec - remove eventfs dir or file from list
+  * @ef: eventfs_file to be removed.
+- * @head: to create list of eventfs_file to be deleted
+  * @level: to check recursion depth
+  *
+  * The helper function eventfs_remove_rec() is used to clean up and free the
+  * associated data from eventfs for both of the added functions.
+  */
+-static void eventfs_remove_rec(struct eventfs_file *ef, struct list_head 
*head, int level)
++static void eventfs_remove_rec(struct eventfs_file *ef, int level)
+ {
+       struct eventfs_file *ef_child;
+ 
+@@ -810,12 +908,16 @@ static void eventfs_remove_rec(struct eventfs_file *ef, 
struct list_head *head,
+               /* search for nested folders or files */
+               list_for_each_entry_srcu(ef_child, &ef->ei->e_top_files, list,
+                                        lockdep_is_held(&eventfs_mutex)) {
+-                      eventfs_remove_rec(ef_child, head, level + 1);
++                      eventfs_remove_rec(ef_child, level + 1);
+               }
+       }
+ 
++      ef->is_freed = 1;
++
++      unhook_dentry(ef->dentry);
++
+       list_del_rcu(&ef->list);
+-      list_add_tail(&ef->del_list, head);
++      call_srcu(&eventfs_srcu, &ef->rcu, free_rcu_ef);
+ }
+ 
+ /**
+@@ -826,61 +928,22 @@ static void eventfs_remove_rec(struct eventfs_file *ef, 
struct list_head *head,
+  */
+ void eventfs_remove(struct eventfs_file *ef)
+ {
+-      struct eventfs_file *tmp;
+-      LIST_HEAD(ef_del_list);
+-      struct dentry *dentry_list = NULL;
+       struct dentry *dentry;
+ 
+       if (!ef)
+               return;
+ 
+       mutex_lock(&eventfs_mutex);
+-      eventfs_remove_rec(ef, &ef_del_list, 0);
+-      list_for_each_entry_safe(ef, tmp, &ef_del_list, del_list) {
+-              if (ef->dentry) {
+-                      unsigned long ptr = (unsigned long)dentry_list;
+-
+-                      /* Keep the dentry from being freed yet */
+-                      dget(ef->dentry);
+-
+-                      /*
+-                       * Paranoid: The dget() above should prevent the dentry
+-                       * from being freed and calling 
eventfs_set_ef_status_free().
+-                       * But just in case, set the link list LSB pointer to 1
+-                       * and have eventfs_set_ef_status_free() check that to
+-                       * make sure that if it does happen, it will not think
+-                       * the d_fsdata is an event_file.
+-                       *
+-                       * For this to work, no event_file should be allocated
+-                       * on a odd space, as the ef should always be allocated
+-                       * to be at least word aligned. Check for that too.
+-                       */
+-                      WARN_ON_ONCE(ptr & 1);
+-
+-                      ef->dentry->d_fsdata = (void *)(ptr | 1);
+-                      dentry_list = ef->dentry;
+-                      ef->dentry = NULL;
+-              }
+-              call_srcu(&eventfs_srcu, &ef->rcu, free_ef);
+-      }
++      dentry = ef->dentry;
++      eventfs_remove_rec(ef, 0);
+       mutex_unlock(&eventfs_mutex);
+ 
+-      while (dentry_list) {
+-              unsigned long ptr;
+-
+-              dentry = dentry_list;
+-              ptr = (unsigned long)dentry->d_fsdata & ~1UL;
+-              dentry_list = (struct dentry *)ptr;
+-              dentry->d_fsdata = NULL;
+-              d_invalidate(dentry);
+-              mutex_lock(&eventfs_mutex);
+-              /* dentry should now have at least a single reference */
+-              WARN_ONCE((int)d_count(dentry) < 1,
+-                        "dentry %p less than one reference (%d) after 
invalidate\n",
+-                        dentry, d_count(dentry));
+-              mutex_unlock(&eventfs_mutex);
+-              dput(dentry);
+-      }
++      /*
++       * If any of the ei children has a dentry, then the ei itself
++       * must have a dentry.
++       */
++      if (dentry)
++              simple_recursive_removal(dentry, NULL);
+ }
+ 
+ /**
+@@ -891,6 +954,8 @@ void eventfs_remove(struct eventfs_file *ef)
+  */
+ void eventfs_remove_events_dir(struct dentry *dentry)
+ {
++      struct eventfs_file *ef_child;
++      struct eventfs_inode *ei;
+       struct tracefs_inode *ti;
+ 
+       if (!dentry || !dentry->d_inode)
+@@ -900,6 +965,11 @@ void eventfs_remove_events_dir(struct dentry *dentry)
+       if (!ti || !(ti->flags & TRACEFS_EVENT_INODE))
+               return;
+ 
+-      d_invalidate(dentry);
+-      dput(dentry);
++      mutex_lock(&eventfs_mutex);
++      ei = ti->private;
++      list_for_each_entry_srcu(ef_child, &ei->e_top_files, list,
++                               lockdep_is_held(&eventfs_mutex)) {
++              eventfs_remove_rec(ef_child, 0);
++      }
++      mutex_unlock(&eventfs_mutex);
+ }
+diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
+index 5fb3d4c393a9e..3a8e24e9a93f9 100644
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -579,6 +579,7 @@
+ #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3 0x12c3
+ #define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3 0x16fb
+ #define PCI_DEVICE_ID_AMD_MI200_DF_F3 0x14d3
++#define PCI_DEVICE_ID_AMD_VANGOGH_USB 0x163a
+ #define PCI_DEVICE_ID_AMD_CNB17H_F3   0x1703
+ #define PCI_DEVICE_ID_AMD_LANCE               0x2000
+ #define PCI_DEVICE_ID_AMD_LANCE_HOME  0x2001
+diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
+index a427f13c757f4..85b86768c0b91 100644
+--- a/include/linux/power_supply.h
++++ b/include/linux/power_supply.h
+@@ -767,7 +767,7 @@ struct power_supply_battery_info {
+       int bti_resistance_tolerance;
+ };
+ 
+-extern struct atomic_notifier_head power_supply_notifier;
++extern struct blocking_notifier_head power_supply_notifier;
+ extern int power_supply_reg_notifier(struct notifier_block *nb);
+ extern void power_supply_unreg_notifier(struct notifier_block *nb);
+ #if IS_ENABLED(CONFIG_POWER_SUPPLY)
+diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
+index 21ae37e49319a..cf9f0c61796e1 100644
+--- a/include/linux/trace_events.h
++++ b/include/linux/trace_events.h
+@@ -492,6 +492,7 @@ enum {
+       EVENT_FILE_FL_TRIGGER_COND_BIT,
+       EVENT_FILE_FL_PID_FILTER_BIT,
+       EVENT_FILE_FL_WAS_ENABLED_BIT,
++      EVENT_FILE_FL_FREED_BIT,
+ };
+ 
+ extern struct trace_event_file *trace_get_event_file(const char *instance,
+@@ -630,6 +631,7 @@ extern int __kprobe_event_add_fields(struct dynevent_cmd 
*cmd, ...);
+  *  TRIGGER_COND  - When set, one or more triggers has an associated filter
+  *  PID_FILTER    - When set, the event is filtered based on pid
+  *  WAS_ENABLED   - Set when enabled to know to clear trace on module removal
++ *  FREED         - File descriptor is freed, all fields should be considered 
invalid
+  */
+ enum {
+       EVENT_FILE_FL_ENABLED           = (1 << EVENT_FILE_FL_ENABLED_BIT),
+@@ -643,6 +645,7 @@ enum {
+       EVENT_FILE_FL_TRIGGER_COND      = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT),
+       EVENT_FILE_FL_PID_FILTER        = (1 << EVENT_FILE_FL_PID_FILTER_BIT),
+       EVENT_FILE_FL_WAS_ENABLED       = (1 << EVENT_FILE_FL_WAS_ENABLED_BIT),
++      EVENT_FILE_FL_FREED             = (1 << EVENT_FILE_FL_FREED_BIT),
+ };
+ 
+ struct trace_event_file {
+@@ -671,6 +674,7 @@ struct trace_event_file {
+        * caching and such. Which is mostly OK ;-)
+        */
+       unsigned long           flags;
++      atomic_t                ref;    /* ref count for opened files */
+       atomic_t                sm_ref; /* soft-mode reference counter */
+       atomic_t                tm_ref; /* trigger-mode reference counter */
+ };
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index abaaf516fcae9..a40d6baf101f0 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -4986,6 +4986,20 @@ int tracing_open_file_tr(struct inode *inode, struct 
file *filp)
+       if (ret)
+               return ret;
+ 
++      mutex_lock(&event_mutex);
++
++      /* Fail if the file is marked for removal */
++      if (file->flags & EVENT_FILE_FL_FREED) {
++              trace_array_put(file->tr);
++              ret = -ENODEV;
++      } else {
++              event_file_get(file);
++      }
++
++      mutex_unlock(&event_mutex);
++      if (ret)
++              return ret;
++
+       filp->private_data = inode->i_private;
+ 
+       return 0;
+@@ -4996,6 +5010,7 @@ int tracing_release_file_tr(struct inode *inode, struct 
file *filp)
+       struct trace_event_file *file = inode->i_private;
+ 
+       trace_array_put(file->tr);
++      event_file_put(file);
+ 
+       return 0;
+ }
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 77debe53f07cf..d608f61287043 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -1664,6 +1664,9 @@ extern void event_trigger_unregister(struct 
event_command *cmd_ops,
+                                    char *glob,
+                                    struct event_trigger_data *trigger_data);
+ 
++extern void event_file_get(struct trace_event_file *file);
++extern void event_file_put(struct trace_event_file *file);
++
+ /**
+  * struct event_trigger_ops - callbacks for trace event triggers
+  *
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index f49d6ddb63425..82cb22ad6d617 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -990,13 +990,35 @@ static void remove_subsystem(struct trace_subsystem_dir 
*dir)
+       }
+ }
+ 
++void event_file_get(struct trace_event_file *file)
++{
++      atomic_inc(&file->ref);
++}
++
++void event_file_put(struct trace_event_file *file)
++{
++      if (WARN_ON_ONCE(!atomic_read(&file->ref))) {
++              if (file->flags & EVENT_FILE_FL_FREED)
++                      kmem_cache_free(file_cachep, file);
++              return;
++      }
++
++      if (atomic_dec_and_test(&file->ref)) {
++              /* Count should only go to zero when it is freed */
++              if (WARN_ON_ONCE(!(file->flags & EVENT_FILE_FL_FREED)))
++                      return;
++              kmem_cache_free(file_cachep, file);
++      }
++}
++
+ static void remove_event_file_dir(struct trace_event_file *file)
+ {
+       eventfs_remove(file->ef);
+       list_del(&file->list);
+       remove_subsystem(file->system);
+       free_event_filter(file->filter);
+-      kmem_cache_free(file_cachep, file);
++      file->flags |= EVENT_FILE_FL_FREED;
++      event_file_put(file);
+ }
+ 
+ /*
+@@ -1369,7 +1391,7 @@ event_enable_read(struct file *filp, char __user *ubuf, 
size_t cnt,
+               flags = file->flags;
+       mutex_unlock(&event_mutex);
+ 
+-      if (!file)
++      if (!file || flags & EVENT_FILE_FL_FREED)
+               return -ENODEV;
+ 
+       if (flags & EVENT_FILE_FL_ENABLED &&
+@@ -1407,7 +1429,7 @@ event_enable_write(struct file *filp, const char __user 
*ubuf, size_t cnt,
+               ret = -ENODEV;
+               mutex_lock(&event_mutex);
+               file = event_file_data(filp);
+-              if (likely(file))
++              if (likely(file && !(file->flags & EVENT_FILE_FL_FREED)))
+                       ret = ftrace_event_enable_disable(file, val);
+               mutex_unlock(&event_mutex);
+               break;
+@@ -1681,7 +1703,7 @@ event_filter_read(struct file *filp, char __user *ubuf, 
size_t cnt,
+ 
+       mutex_lock(&event_mutex);
+       file = event_file_data(filp);
+-      if (file)
++      if (file && !(file->flags & EVENT_FILE_FL_FREED))
+               print_event_filter(file, s);
+       mutex_unlock(&event_mutex);
+ 
+@@ -2803,6 +2825,7 @@ trace_create_new_event(struct trace_event_call *call,
+       atomic_set(&file->tm_ref, 0);
+       INIT_LIST_HEAD(&file->triggers);
+       list_add(&file->list, &tr->events);
++      event_file_get(file);
+ 
+       return file;
+ }
+diff --git a/kernel/trace/trace_events_filter.c 
b/kernel/trace/trace_events_filter.c
+index 33264e510d161..0c611b281a5b5 100644
+--- a/kernel/trace/trace_events_filter.c
++++ b/kernel/trace/trace_events_filter.c
+@@ -2349,6 +2349,9 @@ int apply_event_filter(struct trace_event_file *file, 
char *filter_string)
+       struct event_filter *filter = NULL;
+       int err;
+ 
++      if (file->flags & EVENT_FILE_FL_FREED)
++              return -ENODEV;
++
+       if (!strcmp(strstrip(filter_string), "0")) {
+               filter_disable(file);
+               filter = event_filter(file);
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index 24a948baf1bc0..756fa0aa69bba 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -336,6 +336,12 @@ static const struct config_entry config_table[] = {
+                                       DMI_MATCH(DMI_SYS_VENDOR, "Google"),
+                               }
+                       },
++                      {
++                              .ident = "Google firmware",
++                              .matches = {
++                                      DMI_MATCH(DMI_BIOS_VERSION, "Google"),
++                              }
++                      },
+                       {}
+               }
+       },
+diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
+index f5ece43d0ec24..f42c85df88a80 100644
+--- a/sound/soc/sof/sof-pci-dev.c
++++ b/sound/soc/sof/sof-pci-dev.c
+@@ -145,6 +145,13 @@ static const struct dmi_system_id 
community_key_platforms[] = {
+                       DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"),
+               }
+       },
++      {
++              .ident = "Google firmware",
++              .callback = chromebook_use_community_key,
++              .matches = {
++                      DMI_MATCH(DMI_BIOS_VERSION, "Google"),
++              }
++      },
+       {},
+ };
+ 
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 4e64842245e19..ab2b938502ebe 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2220,6 +2220,8 @@ static const struct usb_audio_quirk_flags_table 
quirk_flags_table[] = {
+                  QUIRK_FLAG_DSD_RAW),
+       VENDOR_FLG(0x2ab6, /* T+A devices */
+                  QUIRK_FLAG_DSD_RAW),
++      VENDOR_FLG(0x2afd, /* McIntosh Laboratory, Inc. */
++                 QUIRK_FLAG_DSD_RAW),
+       VENDOR_FLG(0x2d87, /* Cayin device */
+                  QUIRK_FLAG_DSD_RAW),
+       VENDOR_FLG(0x3336, /* HEM devices */
+diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
+index 7ef43f72098e0..c779b9f2e6220 100644
+--- a/tools/perf/util/evlist.c
++++ b/tools/perf/util/evlist.c
+@@ -251,6 +251,9 @@ static struct evsel *evlist__dummy_event(struct evlist 
*evlist)
+               .type   = PERF_TYPE_SOFTWARE,
+               .config = PERF_COUNT_SW_DUMMY,
+               .size   = sizeof(attr), /* to capture ABI version */
++              /* Avoid frequency mode for dummy events to avoid associated 
timers. */
++              .freq = 0,
++              .sample_period = 1,
+       };
+ 
+       return evsel__new_idx(&attr, evlist->core.nr_entries);
+@@ -277,8 +280,6 @@ struct evsel *evlist__add_aux_dummy(struct evlist *evlist, 
bool system_wide)
+       evsel->core.attr.exclude_kernel = 1;
+       evsel->core.attr.exclude_guest = 1;
+       evsel->core.attr.exclude_hv = 1;
+-      evsel->core.attr.freq = 0;
+-      evsel->core.attr.sample_period = 1;
+       evsel->core.system_wide = system_wide;
+       evsel->no_aux_samples = true;
+       evsel->name = strdup("dummy:u");

Reply via email to