diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
index ac68b4218b56..e6b6beb38fcb 100644
--- a/drivers/usb/dwc3/dwc3-qcom.c
+++ b/drivers/usb/dwc3/dwc3-qcom.c
@@ -85,6 +85,7 @@ struct dwc3_qcom {
struct icc_path *icc_path_apps;
enum usb_role current_role;
+ bool has_eusb2_phy;
};
#define to_dwc3_qcom(d) container_of((d), struct dwc3_qcom, dwc)@@ -272,15 +273,23 @@ static void dwc3_qcom_disable_wakeup_irq(int irq)
disable_irq_nosync(irq);
}
-static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom_port *port)
+static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom *qcom, int port_index)
{
+ struct dwc3_qcom_port *port = &qcom->ports[port_index];
+
dwc3_qcom_disable_wakeup_irq(port->qusb2_phy_irq);
if (port->usb2_speed == USB_SPEED_LOW) {
- dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
+ else
+ dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
} else if ((port->usb2_speed == USB_SPEED_HIGH) ||
(port->usb2_speed == USB_SPEED_FULL)) {
- dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);
+ else
+ dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
} else {
dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq);
dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq);@@ -289,26 +298,38 @@ static void dwc3_qcom_disable_port_interrupts(struct dwc3_qcom_port *port)
dwc3_qcom_disable_wakeup_irq(port->ss_phy_irq);
}
-static void dwc3_qcom_enable_port_interrupts(struct dwc3_qcom_port *port)
+static void dwc3_qcom_enable_port_interrupts(struct dwc3_qcom *qcom, int port_index)
{
+ struct dwc3_qcom_port *port = &qcom->ports[port_index];
+
dwc3_qcom_enable_wakeup_irq(port->qusb2_phy_irq, 0);
/*
* Configure DP/DM line interrupts based on the USB2 device attached to
- * the root hub port. When HS/FS device is connected, configure the DP line
- * as falling edge to detect both disconnect and remote wakeup scenarios. When
- * LS device is connected, configure DM line as falling edge to detect both
- * disconnect and remote wakeup. When no device is connected, configure both
- * DP and DM lines as rising edge to detect HS/HS/LS device connect scenario.
+ * the root hub port. For non-eUSB2 targets, when HS/FS device is connected,
+ * configure the DP line as falling edge to detect disconnect and remote
+ * wakeup. When LS device is connected, configure the DM line as falling edge
+ * for the same. For eUSB2 targets, the lines are swapped and rising edge is
+ * used: DP line for LS and DM line for HS/FS device detection. When no
+ * device is connected, configure both DP and DM lines as rising edge to
+ * detect HS/FS/LS device connect scenario.
*/
if (port->usb2_speed == USB_SPEED_LOW) {
- dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
- IRQ_TYPE_EDGE_FALLING);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
+ IRQ_TYPE_EDGE_RISING);
+ else
+ dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else if ((port->usb2_speed == USB_SPEED_HIGH) ||
(port->usb2_speed == USB_SPEED_FULL)) {
- dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
- IRQ_TYPE_EDGE_FALLING);
+ if (qcom->has_eusb2_phy)
+ dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq,
+ IRQ_TYPE_EDGE_RISING);
+ else
+ dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else {
dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq,
IRQ_TYPE_EDGE_RISING);@@ -324,7 +345,7 @@ static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
int i;
for (i = 0; i < qcom->num_ports; i++)
- dwc3_qcom_disable_port_interrupts(&qcom->ports[i]);
+ dwc3_qcom_disable_port_interrupts(qcom, i);
}
static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
@@ -332,7 +353,7 @@ static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
int i;
for (i = 0; i < qcom->num_ports; i++)
- dwc3_qcom_enable_port_interrupts(&qcom->ports[i]);
+ dwc3_qcom_enable_port_interrupts(qcom, i);
}
static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup)
@@ -617,6 +638,7 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
int ret;
bool ignore_pipe_clk;
bool wakeup_source;
+ struct phy *phy;
qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
if (!qcom)
@@ -683,6 +705,17 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
if (ignore_pipe_clk)
dwc3_qcom_select_utmi_clk(qcom);
+ phy = devm_of_phy_get_by_index(dev, dev->of_node, 0);
+ if (IS_ERR(phy)) {
+ if (PTR_ERR(phy) != -ENODEV) {
+ ret = dev_err_probe(dev, PTR_ERR(phy),
+ "failed to get usb2 phy\n");
+ goto clk_disable;
+ }
+ phy = NULL;
+ }
+ qcom->has_eusb2_phy = (phy_get_type(phy) == PHY_TYPE_EUSB2);
+
qcom->mode = usb_get_dr_mode(dev);
if (qcom->mode == USB_DR_MODE_HOST) {
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy