Loading drivers/usb/phy/phy-msm-qusb.c +40 −17 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/usb/phy.h> #include <linux/usb/msm_hsusb.h> #define QUSB2PHY_PORT_POWERDOWN 0xB4 #define CLAMP_N_EN BIT(5) Loading @@ -34,6 +35,13 @@ #define QUSB2PHY_PORT_TUNE3 0x88 #define QUSB2PHY_PORT_TUNE4 0x8C #define QUSB2PHY_PORT_INTR_CTRL 0xBC #define CHG_DET_INTR_EN BIT(4) #define DMSE_INTR_HIGH_SEL BIT(3) #define DMSE_INTR_EN BIT(2) #define DPSE_INTR_HIGH_SEL BIT(1) #define DPSE_INTR_EN BIT(0) #define UTMI_OTG_VBUS_VALID BIT(20) #define SW_SESSVLD_SEL BIT(28) Loading Loading @@ -246,6 +254,7 @@ static void qusb_write_readback(void *base, u32 offset, static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) { struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy); u32 intr_mask = 0; if (!qphy->clocks_enabled) { dev_dbg(phy->dev, "clocks not enabled yet\n"); Loading @@ -259,26 +268,44 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) } if (suspend) { /* Suspend case */ if (qphy->cable_connected) { return -EAGAIN; /* Bus suspend case */ if (qphy->cable_connected || (qphy->phy.flags & PHY_HOST_MODE)) { /* Clear all interrupts */ writel_relaxed(0x00, qphy->base + QUSB2PHY_PORT_INTR_CTRL); /* Enable D+ interrupt */ intr_mask |= DPSE_INTR_EN; /* Select D+ falling edge as the trigger */ intr_mask &= ~DPSE_INTR_HIGH_SEL; writel_relaxed(intr_mask, qphy->base + QUSB2PHY_PORT_INTR_CTRL); clk_disable_unprepare(qphy->cfg_ahb_clk); clk_disable_unprepare(qphy->ref_clk); } else { /* Disconnect case */ /* Disable the PHY */ writel_relaxed(CLAMP_N_EN | FREEZIO_N | POWER_DOWN, qphy->base + QUSB2PHY_PORT_POWERDOWN); clk_disable_unprepare(qphy->cfg_ahb_clk); clk_disable_unprepare(qphy->ref_clk); qusb_phy_enable_power(qphy, false); } qphy->suspended = true; } else { /* Bus suspend case */ if (qphy->cable_connected || (qphy->phy.flags & PHY_HOST_MODE)) { clk_prepare_enable(qphy->ref_clk); clk_prepare_enable(qphy->cfg_ahb_clk); /* Clear all interrupts on resume */ writel_relaxed(0x00, qphy->base + QUSB2PHY_PORT_INTR_CTRL); } else { qusb_phy_enable_power(qphy, true); clk_prepare_enable(qphy->ref_clk); clk_prepare_enable(qphy->cfg_ahb_clk); /* Enable the PHY */ writel_relaxed(CLAMP_N_EN | FREEZIO_N, qphy->base + QUSB2PHY_PORT_POWERDOWN); /* Caller needs to call qusb_phy_init to apply tuning params */ } qphy->suspended = false; } Loading Loading @@ -411,10 +438,6 @@ static int qusb_phy_probe(struct platform_device *pdev) if (ret) return ret; clk_prepare_enable(qphy->ref_clk); clk_prepare_enable(qphy->cfg_ahb_clk); qphy->clocks_enabled = true; platform_set_drvdata(pdev, qphy); qphy->phy.label = "msm-qusb-phy"; Loading Loading
drivers/usb/phy/phy-msm-qusb.c +40 −17 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/usb/phy.h> #include <linux/usb/msm_hsusb.h> #define QUSB2PHY_PORT_POWERDOWN 0xB4 #define CLAMP_N_EN BIT(5) Loading @@ -34,6 +35,13 @@ #define QUSB2PHY_PORT_TUNE3 0x88 #define QUSB2PHY_PORT_TUNE4 0x8C #define QUSB2PHY_PORT_INTR_CTRL 0xBC #define CHG_DET_INTR_EN BIT(4) #define DMSE_INTR_HIGH_SEL BIT(3) #define DMSE_INTR_EN BIT(2) #define DPSE_INTR_HIGH_SEL BIT(1) #define DPSE_INTR_EN BIT(0) #define UTMI_OTG_VBUS_VALID BIT(20) #define SW_SESSVLD_SEL BIT(28) Loading Loading @@ -246,6 +254,7 @@ static void qusb_write_readback(void *base, u32 offset, static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) { struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy); u32 intr_mask = 0; if (!qphy->clocks_enabled) { dev_dbg(phy->dev, "clocks not enabled yet\n"); Loading @@ -259,26 +268,44 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) } if (suspend) { /* Suspend case */ if (qphy->cable_connected) { return -EAGAIN; /* Bus suspend case */ if (qphy->cable_connected || (qphy->phy.flags & PHY_HOST_MODE)) { /* Clear all interrupts */ writel_relaxed(0x00, qphy->base + QUSB2PHY_PORT_INTR_CTRL); /* Enable D+ interrupt */ intr_mask |= DPSE_INTR_EN; /* Select D+ falling edge as the trigger */ intr_mask &= ~DPSE_INTR_HIGH_SEL; writel_relaxed(intr_mask, qphy->base + QUSB2PHY_PORT_INTR_CTRL); clk_disable_unprepare(qphy->cfg_ahb_clk); clk_disable_unprepare(qphy->ref_clk); } else { /* Disconnect case */ /* Disable the PHY */ writel_relaxed(CLAMP_N_EN | FREEZIO_N | POWER_DOWN, qphy->base + QUSB2PHY_PORT_POWERDOWN); clk_disable_unprepare(qphy->cfg_ahb_clk); clk_disable_unprepare(qphy->ref_clk); qusb_phy_enable_power(qphy, false); } qphy->suspended = true; } else { /* Bus suspend case */ if (qphy->cable_connected || (qphy->phy.flags & PHY_HOST_MODE)) { clk_prepare_enable(qphy->ref_clk); clk_prepare_enable(qphy->cfg_ahb_clk); /* Clear all interrupts on resume */ writel_relaxed(0x00, qphy->base + QUSB2PHY_PORT_INTR_CTRL); } else { qusb_phy_enable_power(qphy, true); clk_prepare_enable(qphy->ref_clk); clk_prepare_enable(qphy->cfg_ahb_clk); /* Enable the PHY */ writel_relaxed(CLAMP_N_EN | FREEZIO_N, qphy->base + QUSB2PHY_PORT_POWERDOWN); /* Caller needs to call qusb_phy_init to apply tuning params */ } qphy->suspended = false; } Loading Loading @@ -411,10 +438,6 @@ static int qusb_phy_probe(struct platform_device *pdev) if (ret) return ret; clk_prepare_enable(qphy->ref_clk); clk_prepare_enable(qphy->cfg_ahb_clk); qphy->clocks_enabled = true; platform_set_drvdata(pdev, qphy); qphy->phy.label = "msm-qusb-phy"; Loading