USB: PHY: tegra: Call tegra_usb_phy_close only on device removal
authorTuomas Tynkkynen <ttynkkynen@nvidia.com>
Fri, 4 Jul 2014 01:09:39 +0000 (04:09 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jul 2014 23:25:46 +0000 (16:25 -0700)
tegra_usb_phy_close() is supposed to undo the effects of
tegra_usb_phy_init(). It is also currently added as the USB PHY shutdown
callback, which is wrong, since tegra_usb_phy_init() is only called
during probing wheras the shutdown callback can get called multiple
times. This then leads to warnings about unbalanced regulator_disable if
the EHCI driver is unbound and bound again at runtime.

Signed-off-by: Tuomas Tynkkynen <ttynkkynen@nvidia.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/phy/phy-tegra-usb.c

index 467a5e152afa34ab438a0619bc496975db703bc1..50dc69e1666f2d2fedf8a76c7e7e3f8ebee5a6a5 100644 (file)
@@ -685,10 +685,8 @@ static int ulpi_phy_power_off(struct tegra_usb_phy *phy)
        return gpio_direction_output(phy->reset_gpio, 0);
 }
 
-static void tegra_usb_phy_close(struct usb_phy *x)
+static void tegra_usb_phy_close(struct tegra_usb_phy *phy)
 {
-       struct tegra_usb_phy *phy = container_of(x, struct tegra_usb_phy, u_phy);
-
        if (!IS_ERR(phy->vbus))
                regulator_disable(phy->vbus);
 
@@ -1060,14 +1058,13 @@ static int tegra_usb_phy_probe(struct platform_device *pdev)
        if (err < 0)
                return err;
 
-       tegra_phy->u_phy.shutdown = tegra_usb_phy_close;
        tegra_phy->u_phy.set_suspend = tegra_usb_phy_suspend;
 
        platform_set_drvdata(pdev, tegra_phy);
 
        err = usb_add_phy_dev(&tegra_phy->u_phy);
        if (err < 0) {
-               tegra_usb_phy_close(&tegra_phy->u_phy);
+               tegra_usb_phy_close(tegra_phy);
                return err;
        }
 
@@ -1079,6 +1076,7 @@ static int tegra_usb_phy_remove(struct platform_device *pdev)
        struct tegra_usb_phy *tegra_phy = platform_get_drvdata(pdev);
 
        usb_remove_phy(&tegra_phy->u_phy);
+       tegra_usb_phy_close(tegra_phy);
 
        return 0;
 }