Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

JC Kuo and committed by
Thierry Reding
0baabcbe 2d102148

+40 -12
+40 -12
drivers/phy/tegra/xusb-tegra210.c
··· 1799 1799 { 1800 1800 struct tegra_xusb_lane *lane = phy_get_drvdata(phy); 1801 1801 struct tegra_xusb_padctl *padctl = lane->pad->padctl; 1802 + unsigned int index = lane->index; 1803 + struct tegra_xusb_usb2_port *port; 1804 + int err; 1802 1805 u32 value; 1806 + 1807 + port = tegra_xusb_find_usb2_port(padctl, index); 1808 + if (!port) { 1809 + dev_err(&phy->dev, "no port found for USB2 lane %u\n", index); 1810 + return -ENODEV; 1811 + } 1812 + 1813 + if (port->supply && port->mode == USB_DR_MODE_HOST) { 1814 + err = regulator_enable(port->supply); 1815 + if (err) 1816 + return err; 1817 + } 1818 + 1819 + mutex_lock(&padctl->lock); 1803 1820 1804 1821 value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX); 1805 1822 value &= ~(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK << ··· 1825 1808 XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT; 1826 1809 padctl_writel(padctl, value, XUSB_PADCTL_USB2_PAD_MUX); 1827 1810 1811 + mutex_unlock(&padctl->lock); 1812 + 1828 1813 return 0; 1829 1814 } 1830 1815 1831 1816 static int tegra210_usb2_phy_exit(struct phy *phy) 1832 1817 { 1818 + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); 1819 + struct tegra_xusb_padctl *padctl = lane->pad->padctl; 1820 + struct tegra_xusb_usb2_port *port; 1821 + int err; 1822 + 1823 + port = tegra_xusb_find_usb2_port(padctl, lane->index); 1824 + if (!port) { 1825 + dev_err(&phy->dev, "no port found for USB2 lane %u\n", lane->index); 1826 + return -ENODEV; 1827 + } 1828 + 1829 + if (port->supply && port->mode == USB_DR_MODE_HOST) { 1830 + err = regulator_disable(port->supply); 1831 + if (err) 1832 + return err; 1833 + } 1834 + 1833 1835 return 0; 1834 1836 } 1835 1837 ··· 1969 1933 1970 1934 priv = to_tegra210_xusb_padctl(padctl); 1971 1935 1936 + mutex_lock(&padctl->lock); 1937 + 1972 1938 if (port->usb3_port_fake != -1) { 1973 1939 value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); 1974 1940 value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK( ··· 2064 2026 padctl_writel(padctl, value, 2065 2027 XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); 2066 2028 2067 - if (port->supply && port->mode == USB_DR_MODE_HOST) { 2068 - err = regulator_enable(port->supply); 2069 - if (err) 2070 - return err; 2071 - } 2072 - 2073 - mutex_lock(&padctl->lock); 2074 - 2075 2029 if (pad->enable > 0) { 2076 2030 pad->enable++; 2077 2031 mutex_unlock(&padctl->lock); ··· 2072 2042 2073 2043 err = clk_prepare_enable(pad->clk); 2074 2044 if (err) 2075 - goto disable_regulator; 2045 + goto out; 2076 2046 2077 2047 value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); 2078 2048 value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK << ··· 2104 2074 2105 2075 return 0; 2106 2076 2107 - disable_regulator: 2108 - regulator_disable(port->supply); 2077 + out: 2109 2078 mutex_unlock(&padctl->lock); 2110 2079 return err; 2111 2080 } ··· 2163 2134 padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); 2164 2135 2165 2136 out: 2166 - regulator_disable(port->supply); 2167 2137 mutex_unlock(&padctl->lock); 2168 2138 return 0; 2169 2139 }