From bec0c58d85cdf345d21ef03560be03757784b3c6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 31 Mar 2022 11:07:07 +0200 Subject: [PATCH] 5.17-stable patches added patches: bus-mhi-fix-mhi-dma-structure-endianness.patch bus-mhi-fix-pm_state-conversion-to-string.patch bus-mhi-pci_generic-add-mru_default-for-quectel-em1xx-series.patch mei-avoid-iterator-usage-outside-of-list_for_each_entry.patch mei-me-add-alder-lake-n-device-id.patch mei-me-disable-driver-on-the-ign-firmware.patch usb-typec-tipd-forward-plug-orientation-to-typec-subsystem.patch usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch xhci-fix-garbage-usbsts-being-logged-in-some-cases.patch xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch --- ...mhi-fix-mhi-dma-structure-endianness.patch | 484 ++++++++++++++++++ ...hi-fix-pm_state-conversion-to-string.patch | 67 +++ ...mru_default-for-quectel-em1xx-series.patch | 35 ++ ...usage-outside-of-list_for_each_entry.patch | 78 +++ .../mei-me-add-alder-lake-n-device-id.patch | 41 ++ ...e-disable-driver-on-the-ign-firmware.patch | 102 ++++ queue-5.17/series | 12 + ...-plug-orientation-to-typec-subsystem.patch | 55 ++ ...ds-for-hardware-data-in-ene_ub6250.c.patch | 353 +++++++++++++ ...ge-usbsts-being-logged-in-some-cases.patch | 51 ++ ...-runtime-pm-imbalance-in-usb2-resume.patch | 41 ++ ...ing-returned-by-xhci_decode_ctrl_ctx.patch | 43 ++ ...ke-timeout-for-xhci_reset-adjustable.patch | 176 +++++++ 13 files changed, 1538 insertions(+) create mode 100644 queue-5.17/bus-mhi-fix-mhi-dma-structure-endianness.patch create mode 100644 queue-5.17/bus-mhi-fix-pm_state-conversion-to-string.patch create mode 100644 queue-5.17/bus-mhi-pci_generic-add-mru_default-for-quectel-em1xx-series.patch create mode 100644 queue-5.17/mei-avoid-iterator-usage-outside-of-list_for_each_entry.patch create mode 100644 queue-5.17/mei-me-add-alder-lake-n-device-id.patch create mode 100644 queue-5.17/mei-me-disable-driver-on-the-ign-firmware.patch create mode 100644 queue-5.17/usb-typec-tipd-forward-plug-orientation-to-typec-subsystem.patch create mode 100644 queue-5.17/usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch create mode 100644 queue-5.17/xhci-fix-garbage-usbsts-being-logged-in-some-cases.patch create mode 100644 queue-5.17/xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch create mode 100644 queue-5.17/xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch create mode 100644 queue-5.17/xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch diff --git a/queue-5.17/bus-mhi-fix-mhi-dma-structure-endianness.patch b/queue-5.17/bus-mhi-fix-mhi-dma-structure-endianness.patch new file mode 100644 index 00000000000..fdb7642e27e --- /dev/null +++ b/queue-5.17/bus-mhi-fix-mhi-dma-structure-endianness.patch @@ -0,0 +1,484 @@ +From ed2d980503235829aa3e0c7ae3b82374c30a081c Mon Sep 17 00:00:00 2001 +From: Paul Davey +Date: Tue, 1 Mar 2022 21:33:01 +0530 +Subject: bus: mhi: Fix MHI DMA structure endianness + +From: Paul Davey + +commit ed2d980503235829aa3e0c7ae3b82374c30a081c upstream. + +The MHI driver does not work on big endian architectures. The +controller never transitions into mission mode. This appears to be due +to the modem device expecting the various contexts and transfer rings to +have fields in little endian order in memory, but the driver constructs +them in native endianness. + +Fix MHI event, channel and command contexts and TRE handling macros to +use explicit conversion to little endian. Mark fields in relevant +structures as little endian to document this requirement. + +Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions") +Fixes: 6cd330ae76ff ("bus: mhi: core: Add support for ringing channel/event ring doorbells") +Cc: stable@vger.kernel.org +Reviewed-by: Manivannan Sadhasivam +Reviewed-by: Alex Elder +Signed-off-by: Paul Davey +Signed-off-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20220301160308.107452-4-manivannan.sadhasivam@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/core/debugfs.c | 26 ++++---- + drivers/bus/mhi/core/init.c | 36 ++++++------ + drivers/bus/mhi/core/internal.h | 119 ++++++++++++++++++++-------------------- + drivers/bus/mhi/core/main.c | 22 +++---- + drivers/bus/mhi/core/pm.c | 4 - + 5 files changed, 104 insertions(+), 103 deletions(-) + +--- a/drivers/bus/mhi/core/debugfs.c ++++ b/drivers/bus/mhi/core/debugfs.c +@@ -60,16 +60,16 @@ static int mhi_debugfs_events_show(struc + } + + seq_printf(m, "Index: %d intmod count: %lu time: %lu", +- i, (er_ctxt->intmod & EV_CTX_INTMODC_MASK) >> ++ i, (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODC_MASK) >> + EV_CTX_INTMODC_SHIFT, +- (er_ctxt->intmod & EV_CTX_INTMODT_MASK) >> ++ (le32_to_cpu(er_ctxt->intmod) & EV_CTX_INTMODT_MASK) >> + EV_CTX_INTMODT_SHIFT); + +- seq_printf(m, " base: 0x%0llx len: 0x%llx", er_ctxt->rbase, +- er_ctxt->rlen); ++ seq_printf(m, " base: 0x%0llx len: 0x%llx", le64_to_cpu(er_ctxt->rbase), ++ le64_to_cpu(er_ctxt->rlen)); + +- seq_printf(m, " rp: 0x%llx wp: 0x%llx", er_ctxt->rp, +- er_ctxt->wp); ++ seq_printf(m, " rp: 0x%llx wp: 0x%llx", le64_to_cpu(er_ctxt->rp), ++ le64_to_cpu(er_ctxt->wp)); + + seq_printf(m, " local rp: 0x%pK db: 0x%pad\n", ring->rp, + &mhi_event->db_cfg.db_val); +@@ -106,18 +106,18 @@ static int mhi_debugfs_channels_show(str + + seq_printf(m, + "%s(%u) state: 0x%lx brstmode: 0x%lx pollcfg: 0x%lx", +- mhi_chan->name, mhi_chan->chan, (chan_ctxt->chcfg & ++ mhi_chan->name, mhi_chan->chan, (le32_to_cpu(chan_ctxt->chcfg) & + CHAN_CTX_CHSTATE_MASK) >> CHAN_CTX_CHSTATE_SHIFT, +- (chan_ctxt->chcfg & CHAN_CTX_BRSTMODE_MASK) >> +- CHAN_CTX_BRSTMODE_SHIFT, (chan_ctxt->chcfg & ++ (le32_to_cpu(chan_ctxt->chcfg) & CHAN_CTX_BRSTMODE_MASK) >> ++ CHAN_CTX_BRSTMODE_SHIFT, (le32_to_cpu(chan_ctxt->chcfg) & + CHAN_CTX_POLLCFG_MASK) >> CHAN_CTX_POLLCFG_SHIFT); + +- seq_printf(m, " type: 0x%x event ring: %u", chan_ctxt->chtype, +- chan_ctxt->erindex); ++ seq_printf(m, " type: 0x%x event ring: %u", le32_to_cpu(chan_ctxt->chtype), ++ le32_to_cpu(chan_ctxt->erindex)); + + seq_printf(m, " base: 0x%llx len: 0x%llx rp: 0x%llx wp: 0x%llx", +- chan_ctxt->rbase, chan_ctxt->rlen, chan_ctxt->rp, +- chan_ctxt->wp); ++ le64_to_cpu(chan_ctxt->rbase), le64_to_cpu(chan_ctxt->rlen), ++ le64_to_cpu(chan_ctxt->rp), le64_to_cpu(chan_ctxt->wp)); + + seq_printf(m, " local rp: 0x%pK local wp: 0x%pK db: 0x%pad\n", + ring->rp, ring->wp, +--- a/drivers/bus/mhi/core/init.c ++++ b/drivers/bus/mhi/core/init.c +@@ -293,17 +293,17 @@ int mhi_init_dev_ctxt(struct mhi_control + if (mhi_chan->offload_ch) + continue; + +- tmp = chan_ctxt->chcfg; ++ tmp = le32_to_cpu(chan_ctxt->chcfg); + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); + tmp &= ~CHAN_CTX_BRSTMODE_MASK; + tmp |= (mhi_chan->db_cfg.brstmode << CHAN_CTX_BRSTMODE_SHIFT); + tmp &= ~CHAN_CTX_POLLCFG_MASK; + tmp |= (mhi_chan->db_cfg.pollcfg << CHAN_CTX_POLLCFG_SHIFT); +- chan_ctxt->chcfg = tmp; ++ chan_ctxt->chcfg = cpu_to_le32(tmp); + +- chan_ctxt->chtype = mhi_chan->type; +- chan_ctxt->erindex = mhi_chan->er_index; ++ chan_ctxt->chtype = cpu_to_le32(mhi_chan->type); ++ chan_ctxt->erindex = cpu_to_le32(mhi_chan->er_index); + + mhi_chan->ch_state = MHI_CH_STATE_DISABLED; + mhi_chan->tre_ring.db_addr = (void __iomem *)&chan_ctxt->wp; +@@ -328,14 +328,14 @@ int mhi_init_dev_ctxt(struct mhi_control + if (mhi_event->offload_ev) + continue; + +- tmp = er_ctxt->intmod; ++ tmp = le32_to_cpu(er_ctxt->intmod); + tmp &= ~EV_CTX_INTMODC_MASK; + tmp &= ~EV_CTX_INTMODT_MASK; + tmp |= (mhi_event->intmod << EV_CTX_INTMODT_SHIFT); +- er_ctxt->intmod = tmp; ++ er_ctxt->intmod = cpu_to_le32(tmp); + +- er_ctxt->ertype = MHI_ER_TYPE_VALID; +- er_ctxt->msivec = mhi_event->irq; ++ er_ctxt->ertype = cpu_to_le32(MHI_ER_TYPE_VALID); ++ er_ctxt->msivec = cpu_to_le32(mhi_event->irq); + mhi_event->db_cfg.db_mode = true; + + ring->el_size = sizeof(struct mhi_tre); +@@ -349,9 +349,9 @@ int mhi_init_dev_ctxt(struct mhi_control + * ring is empty + */ + ring->rp = ring->wp = ring->base; +- er_ctxt->rbase = ring->iommu_base; ++ er_ctxt->rbase = cpu_to_le64(ring->iommu_base); + er_ctxt->rp = er_ctxt->wp = er_ctxt->rbase; +- er_ctxt->rlen = ring->len; ++ er_ctxt->rlen = cpu_to_le64(ring->len); + ring->ctxt_wp = &er_ctxt->wp; + } + +@@ -378,9 +378,9 @@ int mhi_init_dev_ctxt(struct mhi_control + goto error_alloc_cmd; + + ring->rp = ring->wp = ring->base; +- cmd_ctxt->rbase = ring->iommu_base; ++ cmd_ctxt->rbase = cpu_to_le64(ring->iommu_base); + cmd_ctxt->rp = cmd_ctxt->wp = cmd_ctxt->rbase; +- cmd_ctxt->rlen = ring->len; ++ cmd_ctxt->rlen = cpu_to_le64(ring->len); + ring->ctxt_wp = &cmd_ctxt->wp; + } + +@@ -581,10 +581,10 @@ void mhi_deinit_chan_ctxt(struct mhi_con + chan_ctxt->rp = 0; + chan_ctxt->wp = 0; + +- tmp = chan_ctxt->chcfg; ++ tmp = le32_to_cpu(chan_ctxt->chcfg); + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_DISABLED << CHAN_CTX_CHSTATE_SHIFT); +- chan_ctxt->chcfg = tmp; ++ chan_ctxt->chcfg = cpu_to_le32(tmp); + + /* Update to all cores */ + smp_wmb(); +@@ -618,14 +618,14 @@ int mhi_init_chan_ctxt(struct mhi_contro + return -ENOMEM; + } + +- tmp = chan_ctxt->chcfg; ++ tmp = le32_to_cpu(chan_ctxt->chcfg); + tmp &= ~CHAN_CTX_CHSTATE_MASK; + tmp |= (MHI_CH_STATE_ENABLED << CHAN_CTX_CHSTATE_SHIFT); +- chan_ctxt->chcfg = tmp; ++ chan_ctxt->chcfg = cpu_to_le32(tmp); + +- chan_ctxt->rbase = tre_ring->iommu_base; ++ chan_ctxt->rbase = cpu_to_le64(tre_ring->iommu_base); + chan_ctxt->rp = chan_ctxt->wp = chan_ctxt->rbase; +- chan_ctxt->rlen = tre_ring->len; ++ chan_ctxt->rlen = cpu_to_le64(tre_ring->len); + tre_ring->ctxt_wp = &chan_ctxt->wp; + + tre_ring->rp = tre_ring->wp = tre_ring->base; +--- a/drivers/bus/mhi/core/internal.h ++++ b/drivers/bus/mhi/core/internal.h +@@ -209,14 +209,14 @@ extern struct bus_type mhi_bus_type; + #define EV_CTX_INTMODT_MASK GENMASK(31, 16) + #define EV_CTX_INTMODT_SHIFT 16 + struct mhi_event_ctxt { +- __u32 intmod; +- __u32 ertype; +- __u32 msivec; +- +- __u64 rbase __packed __aligned(4); +- __u64 rlen __packed __aligned(4); +- __u64 rp __packed __aligned(4); +- __u64 wp __packed __aligned(4); ++ __le32 intmod; ++ __le32 ertype; ++ __le32 msivec; ++ ++ __le64 rbase __packed __aligned(4); ++ __le64 rlen __packed __aligned(4); ++ __le64 rp __packed __aligned(4); ++ __le64 wp __packed __aligned(4); + }; + + #define CHAN_CTX_CHSTATE_MASK GENMASK(7, 0) +@@ -227,25 +227,25 @@ struct mhi_event_ctxt { + #define CHAN_CTX_POLLCFG_SHIFT 10 + #define CHAN_CTX_RESERVED_MASK GENMASK(31, 16) + struct mhi_chan_ctxt { +- __u32 chcfg; +- __u32 chtype; +- __u32 erindex; +- +- __u64 rbase __packed __aligned(4); +- __u64 rlen __packed __aligned(4); +- __u64 rp __packed __aligned(4); +- __u64 wp __packed __aligned(4); ++ __le32 chcfg; ++ __le32 chtype; ++ __le32 erindex; ++ ++ __le64 rbase __packed __aligned(4); ++ __le64 rlen __packed __aligned(4); ++ __le64 rp __packed __aligned(4); ++ __le64 wp __packed __aligned(4); + }; + + struct mhi_cmd_ctxt { +- __u32 reserved0; +- __u32 reserved1; +- __u32 reserved2; +- +- __u64 rbase __packed __aligned(4); +- __u64 rlen __packed __aligned(4); +- __u64 rp __packed __aligned(4); +- __u64 wp __packed __aligned(4); ++ __le32 reserved0; ++ __le32 reserved1; ++ __le32 reserved2; ++ ++ __le64 rbase __packed __aligned(4); ++ __le64 rlen __packed __aligned(4); ++ __le64 rp __packed __aligned(4); ++ __le64 wp __packed __aligned(4); + }; + + struct mhi_ctxt { +@@ -258,8 +258,8 @@ struct mhi_ctxt { + }; + + struct mhi_tre { +- u64 ptr; +- u32 dword[2]; ++ __le64 ptr; ++ __le32 dword[2]; + }; + + struct bhi_vec_entry { +@@ -277,57 +277,58 @@ enum mhi_cmd_type { + /* No operation command */ + #define MHI_TRE_CMD_NOOP_PTR (0) + #define MHI_TRE_CMD_NOOP_DWORD0 (0) +-#define MHI_TRE_CMD_NOOP_DWORD1 (MHI_CMD_NOP << 16) ++#define MHI_TRE_CMD_NOOP_DWORD1 (cpu_to_le32(MHI_CMD_NOP << 16)) + + /* Channel reset command */ + #define MHI_TRE_CMD_RESET_PTR (0) + #define MHI_TRE_CMD_RESET_DWORD0 (0) +-#define MHI_TRE_CMD_RESET_DWORD1(chid) ((chid << 24) | \ +- (MHI_CMD_RESET_CHAN << 16)) ++#define MHI_TRE_CMD_RESET_DWORD1(chid) (cpu_to_le32((chid << 24) | \ ++ (MHI_CMD_RESET_CHAN << 16))) + + /* Channel stop command */ + #define MHI_TRE_CMD_STOP_PTR (0) + #define MHI_TRE_CMD_STOP_DWORD0 (0) +-#define MHI_TRE_CMD_STOP_DWORD1(chid) ((chid << 24) | \ +- (MHI_CMD_STOP_CHAN << 16)) ++#define MHI_TRE_CMD_STOP_DWORD1(chid) (cpu_to_le32((chid << 24) | \ ++ (MHI_CMD_STOP_CHAN << 16))) + + /* Channel start command */ + #define MHI_TRE_CMD_START_PTR (0) + #define MHI_TRE_CMD_START_DWORD0 (0) +-#define MHI_TRE_CMD_START_DWORD1(chid) ((chid << 24) | \ +- (MHI_CMD_START_CHAN << 16)) ++#define MHI_TRE_CMD_START_DWORD1(chid) (cpu_to_le32((chid << 24) | \ ++ (MHI_CMD_START_CHAN << 16))) + +-#define MHI_TRE_GET_CMD_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) +-#define MHI_TRE_GET_CMD_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) ++#define MHI_TRE_GET_DWORD(tre, word) (le32_to_cpu((tre)->dword[(word)])) ++#define MHI_TRE_GET_CMD_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) ++#define MHI_TRE_GET_CMD_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) + + /* Event descriptor macros */ +-#define MHI_TRE_EV_PTR(ptr) (ptr) +-#define MHI_TRE_EV_DWORD0(code, len) ((code << 24) | len) +-#define MHI_TRE_EV_DWORD1(chid, type) ((chid << 24) | (type << 16)) +-#define MHI_TRE_GET_EV_PTR(tre) ((tre)->ptr) +-#define MHI_TRE_GET_EV_CODE(tre) (((tre)->dword[0] >> 24) & 0xFF) +-#define MHI_TRE_GET_EV_LEN(tre) ((tre)->dword[0] & 0xFFFF) +-#define MHI_TRE_GET_EV_CHID(tre) (((tre)->dword[1] >> 24) & 0xFF) +-#define MHI_TRE_GET_EV_TYPE(tre) (((tre)->dword[1] >> 16) & 0xFF) +-#define MHI_TRE_GET_EV_STATE(tre) (((tre)->dword[0] >> 24) & 0xFF) +-#define MHI_TRE_GET_EV_EXECENV(tre) (((tre)->dword[0] >> 24) & 0xFF) +-#define MHI_TRE_GET_EV_SEQ(tre) ((tre)->dword[0]) +-#define MHI_TRE_GET_EV_TIME(tre) ((tre)->ptr) +-#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits((tre)->ptr) +-#define MHI_TRE_GET_EV_VEID(tre) (((tre)->dword[0] >> 16) & 0xFF) +-#define MHI_TRE_GET_EV_LINKSPEED(tre) (((tre)->dword[1] >> 24) & 0xFF) +-#define MHI_TRE_GET_EV_LINKWIDTH(tre) ((tre)->dword[0] & 0xFF) ++#define MHI_TRE_EV_PTR(ptr) (cpu_to_le64(ptr)) ++#define MHI_TRE_EV_DWORD0(code, len) (cpu_to_le32((code << 24) | len)) ++#define MHI_TRE_EV_DWORD1(chid, type) (cpu_to_le32((chid << 24) | (type << 16))) ++#define MHI_TRE_GET_EV_PTR(tre) (le64_to_cpu((tre)->ptr)) ++#define MHI_TRE_GET_EV_CODE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) ++#define MHI_TRE_GET_EV_LEN(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFFFF) ++#define MHI_TRE_GET_EV_CHID(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) ++#define MHI_TRE_GET_EV_TYPE(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 16) & 0xFF) ++#define MHI_TRE_GET_EV_STATE(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) ++#define MHI_TRE_GET_EV_EXECENV(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 24) & 0xFF) ++#define MHI_TRE_GET_EV_SEQ(tre) MHI_TRE_GET_DWORD(tre, 0) ++#define MHI_TRE_GET_EV_TIME(tre) (MHI_TRE_GET_EV_PTR(tre)) ++#define MHI_TRE_GET_EV_COOKIE(tre) lower_32_bits(MHI_TRE_GET_EV_PTR(tre)) ++#define MHI_TRE_GET_EV_VEID(tre) ((MHI_TRE_GET_DWORD(tre, 0) >> 16) & 0xFF) ++#define MHI_TRE_GET_EV_LINKSPEED(tre) ((MHI_TRE_GET_DWORD(tre, 1) >> 24) & 0xFF) ++#define MHI_TRE_GET_EV_LINKWIDTH(tre) (MHI_TRE_GET_DWORD(tre, 0) & 0xFF) + + /* Transfer descriptor macros */ +-#define MHI_TRE_DATA_PTR(ptr) (ptr) +-#define MHI_TRE_DATA_DWORD0(len) (len & MHI_MAX_MTU) +-#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) ((2 << 16) | (bei << 10) \ +- | (ieot << 9) | (ieob << 8) | chain) ++#define MHI_TRE_DATA_PTR(ptr) (cpu_to_le64(ptr)) ++#define MHI_TRE_DATA_DWORD0(len) (cpu_to_le32(len & MHI_MAX_MTU)) ++#define MHI_TRE_DATA_DWORD1(bei, ieot, ieob, chain) (cpu_to_le32((2 << 16) | (bei << 10) \ ++ | (ieot << 9) | (ieob << 8) | chain)) + + /* RSC transfer descriptor macros */ +-#define MHI_RSCTRE_DATA_PTR(ptr, len) (((u64)len << 48) | ptr) +-#define MHI_RSCTRE_DATA_DWORD0(cookie) (cookie) +-#define MHI_RSCTRE_DATA_DWORD1 (MHI_PKT_TYPE_COALESCING << 16) ++#define MHI_RSCTRE_DATA_PTR(ptr, len) (cpu_to_le64(((u64)len << 48) | ptr)) ++#define MHI_RSCTRE_DATA_DWORD0(cookie) (cpu_to_le32(cookie)) ++#define MHI_RSCTRE_DATA_DWORD1 (cpu_to_le32(MHI_PKT_TYPE_COALESCING << 16)) + + enum mhi_pkt_type { + MHI_PKT_TYPE_INVALID = 0x0, +@@ -500,7 +501,7 @@ struct state_transition { + struct mhi_ring { + dma_addr_t dma_handle; + dma_addr_t iommu_base; +- u64 *ctxt_wp; /* point to ctxt wp */ ++ __le64 *ctxt_wp; /* point to ctxt wp */ + void *pre_aligned; + void *base; + void *rp; +--- a/drivers/bus/mhi/core/main.c ++++ b/drivers/bus/mhi/core/main.c +@@ -114,7 +114,7 @@ void mhi_ring_er_db(struct mhi_event *mh + struct mhi_ring *ring = &mhi_event->ring; + + mhi_event->db_cfg.process_db(mhi_event->mhi_cntrl, &mhi_event->db_cfg, +- ring->db_addr, *ring->ctxt_wp); ++ ring->db_addr, le64_to_cpu(*ring->ctxt_wp)); + } + + void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd) +@@ -123,7 +123,7 @@ void mhi_ring_cmd_db(struct mhi_controll + struct mhi_ring *ring = &mhi_cmd->ring; + + db = ring->iommu_base + (ring->wp - ring->base); +- *ring->ctxt_wp = db; ++ *ring->ctxt_wp = cpu_to_le64(db); + mhi_write_db(mhi_cntrl, ring->db_addr, db); + } + +@@ -140,7 +140,7 @@ void mhi_ring_chan_db(struct mhi_control + * before letting h/w know there is new element to fetch. + */ + dma_wmb(); +- *ring->ctxt_wp = db; ++ *ring->ctxt_wp = cpu_to_le64(db); + + mhi_chan->db_cfg.process_db(mhi_cntrl, &mhi_chan->db_cfg, + ring->db_addr, db); +@@ -432,7 +432,7 @@ irqreturn_t mhi_irq_handler(int irq_numb + struct mhi_event_ctxt *er_ctxt = + &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; + struct mhi_ring *ev_ring = &mhi_event->ring; +- dma_addr_t ptr = er_ctxt->rp; ++ dma_addr_t ptr = le64_to_cpu(er_ctxt->rp); + void *dev_rp; + + if (!is_valid_ring_ptr(ev_ring, ptr)) { +@@ -537,14 +537,14 @@ static void mhi_recycle_ev_ring_element( + + /* Update the WP */ + ring->wp += ring->el_size; +- ctxt_wp = *ring->ctxt_wp + ring->el_size; ++ ctxt_wp = le64_to_cpu(*ring->ctxt_wp) + ring->el_size; + + if (ring->wp >= (ring->base + ring->len)) { + ring->wp = ring->base; + ctxt_wp = ring->iommu_base; + } + +- *ring->ctxt_wp = ctxt_wp; ++ *ring->ctxt_wp = cpu_to_le64(ctxt_wp); + + /* Update the RP */ + ring->rp += ring->el_size; +@@ -801,7 +801,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_ + struct device *dev = &mhi_cntrl->mhi_dev->dev; + u32 chan; + int count = 0; +- dma_addr_t ptr = er_ctxt->rp; ++ dma_addr_t ptr = le64_to_cpu(er_ctxt->rp); + + /* + * This is a quick check to avoid unnecessary event processing +@@ -940,7 +940,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_ + mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); + local_rp = ev_ring->rp; + +- ptr = er_ctxt->rp; ++ ptr = le64_to_cpu(er_ctxt->rp); + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); +@@ -970,7 +970,7 @@ int mhi_process_data_event_ring(struct m + int count = 0; + u32 chan; + struct mhi_chan *mhi_chan; +- dma_addr_t ptr = er_ctxt->rp; ++ dma_addr_t ptr = le64_to_cpu(er_ctxt->rp); + + if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) + return -EIO; +@@ -1011,7 +1011,7 @@ int mhi_process_data_event_ring(struct m + mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); + local_rp = ev_ring->rp; + +- ptr = er_ctxt->rp; ++ ptr = le64_to_cpu(er_ctxt->rp); + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); +@@ -1533,7 +1533,7 @@ static void mhi_mark_stale_events(struct + /* mark all stale events related to channel as STALE event */ + spin_lock_irqsave(&mhi_event->lock, flags); + +- ptr = er_ctxt->rp; ++ ptr = le64_to_cpu(er_ctxt->rp); + if (!is_valid_ring_ptr(ev_ring, ptr)) { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Event ring rp points outside of the event ring\n"); +--- a/drivers/bus/mhi/core/pm.c ++++ b/drivers/bus/mhi/core/pm.c +@@ -218,7 +218,7 @@ int mhi_ready_state_transition(struct mh + continue; + + ring->wp = ring->base + ring->len - ring->el_size; +- *ring->ctxt_wp = ring->iommu_base + ring->len - ring->el_size; ++ *ring->ctxt_wp = cpu_to_le64(ring->iommu_base + ring->len - ring->el_size); + /* Update all cores */ + smp_wmb(); + +@@ -420,7 +420,7 @@ static int mhi_pm_mission_mode_transitio + continue; + + ring->wp = ring->base + ring->len - ring->el_size; +- *ring->ctxt_wp = ring->iommu_base + ring->len - ring->el_size; ++ *ring->ctxt_wp = cpu_to_le64(ring->iommu_base + ring->len - ring->el_size); + /* Update to all cores */ + smp_wmb(); + diff --git a/queue-5.17/bus-mhi-fix-pm_state-conversion-to-string.patch b/queue-5.17/bus-mhi-fix-pm_state-conversion-to-string.patch new file mode 100644 index 00000000000..abfb1527ee5 --- /dev/null +++ b/queue-5.17/bus-mhi-fix-pm_state-conversion-to-string.patch @@ -0,0 +1,67 @@ +From 64f93a9a27c1970fa8ee5ffc5a6ae2bda477ec5b Mon Sep 17 00:00:00 2001 +From: Paul Davey +Date: Tue, 1 Mar 2022 21:33:00 +0530 +Subject: bus: mhi: Fix pm_state conversion to string + +From: Paul Davey + +commit 64f93a9a27c1970fa8ee5ffc5a6ae2bda477ec5b upstream. + +On big endian architectures the mhi debugfs files which report pm state +give "Invalid State" for all states. This is caused by using +find_last_bit which takes an unsigned long* while the state is passed in +as an enum mhi_pm_state which will be of int size. + +Fix by using __fls to pass the value of state instead of find_last_bit. + +Also the current API expects "mhi_pm_state" enumerator as the function +argument but the function only works with bitmasks. So as Alex suggested, +let's change the argument to u32 to avoid confusion. + +Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions") +Cc: stable@vger.kernel.org +[mani: changed the function argument to u32] +Reviewed-by: Manivannan Sadhasivam +Reviewed-by: Hemant Kumar +Reviewed-by: Alex Elder +Signed-off-by: Paul Davey +Signed-off-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20220301160308.107452-3-manivannan.sadhasivam@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/core/init.c | 10 ++++++---- + drivers/bus/mhi/core/internal.h | 2 +- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/bus/mhi/core/init.c ++++ b/drivers/bus/mhi/core/init.c +@@ -77,12 +77,14 @@ static const char * const mhi_pm_state_s + [MHI_PM_STATE_LD_ERR_FATAL_DETECT] = "Linkdown or Error Fatal Detect", + }; + +-const char *to_mhi_pm_state_str(enum mhi_pm_state state) ++const char *to_mhi_pm_state_str(u32 state) + { +- unsigned long pm_state = state; +- int index = find_last_bit(&pm_state, 32); ++ int index; + +- if (index >= ARRAY_SIZE(mhi_pm_state_str)) ++ if (state) ++ index = __fls(state); ++ ++ if (!state || index >= ARRAY_SIZE(mhi_pm_state_str)) + return "Invalid State"; + + return mhi_pm_state_str[index]; +--- a/drivers/bus/mhi/core/internal.h ++++ b/drivers/bus/mhi/core/internal.h +@@ -622,7 +622,7 @@ void mhi_free_bhie_table(struct mhi_cont + enum mhi_pm_state __must_check mhi_tryset_pm_state( + struct mhi_controller *mhi_cntrl, + enum mhi_pm_state state); +-const char *to_mhi_pm_state_str(enum mhi_pm_state state); ++const char *to_mhi_pm_state_str(u32 state); + int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, + enum dev_st_transition state); + void mhi_pm_st_worker(struct work_struct *work); diff --git a/queue-5.17/bus-mhi-pci_generic-add-mru_default-for-quectel-em1xx-series.patch b/queue-5.17/bus-mhi-pci_generic-add-mru_default-for-quectel-em1xx-series.patch new file mode 100644 index 00000000000..8b2c180ffad --- /dev/null +++ b/queue-5.17/bus-mhi-pci_generic-add-mru_default-for-quectel-em1xx-series.patch @@ -0,0 +1,35 @@ +From 2413ffbf19a95cfcd7adf63135c5a9343a66d0a2 Mon Sep 17 00:00:00 2001 +From: Yonglin Tan +Date: Tue, 1 Mar 2022 21:32:59 +0530 +Subject: bus: mhi: pci_generic: Add mru_default for Quectel EM1xx series + +From: Yonglin Tan + +commit 2413ffbf19a95cfcd7adf63135c5a9343a66d0a2 upstream. + +For default mechanism, the driver uses default MRU 3500 if mru_default +is not initialized. The Qualcomm configured the MRU size to 32768 in the +WWAN device FW. So, we align the driver setting with Qualcomm FW setting. + +Link: https://lore.kernel.org/r/MEYP282MB2374EE345DADDB591AFDA6AFFD2E9@MEYP282MB2374.AUSP282.PROD.OUTLOOK.COM +Fixes: ac4bf60bbaa0 ("bus: mhi: pci_generic: Introduce quectel EM1XXGR-L support") +Cc: stable@vger.kernel.org +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Yonglin Tan +Signed-off-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20220301160308.107452-2-manivannan.sadhasivam@linaro.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bus/mhi/pci_generic.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/bus/mhi/pci_generic.c ++++ b/drivers/bus/mhi/pci_generic.c +@@ -327,6 +327,7 @@ static const struct mhi_pci_dev_info mhi + .config = &modem_quectel_em1xx_config, + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, + .dma_data_width = 32, ++ .mru_default = 32768, + .sideband_wake = true, + }; + diff --git a/queue-5.17/mei-avoid-iterator-usage-outside-of-list_for_each_entry.patch b/queue-5.17/mei-avoid-iterator-usage-outside-of-list_for_each_entry.patch new file mode 100644 index 00000000000..02acf0fb4ca --- /dev/null +++ b/queue-5.17/mei-avoid-iterator-usage-outside-of-list_for_each_entry.patch @@ -0,0 +1,78 @@ +From c10187b1c5ebb8681ca467ab7b0ded5ea415d258 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 8 Mar 2022 11:59:26 +0200 +Subject: mei: avoid iterator usage outside of list_for_each_entry + +From: Alexander Usyskin + +commit c10187b1c5ebb8681ca467ab7b0ded5ea415d258 upstream. + +Usage of the iterator outside of the list_for_each_entry +is considered harmful. https://lkml.org/lkml/2022/2/17/1032 + +Do not reference the loop variable outside of the loop, +by rearranging the orders of execution. +Instead of performing search loop and checking outside the loop +if the end of the list was hit and no matching element was found, +the execution is performed inside the loop upon a successful match +followed by a goto statement to the next step, +therefore no condition has to be performed after the loop has ended. + +Cc: +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Link: https://lore.kernel.org/r/20220308095926.300412-1-tomas.winkler@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/mei/interrupt.c | 35 +++++++++++++++-------------------- + 1 file changed, 15 insertions(+), 20 deletions(-) + +--- a/drivers/misc/mei/interrupt.c ++++ b/drivers/misc/mei/interrupt.c +@@ -424,31 +424,26 @@ int mei_irq_read_handler(struct mei_devi + list_for_each_entry(cl, &dev->file_list, link) { + if (mei_cl_hbm_equal(cl, mei_hdr)) { + cl_dbg(dev, cl, "got a message\n"); +- break; ++ ret = mei_cl_irq_read_msg(cl, mei_hdr, meta_hdr, cmpl_list); ++ goto reset_slots; + } + } + + /* if no recipient cl was found we assume corrupted header */ +- if (&cl->link == &dev->file_list) { +- /* A message for not connected fixed address clients +- * should be silently discarded +- * On power down client may be force cleaned, +- * silently discard such messages +- */ +- if (hdr_is_fixed(mei_hdr) || +- dev->dev_state == MEI_DEV_POWER_DOWN) { +- mei_irq_discard_msg(dev, mei_hdr, mei_hdr->length); +- ret = 0; +- goto reset_slots; +- } +- dev_err(dev->dev, "no destination client found 0x%08X\n", +- dev->rd_msg_hdr[0]); +- ret = -EBADMSG; +- goto end; ++ /* A message for not connected fixed address clients ++ * should be silently discarded ++ * On power down client may be force cleaned, ++ * silently discard such messages ++ */ ++ if (hdr_is_fixed(mei_hdr) || ++ dev->dev_state == MEI_DEV_POWER_DOWN) { ++ mei_irq_discard_msg(dev, mei_hdr, mei_hdr->length); ++ ret = 0; ++ goto reset_slots; + } +- +- ret = mei_cl_irq_read_msg(cl, mei_hdr, meta_hdr, cmpl_list); +- ++ dev_err(dev->dev, "no destination client found 0x%08X\n", dev->rd_msg_hdr[0]); ++ ret = -EBADMSG; ++ goto end; + + reset_slots: + /* reset the number of slots and header */ diff --git a/queue-5.17/mei-me-add-alder-lake-n-device-id.patch b/queue-5.17/mei-me-add-alder-lake-n-device-id.patch new file mode 100644 index 00000000000..7d2b0e672ca --- /dev/null +++ b/queue-5.17/mei-me-add-alder-lake-n-device-id.patch @@ -0,0 +1,41 @@ +From 7bbbd0845818cffa9fa8ccfe52fa1cad58e7e4f2 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 1 Mar 2022 09:11:15 +0200 +Subject: mei: me: add Alder Lake N device id. + +From: Alexander Usyskin + +commit 7bbbd0845818cffa9fa8ccfe52fa1cad58e7e4f2 upstream. + +Add Alder Lake N device ID. + +Cc: +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Link: https://lore.kernel.org/r/20220301071115.96145-1-tomas.winkler@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/mei/hw-me-regs.h | 1 + + drivers/misc/mei/pci-me.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/misc/mei/hw-me-regs.h ++++ b/drivers/misc/mei/hw-me-regs.h +@@ -107,6 +107,7 @@ + #define MEI_DEV_ID_ADP_S 0x7AE8 /* Alder Lake Point S */ + #define MEI_DEV_ID_ADP_LP 0x7A60 /* Alder Lake Point LP */ + #define MEI_DEV_ID_ADP_P 0x51E0 /* Alder Lake Point P */ ++#define MEI_DEV_ID_ADP_N 0x54E0 /* Alder Lake Point N */ + + /* + * MEI HW Section +--- a/drivers/misc/mei/pci-me.c ++++ b/drivers/misc/mei/pci-me.c +@@ -113,6 +113,7 @@ static const struct pci_device_id mei_me + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_S, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_LP, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)}, ++ {MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)}, + + /* required last entry */ + {0, } diff --git a/queue-5.17/mei-me-disable-driver-on-the-ign-firmware.patch b/queue-5.17/mei-me-disable-driver-on-the-ign-firmware.patch new file mode 100644 index 00000000000..4ddba687a57 --- /dev/null +++ b/queue-5.17/mei-me-disable-driver-on-the-ign-firmware.patch @@ -0,0 +1,102 @@ +From ccdf6f806fbf559f7c29ed9302a7c1b4da7fd37f Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 15 Feb 2022 10:04:35 +0200 +Subject: mei: me: disable driver on the ign firmware + +From: Alexander Usyskin + +commit ccdf6f806fbf559f7c29ed9302a7c1b4da7fd37f upstream. + +Add a quirk to disable MEI interface on Intel PCH Ignition (IGN) +as the IGN firmware doesn't support the protocol. + +Cc: +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Link: https://lore.kernel.org/r/20220215080438.264876-1-tomas.winkler@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/mei/hw-me-regs.h | 1 + + drivers/misc/mei/hw-me.c | 23 ++++++++++++----------- + 2 files changed, 13 insertions(+), 11 deletions(-) + +--- a/drivers/misc/mei/hw-me-regs.h ++++ b/drivers/misc/mei/hw-me-regs.h +@@ -120,6 +120,7 @@ + #define PCI_CFG_HFS_2 0x48 + #define PCI_CFG_HFS_3 0x60 + # define PCI_CFG_HFS_3_FW_SKU_MSK 0x00000070 ++# define PCI_CFG_HFS_3_FW_SKU_IGN 0x00000000 + # define PCI_CFG_HFS_3_FW_SKU_SPS 0x00000060 + #define PCI_CFG_HFS_4 0x64 + #define PCI_CFG_HFS_5 0x68 +--- a/drivers/misc/mei/hw-me.c ++++ b/drivers/misc/mei/hw-me.c +@@ -1405,16 +1405,16 @@ static bool mei_me_fw_type_sps_4(const s + .quirk_probe = mei_me_fw_type_sps_4 + + /** +- * mei_me_fw_type_sps() - check for sps sku ++ * mei_me_fw_type_sps_ign() - check for sps or ign sku + * +- * Read ME FW Status register to check for SPS Firmware. +- * The SPS FW is only signaled in pci function 0 ++ * Read ME FW Status register to check for SPS or IGN Firmware. ++ * The SPS/IGN FW is only signaled in pci function 0 + * + * @pdev: pci device + * +- * Return: true in case of SPS firmware ++ * Return: true in case of SPS/IGN firmware + */ +-static bool mei_me_fw_type_sps(const struct pci_dev *pdev) ++static bool mei_me_fw_type_sps_ign(const struct pci_dev *pdev) + { + u32 reg; + u32 fw_type; +@@ -1427,14 +1427,15 @@ static bool mei_me_fw_type_sps(const str + + dev_dbg(&pdev->dev, "fw type is %d\n", fw_type); + +- return fw_type == PCI_CFG_HFS_3_FW_SKU_SPS; ++ return fw_type == PCI_CFG_HFS_3_FW_SKU_IGN || ++ fw_type == PCI_CFG_HFS_3_FW_SKU_SPS; + } + + #define MEI_CFG_KIND_ITOUCH \ + .kind = "itouch" + +-#define MEI_CFG_FW_SPS \ +- .quirk_probe = mei_me_fw_type_sps ++#define MEI_CFG_FW_SPS_IGN \ ++ .quirk_probe = mei_me_fw_type_sps_ign + + #define MEI_CFG_FW_VER_SUPP \ + .fw_ver_supported = 1 +@@ -1535,7 +1536,7 @@ static const struct mei_cfg mei_me_pch12 + MEI_CFG_PCH8_HFS, + MEI_CFG_FW_VER_SUPP, + MEI_CFG_DMA_128, +- MEI_CFG_FW_SPS, ++ MEI_CFG_FW_SPS_IGN, + }; + + /* Cannon Lake itouch with quirk for SPS 5.0 and newer Firmware exclusion +@@ -1545,7 +1546,7 @@ static const struct mei_cfg mei_me_pch12 + MEI_CFG_KIND_ITOUCH, + MEI_CFG_PCH8_HFS, + MEI_CFG_FW_VER_SUPP, +- MEI_CFG_FW_SPS, ++ MEI_CFG_FW_SPS_IGN, + }; + + /* Tiger Lake and newer devices */ +@@ -1562,7 +1563,7 @@ static const struct mei_cfg mei_me_pch15 + MEI_CFG_FW_VER_SUPP, + MEI_CFG_DMA_128, + MEI_CFG_TRC, +- MEI_CFG_FW_SPS, ++ MEI_CFG_FW_SPS_IGN, + }; + + /* diff --git a/queue-5.17/series b/queue-5.17/series index e0a7eb9d6db..ea50837ebf5 100644 --- a/queue-5.17/series +++ b/queue-5.17/series @@ -10,3 +10,15 @@ drm-amdgpu-only-check-for-_pr3-on-dgpus.patch iommu-iova-improve-32-bit-free-space-estimate.patch block-flush-plug-based-on-hardware-and-software-queue-order.patch block-ensure-plug-merging-checks-the-correct-queue-at-least-once.patch +usb-typec-tipd-forward-plug-orientation-to-typec-subsystem.patch +usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch +xhci-fix-garbage-usbsts-being-logged-in-some-cases.patch +xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch +xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch +xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch +mei-me-disable-driver-on-the-ign-firmware.patch +mei-me-add-alder-lake-n-device-id.patch +mei-avoid-iterator-usage-outside-of-list_for_each_entry.patch +bus-mhi-pci_generic-add-mru_default-for-quectel-em1xx-series.patch +bus-mhi-fix-pm_state-conversion-to-string.patch +bus-mhi-fix-mhi-dma-structure-endianness.patch diff --git a/queue-5.17/usb-typec-tipd-forward-plug-orientation-to-typec-subsystem.patch b/queue-5.17/usb-typec-tipd-forward-plug-orientation-to-typec-subsystem.patch new file mode 100644 index 00000000000..0cefe71a725 --- /dev/null +++ b/queue-5.17/usb-typec-tipd-forward-plug-orientation-to-typec-subsystem.patch @@ -0,0 +1,55 @@ +From 676748389f5db74e7d28f9d630eebd75cb8a11b4 Mon Sep 17 00:00:00 2001 +From: Sven Peter +Date: Sat, 26 Feb 2022 13:59:12 +0100 +Subject: usb: typec: tipd: Forward plug orientation to typec subsystem + +From: Sven Peter + +commit 676748389f5db74e7d28f9d630eebd75cb8a11b4 upstream. + +In order to bring up the USB3 PHY on the Apple M1 we need to know the +orientation of the Type-C cable. Extract it from the status register and +forward it to the typec subsystem. + +Reviewed-by: Heikki Krogerus +Cc: stable +Signed-off-by: Sven Peter +Link: https://lore.kernel.org/r/20220226125912.59828-1-sven@svenpeter.dev +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/tipd/core.c | 5 +++++ + drivers/usb/typec/tipd/tps6598x.h | 1 + + 2 files changed, 6 insertions(+) + +--- a/drivers/usb/typec/tipd/core.c ++++ b/drivers/usb/typec/tipd/core.c +@@ -256,6 +256,10 @@ static int tps6598x_connect(struct tps65 + typec_set_pwr_opmode(tps->port, mode); + typec_set_pwr_role(tps->port, TPS_STATUS_TO_TYPEC_PORTROLE(status)); + typec_set_vconn_role(tps->port, TPS_STATUS_TO_TYPEC_VCONN(status)); ++ if (TPS_STATUS_TO_UPSIDE_DOWN(status)) ++ typec_set_orientation(tps->port, TYPEC_ORIENTATION_REVERSE); ++ else ++ typec_set_orientation(tps->port, TYPEC_ORIENTATION_NORMAL); + tps6598x_set_data_role(tps, TPS_STATUS_TO_TYPEC_DATAROLE(status), true); + + tps->partner = typec_register_partner(tps->port, &desc); +@@ -278,6 +282,7 @@ static void tps6598x_disconnect(struct t + typec_set_pwr_opmode(tps->port, TYPEC_PWR_MODE_USB); + typec_set_pwr_role(tps->port, TPS_STATUS_TO_TYPEC_PORTROLE(status)); + typec_set_vconn_role(tps->port, TPS_STATUS_TO_TYPEC_VCONN(status)); ++ typec_set_orientation(tps->port, TYPEC_ORIENTATION_NONE); + tps6598x_set_data_role(tps, TPS_STATUS_TO_TYPEC_DATAROLE(status), false); + + power_supply_changed(tps->psy); +--- a/drivers/usb/typec/tipd/tps6598x.h ++++ b/drivers/usb/typec/tipd/tps6598x.h +@@ -17,6 +17,7 @@ + /* TPS_REG_STATUS bits */ + #define TPS_STATUS_PLUG_PRESENT BIT(0) + #define TPS_STATUS_PLUG_UPSIDE_DOWN BIT(4) ++#define TPS_STATUS_TO_UPSIDE_DOWN(s) (!!((s) & TPS_STATUS_PLUG_UPSIDE_DOWN)) + #define TPS_STATUS_PORTROLE BIT(5) + #define TPS_STATUS_TO_TYPEC_PORTROLE(s) (!!((s) & TPS_STATUS_PORTROLE)) + #define TPS_STATUS_DATAROLE BIT(6) diff --git a/queue-5.17/usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch b/queue-5.17/usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch new file mode 100644 index 00000000000..49e736938ce --- /dev/null +++ b/queue-5.17/usb-usb-storage-fix-use-of-bitfields-for-hardware-data-in-ene_ub6250.c.patch @@ -0,0 +1,353 @@ +From 1892bf90677abcad7f06e897e308f5c3e3618dd4 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 17 Mar 2022 16:39:10 -0400 +Subject: USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c + +From: Alan Stern + +commit 1892bf90677abcad7f06e897e308f5c3e3618dd4 upstream. + +The kernel test robot found a problem with the ene_ub6250 subdriver in +usb-storage: It uses structures containing bitfields to represent +hardware bits in its SD_STATUS, MS_STATUS, and SM_STATUS bytes. This +is not safe; it presumes a particular bit ordering and it assumes the +compiler will not insert padding, neither of which is guaranteed. + +This patch fixes the problem by changing the structures to simple u8 +values, with the bitfields replaced by bitmask constants. + +CC: +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/YjOcbuU106UpJ/V8@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/storage/ene_ub6250.c | 153 +++++++++++++++++++-------------------- + 1 file changed, 75 insertions(+), 78 deletions(-) + +--- a/drivers/usb/storage/ene_ub6250.c ++++ b/drivers/usb/storage/ene_ub6250.c +@@ -237,36 +237,33 @@ static struct us_unusual_dev ene_ub6250_ + #define memstick_logaddr(logadr1, logadr0) ((((u16)(logadr1)) << 8) | (logadr0)) + + +-struct SD_STATUS { +- u8 Insert:1; +- u8 Ready:1; +- u8 MediaChange:1; +- u8 IsMMC:1; +- u8 HiCapacity:1; +- u8 HiSpeed:1; +- u8 WtP:1; +- u8 Reserved:1; +-}; +- +-struct MS_STATUS { +- u8 Insert:1; +- u8 Ready:1; +- u8 MediaChange:1; +- u8 IsMSPro:1; +- u8 IsMSPHG:1; +- u8 Reserved1:1; +- u8 WtP:1; +- u8 Reserved2:1; +-}; +- +-struct SM_STATUS { +- u8 Insert:1; +- u8 Ready:1; +- u8 MediaChange:1; +- u8 Reserved:3; +- u8 WtP:1; +- u8 IsMS:1; +-}; ++/* SD_STATUS bits */ ++#define SD_Insert BIT(0) ++#define SD_Ready BIT(1) ++#define SD_MediaChange BIT(2) ++#define SD_IsMMC BIT(3) ++#define SD_HiCapacity BIT(4) ++#define SD_HiSpeed BIT(5) ++#define SD_WtP BIT(6) ++ /* Bit 7 reserved */ ++ ++/* MS_STATUS bits */ ++#define MS_Insert BIT(0) ++#define MS_Ready BIT(1) ++#define MS_MediaChange BIT(2) ++#define MS_IsMSPro BIT(3) ++#define MS_IsMSPHG BIT(4) ++ /* Bit 5 reserved */ ++#define MS_WtP BIT(6) ++ /* Bit 7 reserved */ ++ ++/* SM_STATUS bits */ ++#define SM_Insert BIT(0) ++#define SM_Ready BIT(1) ++#define SM_MediaChange BIT(2) ++ /* Bits 3-5 reserved */ ++#define SM_WtP BIT(6) ++#define SM_IsMS BIT(7) + + struct ms_bootblock_cis { + u8 bCistplDEVICE[6]; /* 0 */ +@@ -437,9 +434,9 @@ struct ene_ub6250_info { + u8 *bbuf; + + /* for 6250 code */ +- struct SD_STATUS SD_Status; +- struct MS_STATUS MS_Status; +- struct SM_STATUS SM_Status; ++ u8 SD_Status; ++ u8 MS_Status; ++ u8 SM_Status; + + /* ----- SD Control Data ---------------- */ + /*SD_REGISTER SD_Regs; */ +@@ -602,7 +599,7 @@ static int sd_scsi_test_unit_ready(struc + { + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + +- if (info->SD_Status.Insert && info->SD_Status.Ready) ++ if ((info->SD_Status & SD_Insert) && (info->SD_Status & SD_Ready)) + return USB_STOR_TRANSPORT_GOOD; + else { + ene_sd_init(us); +@@ -622,7 +619,7 @@ static int sd_scsi_mode_sense(struct us_ + 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + +- if (info->SD_Status.WtP) ++ if (info->SD_Status & SD_WtP) + usb_stor_set_xfer_buf(mediaWP, 12, srb); + else + usb_stor_set_xfer_buf(mediaNoWP, 12, srb); +@@ -641,9 +638,9 @@ static int sd_scsi_read_capacity(struct + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + usb_stor_dbg(us, "sd_scsi_read_capacity\n"); +- if (info->SD_Status.HiCapacity) { ++ if (info->SD_Status & SD_HiCapacity) { + bl_len = 0x200; +- if (info->SD_Status.IsMMC) ++ if (info->SD_Status & SD_IsMMC) + bl_num = info->HC_C_SIZE-1; + else + bl_num = (info->HC_C_SIZE + 1) * 1024 - 1; +@@ -693,7 +690,7 @@ static int sd_scsi_read(struct us_data * + return USB_STOR_TRANSPORT_ERROR; + } + +- if (info->SD_Status.HiCapacity) ++ if (info->SD_Status & SD_HiCapacity) + bnByte = bn; + + /* set up the command wrapper */ +@@ -733,7 +730,7 @@ static int sd_scsi_write(struct us_data + return USB_STOR_TRANSPORT_ERROR; + } + +- if (info->SD_Status.HiCapacity) ++ if (info->SD_Status & SD_HiCapacity) + bnByte = bn; + + /* set up the command wrapper */ +@@ -1456,7 +1453,7 @@ static int ms_scsi_test_unit_ready(struc + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + + /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */ +- if (info->MS_Status.Insert && info->MS_Status.Ready) { ++ if ((info->MS_Status & MS_Insert) && (info->MS_Status & MS_Ready)) { + return USB_STOR_TRANSPORT_GOOD; + } else { + ene_ms_init(us); +@@ -1476,7 +1473,7 @@ static int ms_scsi_mode_sense(struct us_ + 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + +- if (info->MS_Status.WtP) ++ if (info->MS_Status & MS_WtP) + usb_stor_set_xfer_buf(mediaWP, 12, srb); + else + usb_stor_set_xfer_buf(mediaNoWP, 12, srb); +@@ -1495,7 +1492,7 @@ static int ms_scsi_read_capacity(struct + + usb_stor_dbg(us, "ms_scsi_read_capacity\n"); + bl_len = 0x200; +- if (info->MS_Status.IsMSPro) ++ if (info->MS_Status & MS_IsMSPro) + bl_num = info->MSP_TotalBlock - 1; + else + bl_num = info->MS_Lib.NumberOfLogBlock * info->MS_Lib.blockSize * 2 - 1; +@@ -1650,7 +1647,7 @@ static int ms_scsi_read(struct us_data * + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + +- if (info->MS_Status.IsMSPro) { ++ if (info->MS_Status & MS_IsMSPro) { + result = ene_load_bincode(us, MSP_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + usb_stor_dbg(us, "Load MPS RW pattern Fail !!\n"); +@@ -1751,7 +1748,7 @@ static int ms_scsi_write(struct us_data + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + +- if (info->MS_Status.IsMSPro) { ++ if (info->MS_Status & MS_IsMSPro) { + result = ene_load_bincode(us, MSP_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + pr_info("Load MSP RW pattern Fail !!\n"); +@@ -1859,12 +1856,12 @@ static int ene_get_card_status(struct us + + tmpreg = (u16) reg4b; + reg4b = *(u32 *)(&buf[0x14]); +- if (info->SD_Status.HiCapacity && !info->SD_Status.IsMMC) ++ if ((info->SD_Status & SD_HiCapacity) && !(info->SD_Status & SD_IsMMC)) + info->HC_C_SIZE = (reg4b >> 8) & 0x3fffff; + + info->SD_C_SIZE = ((tmpreg & 0x03) << 10) | (u16)(reg4b >> 22); + info->SD_C_SIZE_MULT = (u8)(reg4b >> 7) & 0x07; +- if (info->SD_Status.HiCapacity && info->SD_Status.IsMMC) ++ if ((info->SD_Status & SD_HiCapacity) && (info->SD_Status & SD_IsMMC)) + info->HC_C_SIZE = *(u32 *)(&buf[0x100]); + + if (info->SD_READ_BL_LEN > SD_BLOCK_LEN) { +@@ -2076,6 +2073,7 @@ static int ene_ms_init(struct us_data *u + u16 MSP_BlockSize, MSP_UserAreaBlocks; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + u8 *bbuf = info->bbuf; ++ unsigned int s; + + printk(KERN_INFO "transport --- ENE_MSInit\n"); + +@@ -2100,15 +2098,16 @@ static int ene_ms_init(struct us_data *u + return USB_STOR_TRANSPORT_ERROR; + } + /* the same part to test ENE */ +- info->MS_Status = *(struct MS_STATUS *) bbuf; ++ info->MS_Status = bbuf[0]; + +- if (info->MS_Status.Insert && info->MS_Status.Ready) { +- printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert); +- printk(KERN_INFO "Ready = %x\n", info->MS_Status.Ready); +- printk(KERN_INFO "IsMSPro = %x\n", info->MS_Status.IsMSPro); +- printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG); +- printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP); +- if (info->MS_Status.IsMSPro) { ++ s = info->MS_Status; ++ if ((s & MS_Insert) && (s & MS_Ready)) { ++ printk(KERN_INFO "Insert = %x\n", !!(s & MS_Insert)); ++ printk(KERN_INFO "Ready = %x\n", !!(s & MS_Ready)); ++ printk(KERN_INFO "IsMSPro = %x\n", !!(s & MS_IsMSPro)); ++ printk(KERN_INFO "IsMSPHG = %x\n", !!(s & MS_IsMSPHG)); ++ printk(KERN_INFO "WtP= %x\n", !!(s & MS_WtP)); ++ if (s & MS_IsMSPro) { + MSP_BlockSize = (bbuf[6] << 8) | bbuf[7]; + MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11]; + info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; +@@ -2169,17 +2168,17 @@ static int ene_sd_init(struct us_data *u + return USB_STOR_TRANSPORT_ERROR; + } + +- info->SD_Status = *(struct SD_STATUS *) bbuf; +- if (info->SD_Status.Insert && info->SD_Status.Ready) { +- struct SD_STATUS *s = &info->SD_Status; ++ info->SD_Status = bbuf[0]; ++ if ((info->SD_Status & SD_Insert) && (info->SD_Status & SD_Ready)) { ++ unsigned int s = info->SD_Status; + + ene_get_card_status(us, bbuf); +- usb_stor_dbg(us, "Insert = %x\n", s->Insert); +- usb_stor_dbg(us, "Ready = %x\n", s->Ready); +- usb_stor_dbg(us, "IsMMC = %x\n", s->IsMMC); +- usb_stor_dbg(us, "HiCapacity = %x\n", s->HiCapacity); +- usb_stor_dbg(us, "HiSpeed = %x\n", s->HiSpeed); +- usb_stor_dbg(us, "WtP = %x\n", s->WtP); ++ usb_stor_dbg(us, "Insert = %x\n", !!(s & SD_Insert)); ++ usb_stor_dbg(us, "Ready = %x\n", !!(s & SD_Ready)); ++ usb_stor_dbg(us, "IsMMC = %x\n", !!(s & SD_IsMMC)); ++ usb_stor_dbg(us, "HiCapacity = %x\n", !!(s & SD_HiCapacity)); ++ usb_stor_dbg(us, "HiSpeed = %x\n", !!(s & SD_HiSpeed)); ++ usb_stor_dbg(us, "WtP = %x\n", !!(s & SD_WtP)); + } else { + usb_stor_dbg(us, "SD Card Not Ready --- %x\n", bbuf[0]); + return USB_STOR_TRANSPORT_ERROR; +@@ -2201,14 +2200,14 @@ static int ene_init(struct us_data *us) + + misc_reg03 = bbuf[0]; + if (misc_reg03 & 0x01) { +- if (!info->SD_Status.Ready) { ++ if (!(info->SD_Status & SD_Ready)) { + result = ene_sd_init(us); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + } + } + if (misc_reg03 & 0x02) { +- if (!info->MS_Status.Ready) { ++ if (!(info->MS_Status & MS_Ready)) { + result = ene_ms_init(us); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; +@@ -2307,14 +2306,14 @@ static int ene_transport(struct scsi_cmn + + /*US_DEBUG(usb_stor_show_command(us, srb)); */ + scsi_set_resid(srb, 0); +- if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) ++ if (unlikely(!(info->SD_Status & SD_Ready) || (info->MS_Status & MS_Ready))) + result = ene_init(us); + if (result == USB_STOR_XFER_GOOD) { + result = USB_STOR_TRANSPORT_ERROR; +- if (info->SD_Status.Ready) ++ if (info->SD_Status & SD_Ready) + result = sd_scsi_irp(us, srb); + +- if (info->MS_Status.Ready) ++ if (info->MS_Status & MS_Ready) + result = ms_scsi_irp(us, srb); + } + return result; +@@ -2378,7 +2377,6 @@ static int ene_ub6250_probe(struct usb_i + + static int ene_ub6250_resume(struct usb_interface *iface) + { +- u8 tmp = 0; + struct us_data *us = usb_get_intfdata(iface); + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + +@@ -2390,17 +2388,16 @@ static int ene_ub6250_resume(struct usb_ + mutex_unlock(&us->dev_mutex); + + info->Power_IsResum = true; +- /*info->SD_Status.Ready = 0; */ +- info->SD_Status = *(struct SD_STATUS *)&tmp; +- info->MS_Status = *(struct MS_STATUS *)&tmp; +- info->SM_Status = *(struct SM_STATUS *)&tmp; ++ /* info->SD_Status &= ~SD_Ready; */ ++ info->SD_Status = 0; ++ info->MS_Status = 0; ++ info->SM_Status = 0; + + return 0; + } + + static int ene_ub6250_reset_resume(struct usb_interface *iface) + { +- u8 tmp = 0; + struct us_data *us = usb_get_intfdata(iface); + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + +@@ -2412,10 +2409,10 @@ static int ene_ub6250_reset_resume(struc + * the device + */ + info->Power_IsResum = true; +- /*info->SD_Status.Ready = 0; */ +- info->SD_Status = *(struct SD_STATUS *)&tmp; +- info->MS_Status = *(struct MS_STATUS *)&tmp; +- info->SM_Status = *(struct SM_STATUS *)&tmp; ++ /* info->SD_Status &= ~SD_Ready; */ ++ info->SD_Status = 0; ++ info->MS_Status = 0; ++ info->SM_Status = 0; + + return 0; + } diff --git a/queue-5.17/xhci-fix-garbage-usbsts-being-logged-in-some-cases.patch b/queue-5.17/xhci-fix-garbage-usbsts-being-logged-in-some-cases.patch new file mode 100644 index 00000000000..75e89c14864 --- /dev/null +++ b/queue-5.17/xhci-fix-garbage-usbsts-being-logged-in-some-cases.patch @@ -0,0 +1,51 @@ +From 3105bc977d7cbf2edc35e24cc7e009686f6e4a56 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Thu, 3 Mar 2022 13:08:56 +0200 +Subject: xhci: fix garbage USBSTS being logged in some cases + +From: Anssi Hannula + +commit 3105bc977d7cbf2edc35e24cc7e009686f6e4a56 upstream. + +xhci_decode_usbsts() is expected to return a zero-terminated string by +its only caller, xhci_stop_endpoint_command_watchdog(), which directly +logs the return value: + + xhci_warn(xhci, "USBSTS:%s\n", xhci_decode_usbsts(str, usbsts)); + +However, if no recognized bits are set in usbsts, the function will +return without having called any sprintf() and therefore return an +untouched non-zero-terminated caller-provided buffer, causing garbage +to be output to log. + +Fix that by always including the raw value in the output. + +Note that before commit 4843b4b5ec64 ("xhci: fix even more unsafe memory +usage in xhci tracing") the result effect in the failure case was different +as a static buffer was used here, but the code still worked incorrectly. + +Fixes: 9c1aa36efdae ("xhci: Show host status when watchdog triggers and host is assumed dead.") +Cc: stable@vger.kernel.org +Signed-off-by: Anssi Hannula +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220303110903.1662404-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -2624,8 +2624,11 @@ static inline const char *xhci_decode_us + { + int ret = 0; + ++ ret = sprintf(str, " 0x%08x", usbsts); ++ + if (usbsts == ~(u32)0) +- return " 0xffffffff"; ++ return str; ++ + if (usbsts & STS_HALT) + ret += sprintf(str + ret, " HCHalted"); + if (usbsts & STS_FATAL) diff --git a/queue-5.17/xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch b/queue-5.17/xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch new file mode 100644 index 00000000000..d6dcbcb7dae --- /dev/null +++ b/queue-5.17/xhci-fix-runtime-pm-imbalance-in-usb2-resume.patch @@ -0,0 +1,41 @@ +From 70c05e4cf63054cd755ca66c1819327b22cb085f Mon Sep 17 00:00:00 2001 +From: Henry Lin +Date: Thu, 3 Mar 2022 13:08:58 +0200 +Subject: xhci: fix runtime PM imbalance in USB2 resume + +From: Henry Lin + +commit 70c05e4cf63054cd755ca66c1819327b22cb085f upstream. + +A race between system resume and device-initiated resume may result in +runtime PM imbalance on USB2 root hub. If a device-initiated resume +starts and system resume xhci_bus_resume() directs U0 before hub driver +sees the resuming device in RESUME state, device-initiated resume will +not be finished in xhci_handle_usb2_port_link_resume(). In this case, +usb_hcd_end_port_resume() call is missing. + +This changes calls usb_hcd_end_port_resume() if resuming device reaches +U0 to keep runtime PM balance. + +Fixes: a231ec41e6f6 ("xhci: refactor U0 link state handling in get_port_status") +Cc: stable@vger.kernel.org +Signed-off-by: Henry Lin +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220303110903.1662404-5-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-hub.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1088,6 +1088,9 @@ static void xhci_get_usb2_port_status(st + if (link_state == XDEV_U2) + *status |= USB_PORT_STAT_L1; + if (link_state == XDEV_U0) { ++ if (bus_state->resume_done[portnum]) ++ usb_hcd_end_port_resume(&port->rhub->hcd->self, ++ portnum); + bus_state->resume_done[portnum] = 0; + clear_bit(portnum, &bus_state->resuming_ports); + if (bus_state->suspended_ports & (1 << portnum)) { diff --git a/queue-5.17/xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch b/queue-5.17/xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch new file mode 100644 index 00000000000..629b5e9b99f --- /dev/null +++ b/queue-5.17/xhci-fix-uninitialized-string-returned-by-xhci_decode_ctrl_ctx.patch @@ -0,0 +1,43 @@ +From 05519b8589a679edb8fa781259893d20bece04ad Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Thu, 3 Mar 2022 13:08:57 +0200 +Subject: xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx() + +From: Anssi Hannula + +commit 05519b8589a679edb8fa781259893d20bece04ad upstream. + +xhci_decode_ctrl_ctx() returns the untouched buffer as-is if both "drop" +and "add" parameters are zero. + +Fix the function to return an empty string in that case. + +It was not immediately clear from the possible call chains whether this +issue is currently actually triggerable or not. + +Note that before commit 4843b4b5ec64 ("xhci: fix even more unsafe memory +usage in xhci tracing") the result effect in the failure case was different +as a static buffer was used here, but the code still worked incorrectly. + +Fixes: 90d6d5731da7 ("xhci: Add tracing for input control context") +Cc: stable@vger.kernel.org +Signed-off-by: Anssi Hannula +Signed-off-by: Mathias Nyman +commit 4843b4b5ec64 ("xhci: fix even more unsafe memory usage in xhci tracing") +Link: https://lore.kernel.org/r/20220303110903.1662404-4-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -2470,6 +2470,8 @@ static inline const char *xhci_decode_ct + unsigned int bit; + int ret = 0; + ++ str[0] = '\0'; ++ + if (drop) { + ret = sprintf(str, "Drop:"); + for_each_set_bit(bit, &drop, 32) diff --git a/queue-5.17/xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch b/queue-5.17/xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch new file mode 100644 index 00000000000..52e34614c70 --- /dev/null +++ b/queue-5.17/xhci-make-xhci_handshake-timeout-for-xhci_reset-adjustable.patch @@ -0,0 +1,176 @@ +From 14073ce951b5919da450022c050772902f24f054 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 3 Mar 2022 13:08:55 +0200 +Subject: xhci: make xhci_handshake timeout for xhci_reset() adjustable + +From: Mathias Nyman + +commit 14073ce951b5919da450022c050772902f24f054 upstream. + +xhci_reset() timeout was increased from 250ms to 10 seconds in order to +give Renesas 720201 xHC enough time to get ready in probe. + +xhci_reset() is called with interrupts disabled in other places, and +waiting for 10 seconds there is not acceptable. + +Add a timeout parameter to xhci_reset(), and adjust it back to 250ms +when called from xhci_stop() or xhci_shutdown() where interrupts are +disabled, and successful reset isn't that critical. +This solves issues when deactivating host mode on platforms like SM8450. + +For now don't change the timeout if xHC is reset in xhci_resume(). +No issues are reported for it, and we need the reset to succeed. +Locking around that reset needs to be revisited later. + +Additionally change the signed integer timeout parameter in +xhci_handshake() to a u64 to match the timeout value we pass to +readl_poll_timeout_atomic() + +Fixes: 22ceac191211 ("xhci: Increase reset timeout for Renesas 720201 host.") +Cc: stable@vger.kernel.org +Reported-by: Sergey Shtylyov +Reported-by: Pavan Kondeti +Tested-by: Pavan Kondeti +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20220303110903.1662404-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-hub.c | 2 +- + drivers/usb/host/xhci-mem.c | 2 +- + drivers/usb/host/xhci.c | 20 +++++++++----------- + drivers/usb/host/xhci.h | 7 +++++-- + 4 files changed, 16 insertions(+), 15 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -762,7 +762,7 @@ static int xhci_exit_test_mode(struct xh + } + pm_runtime_allow(xhci_to_hcd(xhci)->self.controller); + xhci->test_mode = 0; +- return xhci_reset(xhci); ++ return xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + } + + void xhci_set_link_state(struct xhci_hcd *xhci, struct xhci_port *port, +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -2583,7 +2583,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, + + fail: + xhci_halt(xhci); +- xhci_reset(xhci); ++ xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + xhci_mem_cleanup(xhci); + return -ENOMEM; + } +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -65,7 +65,7 @@ static bool td_on_ring(struct xhci_td *t + * handshake done). There are two failure modes: "usec" have passed (major + * hardware flakeout), or the register reads as all-ones (hardware removed). + */ +-int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec) ++int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us) + { + u32 result; + int ret; +@@ -73,7 +73,7 @@ int xhci_handshake(void __iomem *ptr, u3 + ret = readl_poll_timeout_atomic(ptr, result, + (result & mask) == done || + result == U32_MAX, +- 1, usec); ++ 1, timeout_us); + if (result == U32_MAX) /* card removed */ + return -ENODEV; + +@@ -162,7 +162,7 @@ int xhci_start(struct xhci_hcd *xhci) + * Transactions will be terminated immediately, and operational registers + * will be set to their defaults. + */ +-int xhci_reset(struct xhci_hcd *xhci) ++int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us) + { + u32 command; + u32 state; +@@ -195,8 +195,7 @@ int xhci_reset(struct xhci_hcd *xhci) + if (xhci->quirks & XHCI_INTEL_HOST) + udelay(1000); + +- ret = xhci_handshake(&xhci->op_regs->command, +- CMD_RESET, 0, 10 * 1000 * 1000); ++ ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, timeout_us); + if (ret) + return ret; + +@@ -209,8 +208,7 @@ int xhci_reset(struct xhci_hcd *xhci) + * xHCI cannot write to any doorbells or operational registers other + * than status until the "Controller Not Ready" flag is cleared. + */ +- ret = xhci_handshake(&xhci->op_regs->status, +- STS_CNR, 0, 10 * 1000 * 1000); ++ ret = xhci_handshake(&xhci->op_regs->status, STS_CNR, 0, timeout_us); + + xhci->usb2_rhub.bus_state.port_c_suspend = 0; + xhci->usb2_rhub.bus_state.suspended_ports = 0; +@@ -731,7 +729,7 @@ static void xhci_stop(struct usb_hcd *hc + xhci->xhc_state |= XHCI_STATE_HALTED; + xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; + xhci_halt(xhci); +- xhci_reset(xhci); ++ xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + spin_unlock_irq(&xhci->lock); + + xhci_cleanup_msix(xhci); +@@ -784,7 +782,7 @@ void xhci_shutdown(struct usb_hcd *hcd) + xhci_halt(xhci); + /* Workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) +- xhci_reset(xhci); ++ xhci_reset(xhci, XHCI_RESET_SHORT_USEC); + spin_unlock_irq(&xhci->lock); + + xhci_cleanup_msix(xhci); +@@ -1170,7 +1168,7 @@ int xhci_resume(struct xhci_hcd *xhci, b + xhci_dbg(xhci, "Stop HCD\n"); + xhci_halt(xhci); + xhci_zero_64b_regs(xhci); +- retval = xhci_reset(xhci); ++ retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC); + spin_unlock_irq(&xhci->lock); + if (retval) + return retval; +@@ -5316,7 +5314,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, + + xhci_dbg(xhci, "Resetting HCD\n"); + /* Reset the internal HC memory state and registers. */ +- retval = xhci_reset(xhci); ++ retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC); + if (retval) + return retval; + xhci_dbg(xhci, "Reset complete\n"); +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -229,6 +229,9 @@ struct xhci_op_regs { + #define CMD_ETE (1 << 14) + /* bits 15:31 are reserved (and should be preserved on writes). */ + ++#define XHCI_RESET_LONG_USEC (10 * 1000 * 1000) ++#define XHCI_RESET_SHORT_USEC (250 * 1000) ++ + /* IMAN - Interrupt Management Register */ + #define IMAN_IE (1 << 1) + #define IMAN_IP (1 << 0) +@@ -2083,11 +2086,11 @@ void xhci_free_container_ctx(struct xhci + + /* xHCI host controller glue */ + typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); +-int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); ++int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us); + void xhci_quiesce(struct xhci_hcd *xhci); + int xhci_halt(struct xhci_hcd *xhci); + int xhci_start(struct xhci_hcd *xhci); +-int xhci_reset(struct xhci_hcd *xhci); ++int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us); + int xhci_run(struct usb_hcd *hcd); + int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); + void xhci_shutdown(struct usb_hcd *hcd); -- 2.47.3