Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions drivers/phy/phy-snps-eusb2.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,8 @@ static int snps_eusb2_hsphy_probe(struct platform_device *pdev)
return PTR_ERR(generic_phy);
}

phy_set_type(generic_phy, PHY_TYPE_EUSB2);

dev_set_drvdata(dev, phy);
phy_set_drvdata(generic_phy, phy);

Expand Down
2 changes: 2 additions & 0 deletions drivers/phy/qualcomm/phy-qcom-m31-eusb2.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ static int m31eusb2_phy_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(phy->phy),
"failed to create phy\n");

phy_set_type(phy->phy, PHY_TYPE_EUSB2);

ret = devm_regulator_bulk_get_const(dev, M31_EUSB_NUM_VREGS,
m31_eusb_phy_vregs, &phy->vregs);
if (ret)
Expand Down
63 changes: 48 additions & 15 deletions drivers/usb/dwc3/dwc3-qcom.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,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)
Expand Down Expand Up @@ -273,15 +274,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);
Expand All @@ -290,26 +299,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);
Expand All @@ -325,15 +346,15 @@ 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)
{
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)
Expand Down Expand Up @@ -620,6 +641,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)
Expand Down Expand Up @@ -686,6 +708,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) {
Expand Down
2 changes: 2 additions & 0 deletions include/dt-bindings/phy/phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@
#define PHY_TYPE_DPHY 10
#define PHY_TYPE_CPHY 11
#define PHY_TYPE_USXGMII 12
#define PHY_TYPE_XAUI 13
#define PHY_TYPE_EUSB2 14

#endif /* _DT_BINDINGS_PHY */
27 changes: 27 additions & 0 deletions include/linux/phy/phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <linux/phy/phy-lvds.h>
#include <linux/phy/phy-mipi-dphy.h>

#include <dt-bindings/phy/phy.h>

struct phy;

enum phy_mode {
Expand Down Expand Up @@ -141,11 +143,13 @@ struct phy_ops {
* @bus_width: Data path width implemented by PHY
* @max_link_rate: Maximum link rate supported by PHY (units to be decided by producer and consumer)
* @mode: PHY mode
* @type: PHY type
*/
struct phy_attrs {
u32 bus_width;
u32 max_link_rate;
enum phy_mode mode;
int type;
};

/**
Expand Down Expand Up @@ -251,6 +255,20 @@ static inline enum phy_mode phy_get_mode(struct phy *phy)
{
return phy->attrs.mode;
}

static inline int phy_get_type(struct phy *phy)
{
if (phy)
return phy->attrs.type;

return PHY_NONE;
}

static inline void phy_set_type(struct phy *phy, int type)
{
phy->attrs.type = type;
}

int phy_reset(struct phy *phy);
int phy_calibrate(struct phy *phy);
int phy_notify_connect(struct phy *phy, int port);
Expand Down Expand Up @@ -384,6 +402,15 @@ static inline enum phy_mode phy_get_mode(struct phy *phy)
return PHY_MODE_INVALID;
}

static inline int phy_get_type(struct phy *phy)
{
return PHY_NONE;
}

static inline void phy_set_type(struct phy *phy, int type)
{
}

static inline int phy_reset(struct phy *phy)
{
if (!phy)
Expand Down
Loading