usb: pdphy: Prevent sending when message is just received
Prevent pd_phy_write() from sending a TX message if an RX message IRQ is being handled, or if the RX_TOKEN is set (indicating a message has just arrived) by returning -EBUSY to let the upper layer gracefully abort. This helps in cases (such as compliance testing) in which VDM messages are received very quickly after one another and the protocol layer needs to first handle the incoming message. Change-Id: I3e26d7ff062ff7f51b6c66ab8d078b05749f808a Signed-off-by: Jack Pham <jackp@codeaurora.org>
This commit is contained in:
parent
00adcfcbad
commit
71c2e3fc4f
1 changed files with 18 additions and 1 deletions
|
@ -108,6 +108,7 @@ struct usb_pdphy {
|
|||
int tx_status;
|
||||
u8 frame_filter_val;
|
||||
bool in_test_data_mode;
|
||||
bool rx_busy;
|
||||
|
||||
enum data_role data_role;
|
||||
enum power_role power_role;
|
||||
|
@ -492,6 +493,12 @@ int pd_phy_write(u16 hdr, const u8 *data, size_t data_len,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = pdphy_reg_read(pdphy, &val, USB_PDPHY_RX_ACKNOWLEDGE, 1);
|
||||
if (ret || val || pdphy->rx_busy) {
|
||||
dev_err(pdphy->dev, "%s: RX message pending\n", __func__);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
pdphy->tx_status = -EINPROGRESS;
|
||||
|
||||
/* write 2 byte SOP message header */
|
||||
|
@ -664,6 +671,15 @@ static int pd_phy_bist_mode(u8 bist_mode)
|
|||
BIST_MODE_MASK | BIST_ENABLE, bist_mode | BIST_ENABLE);
|
||||
}
|
||||
|
||||
static irqreturn_t pdphy_msg_rx_irq(int irq, void *data)
|
||||
{
|
||||
struct usb_pdphy *pdphy = data;
|
||||
|
||||
pdphy->rx_busy = true;
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static irqreturn_t pdphy_msg_rx_irq_thread(int irq, void *data)
|
||||
{
|
||||
u8 size, rx_status, frame_type;
|
||||
|
@ -720,6 +736,7 @@ static irqreturn_t pdphy_msg_rx_irq_thread(int irq, void *data)
|
|||
false);
|
||||
pdphy->rx_bytes += size + 1;
|
||||
done:
|
||||
pdphy->rx_busy = false;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -805,7 +822,7 @@ static int pdphy_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
|
||||
ret = pdphy_request_irq(pdphy, pdev->dev.of_node,
|
||||
&pdphy->msg_rx_irq, "msg-rx", NULL,
|
||||
&pdphy->msg_rx_irq, "msg-rx", pdphy_msg_rx_irq,
|
||||
pdphy_msg_rx_irq_thread, (IRQF_TRIGGER_RISING | IRQF_ONESHOT));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Reference in a new issue