summaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/phy-am335x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/phy/phy-am335x.c')
-rw-r--r--drivers/usb/phy/phy-am335x.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c
index 0e3c60cb669a..12fc3468a01e 100644
--- a/drivers/usb/phy/phy-am335x.c
+++ b/drivers/usb/phy/phy-am335x.c
@@ -63,6 +63,19 @@ static int am335x_phy_probe(struct platform_device *pdev)
am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown;
platform_set_drvdata(pdev, am_phy);
+ device_init_wakeup(dev, true);
+
+ /*
+ * If we leave PHY wakeup enabled then AM33XX wakes up
+ * immediately from DS0. To avoid this we mark dev->power.can_wakeup
+ * to false. The same is checked in suspend routine to decide
+ * on whether to enable PHY wakeup or not.
+ * PHY wakeup works fine in standby mode, there by allowing us to
+ * handle remote wakeup, wakeup on disconnect and connect.
+ */
+
+ device_set_wakeup_enable(dev, false);
+ phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false);
return 0;
}
@@ -75,38 +88,48 @@ static int am335x_phy_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM_RUNTIME
-
-static int am335x_phy_runtime_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int am335x_phy_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct am335x_phy *am_phy = platform_get_drvdata(pdev);
+ /*
+ * Enable phy wakeup only if dev->power.can_wakeup is true.
+ * Make sure to enable wakeup to support remote wakeup in
+ * standby mode ( same is not supported in OFF(DS0) mode).
+ * Enable it by doing
+ * echo enabled > /sys/bus/platform/devices/<usb-phy-id>/power/wakeup
+ */
+
if (device_may_wakeup(dev))
phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, true);
+
phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, false);
+
return 0;
}
-static int am335x_phy_runtime_resume(struct device *dev)
+static int am335x_phy_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct am335x_phy *am_phy = platform_get_drvdata(pdev);
phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, true);
+
if (device_may_wakeup(dev))
phy_ctrl_wkup(am_phy->phy_ctrl, am_phy->id, false);
+
return 0;
}
static const struct dev_pm_ops am335x_pm_ops = {
- SET_RUNTIME_PM_OPS(am335x_phy_runtime_suspend,
- am335x_phy_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(am335x_phy_suspend, am335x_phy_resume)
};
-#define DEV_PM_OPS (&am335x_pm_ops)
+#define DEV_PM_OPS (&am335x_pm_ops)
#else
-#define DEV_PM_OPS NULL
+#define DEV_PM_OPS NULL
#endif
static const struct of_device_id am335x_phy_ids[] = {
OpenPOWER on IntegriCloud