Re: [PATCH v2] usb: typec: tcpci: pass correct rx_type to tcpm_pd_receive()
Badhri Jagan Sridharan <[email protected]> Thu, 6 Aug 2026 02:09:24 -0700
| Newsgroups | org.kernel.vger.linux-usb,dev.linux.lists.imx,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAPTae5LkT5EqCi8w4oTRNxX9oWdi4eovZ41u7LMGrG=64ocJUw@mail.gmail.com> |
On Wed, Aug 5, 2026 at 3:33 AM Heikki Krogerus <[email protected]> wrote: > > 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]> Reviewed-by: Badhri Jagan Sridharan <[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