diff options
Diffstat (limited to 'drivers/usb/pd/qpnp-pdphy.c')
| -rw-r--r-- | drivers/usb/pd/qpnp-pdphy.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c index fa3b71d6ce08..e200c25bc23a 100644 --- a/drivers/usb/pd/qpnp-pdphy.c +++ b/drivers/usb/pd/qpnp-pdphy.c @@ -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; @@ -485,6 +486,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 */ @@ -657,6 +664,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; @@ -713,6 +729,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; } @@ -798,7 +815,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; |
