Re: [PATCH v2] usb: typec: tcpci: pass correct rx_type to tcpm_pd_receive()

Heikki Krogerus <[email protected]>
Newsgroups dev.linux.lists.imx,org.kernel.vger.linux-kernel,org.kernel.vger.linux-usb
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.