From: Sasha Levin Date: Thu, 25 May 2023 14:38:19 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: review~95 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2da3ec026cac4fb0b19f789a87d321519339a758;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- 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 index 00000000000..edcf0568567 --- /dev/null +++ b/queue-5.15/dt-bindings-ata-ahci-ceva-convert-to-yaml.patch @@ -0,0 +1,290 @@ +From bbb5ed6b8bd6a4ee266a1a72a487f158f5dcb5c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Jun 2022 13:07:17 +0530 +Subject: dt-bindings: ata: ahci-ceva: convert to yaml + +From: Piyush Mehta + +[ Upstream commit f2fb1b50fbac4a0a462e1705ac913abf52aae906 ] + +Convert the ahci-ceva doc to yaml. + +Signed-off-by: Piyush Mehta +Signed-off-by: Rob Herring +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 +--- + .../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 ; +- 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: 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: 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: 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 ++ ++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 ; ++ 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 ; ++ 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 ; ++ 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 ; ++ 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 ; ++ 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 ; ++ 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 ; ++ 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 ; ++ 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 ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ 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 index 00000000000..92329f21255 --- /dev/null +++ b/queue-5.15/dt-bindings-ata-ahci-ceva-cover-all-4-iommus-entries.patch @@ -0,0 +1,45 @@ +From d3f9cd11735ebbd6556d0e0cb3b4da0f65441db4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 13:52:04 +0200 +Subject: dt-bindings: ata: ahci-ceva: Cover all 4 iommus entries + +From: Michal Simek + +[ 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 +Acked-by: Krzysztof Kozlowski +Signed-off-by: Damien Le Moal +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..a261eb5f87a --- /dev/null +++ b/queue-5.15/series @@ -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 index 00000000000..74af1a021c7 --- /dev/null +++ b/queue-5.15/usb-dwc3-fix-gadget-mode-suspend-interrupt-handler-i.patch @@ -0,0 +1,98 @@ +From 7335e0994a28b1167e2549fc5c0331d6bdf31df1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 08:45:24 +0800 +Subject: usb: dwc3: fix gadget mode suspend interrupt handler issue + +From: Linyu Yuan + +[ 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 +Acked-by: Thinh Nguyen +Signed-off-by: Linyu Yuan +Link: https://lore.kernel.org/r/20230512004524.31950-1-quic_linyyuan@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..7747be91da3 --- /dev/null +++ b/queue-5.15/usb-gadget-properly-configure-the-device-for-remote-.patch @@ -0,0 +1,197 @@ +From 4c817c2ac990824486d13dc59567f6cc93336742 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Mar 2023 14:47:57 -0700 +Subject: usb: gadget: Properly configure the device for remote wakeup + +From: Elson Roy Serrao + +[ 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 +Signed-off-by: Elson Roy Serrao +Link: https://lore.kernel.org/r/1679694482-16430-2-git-send-email-quic_eserrao@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 4e8ef34e36f2 ("usb: dwc3: fix gadget mode suspend interrupt handler issue") +Signed-off-by: Sasha Levin +--- + 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 +