phy: tegra: xusb: Tegra210 host mode VBUS control
To support XUSB host controller ELPG, this commit moves VBUS control .phy_power_on()/.phy_power_off() to .phy_init()/.phy_exit(). When XUSB host controller enters ELPG, host driver invokes .phy_power_off(), VBUS should remain ON so that USB devices will not disconnect. VBUS can be turned OFF when host driver invokes .phy_exit() which indicates disabling a USB port. Signed-off-by: JC Kuo <jckuo@nvidia.com> Acked-By: Vinod Koul <vkoul@kernel.org> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
2d10214872
commit
0baabcbedd
|
@ -1799,8 +1799,25 @@ static int tegra210_usb2_phy_init(struct phy *phy)
|
|||
{
|
||||
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
|
||||
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
|
||||
unsigned int index = lane->index;
|
||||
struct tegra_xusb_usb2_port *port;
|
||||
int err;
|
||||
u32 value;
|
||||
|
||||
port = tegra_xusb_find_usb2_port(padctl, index);
|
||||
if (!port) {
|
||||
dev_err(&phy->dev, "no port found for USB2 lane %u\n", index);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (port->supply && port->mode == USB_DR_MODE_HOST) {
|
||||
err = regulator_enable(port->supply);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
mutex_lock(&padctl->lock);
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX);
|
||||
value &= ~(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK <<
|
||||
XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT);
|
||||
|
@ -1808,11 +1825,30 @@ static int tegra210_usb2_phy_init(struct phy *phy)
|
|||
XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT;
|
||||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_PAD_MUX);
|
||||
|
||||
mutex_unlock(&padctl->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra210_usb2_phy_exit(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
|
||||
struct tegra_xusb_padctl *padctl = lane->pad->padctl;
|
||||
struct tegra_xusb_usb2_port *port;
|
||||
int err;
|
||||
|
||||
port = tegra_xusb_find_usb2_port(padctl, lane->index);
|
||||
if (!port) {
|
||||
dev_err(&phy->dev, "no port found for USB2 lane %u\n", lane->index);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (port->supply && port->mode == USB_DR_MODE_HOST) {
|
||||
err = regulator_disable(port->supply);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1933,6 +1969,8 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
|||
|
||||
priv = to_tegra210_xusb_padctl(padctl);
|
||||
|
||||
mutex_lock(&padctl->lock);
|
||||
|
||||
if (port->usb3_port_fake != -1) {
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP);
|
||||
value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(
|
||||
|
@ -2026,14 +2064,6 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
|||
padctl_writel(padctl, value,
|
||||
XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index));
|
||||
|
||||
if (port->supply && port->mode == USB_DR_MODE_HOST) {
|
||||
err = regulator_enable(port->supply);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
mutex_lock(&padctl->lock);
|
||||
|
||||
if (pad->enable > 0) {
|
||||
pad->enable++;
|
||||
mutex_unlock(&padctl->lock);
|
||||
|
@ -2042,7 +2072,7 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
|||
|
||||
err = clk_prepare_enable(pad->clk);
|
||||
if (err)
|
||||
goto disable_regulator;
|
||||
goto out;
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
|
||||
value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK <<
|
||||
|
@ -2074,8 +2104,7 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
|
|||
|
||||
return 0;
|
||||
|
||||
disable_regulator:
|
||||
regulator_disable(port->supply);
|
||||
out:
|
||||
mutex_unlock(&padctl->lock);
|
||||
return err;
|
||||
}
|
||||
|
@ -2134,7 +2163,6 @@ static int tegra210_usb2_phy_power_off(struct phy *phy)
|
|||
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
|
||||
|
||||
out:
|
||||
regulator_disable(port->supply);
|
||||
mutex_unlock(&padctl->lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue