From 50d4d433d4b9c6916f1c96df84fc279643c55f10 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Nov 2025 10:38:09 +0900 Subject: [PATCH] 5.15-stable patches added patches: arch-back-to-std-gnu89-in-v5.18.patch can-gs_usb-increase-max-interface-to-u8_max.patch dt-bindings-usb-dwc3-imx8mp-dma-range-is-required-only-for-imx8mp.patch mptcp-drop-bogus-optimization-in-__mptcp_check_push.patch net-phy-dp83867-disable-eee-support-as-not-implemented.patch net-ravb-enforce-descriptor-type-ordering.patch ravb-exclude-gptp-feature-support-for-rz-g2l.patch revert-docs-process-howto-replace-c89-with-c11.patch serial-8250_dw-handle-reset-control-deassert-error.patch serial-8250_dw-use-devm_add_action_or_reset.patch x86-boot-compile-boot-code-with-std-gnu11-too.patch x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch xhci-dbc-allow-users-to-modify-dbc-poll-interval-via-sysfs.patch xhci-dbc-avoid-event-polling-busyloop-if-pending-rx-transfers-are-inactive.patch xhci-dbc-fix-bogus-1024-byte-prefix-if-ttydbc-read-races-with-stall-event.patch xhci-dbc-improve-performance-by-removing-delay-in-transfer-event-polling.patch xhci-dbc-poll-at-different-rate-depending-on-data-transfer-activity.patch xhci-dbc-provide-sysfs-option-to-configure-dbc-descriptors.patch --- .../arch-back-to-std-gnu89-in-v5.18.patch | 111 ++++++ ...usb-increase-max-interface-to-u8_max.patch | 117 ++++++ ...ma-range-is-required-only-for-imx8mp.patch | 52 +++ ...s-optimization-in-__mptcp_check_push.patch | 109 ++++++ ...sable-eee-support-as-not-implemented.patch | 55 +++ ...avb-enforce-descriptor-type-ordering.patch | 74 ++++ ...lude-gptp-feature-support-for-rz-g2l.patch | 177 +++++++++ ...s-process-howto-replace-c89-with-c11.patch | 105 ++++++ ...-handle-reset-control-deassert-error.patch | 47 +++ ...8250_dw-use-devm_add_action_or_reset.patch | 143 ++++++++ queue-5.15/series | 18 + ...compile-boot-code-with-std-gnu11-too.patch | 66 ++++ ...tivating-previously-unavailable-rmid.patch | 139 +++++++ ...o-modify-dbc-poll-interval-via-sysfs.patch | 131 +++++++ ...if-pending-rx-transfers-are-inactive.patch | 123 +++++++ ...f-ttydbc-read-races-with-stall-event.patch | 74 ++++ ...ving-delay-in-transfer-event-polling.patch | 44 +++ ...-depending-on-data-transfer-activity.patch | 101 ++++++ ...-option-to-configure-dbc-descriptors.patch | 339 ++++++++++++++++++ 19 files changed, 2025 insertions(+) create mode 100644 queue-5.15/arch-back-to-std-gnu89-in-v5.18.patch create mode 100644 queue-5.15/can-gs_usb-increase-max-interface-to-u8_max.patch create mode 100644 queue-5.15/dt-bindings-usb-dwc3-imx8mp-dma-range-is-required-only-for-imx8mp.patch create mode 100644 queue-5.15/mptcp-drop-bogus-optimization-in-__mptcp_check_push.patch create mode 100644 queue-5.15/net-phy-dp83867-disable-eee-support-as-not-implemented.patch create mode 100644 queue-5.15/net-ravb-enforce-descriptor-type-ordering.patch create mode 100644 queue-5.15/ravb-exclude-gptp-feature-support-for-rz-g2l.patch create mode 100644 queue-5.15/revert-docs-process-howto-replace-c89-with-c11.patch create mode 100644 queue-5.15/serial-8250_dw-handle-reset-control-deassert-error.patch create mode 100644 queue-5.15/serial-8250_dw-use-devm_add_action_or_reset.patch create mode 100644 queue-5.15/x86-boot-compile-boot-code-with-std-gnu11-too.patch create mode 100644 queue-5.15/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch create mode 100644 queue-5.15/xhci-dbc-allow-users-to-modify-dbc-poll-interval-via-sysfs.patch create mode 100644 queue-5.15/xhci-dbc-avoid-event-polling-busyloop-if-pending-rx-transfers-are-inactive.patch create mode 100644 queue-5.15/xhci-dbc-fix-bogus-1024-byte-prefix-if-ttydbc-read-races-with-stall-event.patch create mode 100644 queue-5.15/xhci-dbc-improve-performance-by-removing-delay-in-transfer-event-polling.patch create mode 100644 queue-5.15/xhci-dbc-poll-at-different-rate-depending-on-data-transfer-activity.patch create mode 100644 queue-5.15/xhci-dbc-provide-sysfs-option-to-configure-dbc-descriptors.patch diff --git a/queue-5.15/arch-back-to-std-gnu89-in-v5.18.patch b/queue-5.15/arch-back-to-std-gnu89-in-v5.18.patch new file mode 100644 index 0000000000..f9c8c1d119 --- /dev/null +++ b/queue-5.15/arch-back-to-std-gnu89-in-v5.18.patch @@ -0,0 +1,111 @@ +From matttbe@kernel.org Sat Oct 18 01:24:25 2025 +From: "Matthieu Baerts (NGI0)" +Date: Fri, 17 Oct 2025 18:24:01 +0200 +Subject: arch: back to -std=gnu89 in < v5.18 +To: stable@vger.kernel.org, Greg Kroah-Hartman , Sasha Levin +Cc: MPTCP Upstream , "Matthieu Baerts (NGI0)" , Nathan Chancellor , Ard Biesheuvel , Alexey Dobriyan , Arnd Bergmann +Message-ID: <20251017-v5-15-gcc-15-v1-2-da6c065049d7@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +Recent fixes have been backported to < v5.18 to fix build issues with +GCC 5.15. They all force -std=gnu11 in the CFLAGS, "because [the kernel] +requests the gnu11 standard via '-std=' in the main Makefile". + +This is true for >= 5.18 versions, but not before. This switch to +-std=gnu11 has been done in commit e8c07082a810 ("Kbuild: move to +-std=gnu11"). + +For a question of uniformity, force -std=gnu89, similar to what is done +in the main Makefile. + +Note: the fixes tags below refers to upstream commits, but this fix is +only for kernels not having commit e8c07082a810 ("Kbuild: move to +-std=gnu11"). + +Fixes: 7cbb015e2d3d ("parisc: fix building with gcc-15") +Fixes: 3b8b80e99376 ("s390: Add '-std=gnu11' to decompressor and purgatory CFLAGS") +Fixes: b3bee1e7c3f2 ("x86/boot: Compile boot code with -std=gnu11 too") +Fixes: ee2ab467bddf ("x86/boot: Use '-std=gnu11' to fix build with GCC 15") +Fixes: 8ba14d9f490a ("efi: libstub: Use '-std=gnu11' to fix build with GCC 15") +Signed-off-by: Matthieu Baerts (NGI0) +Cc: Nathan Chancellor +Cc: Ard Biesheuvel +Cc: Alexey Dobriyan +Cc: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman +--- + arch/parisc/boot/compressed/Makefile | 2 +- + arch/s390/Makefile | 2 +- + arch/s390/purgatory/Makefile | 2 +- + arch/x86/Makefile | 2 +- + arch/x86/boot/compressed/Makefile | 2 +- + drivers/firmware/efi/libstub/Makefile | 2 +- + 6 files changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/parisc/boot/compressed/Makefile ++++ b/arch/parisc/boot/compressed/Makefile +@@ -22,7 +22,7 @@ KBUILD_CFLAGS += -fno-PIE -mno-space-reg + ifndef CONFIG_64BIT + KBUILD_CFLAGS += -mfast-indirect-calls + endif +-KBUILD_CFLAGS += -std=gnu11 ++KBUILD_CFLAGS += -std=gnu89 + + OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o + +--- a/arch/s390/Makefile ++++ b/arch/s390/Makefile +@@ -23,7 +23,7 @@ endif + aflags_dwarf := -Wa,-gdwarf-2 + KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__ + KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf)) +-KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -std=gnu11 ++KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -std=gnu89 + KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY + KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float -mbackchain + KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables +--- a/arch/s390/purgatory/Makefile ++++ b/arch/s390/purgatory/Makefile +@@ -21,7 +21,7 @@ UBSAN_SANITIZE := n + KASAN_SANITIZE := n + KCSAN_SANITIZE := n + +-KBUILD_CFLAGS := -std=gnu11 -fno-strict-aliasing -Wall -Wstrict-prototypes ++KBUILD_CFLAGS := -std=gnu89 -fno-strict-aliasing -Wall -Wstrict-prototypes + KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare + KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding + KBUILD_CFLAGS += -c -MD -Os -m64 -msoft-float -fno-common +--- a/arch/x86/Makefile ++++ b/arch/x86/Makefile +@@ -24,7 +24,7 @@ endif + + # How to compile the 16-bit code. Note we always compile for -march=i386; + # that way we can complain to the user if the CPU is insufficient. +-REALMODE_CFLAGS := -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ ++REALMODE_CFLAGS := -std=gnu89 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ + -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ + -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ + -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none) +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -33,7 +33,7 @@ targets := vmlinux vmlinux.bin vmlinux.b + # avoid errors with '-march=i386', and future flags may depend on the target to + # be valid. + KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) +-KBUILD_CFLAGS += -std=gnu11 ++KBUILD_CFLAGS += -std=gnu89 + KBUILD_CFLAGS += -fno-strict-aliasing -fPIE + KBUILD_CFLAGS += -Wundef + KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +--- a/drivers/firmware/efi/libstub/Makefile ++++ b/drivers/firmware/efi/libstub/Makefile +@@ -7,7 +7,7 @@ + # + cflags-$(CONFIG_X86_32) := -march=i386 + cflags-$(CONFIG_X86_64) := -mcmodel=small +-cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu11 \ ++cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -std=gnu89 \ + -fPIC -fno-strict-aliasing -mno-red-zone \ + -mno-mmx -mno-sse -fshort-wchar \ + -Wno-pointer-sign \ diff --git a/queue-5.15/can-gs_usb-increase-max-interface-to-u8_max.patch b/queue-5.15/can-gs_usb-increase-max-interface-to-u8_max.patch new file mode 100644 index 0000000000..37899c6bd0 --- /dev/null +++ b/queue-5.15/can-gs_usb-increase-max-interface-to-u8_max.patch @@ -0,0 +1,117 @@ +From stable+bounces-189968-greg=kroah.com@vger.kernel.org Mon Oct 27 21:53:33 2025 +From: Celeste Liu +Date: Mon, 27 Oct 2025 20:47:27 +0800 +Subject: can: gs_usb: increase max interface to U8_MAX +To: stable@vger.kernel.org +Cc: Celeste Liu , Runcheng Lu , Vincent Mailhol , Marc Kleine-Budde +Message-ID: <20251027124726.734092-2-uwu@coelacanthus.name> + +From: Celeste Liu + +commit 2a27f6a8fb5722223d526843040f747e9b0e8060 upstream + +This issue was found by Runcheng Lu when develop HSCanT USB to CAN FD +converter[1]. The original developers may have only 3 interfaces +device to test so they write 3 here and wait for future change. + +During the HSCanT development, we actually used 4 interfaces, so the +limitation of 3 is not enough now. But just increase one is not +future-proofed. Since the channel index type in gs_host_frame is u8, +just make canch[] become a flexible array with a u8 index, so it +naturally constraint by U8_MAX and avoid statically allocate 256 +pointer for every gs_usb device. + +[1]: https://github.com/cherry-embedded/HSCanT-hardware + +Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") +Reported-by: Runcheng Lu +Cc: stable@vger.kernel.org +Reviewed-by: Vincent Mailhol +Signed-off-by: Celeste Liu +Link: https://patch.msgid.link/20250930-gs-usb-max-if-v5-1-863330bf6666@coelacanthus.name +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/gs_usb.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -157,10 +157,6 @@ struct gs_host_frame { + #define GS_MAX_TX_URBS 10 + /* Only launch a max of GS_MAX_RX_URBS usb requests at a time. */ + #define GS_MAX_RX_URBS 30 +-/* Maximum number of interfaces the driver supports per device. +- * Current hardware only supports 2 interfaces. The future may vary. +- */ +-#define GS_MAX_INTF 2 + + struct gs_tx_context { + struct gs_can *dev; +@@ -191,10 +187,11 @@ struct gs_can { + + /* usb interface struct */ + struct gs_usb { +- struct gs_can *canch[GS_MAX_INTF]; + struct usb_anchor rx_submitted; + struct usb_device *udev; + u8 active_channels; ++ u8 channel_cnt; ++ struct gs_can *canch[]; + }; + + /* 'allocate' a tx context. +@@ -322,7 +319,7 @@ static void gs_usb_receive_bulk_callback + } + + /* device reports out of range channel id */ +- if (hf->channel >= GS_MAX_INTF) ++ if (hf->channel >= usbcan->channel_cnt) + goto device_detach; + + dev = usbcan->canch[hf->channel]; +@@ -410,7 +407,7 @@ static void gs_usb_receive_bulk_callback + /* USB failure take down all interfaces */ + if (rc == -ENODEV) { + device_detach: +- for (rc = 0; rc < GS_MAX_INTF; rc++) { ++ for (rc = 0; rc < usbcan->channel_cnt; rc++) { + if (usbcan->canch[rc]) + netif_device_detach(usbcan->canch[rc]->netdev); + } +@@ -993,20 +990,22 @@ static int gs_usb_probe(struct usb_inter + icount = dconf->icount + 1; + dev_info(&intf->dev, "Configuring for %d interfaces\n", icount); + +- if (icount > GS_MAX_INTF) { ++ if (icount > type_max(typeof(dev->channel_cnt))) { + dev_err(&intf->dev, +- "Driver cannot handle more that %d CAN interfaces\n", +- GS_MAX_INTF); ++ "Driver cannot handle more that %u CAN interfaces\n", ++ type_max(typeof(dev->channel_cnt))); + kfree(dconf); + return -EINVAL; + } + +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ dev = kzalloc(struct_size(dev, canch, icount), GFP_KERNEL); + if (!dev) { + kfree(dconf); + return -ENOMEM; + } + ++ dev->channel_cnt = icount; ++ + init_usb_anchor(&dev->rx_submitted); + + usb_set_intfdata(intf, dev); +@@ -1047,7 +1046,7 @@ static void gs_usb_disconnect(struct usb + return; + } + +- for (i = 0; i < GS_MAX_INTF; i++) ++ for (i = 0; i < dev->channel_cnt; i++) + if (dev->canch[i]) + gs_destroy_candev(dev->canch[i]); + diff --git a/queue-5.15/dt-bindings-usb-dwc3-imx8mp-dma-range-is-required-only-for-imx8mp.patch b/queue-5.15/dt-bindings-usb-dwc3-imx8mp-dma-range-is-required-only-for-imx8mp.patch new file mode 100644 index 0000000000..21f2e80bb5 --- /dev/null +++ b/queue-5.15/dt-bindings-usb-dwc3-imx8mp-dma-range-is-required-only-for-imx8mp.patch @@ -0,0 +1,52 @@ +From stable+bounces-190037-greg=kroah.com@vger.kernel.org Tue Oct 28 01:29:09 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 12:28:58 -0400 +Subject: dt-bindings: usb: dwc3-imx8mp: dma-range is required only for imx8mp +To: stable@vger.kernel.org +Cc: Xu Yang , stable , Jun Li , Frank Li , Conor Dooley , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027162858.577729-1-sashal@kernel.org> + +From: Xu Yang + +[ Upstream commit 268eb6fb908bc82ce479e4dba9a2cad11f536c9c ] + +Only i.MX8MP need dma-range property to let USB controller work properly. +Remove dma-range from required list and add limitation for imx8mp. + +Fixes: d2a704e29711 ("dt-bindings: usb: dwc3-imx8mp: add imx8mp dwc3 glue bindings") +Cc: stable +Reviewed-by: Jun Li +Signed-off-by: Xu Yang +Reviewed-by: Frank Li +Acked-by: Conor Dooley +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml ++++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml +@@ -60,12 +60,20 @@ required: + - reg + - "#address-cells" + - "#size-cells" +- - dma-ranges + - ranges + - clocks + - clock-names + - interrupts + ++allOf: ++ - if: ++ properties: ++ compatible: ++ const: fsl,imx8mp-dwc3 ++ then: ++ required: ++ - dma-ranges ++ + additionalProperties: false + + examples: diff --git a/queue-5.15/mptcp-drop-bogus-optimization-in-__mptcp_check_push.patch b/queue-5.15/mptcp-drop-bogus-optimization-in-__mptcp_check_push.patch new file mode 100644 index 0000000000..8fb91889dc --- /dev/null +++ b/queue-5.15/mptcp-drop-bogus-optimization-in-__mptcp_check_push.patch @@ -0,0 +1,109 @@ +From stable+bounces-192087-greg=kroah.com@vger.kernel.org Mon Nov 3 05:15:58 2025 +From: Sasha Levin +Date: Sun, 2 Nov 2025 15:15:50 -0500 +Subject: mptcp: drop bogus optimization in __mptcp_check_push() +To: stable@vger.kernel.org +Cc: Paolo Abeni , Geliang Tang , Mat Martineau , "Matthieu Baerts (NGI0)" , Jakub Kicinski , Sasha Levin +Message-ID: <20251102201550.3588174-1-sashal@kernel.org> + +From: Paolo Abeni + +[ Upstream commit 27b0e701d3872ba59c5b579a9e8a02ea49ad3d3b ] + +Accessing the transmit queue without owning the msk socket lock is +inherently racy, hence __mptcp_check_push() could actually quit early +even when there is pending data. + +That in turn could cause unexpected tx lock and timeout. + +Dropping the early check avoids the race, implicitly relaying on later +tests under the relevant lock. With such change, all the other +mptcp_send_head() call sites are now under the msk socket lock and we +can additionally drop the now unneeded annotation on the transmit head +pointer accesses. + +Fixes: 6e628cd3a8f7 ("mptcp: use mptcp release_cb for delayed tasks") +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Abeni +Reviewed-by: Geliang Tang +Tested-by: Geliang Tang +Reviewed-by: Mat Martineau +Signed-off-by: Matthieu Baerts (NGI0) +Link: https://patch.msgid.link/20251028-net-mptcp-send-timeout-v1-1-38ffff5a9ec8@kernel.org +Signed-off-by: Jakub Kicinski +[ split upstream __subflow_push_pending modification across __mptcp_push_pending and __mptcp_subflow_push_pending ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/mptcp/protocol.c | 13 +++++-------- + net/mptcp/protocol.h | 2 +- + 2 files changed, 6 insertions(+), 9 deletions(-) + +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -1137,7 +1137,7 @@ static void __mptcp_clean_una(struct soc + if (WARN_ON_ONCE(!msk->recovery)) + break; + +- WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); ++ msk->first_pending = mptcp_send_next(sk); + } + + dfrag_clear(sk, dfrag); +@@ -1674,7 +1674,7 @@ void __mptcp_push_pending(struct sock *s + + mptcp_update_post_push(msk, dfrag, ret); + } +- WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); ++ msk->first_pending = mptcp_send_next(sk); + } + + /* at this point we held the socket lock for the last subflow we used */ +@@ -1732,7 +1732,7 @@ static void __mptcp_subflow_push_pending + + mptcp_update_post_push(msk, dfrag, ret); + } +- WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); ++ msk->first_pending = mptcp_send_next(sk); + } + + out: +@@ -1850,7 +1850,7 @@ static int mptcp_sendmsg(struct sock *sk + get_page(dfrag->page); + list_add_tail(&dfrag->list, &msk->rtx_queue); + if (!msk->first_pending) +- WRITE_ONCE(msk->first_pending, dfrag); ++ msk->first_pending = dfrag; + } + pr_debug("msk=%p dfrag at seq=%llu len=%u sent=%u new=%d\n", msk, + dfrag->data_seq, dfrag->data_len, dfrag->already_sent, +@@ -2645,7 +2645,7 @@ static void __mptcp_clear_xmit(struct so + struct mptcp_sock *msk = mptcp_sk(sk); + struct mptcp_data_frag *dtmp, *dfrag; + +- WRITE_ONCE(msk->first_pending, NULL); ++ msk->first_pending = NULL; + list_for_each_entry_safe(dfrag, dtmp, &msk->rtx_queue, list) + dfrag_clear(sk, dfrag); + } +@@ -3114,9 +3114,6 @@ void __mptcp_data_acked(struct sock *sk) + + void __mptcp_check_push(struct sock *sk, struct sock *ssk) + { +- if (!mptcp_send_head(sk)) +- return; +- + if (!sock_owned_by_user(sk)) { + struct sock *xmit_ssk = mptcp_subflow_get_send(mptcp_sk(sk)); + +--- a/net/mptcp/protocol.h ++++ b/net/mptcp/protocol.h +@@ -325,7 +325,7 @@ static inline struct mptcp_data_frag *mp + { + const struct mptcp_sock *msk = mptcp_sk(sk); + +- return READ_ONCE(msk->first_pending); ++ return msk->first_pending; + } + + static inline struct mptcp_data_frag *mptcp_send_next(struct sock *sk) diff --git a/queue-5.15/net-phy-dp83867-disable-eee-support-as-not-implemented.patch b/queue-5.15/net-phy-dp83867-disable-eee-support-as-not-implemented.patch new file mode 100644 index 0000000000..ec86c1188e --- /dev/null +++ b/queue-5.15/net-phy-dp83867-disable-eee-support-as-not-implemented.patch @@ -0,0 +1,55 @@ +From stable+bounces-192088-greg=kroah.com@vger.kernel.org Mon Nov 3 05:30:47 2025 +From: Sasha Levin +Date: Sun, 2 Nov 2025 15:30:39 -0500 +Subject: net: phy: dp83867: Disable EEE support as not implemented +To: stable@vger.kernel.org +Cc: Emanuele Ghidoli , Andrew Lunn , Jakub Kicinski , Sasha Levin +Message-ID: <20251102203040.3593522-1-sashal@kernel.org> + +From: Emanuele Ghidoli + +[ Upstream commit 84a905290cb4c3d9a71a9e3b2f2e02e031e7512f ] + +While the DP83867 PHYs report EEE capability through their feature +registers, the actual hardware does not support EEE (see Links). +When the connected MAC enables EEE, it causes link instability and +communication failures. + +The issue is reproducible with a iMX8MP and relevant stmmac ethernet port. +Since the introduction of phylink-managed EEE support in the stmmac driver, +EEE is now enabled by default, leading to issues on systems using the +DP83867 PHY. + +Call phy_disable_eee during phy initialization to prevent EEE from being +enabled on DP83867 PHYs. + +Link: https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1445244/dp83867ir-dp83867-disable-eee-lpi +Link: https://e2e.ti.com/support/interface-group/interface/f/interface-forum/658638/dp83867ir-eee-energy-efficient-ethernet +Fixes: 2a10154abcb7 ("net: phy: dp83867: Add TI dp83867 phy") +Cc: stable@vger.kernel.org +Signed-off-by: Emanuele Ghidoli +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251023144857.529566-1-ghidoliemanuele@gmail.com +Signed-off-by: Jakub Kicinski +[ replaced phy_disable_eee() call with direct eee_broken_modes assignment ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/dp83867.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/phy/dp83867.c ++++ b/drivers/net/phy/dp83867.c +@@ -674,6 +674,12 @@ static int dp83867_config_init(struct ph + return ret; + } + ++ /* Although the DP83867 reports EEE capability through the ++ * MDIO_PCS_EEE_ABLE and MDIO_AN_EEE_ADV registers, the feature ++ * is not actually implemented in hardware. ++ */ ++ phydev->eee_broken_modes = MDIO_EEE_100TX | MDIO_EEE_1000T; ++ + if (phy_interface_is_rgmii(phydev) || + phydev->interface == PHY_INTERFACE_MODE_SGMII) { + val = phy_read(phydev, MII_DP83867_PHYCTRL); diff --git a/queue-5.15/net-ravb-enforce-descriptor-type-ordering.patch b/queue-5.15/net-ravb-enforce-descriptor-type-ordering.patch new file mode 100644 index 0000000000..36ab06b6f2 --- /dev/null +++ b/queue-5.15/net-ravb-enforce-descriptor-type-ordering.patch @@ -0,0 +1,74 @@ +From stable+bounces-189988-greg=kroah.com@vger.kernel.org Mon Oct 27 22:57:20 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 09:49:31 -0400 +Subject: net: ravb: Enforce descriptor type ordering +To: stable@vger.kernel.org +Cc: "Lad Prabhakar" , "Fabrizio Castro" , "Niklas Söderlund" , "Jakub Kicinski" , "Sasha Levin" +Message-ID: <20251027134931.492032-2-sashal@kernel.org> + +From: Lad Prabhakar + +[ Upstream commit 5370c31e84b0e0999c7b5ff949f4e104def35584 ] + +Ensure the TX descriptor type fields are published in a safe order so the +DMA engine never begins processing a descriptor chain before all descriptor +fields are fully initialised. + +For multi-descriptor transmits the driver writes DT_FEND into the last +descriptor and DT_FSTART into the first. The DMA engine begins processing +when it observes DT_FSTART. Move the dma_wmb() barrier so it executes +immediately after DT_FEND and immediately before writing DT_FSTART +(and before DT_FSINGLE in the single-descriptor case). This guarantees +that all prior CPU writes to the descriptor memory are visible to the +device before DT_FSTART is seen. + +This avoids a situation where compiler/CPU reordering could publish +DT_FSTART ahead of DT_FEND or other descriptor fields, allowing the DMA to +start on a partially initialised chain and causing corrupted transmissions +or TX timeouts. Such a failure was observed on RZ/G2L with an RT kernel as +transmit queue timeouts and device resets. + +Fixes: 2f45d1902acf ("ravb: minimize TX data copying") +Cc: stable@vger.kernel.org +Co-developed-by: Fabrizio Castro +Signed-off-by: Fabrizio Castro +Signed-off-by: Lad Prabhakar +Reviewed-by: Niklas Söderlund +Link: https://patch.msgid.link/20251017151830.171062-4-prabhakar.mahadev-lad.rj@bp.renesas.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/renesas/ravb_main.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -1668,13 +1668,25 @@ static netdev_tx_t ravb_start_xmit(struc + + skb_tx_timestamp(skb); + } +- /* Descriptor type must be set after all the above writes */ +- dma_wmb(); ++ + if (num_tx_desc > 1) { + desc->die_dt = DT_FEND; + desc--; ++ /* When using multi-descriptors, DT_FEND needs to get written ++ * before DT_FSTART, but the compiler may reorder the memory ++ * writes in an attempt to optimize the code. ++ * Use a dma_wmb() barrier to make sure DT_FEND and DT_FSTART ++ * are written exactly in the order shown in the code. ++ * This is particularly important for cases where the DMA engine ++ * is already running when we are running this code. If the DMA ++ * sees DT_FSTART without the corresponding DT_FEND it will enter ++ * an error condition. ++ */ ++ dma_wmb(); + desc->die_dt = DT_FSTART; + } else { ++ /* Descriptor type must be set after all the above writes */ ++ dma_wmb(); + desc->die_dt = DT_FSINGLE; + } + diff --git a/queue-5.15/ravb-exclude-gptp-feature-support-for-rz-g2l.patch b/queue-5.15/ravb-exclude-gptp-feature-support-for-rz-g2l.patch new file mode 100644 index 0000000000..bc0547ae2b --- /dev/null +++ b/queue-5.15/ravb-exclude-gptp-feature-support-for-rz-g2l.patch @@ -0,0 +1,177 @@ +From stable+bounces-189987-greg=kroah.com@vger.kernel.org Mon Oct 27 22:52:03 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 09:49:30 -0400 +Subject: ravb: Exclude gPTP feature support for RZ/G2L +To: stable@vger.kernel.org +Cc: Biju Das , Lad Prabhakar , "David S. Miller" , Sasha Levin +Message-ID: <20251027134931.492032-1-sashal@kernel.org> + +From: Biju Das + +[ Upstream commit 7e09a052dc4e30ce07fd7b3aa58a7d993f73a9d7 ] + +R-Car supports gPTP feature whereas RZ/G2L does not support it. +This patch excludes gtp feature support for RZ/G2L. + +Signed-off-by: Biju Das +Reviewed-by: Lad Prabhakar +Signed-off-by: David S. Miller +Stable-dep-of: 5370c31e84b0 ("net: ravb: Enforce descriptor type ordering") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/renesas/ravb_main.c | 87 +++++++++++++++++-------------- + 1 file changed, 50 insertions(+), 37 deletions(-) + +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -1321,6 +1321,7 @@ static int ravb_get_ts_info(struct net_d + struct ethtool_ts_info *info) + { + struct ravb_private *priv = netdev_priv(ndev); ++ const struct ravb_hw_info *hw_info = priv->info; + + info->so_timestamping = + SOF_TIMESTAMPING_TX_SOFTWARE | +@@ -1334,7 +1335,8 @@ static int ravb_get_ts_info(struct net_d + (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | + (1 << HWTSTAMP_FILTER_ALL); +- info->phc_index = ptp_clock_index(priv->ptp.clock); ++ if (hw_info->gptp || hw_info->ccc_gac) ++ info->phc_index = ptp_clock_index(priv->ptp.clock); + + return 0; + } +@@ -1565,6 +1567,7 @@ out_unlock: + static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) + { + struct ravb_private *priv = netdev_priv(ndev); ++ const struct ravb_hw_info *info = priv->info; + unsigned int num_tx_desc = priv->num_tx_desc; + u16 q = skb_get_queue_mapping(skb); + struct ravb_tstamp_skb *ts_skb; +@@ -1641,28 +1644,30 @@ static netdev_tx_t ravb_start_xmit(struc + desc->dptr = cpu_to_le32(dma_addr); + + /* TX timestamp required */ +- if (q == RAVB_NC) { +- ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC); +- if (!ts_skb) { +- if (num_tx_desc > 1) { +- desc--; +- dma_unmap_single(ndev->dev.parent, dma_addr, +- len, DMA_TO_DEVICE); ++ if (info->gptp || info->ccc_gac) { ++ if (q == RAVB_NC) { ++ ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC); ++ if (!ts_skb) { ++ if (num_tx_desc > 1) { ++ desc--; ++ dma_unmap_single(ndev->dev.parent, dma_addr, ++ len, DMA_TO_DEVICE); ++ } ++ goto unmap; + } +- goto unmap; ++ ts_skb->skb = skb_get(skb); ++ ts_skb->tag = priv->ts_skb_tag++; ++ priv->ts_skb_tag &= 0x3ff; ++ list_add_tail(&ts_skb->list, &priv->ts_skb_list); ++ ++ /* TAG and timestamp required flag */ ++ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; ++ desc->tagh_tsr = (ts_skb->tag >> 4) | TX_TSR; ++ desc->ds_tagl |= cpu_to_le16(ts_skb->tag << 12); + } +- ts_skb->skb = skb_get(skb); +- ts_skb->tag = priv->ts_skb_tag++; +- priv->ts_skb_tag &= 0x3ff; +- list_add_tail(&ts_skb->list, &priv->ts_skb_list); +- +- /* TAG and timestamp required flag */ +- skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; +- desc->tagh_tsr = (ts_skb->tag >> 4) | TX_TSR; +- desc->ds_tagl |= cpu_to_le16(ts_skb->tag << 12); +- } + +- skb_tx_timestamp(skb); ++ skb_tx_timestamp(skb); ++ } + /* Descriptor type must be set after all the above writes */ + dma_wmb(); + if (num_tx_desc > 1) { +@@ -1781,10 +1786,12 @@ static int ravb_close(struct net_device + "device will be stopped after h/w processes are done.\n"); + + /* Clear the timestamp list */ +- list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) { +- list_del(&ts_skb->list); +- kfree_skb(ts_skb->skb); +- kfree(ts_skb); ++ if (info->gptp || info->ccc_gac) { ++ list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) { ++ list_del(&ts_skb->list); ++ kfree_skb(ts_skb->skb); ++ kfree(ts_skb); ++ } + } + + /* PHY disconnect */ +@@ -2116,9 +2123,11 @@ static void ravb_set_config_mode(struct + ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); + /* Set CSEL value */ + ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB); +- } else { ++ } else if (info->ccc_gac) { + ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG | + CCC_GAC | CCC_CSEL_HPB); ++ } else { ++ ravb_modify(ndev, CCC, CCC_OPC, CCC_OPC_CONFIG); + } + } + +@@ -2306,13 +2315,15 @@ static int ravb_probe(struct platform_de + /* Set AVB config mode */ + ravb_set_config_mode(ndev); + +- /* Set GTI value */ +- error = ravb_set_gti(ndev); +- if (error) +- goto out_disable_refclk; ++ if (info->gptp || info->ccc_gac) { ++ /* Set GTI value */ ++ error = ravb_set_gti(ndev); ++ if (error) ++ goto out_disable_refclk; + +- /* Request GTI loading */ +- ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI); ++ /* Request GTI loading */ ++ ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI); ++ } + + if (info->internal_delay) { + ravb_parse_delay_mode(np, ndev); +@@ -2509,13 +2520,15 @@ static int __maybe_unused ravb_resume(st + /* Set AVB config mode */ + ravb_set_config_mode(ndev); + +- /* Set GTI value */ +- ret = ravb_set_gti(ndev); +- if (ret) +- return ret; ++ if (info->gptp || info->ccc_gac) { ++ /* Set GTI value */ ++ ret = ravb_set_gti(ndev); ++ if (ret) ++ return ret; + +- /* Request GTI loading */ +- ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI); ++ /* Request GTI loading */ ++ ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI); ++ } + + if (info->internal_delay) + ravb_set_delay_mode(ndev); diff --git a/queue-5.15/revert-docs-process-howto-replace-c89-with-c11.patch b/queue-5.15/revert-docs-process-howto-replace-c89-with-c11.patch new file mode 100644 index 0000000000..d7a01176b9 --- /dev/null +++ b/queue-5.15/revert-docs-process-howto-replace-c89-with-c11.patch @@ -0,0 +1,105 @@ +From matttbe@kernel.org Sat Oct 18 01:24:23 2025 +From: "Matthieu Baerts (NGI0)" +Date: Fri, 17 Oct 2025 18:24:02 +0200 +Subject: Revert "docs/process/howto: Replace C89 with C11" +To: stable@vger.kernel.org, Greg Kroah-Hartman , Sasha Levin +Cc: MPTCP Upstream , "Matthieu Baerts (NGI0)" , Akira Yokosawa , Arnd Bergmann , Federico Vaga , Alex Shi , Hu Haowen , Tsugikazu Shibata , Jonathan Corbet +Message-ID: <20251017-v5-15-gcc-15-v1-3-da6c065049d7@kernel.org> + +From: "Matthieu Baerts (NGI0)" + +This reverts commit dc52117cd797f71f9686fa0cec91509eb7a9623d which is +commit 2f3f53d62307262f0086804ea7cea99b0e085450 upstream. + +In this kernel version, C89 is still the default ISO standard. + +The reverted commit was fixing commit e8c07082a810 ("Kbuild: move to +-std=gnu11"), introduced in v5.18, and not backported to older versions. +It was then not supported to be backported to v5.15. It can then safely +be reverted. + +Fixes: 2f3f53d62307 ("docs/process/howto: Replace C89 with C11") +Signed-off-by: Matthieu Baerts (NGI0) +Cc: Akira Yokosawa +Cc: Arnd Bergmann +Cc: Federico Vaga +Cc: Alex Shi +Cc: Hu Haowen +Cc: Tsugikazu Shibata +Cc: Jonathan Corbet +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/process/howto.rst | 2 +- + Documentation/translations/it_IT/process/howto.rst | 2 +- + Documentation/translations/ja_JP/howto.rst | 2 +- + Documentation/translations/ko_KR/howto.rst | 2 +- + Documentation/translations/zh_CN/process/howto.rst | 2 +- + Documentation/translations/zh_TW/process/howto.rst | 2 +- + 6 files changed, 6 insertions(+), 6 deletions(-) + +--- a/Documentation/process/howto.rst ++++ b/Documentation/process/howto.rst +@@ -36,7 +36,7 @@ experience, the following books are good + - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] + + The kernel is written using GNU C and the GNU toolchain. While it +-adheres to the ISO C11 standard, it uses a number of extensions that are ++adheres to the ISO C89 standard, it uses a number of extensions that are + not featured in the standard. The kernel is a freestanding C + environment, with no reliance on the standard C library, so some + portions of the C standard are not supported. Arbitrary long long +--- a/Documentation/translations/it_IT/process/howto.rst ++++ b/Documentation/translations/it_IT/process/howto.rst +@@ -44,7 +44,7 @@ altro, utili riferimenti: + - "C: A Reference Manual" di Harbison and Steele [Prentice Hall] + + Il kernel è stato scritto usando GNU C e la toolchain GNU. +-Sebbene si attenga allo standard ISO C11, esso utilizza una serie di ++Sebbene si attenga allo standard ISO C89, esso utilizza una serie di + estensioni che non sono previste in questo standard. Il kernel è un + ambiente C indipendente, che non ha alcuna dipendenza dalle librerie + C standard, così alcune parti del C standard non sono supportate. +--- a/Documentation/translations/ja_JP/howto.rst ++++ b/Documentation/translations/ja_JP/howto.rst +@@ -65,7 +65,7 @@ Linux カーネル開発のやり方 + - 『新・詳説 C 言語 H&S リファレンス』 (サミュエル P ハービソン/ガイ L スティール共著 斉藤 信男監訳)[ソフトバンク] + + カーネルは GNU C と GNU ツールチェインを使って書かれています。カーネル +-は ISO C11 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って ++は ISO C89 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って + います。カーネルは標準 C ライブラリに依存しない、C 言語非依存環境です。 + そのため、C の標準の中で使えないものもあります。特に任意の long long + の除算や浮動小数点は使えません。カーネルがツールチェインや C 言語拡張 +--- a/Documentation/translations/ko_KR/howto.rst ++++ b/Documentation/translations/ko_KR/howto.rst +@@ -62,7 +62,7 @@ Documentation/process/howto.rst + - "Practical C Programming" by Steve Oualline [O'Reilly] + - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] + +-커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C11 표준을 ++커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C89 표준을 + 따르는 반면 표준에 있지 않은 많은 확장기능도 가지고 있다. 커널은 표준 C + 라이브러리와는 관계없이 freestanding C 환경이어서 C 표준의 일부는 + 지원되지 않는다. 임의의 long long 나누기나 floating point는 지원되지 않는다. +--- a/Documentation/translations/zh_CN/process/howto.rst ++++ b/Documentation/translations/zh_CN/process/howto.rst +@@ -45,7 +45,7 @@ Linux内核大部分是由C语言写成ç + - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] + 《C语言参考手册(原书第5版)》(邱仲潘 等译)[机械工业出版社] + +-Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C11标准,但也用到了一些 ++Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C89标准,但也用到了一些 + 标准中没有定义的扩展。内核是自给自足的C环境,不依赖于标准C库的支持,所以 + 并不支持C标准中的部分定义。比如long long类型的大数除法和浮点运算就不允许 + 使用。有时候确实很难弄清楚内核对工具链的要求和它所使用的扩展,不幸的是目 +--- a/Documentation/translations/zh_TW/process/howto.rst ++++ b/Documentation/translations/zh_TW/process/howto.rst +@@ -48,7 +48,7 @@ Linux內核大部分是由C語言寫成ç + - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] + 《C語言參考手冊(原書第5版)》(邱仲潘 等譯)[機械工業出版社] + +-Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C11標準,但也用到了一些 ++Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C89標準,但也用到了一些 + 標準中沒有定義的擴展。內核是自給自足的C環境,不依賴於標準C庫的支持,所以 + 並不支持C標準中的部分定義。比如long long類型的大數除法和浮點運算就不允許 + 使用。有時候確實很難弄清楚內核對工具鏈的要求和它所使用的擴展,不幸的是目 diff --git a/queue-5.15/serial-8250_dw-handle-reset-control-deassert-error.patch b/queue-5.15/serial-8250_dw-handle-reset-control-deassert-error.patch new file mode 100644 index 0000000000..5af2085270 --- /dev/null +++ b/queue-5.15/serial-8250_dw-handle-reset-control-deassert-error.patch @@ -0,0 +1,47 @@ +From stable+bounces-190054-greg=kroah.com@vger.kernel.org Tue Oct 28 02:31:53 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 13:31:45 -0400 +Subject: serial: 8250_dw: handle reset control deassert error +To: stable@vger.kernel.org +Cc: Artem Shimko , stable , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027173145.608096-2-sashal@kernel.org> + +From: Artem Shimko + +[ Upstream commit daeb4037adf7d3349b4a1fb792f4bc9824686a4b ] + +Check the return value of reset_control_deassert() in the probe +function to prevent continuing probe when reset deassertion fails. + +Previously, reset_control_deassert() was called without checking its +return value, which could lead to probe continuing even when the +device reset wasn't properly deasserted. + +The fix checks the return value and returns an error with dev_err_probe() +if reset deassertion fails, providing better error handling and +diagnostics. + +Fixes: acbdad8dd1ab ("serial: 8250_dw: simplify optional reset handling") +Cc: stable +Signed-off-by: Artem Shimko +Link: https://patch.msgid.link/20251019095131.252848-1-a.shimko.dev@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_dw.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/8250/8250_dw.c ++++ b/drivers/tty/serial/8250/8250_dw.c +@@ -580,7 +580,9 @@ static int dw8250_probe(struct platform_ + if (IS_ERR(data->rst)) + return PTR_ERR(data->rst); + +- reset_control_deassert(data->rst); ++ err = reset_control_deassert(data->rst); ++ if (err) ++ return dev_err_probe(dev, err, "failed to deassert resets\n"); + + err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); + if (err) diff --git a/queue-5.15/serial-8250_dw-use-devm_add_action_or_reset.patch b/queue-5.15/serial-8250_dw-use-devm_add_action_or_reset.patch new file mode 100644 index 0000000000..331bb89a94 --- /dev/null +++ b/queue-5.15/serial-8250_dw-use-devm_add_action_or_reset.patch @@ -0,0 +1,143 @@ +From stable+bounces-190055-greg=kroah.com@vger.kernel.org Tue Oct 28 02:32:02 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 13:31:44 -0400 +Subject: serial: 8250_dw: Use devm_add_action_or_reset() +To: stable@vger.kernel.org +Cc: Andy Shevchenko , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027173145.608096-1-sashal@kernel.org> + +From: Andy Shevchenko + +[ Upstream commit 295b09128d12fb1a7a67f771cc0ae0df869eafaf ] + +Slightly simplify ->probe() and drop a few goto labels by using +devm_add_action_or_reset() for clock and reset cleanup. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220509172129.37770-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: daeb4037adf7 ("serial: 8250_dw: handle reset control deassert error") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_dw.c | 63 ++++++++++++++++++-------------------- + 1 file changed, 31 insertions(+), 32 deletions(-) + +--- a/drivers/tty/serial/8250/8250_dw.c ++++ b/drivers/tty/serial/8250/8250_dw.c +@@ -438,6 +438,16 @@ static void dw8250_quirks(struct uart_po + } + } + ++static void dw8250_clk_disable_unprepare(void *data) ++{ ++ clk_disable_unprepare(data); ++} ++ ++static void dw8250_reset_control_assert(void *data) ++{ ++ reset_control_assert(data); ++} ++ + static int dw8250_probe(struct platform_device *pdev) + { + struct uart_8250_port uart = {}, *up = &uart; +@@ -539,35 +549,43 @@ static int dw8250_probe(struct platform_ + if (err) + dev_warn(dev, "could not enable optional baudclk: %d\n", err); + ++ err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->clk); ++ if (err) ++ return err; ++ + if (data->clk) + p->uartclk = clk_get_rate(data->clk); + + /* If no clock rate is defined, fail. */ + if (!p->uartclk) { + dev_err(dev, "clock rate not defined\n"); +- err = -EINVAL; +- goto err_clk; ++ return -EINVAL; + } + + data->pclk = devm_clk_get_optional(dev, "apb_pclk"); +- if (IS_ERR(data->pclk)) { +- err = PTR_ERR(data->pclk); +- goto err_clk; +- } ++ if (IS_ERR(data->pclk)) ++ return PTR_ERR(data->pclk); + + err = clk_prepare_enable(data->pclk); + if (err) { + dev_err(dev, "could not enable apb_pclk\n"); +- goto err_clk; ++ return err; + } + ++ err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->pclk); ++ if (err) ++ return err; ++ + data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); +- if (IS_ERR(data->rst)) { +- err = PTR_ERR(data->rst); +- goto err_pclk; +- } ++ if (IS_ERR(data->rst)) ++ return PTR_ERR(data->rst); ++ + reset_control_deassert(data->rst); + ++ err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); ++ if (err) ++ return err; ++ + dw8250_quirks(p, data); + + /* If the Busy Functionality is not implemented, don't handle it */ +@@ -585,10 +603,8 @@ static int dw8250_probe(struct platform_ + } + + data->data.line = serial8250_register_8250_port(up); +- if (data->data.line < 0) { +- err = data->data.line; +- goto err_reset; +- } ++ if (data->data.line < 0) ++ return data->data.line; + + /* + * Some platforms may provide a reference clock shared between several +@@ -609,17 +625,6 @@ static int dw8250_probe(struct platform_ + pm_runtime_enable(dev); + + return 0; +- +-err_reset: +- reset_control_assert(data->rst); +- +-err_pclk: +- clk_disable_unprepare(data->pclk); +- +-err_clk: +- clk_disable_unprepare(data->clk); +- +- return err; + } + + static int dw8250_remove(struct platform_device *pdev) +@@ -637,12 +642,6 @@ static int dw8250_remove(struct platform + + serial8250_unregister_port(data->data.line); + +- reset_control_assert(data->rst); +- +- clk_disable_unprepare(data->pclk); +- +- clk_disable_unprepare(data->clk); +- + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + diff --git a/queue-5.15/series b/queue-5.15/series index e02716eff8..0dd5706414 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -29,3 +29,21 @@ drm-amd-pm-powerplay-smumgr-fix-pciebootlinklevel-va.patch drm-amd-pm-powerplay-smumgr-fix-pciebootlinklevel-va.patch-3340 block-fix-op_is_zone_mgmt-to-handle-req_op_zone_reset_all.patch regmap-slimbus-fix-bus_context-pointer-in-regmap-init-calls.patch +serial-8250_dw-use-devm_add_action_or_reset.patch +serial-8250_dw-handle-reset-control-deassert-error.patch +dt-bindings-usb-dwc3-imx8mp-dma-range-is-required-only-for-imx8mp.patch +ravb-exclude-gptp-feature-support-for-rz-g2l.patch +net-ravb-enforce-descriptor-type-ordering.patch +can-gs_usb-increase-max-interface-to-u8_max.patch +net-phy-dp83867-disable-eee-support-as-not-implemented.patch +mptcp-drop-bogus-optimization-in-__mptcp_check_push.patch +x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch +xhci-dbc-provide-sysfs-option-to-configure-dbc-descriptors.patch +xhci-dbc-poll-at-different-rate-depending-on-data-transfer-activity.patch +xhci-dbc-allow-users-to-modify-dbc-poll-interval-via-sysfs.patch +xhci-dbc-improve-performance-by-removing-delay-in-transfer-event-polling.patch +xhci-dbc-avoid-event-polling-busyloop-if-pending-rx-transfers-are-inactive.patch +xhci-dbc-fix-bogus-1024-byte-prefix-if-ttydbc-read-races-with-stall-event.patch +x86-boot-compile-boot-code-with-std-gnu11-too.patch +arch-back-to-std-gnu89-in-v5.18.patch +revert-docs-process-howto-replace-c89-with-c11.patch diff --git a/queue-5.15/x86-boot-compile-boot-code-with-std-gnu11-too.patch b/queue-5.15/x86-boot-compile-boot-code-with-std-gnu11-too.patch new file mode 100644 index 0000000000..a6cd01b838 --- /dev/null +++ b/queue-5.15/x86-boot-compile-boot-code-with-std-gnu11-too.patch @@ -0,0 +1,66 @@ +From matttbe@kernel.org Sat Oct 18 01:24:24 2025 +From: "Matthieu Baerts (NGI0)" +Date: Fri, 17 Oct 2025 18:24:00 +0200 +Subject: x86/boot: Compile boot code with -std=gnu11 too +To: stable@vger.kernel.org, Greg Kroah-Hartman , Sasha Levin +Cc: MPTCP Upstream , "Matthieu Baerts (NGI0)" , Alexey Dobriyan , Ingo Molnar , "H. Peter Anvin (Intel)" , Nathan Chancellor , Dave Hansen , Ard Biesheuvel +Message-ID: <20251017-v5-15-gcc-15-v1-1-da6c065049d7@kernel.org> + +From: Alexey Dobriyan + +commit b3bee1e7c3f2b1b77182302c7b2131c804175870 upstream. + +Use -std=gnu11 for consistency with main kernel code. + +It doesn't seem to change anything in vmlinux. + +Signed-off-by: Alexey Dobriyan +Signed-off-by: Ingo Molnar +Acked-by: H. Peter Anvin (Intel) +Link: https://lore.kernel.org/r/2058761e-12a4-4b2f-9690-3c3c1c9902a5@p183 +[ This kernel version doesn't build with GCC 15: + In file included from include/uapi/linux/posix_types.h:5, + from include/uapi/linux/types.h:14, + from include/linux/types.h:6, + from arch/x86/realmode/rm/wakeup.h:11, + from arch/x86/realmode/rm/wakemain.c:2: + include/linux/stddef.h:11:9: error: cannot use keyword 'false' as enumeration constant + 11 | false = 0, + | ^~~~~ + include/linux/stddef.h:11:9: note: 'false' is a keyword with '-std=c23' onwards + include/linux/types.h:30:33: error: 'bool' cannot be defined via 'typedef' + 30 | typedef _Bool bool; + | ^~~~ + include/linux/types.h:30:33: note: 'bool' is a keyword with '-std=c23' onwards + include/linux/types.h:30:1: warning: useless type name in empty declaration + 30 | typedef _Bool bool; + | ^~~~~~~ + + The fix is similar to commit ee2ab467bddf ("x86/boot: Use '-std=gnu11' + to fix build with GCC 15") which has been backported to this kernel. + + Note: In < 5.18 version, -std=gnu89 is used instead of -std=gnu11, see + commit e8c07082a810 ("Kbuild: move to -std=gnu11"). I suggest not to + modify that in this commit here as all the other similar fixes to + support GCC 15 set -std=gnu11. This can be done in a dedicated commit + if needed. ] +Signed-off-by: Matthieu Baerts (NGI0) +Cc: Nathan Chancellor +Cc: Dave Hansen +Cc: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/Makefile ++++ b/arch/x86/Makefile +@@ -24,7 +24,7 @@ endif + + # How to compile the 16-bit code. Note we always compile for -march=i386; + # that way we can complain to the user if the CPU is insufficient. +-REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ ++REALMODE_CFLAGS := -std=gnu11 -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \ + -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ + -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ + -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none) diff --git a/queue-5.15/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch b/queue-5.15/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch new file mode 100644 index 0000000000..583e385346 --- /dev/null +++ b/queue-5.15/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch @@ -0,0 +1,139 @@ +From stable+bounces-191509-greg=kroah.com@vger.kernel.org Wed Oct 29 01:02:30 2025 +From: Babu Moger +Date: Tue, 28 Oct 2025 10:56:50 -0500 +Subject: x86/resctrl: Fix miscount of bandwidth event when reactivating previously unavailable RMID +To: +Message-ID: <20251028155650.159936-1-babu.moger@amd.com> + +From: Babu Moger + +[ Upstream commit 15292f1b4c55a3a7c940dbcb6cb8793871ed3d92 ] + +Users can create as many monitoring groups as the number of RMIDs supported +by the hardware. However, on AMD systems, only a limited number of RMIDs +are guaranteed to be actively tracked by the hardware. RMIDs that exceed +this limit are placed in an "Unavailable" state. + +When a bandwidth counter is read for such an RMID, the hardware sets +MSR_IA32_QM_CTR.Unavailable (bit 62). When such an RMID starts being tracked +again the hardware counter is reset to zero. MSR_IA32_QM_CTR.Unavailable +remains set on first read after tracking re-starts and is clear on all +subsequent reads as long as the RMID is tracked. + +resctrl miscounts the bandwidth events after an RMID transitions from the +"Unavailable" state back to being tracked. This happens because when the +hardware starts counting again after resetting the counter to zero, resctrl +in turn compares the new count against the counter value stored from the +previous time the RMID was tracked. + +This results in resctrl computing an event value that is either undercounting +(when new counter is more than stored counter) or a mistaken overflow (when +new counter is less than stored counter). + +Reset the stored value (arch_mbm_state::prev_msr) of MSR_IA32_QM_CTR to +zero whenever the RMID is in the "Unavailable" state to ensure accurate +counting after the RMID resets to zero when it starts to be tracked again. + +Example scenario that results in mistaken overflow +================================================== +1. The resctrl filesystem is mounted, and a task is assigned to a + monitoring group. + + $mount -t resctrl resctrl /sys/fs/resctrl + $mkdir /sys/fs/resctrl/mon_groups/test1/ + $echo 1234 > /sys/fs/resctrl/mon_groups/test1/tasks + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + 21323 <- Total bytes on domain 0 + "Unavailable" <- Total bytes on domain 1 + + Task is running on domain 0. Counter on domain 1 is "Unavailable". + +2. The task runs on domain 0 for a while and then moves to domain 1. The + counter starts incrementing on domain 1. + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + 7345357 <- Total bytes on domain 0 + 4545 <- Total bytes on domain 1 + +3. At some point, the RMID in domain 0 transitions to the "Unavailable" + state because the task is no longer executing in that domain. + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + "Unavailable" <- Total bytes on domain 0 + 434341 <- Total bytes on domain 1 + +4. Since the task continues to migrate between domains, it may eventually + return to domain 0. + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + 17592178699059 <- Overflow on domain 0 + 3232332 <- Total bytes on domain 1 + +In this case, the RMID on domain 0 transitions from "Unavailable" state to +active state. The hardware sets MSR_IA32_QM_CTR.Unavailable (bit 62) when +the counter is read and begins tracking the RMID counting from 0. + +Subsequent reads succeed but return a value smaller than the previously +saved MSR value (7345357). Consequently, the resctrl's overflow logic is +triggered, it compares the previous value (7345357) with the new, smaller +value and incorrectly interprets this as a counter overflow, adding a large +delta. + +In reality, this is a false positive: the counter did not overflow but was +simply reset when the RMID transitioned from "Unavailable" back to active +state. + +Here is the text from APM [1] available from [2]. + +"In PQOS Version 2.0 or higher, the MBM hardware will set the U bit on the +first QM_CTR read when it begins tracking an RMID that it was not +previously tracking. The U bit will be zero for all subsequent reads from +that RMID while it is still tracked by the hardware. Therefore, a QM_CTR +read with the U bit set when that RMID is in use by a processor can be +considered 0 when calculating the difference with a subsequent read." + +[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming + Publication # 24593 Revision 3.41 section 19.3.3 Monitoring L3 Memory + Bandwidth (MBM). + + [ bp: Split commit message into smaller paragraph chunks for better + consumption. ] + +Fixes: 4d05bf71f157d ("x86/resctrl: Introduce AMD QOS feature") +Signed-off-by: Babu Moger +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Reinette Chatre +Tested-by: Reinette Chatre +Cc: stable@vger.kernel.org # needs adjustments for <= v6.17 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537 # [2] +(cherry picked from commit 15292f1b4c55a3a7c940dbcb6cb8793871ed3d92) +[babu.moger@amd.com: Fix conflict in monitor.c for v5.15 stable] +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/resctrl/monitor.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/resctrl/monitor.c ++++ b/arch/x86/kernel/cpu/resctrl/monitor.c +@@ -288,11 +288,19 @@ static u64 mbm_overflow_count(u64 prev_m + static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) + { + struct rdt_hw_resource *hw_res = resctrl_to_arch_res(rr->r); +- struct mbm_state *m; ++ struct mbm_state *m = NULL; + u64 chunks, tval; + + tval = __rmid_read(rmid, rr->evtid); + if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { ++ if (tval & RMID_VAL_UNAVAIL) { ++ if (rr->evtid == QOS_L3_MBM_TOTAL_EVENT_ID) ++ m = &rr->d->mbm_total[rmid]; ++ else if (rr->evtid == QOS_L3_MBM_LOCAL_EVENT_ID) ++ m = &rr->d->mbm_local[rmid]; ++ if (m) ++ m->prev_msr = 0; ++ } + return tval; + } + switch (rr->evtid) { diff --git a/queue-5.15/xhci-dbc-allow-users-to-modify-dbc-poll-interval-via-sysfs.patch b/queue-5.15/xhci-dbc-allow-users-to-modify-dbc-poll-interval-via-sysfs.patch new file mode 100644 index 0000000000..47643ad701 --- /dev/null +++ b/queue-5.15/xhci-dbc-allow-users-to-modify-dbc-poll-interval-via-sysfs.patch @@ -0,0 +1,131 @@ +From stable+bounces-190160-greg=kroah.com@vger.kernel.org Tue Oct 28 03:45:53 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:49 -0400 +Subject: xhci: dbc: Allow users to modify DbC poll interval via sysfs +To: stable@vger.kernel.org +Cc: Uday M Bhat , Samuel Jacob , Mathias Nyman , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027184252.639069-3-sashal@kernel.org> + +From: Uday M Bhat + +[ Upstream commit de3edd47a18fe05a560847cc3165871474e08196 ] + +xhci DbC driver polls the host controller for DbC events at a reduced +rate when DbC is enabled but there are no active data transfers. + +Allow users to modify this reduced poll interval via dbc_poll_interval_ms +sysfs entry. Unit is milliseconds and accepted range is 0 to 5000. +Max interval of 5000 ms is selected as it matches the common 5 second +timeout used in usb stack. +Default value is 64 milliseconds. + +A long interval is useful when users know there won't be any activity +on systems connected via DbC for long periods, and want to avoid +battery drainage due to unnecessary CPU usage. + +Example being Android Debugger (ADB) usage over DbC on ChromeOS systems +running Android Runtime. + +[minor changes and rewording -Mathias] + +Co-developed-by: Samuel Jacob +Signed-off-by: Samuel Jacob +Signed-off-by: Uday M Bhat +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20240626124835.1023046-5-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f3d12ec847b9 ("xhci: dbc: fix bogus 1024 byte prefix if ttyDBC read races with stall event") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd | 10 +++ + drivers/usb/host/xhci-dbgcap.c | 38 +++++++++++++++ + drivers/usb/host/xhci-dbgcap.h | 2 + 3 files changed, 49 insertions(+), 1 deletion(-) + +--- a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd ++++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd +@@ -75,3 +75,13 @@ Description: + The default value is 1 (GNU Remote Debug command). + Other permissible value is 0 which is for vendor defined debug + target. ++ ++What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_poll_interval_ms ++Date: February 2024 ++Contact: Mathias Nyman ++Description: ++ This attribute adjust the polling interval used to check for ++ DbC events. Unit is milliseconds. Accepted values range from 0 ++ up to 5000. The default value is 64 ms. ++ This polling interval is used while DbC is enabled but has no ++ active data transfers. +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -1214,11 +1214,48 @@ static ssize_t dbc_bInterfaceProtocol_st + return size; + } + ++static ssize_t dbc_poll_interval_ms_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ ++ return sysfs_emit(buf, "%u\n", dbc->poll_interval); ++} ++ ++static ssize_t dbc_poll_interval_ms_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ u32 value; ++ int ret; ++ ++ ret = kstrtou32(buf, 0, &value); ++ if (ret || value > DBC_POLL_INTERVAL_MAX) ++ return -EINVAL; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ ++ dbc->poll_interval = value; ++ ++ mod_delayed_work(system_wq, &dbc->event_work, 0); ++ ++ return size; ++} ++ + static DEVICE_ATTR_RW(dbc); + static DEVICE_ATTR_RW(dbc_idVendor); + static DEVICE_ATTR_RW(dbc_idProduct); + static DEVICE_ATTR_RW(dbc_bcdDevice); + static DEVICE_ATTR_RW(dbc_bInterfaceProtocol); ++static DEVICE_ATTR_RW(dbc_poll_interval_ms); + + static struct attribute *dbc_dev_attributes[] = { + &dev_attr_dbc.attr, +@@ -1226,6 +1263,7 @@ static struct attribute *dbc_dev_attribu + &dev_attr_dbc_idProduct.attr, + &dev_attr_dbc_bcdDevice.attr, + &dev_attr_dbc_bInterfaceProtocol.attr, ++ &dev_attr_dbc_poll_interval_ms.attr, + NULL + }; + +--- a/drivers/usb/host/xhci-dbgcap.h ++++ b/drivers/usb/host/xhci-dbgcap.h +@@ -94,7 +94,7 @@ struct dbc_ep { + #define DBC_QUEUE_SIZE 16 + #define DBC_WRITE_BUF_SIZE 8192 + #define DBC_POLL_INTERVAL_DEFAULT 64 /* milliseconds */ +- ++#define DBC_POLL_INTERVAL_MAX 5000 /* milliseconds */ + /* + * Private structure for DbC hardware state: + */ diff --git a/queue-5.15/xhci-dbc-avoid-event-polling-busyloop-if-pending-rx-transfers-are-inactive.patch b/queue-5.15/xhci-dbc-avoid-event-polling-busyloop-if-pending-rx-transfers-are-inactive.patch new file mode 100644 index 0000000000..992361eb02 --- /dev/null +++ b/queue-5.15/xhci-dbc-avoid-event-polling-busyloop-if-pending-rx-transfers-are-inactive.patch @@ -0,0 +1,123 @@ +From stable+bounces-190163-greg=kroah.com@vger.kernel.org Tue Oct 28 03:46:12 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:51 -0400 +Subject: xhci: dbc: Avoid event polling busyloop if pending rx transfers are inactive. +To: stable@vger.kernel.org +Cc: "Mathias Nyman" , "Łukasz Bartosik" , "Greg Kroah-Hartman" , "Sasha Levin" +Message-ID: <20251027184252.639069-5-sashal@kernel.org> + +From: Mathias Nyman + +[ Upstream commit cab63934c33b12c0d1e9f4da7450928057f2c142 ] + +Event polling delay is set to 0 if there are any pending requests in +either rx or tx requests lists. Checking for pending requests does +not work well for "IN" transfers as the tty driver always queues +requests to the list and TRBs to the ring, preparing to receive data +from the host. + +This causes unnecessary busylooping and cpu hogging. + +Only set the event polling delay to 0 if there are pending tx "write" +transfers, or if it was less than 10ms since last active data transfer +in any direction. + +Cc: Łukasz Bartosik +Fixes: fb18e5bb9660 ("xhci: dbc: poll at different rate depending on data transfer activity") +Cc: stable@vger.kernel.org +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250505125630.561699-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f3d12ec847b9 ("xhci: dbc: fix bogus 1024 byte prefix if ttyDBC read races with stall event") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgcap.c | 19 ++++++++++++++++--- + drivers/usb/host/xhci-dbgcap.h | 3 +++ + 2 files changed, 19 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -855,6 +855,7 @@ static enum evtreturn xhci_dbc_do_handle + { + dma_addr_t deq; + union xhci_trb *evt; ++ enum evtreturn ret = EVT_DONE; + u32 ctrl, portsc; + bool update_erdp = false; + +@@ -939,6 +940,7 @@ static enum evtreturn xhci_dbc_do_handle + break; + case TRB_TYPE(TRB_TRANSFER): + dbc_handle_xfer_event(dbc, evt); ++ ret = EVT_XFER_DONE; + break; + default: + break; +@@ -957,7 +959,7 @@ static enum evtreturn xhci_dbc_do_handle + lo_hi_writeq(deq, &dbc->regs->erdp); + } + +- return EVT_DONE; ++ return ret; + } + + static void xhci_dbc_handle_events(struct work_struct *work) +@@ -966,6 +968,7 @@ static void xhci_dbc_handle_events(struc + struct xhci_dbc *dbc; + unsigned long flags; + unsigned int poll_interval; ++ unsigned long busypoll_timelimit; + + dbc = container_of(to_delayed_work(work), struct xhci_dbc, event_work); + poll_interval = dbc->poll_interval; +@@ -984,11 +987,21 @@ static void xhci_dbc_handle_events(struc + dbc->driver->disconnect(dbc); + break; + case EVT_DONE: +- /* set fast poll rate if there are pending data transfers */ ++ /* ++ * Set fast poll rate if there are pending out transfers, or ++ * a transfer was recently processed ++ */ ++ busypoll_timelimit = dbc->xfer_timestamp + ++ msecs_to_jiffies(DBC_XFER_INACTIVITY_TIMEOUT); ++ + if (!list_empty(&dbc->eps[BULK_OUT].list_pending) || +- !list_empty(&dbc->eps[BULK_IN].list_pending)) ++ time_is_after_jiffies(busypoll_timelimit)) + poll_interval = 0; + break; ++ case EVT_XFER_DONE: ++ dbc->xfer_timestamp = jiffies; ++ poll_interval = 0; ++ break; + default: + dev_info(dbc->dev, "stop handling dbc events\n"); + return; +--- a/drivers/usb/host/xhci-dbgcap.h ++++ b/drivers/usb/host/xhci-dbgcap.h +@@ -95,6 +95,7 @@ struct dbc_ep { + #define DBC_WRITE_BUF_SIZE 8192 + #define DBC_POLL_INTERVAL_DEFAULT 64 /* milliseconds */ + #define DBC_POLL_INTERVAL_MAX 5000 /* milliseconds */ ++#define DBC_XFER_INACTIVITY_TIMEOUT 10 /* milliseconds */ + /* + * Private structure for DbC hardware state: + */ +@@ -140,6 +141,7 @@ struct xhci_dbc { + enum dbc_state state; + struct delayed_work event_work; + unsigned int poll_interval; /* ms */ ++ unsigned long xfer_timestamp; + unsigned resume_required:1; + struct dbc_ep eps[2]; + +@@ -185,6 +187,7 @@ struct dbc_request { + enum evtreturn { + EVT_ERR = -1, + EVT_DONE, ++ EVT_XFER_DONE, + EVT_GSER, + EVT_DISC, + }; diff --git a/queue-5.15/xhci-dbc-fix-bogus-1024-byte-prefix-if-ttydbc-read-races-with-stall-event.patch b/queue-5.15/xhci-dbc-fix-bogus-1024-byte-prefix-if-ttydbc-read-races-with-stall-event.patch new file mode 100644 index 0000000000..03d6b4b921 --- /dev/null +++ b/queue-5.15/xhci-dbc-fix-bogus-1024-byte-prefix-if-ttydbc-read-races-with-stall-event.patch @@ -0,0 +1,74 @@ +From stable+bounces-190165-greg=kroah.com@vger.kernel.org Tue Oct 28 03:46:16 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:52 -0400 +Subject: xhci: dbc: fix bogus 1024 byte prefix if ttyDBC read races with stall event +To: stable@vger.kernel.org +Cc: "Mathias Nyman" , stable , "Łukasz Bartosik" , "Greg Kroah-Hartman" , "Sasha Levin" +Message-ID: <20251027184252.639069-6-sashal@kernel.org> + +From: Mathias Nyman + +[ Upstream commit f3d12ec847b945d5d65846c85f062d07d5e73164 ] + +DbC may add 1024 bogus bytes to the beginneing of the receiving endpoint +if DbC hw triggers a STALL event before any Transfer Blocks (TRBs) for +incoming data are queued, but driver handles the event after it queued +the TRBs. + +This is possible as xHCI DbC hardware may trigger spurious STALL transfer +events even if endpoint is empty. The STALL event contains a pointer +to the stalled TRB, and "remaining" untransferred data length. + +As there are no TRBs queued yet the STALL event will just point to first +TRB position of the empty ring, with '0' bytes remaining untransferred. + +DbC driver is polling for events, and may not handle the STALL event +before /dev/ttyDBC0 is opened and incoming data TRBs are queued. + +The DbC event handler will now assume the first queued TRB (length 1024) +has stalled with '0' bytes remaining untransferred, and copies the data + +This race situation can be practically mitigated by making sure the event +handler handles all pending transfer events when DbC reaches configured +state, and only then create dev/ttyDbC0, and start queueing transfers. +The event handler can this way detect the STALL events on empty rings +and discard them before any transfers are queued. + +This does in practice solve the issue, but still leaves a small possible +gap for the race to trigger. +We still need a way to distinguish spurious STALLs on empty rings with '0' +bytes remaing, from actual STALL events with all bytes transmitted. + +Cc: stable +Fixes: dfba2174dc42 ("usb: xhci: Add DbC support in xHCI driver") +Tested-by: Łukasz Bartosik +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgcap.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -880,7 +880,8 @@ static enum evtreturn xhci_dbc_do_handle + dev_info(dbc->dev, "DbC configured\n"); + portsc = readl(&dbc->regs->portsc); + writel(portsc, &dbc->regs->portsc); +- return EVT_GSER; ++ ret = EVT_GSER; ++ break; + } + + return EVT_DONE; +@@ -940,7 +941,8 @@ static enum evtreturn xhci_dbc_do_handle + break; + case TRB_TYPE(TRB_TRANSFER): + dbc_handle_xfer_event(dbc, evt); +- ret = EVT_XFER_DONE; ++ if (ret != EVT_GSER) ++ ret = EVT_XFER_DONE; + break; + default: + break; diff --git a/queue-5.15/xhci-dbc-improve-performance-by-removing-delay-in-transfer-event-polling.patch b/queue-5.15/xhci-dbc-improve-performance-by-removing-delay-in-transfer-event-polling.patch new file mode 100644 index 0000000000..0b6704d5c3 --- /dev/null +++ b/queue-5.15/xhci-dbc-improve-performance-by-removing-delay-in-transfer-event-polling.patch @@ -0,0 +1,44 @@ +From stable+bounces-190162-greg=kroah.com@vger.kernel.org Tue Oct 28 03:44:50 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:50 -0400 +Subject: xhci: dbc: Improve performance by removing delay in transfer event polling. +To: stable@vger.kernel.org +Cc: "Mathias Nyman" , "Łukasz Bartosik" , "Greg Kroah-Hartman" , "Sasha Levin" +Message-ID: <20251027184252.639069-4-sashal@kernel.org> + +From: Mathias Nyman + +[ Upstream commit 03e3d9c2bd85cda941b3cf78e895c1498ac05c5f ] + +Queue event polling work with 0 delay in case there are pending transfers +queued up. This is part 2 of a 3 part series that roughly triples dbc +performace when using adb push and pull over dbc. + +Max/min push rate after patches is 210/118 MB/s, pull rate 171/133 MB/s, +tested with large files (300MB-9GB) by Łukasz Bartosik + +First performance improvement patch was commit 31128e7492dc +("xhci: dbc: add dbgtty request to end of list once it completes") + +Cc: Łukasz Bartosik +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20241227120142.1035206-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f3d12ec847b9 ("xhci: dbc: fix bogus 1024 byte prefix if ttyDBC read races with stall event") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgcap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -987,7 +987,7 @@ static void xhci_dbc_handle_events(struc + /* set fast poll rate if there are pending data transfers */ + if (!list_empty(&dbc->eps[BULK_OUT].list_pending) || + !list_empty(&dbc->eps[BULK_IN].list_pending)) +- poll_interval = 1; ++ poll_interval = 0; + break; + default: + dev_info(dbc->dev, "stop handling dbc events\n"); diff --git a/queue-5.15/xhci-dbc-poll-at-different-rate-depending-on-data-transfer-activity.patch b/queue-5.15/xhci-dbc-poll-at-different-rate-depending-on-data-transfer-activity.patch new file mode 100644 index 0000000000..52c1c4acfa --- /dev/null +++ b/queue-5.15/xhci-dbc-poll-at-different-rate-depending-on-data-transfer-activity.patch @@ -0,0 +1,101 @@ +From stable+bounces-190159-greg=kroah.com@vger.kernel.org Tue Oct 28 03:44:38 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:48 -0400 +Subject: xhci: dbc: poll at different rate depending on data transfer activity +To: stable@vger.kernel.org +Cc: Mathias Nyman , Uday M Bhat , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027184252.639069-2-sashal@kernel.org> + +From: Mathias Nyman + +[ Upstream commit fb18e5bb96603cc79d97f03e4c05f3992cf28624 ] + +DbC driver starts polling for events immediately when DbC is enabled. +The current polling interval is 1ms, which keeps the CPU busy, impacting +power management even when there are no active data transfers. + +Solve this by polling at a slower rate, with a 64ms interval as default +until a transfer request is queued, or if there are still are pending +unhandled transfers at event completion. + +Tested-by: Uday M Bhat +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20240229141438.619372-9-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f3d12ec847b9 ("xhci: dbc: fix bogus 1024 byte prefix if ttyDBC read races with stall event") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-dbgcap.c | 13 +++++++++++-- + drivers/usb/host/xhci-dbgcap.h | 2 ++ + 2 files changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -665,7 +665,8 @@ static int xhci_dbc_start(struct xhci_db + return ret; + } + +- return mod_delayed_work(system_wq, &dbc->event_work, 1); ++ return mod_delayed_work(system_wq, &dbc->event_work, ++ msecs_to_jiffies(dbc->poll_interval)); + } + + static void xhci_dbc_stop(struct xhci_dbc *dbc) +@@ -964,8 +965,10 @@ static void xhci_dbc_handle_events(struc + enum evtreturn evtr; + struct xhci_dbc *dbc; + unsigned long flags; ++ unsigned int poll_interval; + + dbc = container_of(to_delayed_work(work), struct xhci_dbc, event_work); ++ poll_interval = dbc->poll_interval; + + spin_lock_irqsave(&dbc->lock, flags); + evtr = xhci_dbc_do_handle_events(dbc); +@@ -981,13 +984,18 @@ static void xhci_dbc_handle_events(struc + dbc->driver->disconnect(dbc); + break; + case EVT_DONE: ++ /* set fast poll rate if there are pending data transfers */ ++ if (!list_empty(&dbc->eps[BULK_OUT].list_pending) || ++ !list_empty(&dbc->eps[BULK_IN].list_pending)) ++ poll_interval = 1; + break; + default: + dev_info(dbc->dev, "stop handling dbc events\n"); + return; + } + +- mod_delayed_work(system_wq, &dbc->event_work, 1); ++ mod_delayed_work(system_wq, &dbc->event_work, ++ msecs_to_jiffies(poll_interval)); + } + + static ssize_t dbc_show(struct device *dev, +@@ -1242,6 +1250,7 @@ xhci_alloc_dbc(struct device *dev, void + dbc->idVendor = DBC_VENDOR_ID; + dbc->bcdDevice = DBC_DEVICE_REV; + dbc->bInterfaceProtocol = DBC_PROTOCOL; ++ dbc->poll_interval = DBC_POLL_INTERVAL_DEFAULT; + + if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE) + goto err; +--- a/drivers/usb/host/xhci-dbgcap.h ++++ b/drivers/usb/host/xhci-dbgcap.h +@@ -93,6 +93,7 @@ struct dbc_ep { + + #define DBC_QUEUE_SIZE 16 + #define DBC_WRITE_BUF_SIZE 8192 ++#define DBC_POLL_INTERVAL_DEFAULT 64 /* milliseconds */ + + /* + * Private structure for DbC hardware state: +@@ -138,6 +139,7 @@ struct xhci_dbc { + + enum dbc_state state; + struct delayed_work event_work; ++ unsigned int poll_interval; /* ms */ + unsigned resume_required:1; + struct dbc_ep eps[2]; + diff --git a/queue-5.15/xhci-dbc-provide-sysfs-option-to-configure-dbc-descriptors.patch b/queue-5.15/xhci-dbc-provide-sysfs-option-to-configure-dbc-descriptors.patch new file mode 100644 index 0000000000..71b963c0a2 --- /dev/null +++ b/queue-5.15/xhci-dbc-provide-sysfs-option-to-configure-dbc-descriptors.patch @@ -0,0 +1,339 @@ +From stable+bounces-190158-greg=kroah.com@vger.kernel.org Tue Oct 28 03:53:52 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:47 -0400 +Subject: xhci: dbc: Provide sysfs option to configure dbc descriptors +To: stable@vger.kernel.org +Cc: Mathias Nyman , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027184252.639069-1-sashal@kernel.org> + +From: Mathias Nyman + +[ Upstream commit edf1664f3249a091a2b91182fc087b3253b0b4c2 ] + +When DbC is enabled the first port on the xHC host acts as a usb device. +xHC provides the descriptors automatically when the DbC device is +enumerated. Most of the values are hardcoded, but some fields such as +idProduct, idVendor, bcdDevice and bInterfaceProtocol can be modified. + +Add sysfs entries that allow userspace to change these. +User can only change them before dbc is enabled, i.e. before writing +"enable" to dbc sysfs file as we don't want these values to change while +device is connected, or during enumeration. + +Add documentation for these entries in +Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd + +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20230317154715.535523-9-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f3d12ec847b9 ("xhci: dbc: fix bogus 1024 byte prefix if ttyDBC read races with stall event") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd | 52 ++++ + drivers/usb/host/xhci-dbgcap.c | 191 ++++++++++++++- + drivers/usb/host/xhci-dbgcap.h | 4 + 3 files changed, 243 insertions(+), 4 deletions(-) + +--- a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd ++++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd +@@ -23,3 +23,55 @@ Description: + Reading this attribute gives the state of the DbC. It + can be one of the following states: disabled, enabled, + initialized, connected, configured and stalled. ++ ++What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_idVendor ++Date: March 2023 ++Contact: Mathias Nyman ++Description: ++ This dbc_idVendor attribute lets us change the idVendor field ++ presented in the USB device descriptor by this xhci debug ++ device. ++ Value can only be changed while debug capability (DbC) is in ++ disabled state to prevent USB device descriptor change while ++ connected to a USB host. ++ The default value is 0x1d6b (Linux Foundation). ++ It can be any 16-bit integer. ++ ++What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_idProduct ++Date: March 2023 ++Contact: Mathias Nyman ++Description: ++ This dbc_idProduct attribute lets us change the idProduct field ++ presented in the USB device descriptor by this xhci debug ++ device. ++ Value can only be changed while debug capability (DbC) is in ++ disabled state to prevent USB device descriptor change while ++ connected to a USB host. ++ The default value is 0x0010. It can be any 16-bit integer. ++ ++What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_bcdDevice ++Date: March 2023 ++Contact: Mathias Nyman ++Description: ++ This dbc_bcdDevice attribute lets us change the bcdDevice field ++ presented in the USB device descriptor by this xhci debug ++ device. ++ Value can only be changed while debug capability (DbC) is in ++ disabled state to prevent USB device descriptor change while ++ connected to a USB host. ++ The default value is 0x0010. (device rev 0.10) ++ It can be any 16-bit integer. ++ ++What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_bInterfaceProtocol ++Date: March 2023 ++Contact: Mathias Nyman ++Description: ++ This attribute lets us change the bInterfaceProtocol field ++ presented in the USB Interface descriptor by the xhci debug ++ device. ++ Value can only be changed while debug capability (DbC) is in ++ disabled state to prevent USB descriptor change while ++ connected to a USB host. ++ The default value is 1 (GNU Remote Debug command). ++ Other permissible value is 0 which is for vendor defined debug ++ target. +--- a/drivers/usb/host/xhci-dbgcap.c ++++ b/drivers/usb/host/xhci-dbgcap.c +@@ -133,10 +133,10 @@ static void xhci_dbc_init_contexts(struc + /* Set DbC context and info registers: */ + lo_hi_writeq(dbc->ctx->dma, &dbc->regs->dccp); + +- dev_info = cpu_to_le32((DBC_VENDOR_ID << 16) | DBC_PROTOCOL); ++ dev_info = (dbc->idVendor << 16) | dbc->bInterfaceProtocol; + writel(dev_info, &dbc->regs->devinfo1); + +- dev_info = cpu_to_le32((DBC_DEVICE_REV << 16) | DBC_PRODUCT_ID); ++ dev_info = (dbc->bcdDevice << 16) | dbc->idProduct; + writel(dev_info, &dbc->regs->devinfo2); + } + +@@ -1044,7 +1044,186 @@ static ssize_t dbc_store(struct device * + return count; + } + ++static ssize_t dbc_idVendor_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ ++ return sprintf(buf, "%04x\n", dbc->idVendor); ++} ++ ++static ssize_t dbc_idVendor_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ void __iomem *ptr; ++ u16 value; ++ u32 dev_info; ++ ++ if (kstrtou16(buf, 0, &value)) ++ return -EINVAL; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ if (dbc->state != DS_DISABLED) ++ return -EBUSY; ++ ++ dbc->idVendor = value; ++ ptr = &dbc->regs->devinfo1; ++ dev_info = readl(ptr); ++ dev_info = (dev_info & ~(0xffffu << 16)) | (value << 16); ++ writel(dev_info, ptr); ++ ++ return size; ++} ++ ++static ssize_t dbc_idProduct_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ ++ return sprintf(buf, "%04x\n", dbc->idProduct); ++} ++ ++static ssize_t dbc_idProduct_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ void __iomem *ptr; ++ u32 dev_info; ++ u16 value; ++ ++ if (kstrtou16(buf, 0, &value)) ++ return -EINVAL; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ if (dbc->state != DS_DISABLED) ++ return -EBUSY; ++ ++ dbc->idProduct = value; ++ ptr = &dbc->regs->devinfo2; ++ dev_info = readl(ptr); ++ dev_info = (dev_info & ~(0xffffu)) | value; ++ writel(dev_info, ptr); ++ return size; ++} ++ ++static ssize_t dbc_bcdDevice_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ ++ return sprintf(buf, "%04x\n", dbc->bcdDevice); ++} ++ ++static ssize_t dbc_bcdDevice_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ void __iomem *ptr; ++ u32 dev_info; ++ u16 value; ++ ++ if (kstrtou16(buf, 0, &value)) ++ return -EINVAL; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ if (dbc->state != DS_DISABLED) ++ return -EBUSY; ++ ++ dbc->bcdDevice = value; ++ ptr = &dbc->regs->devinfo2; ++ dev_info = readl(ptr); ++ dev_info = (dev_info & ~(0xffffu << 16)) | (value << 16); ++ writel(dev_info, ptr); ++ ++ return size; ++} ++ ++static ssize_t dbc_bInterfaceProtocol_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ ++ return sprintf(buf, "%02x\n", dbc->bInterfaceProtocol); ++} ++ ++static ssize_t dbc_bInterfaceProtocol_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ struct xhci_dbc *dbc; ++ struct xhci_hcd *xhci; ++ void __iomem *ptr; ++ u32 dev_info; ++ u8 value; ++ int ret; ++ ++ /* bInterfaceProtocol is 8 bit, but xhci only supports values 0 and 1 */ ++ ret = kstrtou8(buf, 0, &value); ++ if (ret || value > 1) ++ return -EINVAL; ++ ++ xhci = hcd_to_xhci(dev_get_drvdata(dev)); ++ dbc = xhci->dbc; ++ if (dbc->state != DS_DISABLED) ++ return -EBUSY; ++ ++ dbc->bInterfaceProtocol = value; ++ ptr = &dbc->regs->devinfo1; ++ dev_info = readl(ptr); ++ dev_info = (dev_info & ~(0xffu)) | value; ++ writel(dev_info, ptr); ++ ++ return size; ++} ++ + static DEVICE_ATTR_RW(dbc); ++static DEVICE_ATTR_RW(dbc_idVendor); ++static DEVICE_ATTR_RW(dbc_idProduct); ++static DEVICE_ATTR_RW(dbc_bcdDevice); ++static DEVICE_ATTR_RW(dbc_bInterfaceProtocol); ++ ++static struct attribute *dbc_dev_attributes[] = { ++ &dev_attr_dbc.attr, ++ &dev_attr_dbc_idVendor.attr, ++ &dev_attr_dbc_idProduct.attr, ++ &dev_attr_dbc_bcdDevice.attr, ++ &dev_attr_dbc_bInterfaceProtocol.attr, ++ NULL ++}; ++ ++static const struct attribute_group dbc_dev_attrib_grp = { ++ .attrs = dbc_dev_attributes, ++}; + + struct xhci_dbc * + xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver *driver) +@@ -1059,6 +1238,10 @@ xhci_alloc_dbc(struct device *dev, void + dbc->regs = base; + dbc->dev = dev; + dbc->driver = driver; ++ dbc->idProduct = DBC_PRODUCT_ID; ++ dbc->idVendor = DBC_VENDOR_ID; ++ dbc->bcdDevice = DBC_DEVICE_REV; ++ dbc->bInterfaceProtocol = DBC_PROTOCOL; + + if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE) + goto err; +@@ -1066,7 +1249,7 @@ xhci_alloc_dbc(struct device *dev, void + INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events); + spin_lock_init(&dbc->lock); + +- ret = device_create_file(dev, &dev_attr_dbc); ++ ret = sysfs_create_group(&dev->kobj, &dbc_dev_attrib_grp); + if (ret) + goto err; + +@@ -1085,7 +1268,7 @@ void xhci_dbc_remove(struct xhci_dbc *db + xhci_dbc_stop(dbc); + + /* remove sysfs files */ +- device_remove_file(dbc->dev, &dev_attr_dbc); ++ sysfs_remove_group(&dbc->dev->kobj, &dbc_dev_attrib_grp); + + kfree(dbc); + } +--- a/drivers/usb/host/xhci-dbgcap.h ++++ b/drivers/usb/host/xhci-dbgcap.h +@@ -131,6 +131,10 @@ struct xhci_dbc { + struct dbc_str_descs *string; + dma_addr_t string_dma; + size_t string_size; ++ u16 idVendor; ++ u16 idProduct; ++ u16 bcdDevice; ++ u8 bInterfaceProtocol; + + enum dbc_state state; + struct delayed_work event_work; -- 2.47.3