Re: [PATCH v2] usb: typec: tcpci: pass correct rx_type to tcpm_pd_receive()
Heikki Krogerus <[email protected]> Wed, 5 Aug 2026 12:33:18 +0200
| Newsgroups | org.kernel.vger.linux-usb,dev.linux.lists.imx,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Jul 23, 2026 at 06:46:14PM +0800, Xu Yang wrote: > From: Xu Yang <[email protected]> > > 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: [email protected] > Signed-off-by: Xu Yang <[email protected]> Acked-by: Heikki Krogerus <[email protected]> > --- > Changes in v2: > - add fix tag > - check return value when get RX SOP type > - pass all possible RX message type to tcpm_pd_receive() > - cache TCPC_RX_DETECT to filter out unallowed RX messages as suggested by Badhri > --- > drivers/usb/typec/tcpm/tcpci.c | 12 +++++++++++- > include/linux/usb/tcpci.h | 1 + > 2 files changed, 12 insertions(+), 1 deletion(-) > > 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 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) > 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 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci) > 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)) { > diff --git a/include/linux/usb/tcpci.h b/include/linux/usb/tcpci.h > index f7f5cfbdef12..9b46a6bc762c 100644 > --- a/include/linux/usb/tcpci.h > +++ b/include/linux/usb/tcpci.h > @@ -144,6 +144,7 @@ > #define TCPC_RX_BUF_FRAME_TYPE 0x31 > #define TCPC_RX_BUF_FRAME_TYPE_SOP 0 > #define TCPC_RX_BUF_FRAME_TYPE_SOP1 1 > +#define TCPC_RX_BUF_FRAME_TYPE_MASK GENMASK(2, 0) > #define TCPC_RX_HDR 0x32 > #define TCPC_RX_DATA 0x34 /* through 0x4f */ > > -- > 2.34.1 -- heikki