summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorXu Yang <xu.yang_2@nxp.com>2026-07-23 18:46:14 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-08-14 10:49:06 +0900
commitb691a07c5f644080374ddd24de6a0e05f5d28744 (patch)
tree922be64a7c3858b0264a95cdb66b9cae943587bb /drivers/usb
parentb1e24de475bf2d66fffc9103f3444b783527d55a (diff)
downloadlinux-next-b691a07c5f644080374ddd24de6a0e05f5d28744.tar.gz
linux-next-b691a07c5f644080374ddd24de6a0e05f5d28744.zip
usb: typec: tcpci: pass correct rx_type to tcpm_pd_receive()
Previously, tcpci_irq() always passed TCPC_TX_SOP as the receive type to tcpm_pd_receive(), ignoring the actual frame type reported by the TCPC_RX_BUF_FRAME_TYPE register. Cache the TCPC_RX_DETECT register value in rx_type_mask variable. When a PD messageis received, read TCPC_RX_BUF_FRAME_TYPE register and handle the message only if its frame type is enabled in mask. The TCPC_RX_BUF_FRAME_TYPE register records the received message type, which has a 1:1 mapping to enum tcpm_transmit_type. Fixes: fb7ff25ae433 ("usb: typec: tcpm: add discover identity support for SOP'") Cc: stable@vger.kernel.org Signed-off-by: Xu Yang <xu.yang_2@nxp.com> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Reviewed-by: Badhri Jagan Sridharan <badhri@google.com> Link: https://patch.msgid.link/20260723104614.3717623-1-xu.yang_2@oss.nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/typec/tcpm/tcpci.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
index 7ac7000b2d13..6717ac914c6a 100644
--- a/drivers/usb/typec/tcpm/tcpci.c
+++ b/drivers/usb/typec/tcpm/tcpci.c
@@ -38,6 +38,7 @@ struct tcpci {
struct regmap *regmap;
unsigned int alert_mask;
+ unsigned int rx_type_mask;
bool controls_vbus;
@@ -488,6 +489,8 @@ static int tcpci_set_pd_rx(struct tcpc_dev *tcpc, bool enable)
if (tcpci->data->cable_comm_capable)
reg |= TCPC_RX_DETECT_SOP1;
}
+
+ tcpci->rx_type_mask = reg;
ret = regmap_write(tcpci->regmap, TCPC_RX_DETECT, reg);
if (ret < 0)
return ret;
@@ -749,6 +752,7 @@ process_status:
if (status & TCPC_ALERT_RX_STATUS) {
struct pd_message msg;
unsigned int cnt, payload_cnt;
+ enum tcpm_transmit_type rx_type;
u16 header;
regmap_read(tcpci->regmap, TCPC_RX_BYTE_CNT, &cnt);
@@ -773,10 +777,16 @@ process_status:
regmap_raw_read(tcpci->regmap, TCPC_RX_DATA,
&msg.payload, payload_cnt);
+ ret = regmap_read(tcpci->regmap, TCPC_RX_BUF_FRAME_TYPE, &rx_type);
+ if (ret)
+ return ret;
+
/* Read complete, clear RX status alert bit */
tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
- tcpm_pd_receive(tcpci->port, &msg, TCPC_TX_SOP);
+ rx_type &= TCPC_RX_BUF_FRAME_TYPE_MASK;
+ if (tcpci->rx_type_mask & BIT(rx_type))
+ tcpm_pd_receive(tcpci->port, &msg, rx_type);
}
if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) {