]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Thu, 25 May 2023 14:38:19 +0000 (10:38 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 25 May 2023 14:38:19 +0000 (10:38 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.15/dt-bindings-ata-ahci-ceva-convert-to-yaml.patch [new file with mode: 0644]
queue-5.15/dt-bindings-ata-ahci-ceva-cover-all-4-iommus-entries.patch [new file with mode: 0644]
queue-5.15/series [new file with mode: 0644]
queue-5.15/usb-dwc3-fix-gadget-mode-suspend-interrupt-handler-i.patch [new file with mode: 0644]
queue-5.15/usb-gadget-properly-configure-the-device-for-remote-.patch [new file with mode: 0644]

diff --git a/queue-5.15/dt-bindings-ata-ahci-ceva-convert-to-yaml.patch b/queue-5.15/dt-bindings-ata-ahci-ceva-convert-to-yaml.patch
new file mode 100644 (file)
index 0000000..edcf056
--- /dev/null
@@ -0,0 +1,290 @@
+From bbb5ed6b8bd6a4ee266a1a72a487f158f5dcb5c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Jun 2022 13:07:17 +0530
+Subject: dt-bindings: ata: ahci-ceva: convert to yaml
+
+From: Piyush Mehta <piyush.mehta@xilinx.com>
+
+[ Upstream commit f2fb1b50fbac4a0a462e1705ac913abf52aae906 ]
+
+Convert the ahci-ceva doc to yaml.
+
+Signed-off-by: Piyush Mehta <piyush.mehta@xilinx.com>
+Signed-off-by: Rob Herring <robh@kernel.org>
+Link: https://lore.kernel.org/r/20220620073717.3079-1-piyush.mehta@xilinx.com
+Stable-dep-of: a78445287226 ("dt-bindings: ata: ahci-ceva: Cover all 4 iommus entries")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../devicetree/bindings/ata/ahci-ceva.txt     |  63 ------
+ .../bindings/ata/ceva,ahci-1v84.yaml          | 189 ++++++++++++++++++
+ 2 files changed, 189 insertions(+), 63 deletions(-)
+ delete mode 100644 Documentation/devicetree/bindings/ata/ahci-ceva.txt
+ create mode 100644 Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml
+
+diff --git a/Documentation/devicetree/bindings/ata/ahci-ceva.txt b/Documentation/devicetree/bindings/ata/ahci-ceva.txt
+deleted file mode 100644
+index bfb6da0281ecd..0000000000000
+--- a/Documentation/devicetree/bindings/ata/ahci-ceva.txt
++++ /dev/null
+@@ -1,63 +0,0 @@
+-Binding for CEVA AHCI SATA Controller
+-
+-Required properties:
+-  - reg: Physical base address and size of the controller's register area.
+-  - compatible: Compatibility string. Must be 'ceva,ahci-1v84'.
+-  - clocks: Input clock specifier. Refer to common clock bindings.
+-  - interrupts: Interrupt specifier. Refer to interrupt binding.
+-  - ceva,p0-cominit-params: OOB timing value for COMINIT parameter for port 0.
+-  - ceva,p1-cominit-params: OOB timing value for COMINIT parameter for port 1.
+-                      The fields for the above parameter must be as shown below:
+-                      ceva,pN-cominit-params = /bits/ 8 <CIBGMN CIBGMX CIBGN CINMP>;
+-                      CINMP : COMINIT Negate Minimum Period.
+-                      CIBGN : COMINIT Burst Gap Nominal.
+-                      CIBGMX: COMINIT Burst Gap Maximum.
+-                      CIBGMN: COMINIT Burst Gap Minimum.
+-  - ceva,p0-comwake-params: OOB timing value for COMWAKE parameter for port 0.
+-  - ceva,p1-comwake-params: OOB timing value for COMWAKE parameter for port 1.
+-                      The fields for the above parameter must be as shown below:
+-                      ceva,pN-comwake-params = /bits/ 8 <CWBGMN CWBGMX CWBGN CWNMP>;
+-                      CWBGMN: COMWAKE Burst Gap Minimum.
+-                      CWBGMX: COMWAKE Burst Gap Maximum.
+-                      CWBGN: COMWAKE Burst Gap Nominal.
+-                      CWNMP: COMWAKE Negate Minimum Period.
+-  - ceva,p0-burst-params: Burst timing value for COM parameter for port 0.
+-  - ceva,p1-burst-params: Burst timing value for COM parameter for port 1.
+-                      The fields for the above parameter must be as shown below:
+-                      ceva,pN-burst-params = /bits/ 8 <BMX BNM SFD PTST>;
+-                      BMX: COM Burst Maximum.
+-                      BNM: COM Burst Nominal.
+-                      SFD: Signal Failure Detection value.
+-                      PTST: Partial to Slumber timer value.
+-  - ceva,p0-retry-params: Retry interval timing value for port 0.
+-  - ceva,p1-retry-params: Retry interval timing value for port 1.
+-                      The fields for the above parameter must be as shown below:
+-                      ceva,pN-retry-params = /bits/ 16 <RIT RCT>;
+-                      RIT:  Retry Interval Timer.
+-                      RCT:  Rate Change Timer.
+-
+-Optional properties:
+-  - ceva,broken-gen2: limit to gen1 speed instead of gen2.
+-  - phys: phandle for the PHY device
+-  - resets: phandle to the reset controller for the SATA IP
+-
+-Examples:
+-      ahci@fd0c0000 {
+-              compatible = "ceva,ahci-1v84";
+-              reg = <0xfd0c0000 0x200>;
+-              interrupt-parent = <&gic>;
+-              interrupts = <0 133 4>;
+-              clocks = <&clkc SATA_CLK_ID>;
+-              ceva,p0-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
+-              ceva,p0-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
+-              ceva,p0-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
+-              ceva,p0-retry-params = /bits/ 16 <0x0216 0x7F06>;
+-
+-              ceva,p1-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
+-              ceva,p1-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
+-              ceva,p1-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
+-              ceva,p1-retry-params = /bits/ 16 <0x0216 0x7F06>;
+-              ceva,broken-gen2;
+-              phys = <&psgtr 1 PHY_TYPE_SATA 1 1>;
+-              resets = <&zynqmp_reset ZYNQMP_RESET_SATA>;
+-      };
+diff --git a/Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml b/Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml
+new file mode 100644
+index 0000000000000..9b31f864e071e
+--- /dev/null
++++ b/Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml
+@@ -0,0 +1,189 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/ata/ceva,ahci-1v84.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Ceva AHCI SATA Controller
++
++maintainers:
++  - Piyush Mehta <piyush.mehta@xilinx.com>
++
++description: |
++  The Ceva SATA controller mostly conforms to the AHCI interface with some
++  special extensions to add functionality, is a high-performance dual-port
++  SATA host controller with an AHCI compliant command layer which supports
++  advanced features such as native command queuing and frame information
++  structure (FIS) based switching for systems employing port multipliers.
++
++properties:
++  compatible:
++    const: ceva,ahci-1v84
++
++  reg:
++    maxItems: 1
++
++  clocks:
++    maxItems: 1
++
++  dma-coherent: true
++
++  interrupts:
++    maxItems: 1
++
++  iommus:
++    maxItems: 1
++
++  power-domains:
++    maxItems: 1
++
++  ceva,p0-cominit-params:
++    $ref: /schemas/types.yaml#/definitions/uint8-array
++    description: |
++      OOB timing value for COMINIT parameter for port 0.
++      The fields for the above parameter must be as shown below:-
++      ceva,p0-cominit-params = /bits/ 8 <CIBGMN CIBGMX CIBGN CINMP>;
++    items:
++      - description: CINMP - COMINIT Negate Minimum Period.
++      - description: CIBGN - COMINIT Burst Gap Nominal.
++      - description: CIBGMX - COMINIT Burst Gap Maximum.
++      - description: CIBGMN - COMINIT Burst Gap Minimum.
++
++  ceva,p0-comwake-params:
++    $ref: /schemas/types.yaml#/definitions/uint8-array
++    description: |
++      OOB timing value for COMWAKE parameter for port 0.
++      The fields for the above parameter must be as shown below:-
++      ceva,p0-comwake-params = /bits/ 8 <CWBGMN CWBGMX CWBGN CWNMP>;
++    items:
++      - description: CWBGMN - COMWAKE Burst Gap Minimum.
++      - description: CWBGMX - COMWAKE Burst Gap Maximum.
++      - description: CWBGN - COMWAKE Burst Gap Nominal.
++      - description: CWNMP - COMWAKE Negate Minimum Period.
++
++  ceva,p0-burst-params:
++    $ref: /schemas/types.yaml#/definitions/uint8-array
++    description: |
++      Burst timing value for COM parameter for port 0.
++      The fields for the above parameter must be as shown below:-
++      ceva,p0-burst-params = /bits/ 8 <BMX BNM SFD PTST>;
++    items:
++      - description: BMX - COM Burst Maximum.
++      - description: BNM - COM Burst Nominal.
++      - description: SFD - Signal Failure Detection value.
++      - description: PTST - Partial to Slumber timer value.
++
++  ceva,p0-retry-params:
++    $ref: /schemas/types.yaml#/definitions/uint16-array
++    description: |
++      Retry interval timing value for port 0.
++      The fields for the above parameter must be as shown below:-
++      ceva,p0-retry-params = /bits/ 16 <RIT RCT>;
++    items:
++      - description: RIT - Retry Interval Timer.
++      - description: RCT - Rate Change Timer.
++
++  ceva,p1-cominit-params:
++    $ref: /schemas/types.yaml#/definitions/uint8-array
++    description: |
++      OOB timing value for COMINIT parameter for port 1.
++      The fields for the above parameter must be as shown below:-
++      ceva,p1-cominit-params = /bits/ 8 <CIBGMN CIBGMX CIBGN CINMP>;
++    items:
++      - description: CINMP - COMINIT Negate Minimum Period.
++      - description: CIBGN - COMINIT Burst Gap Nominal.
++      - description: CIBGMX - COMINIT Burst Gap Maximum.
++      - description: CIBGMN - COMINIT Burst Gap Minimum.
++
++  ceva,p1-comwake-params:
++    $ref: /schemas/types.yaml#/definitions/uint8-array
++    description: |
++      OOB timing value for COMWAKE parameter for port 1.
++      The fields for the above parameter must be as shown below:-
++      ceva,p1-comwake-params = /bits/ 8 <CWBGMN CWBGMX CWBGN CWNMP>;
++    items:
++      - description: CWBGMN - COMWAKE Burst Gap Minimum.
++      - description: CWBGMX - COMWAKE Burst Gap Maximum.
++      - description: CWBGN - COMWAKE Burst Gap Nominal.
++      - description: CWNMP - COMWAKE Negate Minimum Period.
++
++  ceva,p1-burst-params:
++    $ref: /schemas/types.yaml#/definitions/uint8-array
++    description: |
++      Burst timing value for COM parameter for port 1.
++      The fields for the above parameter must be as shown below:-
++      ceva,p1-burst-params = /bits/ 8 <BMX BNM SFD PTST>;
++    items:
++      - description: BMX - COM Burst Maximum.
++      - description: BNM - COM Burst Nominal.
++      - description: SFD - Signal Failure Detection value.
++      - description: PTST - Partial to Slumber timer value.
++
++  ceva,p1-retry-params:
++    $ref: /schemas/types.yaml#/definitions/uint16-array
++    description: |
++      Retry interval timing value for port 1.
++      The fields for the above parameter must be as shown below:-
++      ceva,pN-retry-params = /bits/ 16 <RIT RCT>;
++    items:
++      - description: RIT - Retry Interval Timer.
++      - description: RCT - Rate Change Timer.
++
++  ceva,broken-gen2:
++    $ref: /schemas/types.yaml#/definitions/flag
++    description: |
++      limit to gen1 speed instead of gen2.
++
++  phys:
++    maxItems: 1
++
++  phy-names:
++    items:
++      - const: sata-phy
++
++  resets:
++    maxItems: 1
++
++required:
++  - compatible
++  - reg
++  - clocks
++  - interrupts
++  - ceva,p0-cominit-params
++  - ceva,p0-comwake-params
++  - ceva,p0-burst-params
++  - ceva,p0-retry-params
++  - ceva,p1-cominit-params
++  - ceva,p1-comwake-params
++  - ceva,p1-burst-params
++  - ceva,p1-retry-params
++
++additionalProperties: false
++
++examples:
++  - |
++    #include <dt-bindings/clock/xlnx-zynqmp-clk.h>
++    #include <dt-bindings/interrupt-controller/irq.h>
++    #include <dt-bindings/power/xlnx-zynqmp-power.h>
++    #include <dt-bindings/reset/xlnx-zynqmp-resets.h>
++    #include <dt-bindings/clock/xlnx-zynqmp-clk.h>
++    #include <dt-bindings/phy/phy.h>
++
++    sata: ahci@fd0c0000 {
++        compatible = "ceva,ahci-1v84";
++        reg = <0xfd0c0000 0x200>;
++        interrupt-parent = <&gic>;
++        interrupts = <0 133 IRQ_TYPE_LEVEL_HIGH>;
++        clocks = <&zynqmp_clk SATA_REF>;
++        ceva,p0-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
++        ceva,p0-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
++        ceva,p0-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
++        ceva,p0-retry-params = /bits/ 16 <0x0216 0x7F06>;
++        ceva,p1-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
++        ceva,p1-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
++        ceva,p1-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
++        ceva,p1-retry-params = /bits/ 16 <0x0216 0x7F06>;
++        ceva,broken-gen2;
++        phys = <&psgtr 1 PHY_TYPE_SATA 1 1>;
++        resets = <&zynqmp_reset ZYNQMP_RESET_SATA>;
++    };
+-- 
+2.39.2
+
diff --git a/queue-5.15/dt-bindings-ata-ahci-ceva-cover-all-4-iommus-entries.patch b/queue-5.15/dt-bindings-ata-ahci-ceva-cover-all-4-iommus-entries.patch
new file mode 100644 (file)
index 0000000..92329f2
--- /dev/null
@@ -0,0 +1,45 @@
+From d3f9cd11735ebbd6556d0e0cb3b4da0f65441db4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 13:52:04 +0200
+Subject: dt-bindings: ata: ahci-ceva: Cover all 4 iommus entries
+
+From: Michal Simek <michal.simek@amd.com>
+
+[ Upstream commit a7844528722619d2f97740ae5ec747afff18c4be ]
+
+Current only one entry is enabled but IP itself is using 4 different IDs
+which are already listed in zynqmp.dtsi.
+
+sata: ahci@fd0c0000 {
+       compatible = "ceva,ahci-1v84";
+       ...
+       iommus = <&smmu 0x4c0>, <&smmu 0x4c1>,
+                <&smmu 0x4c2>, <&smmu 0x4c3>;
+};
+
+Fixes: 8ac47837f0e0 ("arm64: dts: zynqmp: Add missing iommu IDs")
+Cc: stable@vger.kernel.org # v5.12+
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml b/Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml
+index 9b31f864e071e..71364c6081ff5 100644
+--- a/Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml
++++ b/Documentation/devicetree/bindings/ata/ceva,ahci-1v84.yaml
+@@ -32,7 +32,7 @@ properties:
+     maxItems: 1
+   iommus:
+-    maxItems: 1
++    maxItems: 4
+   power-domains:
+     maxItems: 1
+-- 
+2.39.2
+
diff --git a/queue-5.15/series b/queue-5.15/series
new file mode 100644 (file)
index 0000000..a261eb5
--- /dev/null
@@ -0,0 +1,4 @@
+usb-gadget-properly-configure-the-device-for-remote-.patch
+usb-dwc3-fix-gadget-mode-suspend-interrupt-handler-i.patch
+dt-bindings-ata-ahci-ceva-convert-to-yaml.patch
+dt-bindings-ata-ahci-ceva-cover-all-4-iommus-entries.patch
diff --git a/queue-5.15/usb-dwc3-fix-gadget-mode-suspend-interrupt-handler-i.patch b/queue-5.15/usb-dwc3-fix-gadget-mode-suspend-interrupt-handler-i.patch
new file mode 100644 (file)
index 0000000..74af1a0
--- /dev/null
@@ -0,0 +1,98 @@
+From 7335e0994a28b1167e2549fc5c0331d6bdf31df1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 08:45:24 +0800
+Subject: usb: dwc3: fix gadget mode suspend interrupt handler issue
+
+From: Linyu Yuan <quic_linyyuan@quicinc.com>
+
+[ Upstream commit 4e8ef34e36f2839ef8c8da521ab7035956436818 ]
+
+When work in gadget mode, currently driver doesn't update software level
+link_state correctly as link state change event is not enabled for most
+devices, in function dwc3_gadget_suspend_interrupt(), it will only pass
+suspend event to UDC core when software level link state changes, so when
+interrupt generated in sequences of suspend -> reset -> conndone ->
+suspend, link state is not updated during reset and conndone, so second
+suspend interrupt event will not pass to UDC core.
+
+Remove link_state compare in dwc3_gadget_suspend_interrupt() and add a
+suspended flag to replace the compare function.
+
+Fixes: 799e9dc82968 ("usb: dwc3: gadget: conditionally disable Link State change events")
+Cc: stable <stable@kernel.org>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Linyu Yuan <quic_linyyuan@quicinc.com>
+Link: https://lore.kernel.org/r/20230512004524.31950-1-quic_linyyuan@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/core.h   |  2 ++
+ drivers/usb/dwc3/gadget.c | 10 +++++++++-
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 725653711411d..84cdac33cb359 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -1085,6 +1085,7 @@ struct dwc3_scratchpad_array {
+  *    3       - Reserved
+  * @dis_metastability_quirk: set to disable metastability quirk.
+  * @dis_split_quirk: set to disable split boundary.
++ * @suspended: set to track suspend event due to U3/L2.
+  * @imod_interval: set the interrupt moderation interval in 250ns
+  *                    increments or 0 to disable.
+  * @max_cfg_eps: current max number of IN eps used across all USB configs.
+@@ -1298,6 +1299,7 @@ struct dwc3 {
+       unsigned                dis_split_quirk:1;
+       unsigned                async_callbacks:1;
++      unsigned                suspended:1;
+       u16                     imod_interval;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 7ff77a0de5152..e42d50e4aba30 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3694,6 +3694,8 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
+ {
+       int                     reg;
++      dwc->suspended = false;
++
+       dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RX_DET);
+       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+@@ -3714,6 +3716,8 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
+ {
+       u32                     reg;
++      dwc->suspended = false;
++
+       /*
+        * Ideally, dwc3_reset_gadget() would trigger the function
+        * drivers to stop any active transfers through ep disable.
+@@ -3919,6 +3923,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
+ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
+ {
++      dwc->suspended = false;
++
+       /*
+        * TODO take core out of low power mode when that's
+        * implemented.
+@@ -4034,8 +4040,10 @@ static void dwc3_gadget_suspend_interrupt(struct dwc3 *dwc,
+ {
+       enum dwc3_link_state next = evtinfo & DWC3_LINK_STATE_MASK;
+-      if (dwc->link_state != next && next == DWC3_LINK_STATE_U3)
++      if (!dwc->suspended && next == DWC3_LINK_STATE_U3) {
++              dwc->suspended = true;
+               dwc3_suspend_gadget(dwc);
++      }
+       dwc->link_state = next;
+ }
+-- 
+2.39.2
+
diff --git a/queue-5.15/usb-gadget-properly-configure-the-device-for-remote-.patch b/queue-5.15/usb-gadget-properly-configure-the-device-for-remote-.patch
new file mode 100644 (file)
index 0000000..7747be9
--- /dev/null
@@ -0,0 +1,197 @@
+From 4c817c2ac990824486d13dc59567f6cc93336742 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Mar 2023 14:47:57 -0700
+Subject: usb: gadget: Properly configure the device for remote wakeup
+
+From: Elson Roy Serrao <quic_eserrao@quicinc.com>
+
+[ Upstream commit b93c2a68f3d9dc98ec30dcb342ae47c1c8d09d18 ]
+
+The wakeup bit in the bmAttributes field indicates whether the device
+is configured for remote wakeup. But this field should be allowed to
+set only if the UDC supports such wakeup mechanism. So configure this
+field based on UDC capability. Also inform the UDC whether the device
+is configured for remote wakeup by implementing a gadget op.
+
+Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Elson Roy Serrao <quic_eserrao@quicinc.com>
+Link: https://lore.kernel.org/r/1679694482-16430-2-git-send-email-quic_eserrao@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 4e8ef34e36f2 ("usb: dwc3: fix gadget mode suspend interrupt handler issue")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/composite.c | 18 ++++++++++++++++++
+ drivers/usb/gadget/configfs.c  |  3 +++
+ drivers/usb/gadget/udc/core.c  | 27 +++++++++++++++++++++++++++
+ drivers/usb/gadget/udc/trace.h |  5 +++++
+ include/linux/usb/composite.h  |  2 ++
+ include/linux/usb/gadget.h     |  8 ++++++++
+ 6 files changed, 63 insertions(+)
+
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index 553382ce38378..0886cff9aa1c0 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -498,6 +498,19 @@ static u8 encode_bMaxPower(enum usb_device_speed speed,
+               return min(val, 900U) / 8;
+ }
++void check_remote_wakeup_config(struct usb_gadget *g,
++                              struct usb_configuration *c)
++{
++      if (USB_CONFIG_ATT_WAKEUP & c->bmAttributes) {
++              /* Reset the rw bit if gadget is not capable of it */
++              if (!g->wakeup_capable && g->ops->set_remote_wakeup) {
++                      WARN(c->cdev, "Clearing wakeup bit for config c.%d\n",
++                           c->bConfigurationValue);
++                      c->bmAttributes &= ~USB_CONFIG_ATT_WAKEUP;
++              }
++      }
++}
++
+ static int config_buf(struct usb_configuration *config,
+               enum usb_device_speed speed, void *buf, u8 type)
+ {
+@@ -945,6 +958,11 @@ static int set_config(struct usb_composite_dev *cdev,
+               power = min(power, 500U);
+       else
+               power = min(power, 900U);
++
++      if (USB_CONFIG_ATT_WAKEUP & c->bmAttributes)
++              usb_gadget_set_remote_wakeup(gadget, 1);
++      else
++              usb_gadget_set_remote_wakeup(gadget, 0);
+ done:
+       if (power <= USB_SELF_POWER_VBUS_MAX_DRAW)
+               usb_gadget_set_selfpowered(gadget);
+diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
+index 5cbf4084daedc..528b9ec1d9e85 100644
+--- a/drivers/usb/gadget/configfs.c
++++ b/drivers/usb/gadget/configfs.c
+@@ -1384,6 +1384,9 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
+               if (gadget_is_otg(gadget))
+                       c->descriptors = otg_desc;
++              /* Properly configure the bmAttributes wakeup bit */
++              check_remote_wakeup_config(gadget, c);
++
+               cfg = container_of(c, struct config_usb_cfg, c);
+               if (!list_empty(&cfg->string_list)) {
+                       i = 0;
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index 61099f2d057dc..6c05a3a9b542f 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -508,6 +508,33 @@ int usb_gadget_wakeup(struct usb_gadget *gadget)
+ }
+ EXPORT_SYMBOL_GPL(usb_gadget_wakeup);
++/**
++ * usb_gadget_set_remote_wakeup - configures the device remote wakeup feature.
++ * @gadget:the device being configured for remote wakeup
++ * @set:value to be configured.
++ *
++ * set to one to enable remote wakeup feature and zero to disable it.
++ *
++ * returns zero on success, else negative errno.
++ */
++int usb_gadget_set_remote_wakeup(struct usb_gadget *gadget, int set)
++{
++      int ret = 0;
++
++      if (!gadget->ops->set_remote_wakeup) {
++              ret = -EOPNOTSUPP;
++              goto out;
++      }
++
++      ret = gadget->ops->set_remote_wakeup(gadget, set);
++
++out:
++      trace_usb_gadget_set_remote_wakeup(gadget, ret);
++
++      return ret;
++}
++EXPORT_SYMBOL_GPL(usb_gadget_set_remote_wakeup);
++
+ /**
+  * usb_gadget_set_selfpowered - sets the device selfpowered feature.
+  * @gadget:the device being declared as self-powered
+diff --git a/drivers/usb/gadget/udc/trace.h b/drivers/usb/gadget/udc/trace.h
+index 98584f6b6c662..428819311afbf 100644
+--- a/drivers/usb/gadget/udc/trace.h
++++ b/drivers/usb/gadget/udc/trace.h
+@@ -91,6 +91,11 @@ DEFINE_EVENT(udc_log_gadget, usb_gadget_wakeup,
+       TP_ARGS(g, ret)
+ );
++DEFINE_EVENT(udc_log_gadget, usb_gadget_set_remote_wakeup,
++      TP_PROTO(struct usb_gadget *g, int ret),
++      TP_ARGS(g, ret)
++);
++
+ DEFINE_EVENT(udc_log_gadget, usb_gadget_set_selfpowered,
+       TP_PROTO(struct usb_gadget *g, int ret),
+       TP_ARGS(g, ret)
+diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
+index 9d27622792867..0399d1226323b 100644
+--- a/include/linux/usb/composite.h
++++ b/include/linux/usb/composite.h
+@@ -426,6 +426,8 @@ extern int composite_dev_prepare(struct usb_composite_driver *composite,
+ extern int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
+                                        struct usb_ep *ep0);
+ void composite_dev_cleanup(struct usb_composite_dev *cdev);
++void check_remote_wakeup_config(struct usb_gadget *g,
++                              struct usb_configuration *c);
+ static inline struct usb_composite_driver *to_cdriver(
+               struct usb_gadget_driver *gdrv)
+diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
+index 10fe57cf40bec..c5bc739266ed6 100644
+--- a/include/linux/usb/gadget.h
++++ b/include/linux/usb/gadget.h
+@@ -311,6 +311,7 @@ struct usb_udc;
+ struct usb_gadget_ops {
+       int     (*get_frame)(struct usb_gadget *);
+       int     (*wakeup)(struct usb_gadget *);
++      int     (*set_remote_wakeup)(struct usb_gadget *, int set);
+       int     (*set_selfpowered) (struct usb_gadget *, int is_selfpowered);
+       int     (*vbus_session) (struct usb_gadget *, int is_active);
+       int     (*vbus_draw) (struct usb_gadget *, unsigned mA);
+@@ -385,6 +386,8 @@ struct usb_gadget_ops {
+  * @connected: True if gadget is connected.
+  * @lpm_capable: If the gadget max_speed is FULL or HIGH, this flag
+  *    indicates that it supports LPM as per the LPM ECN & errata.
++ * @wakeup_capable: True if gadget is capable of sending remote wakeup.
++ * @wakeup_armed: True if gadget is armed by the host for remote wakeup.
+  * @irq: the interrupt number for device controller.
+  *
+  * Gadgets have a mostly-portable "gadget driver" implementing device
+@@ -445,6 +448,8 @@ struct usb_gadget {
+       unsigned                        deactivated:1;
+       unsigned                        connected:1;
+       unsigned                        lpm_capable:1;
++      unsigned                        wakeup_capable:1;
++      unsigned                        wakeup_armed:1;
+       int                             irq;
+ };
+ #define work_to_gadget(w)     (container_of((w), struct usb_gadget, work))
+@@ -600,6 +605,7 @@ static inline int gadget_is_otg(struct usb_gadget *g)
+ #if IS_ENABLED(CONFIG_USB_GADGET)
+ int usb_gadget_frame_number(struct usb_gadget *gadget);
+ int usb_gadget_wakeup(struct usb_gadget *gadget);
++int usb_gadget_set_remote_wakeup(struct usb_gadget *gadget, int set);
+ int usb_gadget_set_selfpowered(struct usb_gadget *gadget);
+ int usb_gadget_clear_selfpowered(struct usb_gadget *gadget);
+ int usb_gadget_vbus_connect(struct usb_gadget *gadget);
+@@ -615,6 +621,8 @@ static inline int usb_gadget_frame_number(struct usb_gadget *gadget)
+ { return 0; }
+ static inline int usb_gadget_wakeup(struct usb_gadget *gadget)
+ { return 0; }
++static inline int usb_gadget_set_remote_wakeup(struct usb_gadget *gadget, int set)
++{ return 0; }
+ static inline int usb_gadget_set_selfpowered(struct usb_gadget *gadget)
+ { return 0; }
+ static inline int usb_gadget_clear_selfpowered(struct usb_gadget *gadget)
+-- 
+2.39.2
+