Message ID | 20210325164057.793954-7-thierry.reding@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Tegra XHCI controller ELPG support | expand |
On 25-03-21, 17:40, Thierry Reding wrote: > From: JC Kuo <jckuo@nvidia.com> > > This commit adds sleepwalk/wake and suspend/resume interfaces > to Tegra XUSB PHY driver. > > Tegra XUSB host controller driver makes use of sleepwalk functions > to enable/disable sleepwalk circuit which is in always-on partition > and can respond to USB resume signals when controller is not powered. > Sleepwalk can be enabled/disabled for any USB UPHY individually. > > - tegra_xusb_padctl_enable_phy_sleepwalk() > - tegra_xusb_padctl_disable_phy_sleepwalk() > > Tegra XUSB host controller driver makes use of wake functions to > enable/disable/query wake circuit which is in always-on partition > can wake system up when USB resume happens. > Wake circuit can be enabled/disabled for any USB PHY individually. > > - tegra_xusb_padctl_enable_phy_wake() > - tegra_xusb_padctl_disable_phy_wake() > - tegra_xusb_padctl_remote_wake_detected() > > This commit also adds two system suspend stubs that can be used to > save and restore XUSB PADCTL context during system suspend and > resume. > - tegra_xusb_padctl_suspend_noirq() > - tegra_xusb_padctl_resume_noirq() Acked-By: Vinod Koul <vkoul@kernel.org>
On Tue, Mar 30, 2021 at 07:53:32PM +0530, Vinod Koul wrote: > On 25-03-21, 17:40, Thierry Reding wrote: > > From: JC Kuo <jckuo@nvidia.com> > > > > This commit adds sleepwalk/wake and suspend/resume interfaces > > to Tegra XUSB PHY driver. > > > > Tegra XUSB host controller driver makes use of sleepwalk functions > > to enable/disable sleepwalk circuit which is in always-on partition > > and can respond to USB resume signals when controller is not powered. > > Sleepwalk can be enabled/disabled for any USB UPHY individually. > > > > - tegra_xusb_padctl_enable_phy_sleepwalk() > > - tegra_xusb_padctl_disable_phy_sleepwalk() > > > > Tegra XUSB host controller driver makes use of wake functions to > > enable/disable/query wake circuit which is in always-on partition > > can wake system up when USB resume happens. > > Wake circuit can be enabled/disabled for any USB PHY individually. > > > > - tegra_xusb_padctl_enable_phy_wake() > > - tegra_xusb_padctl_disable_phy_wake() > > - tegra_xusb_padctl_remote_wake_detected() > > > > This commit also adds two system suspend stubs that can be used to > > save and restore XUSB PADCTL context during system suspend and > > resume. > > - tegra_xusb_padctl_suspend_noirq() > > - tegra_xusb_padctl_resume_noirq() > > Acked-By: Vinod Koul <vkoul@kernel.org> Thanks. I didn't see an Acked-by on patches 7-9. Did I miss them or did you not get around to that yet? Thierry
On Wed, Mar 31, 2021 at 06:38:39PM +0200, Thierry Reding wrote: > On Tue, Mar 30, 2021 at 07:53:32PM +0530, Vinod Koul wrote: > > On 25-03-21, 17:40, Thierry Reding wrote: > > > From: JC Kuo <jckuo@nvidia.com> > > > > > > This commit adds sleepwalk/wake and suspend/resume interfaces > > > to Tegra XUSB PHY driver. > > > > > > Tegra XUSB host controller driver makes use of sleepwalk functions > > > to enable/disable sleepwalk circuit which is in always-on partition > > > and can respond to USB resume signals when controller is not powered. > > > Sleepwalk can be enabled/disabled for any USB UPHY individually. > > > > > > - tegra_xusb_padctl_enable_phy_sleepwalk() > > > - tegra_xusb_padctl_disable_phy_sleepwalk() > > > > > > Tegra XUSB host controller driver makes use of wake functions to > > > enable/disable/query wake circuit which is in always-on partition > > > can wake system up when USB resume happens. > > > Wake circuit can be enabled/disabled for any USB PHY individually. > > > > > > - tegra_xusb_padctl_enable_phy_wake() > > > - tegra_xusb_padctl_disable_phy_wake() > > > - tegra_xusb_padctl_remote_wake_detected() > > > > > > This commit also adds two system suspend stubs that can be used to > > > save and restore XUSB PADCTL context during system suspend and > > > resume. > > > - tegra_xusb_padctl_suspend_noirq() > > > - tegra_xusb_padctl_resume_noirq() > > > > Acked-By: Vinod Koul <vkoul@kernel.org> > > Thanks. I didn't see an Acked-by on patches 7-9. Did I miss them or did > you not get around to that yet? Patch 10 is also missing an Acked-by, I think. Thierry
On Wed, Mar 31, 2021 at 06:45:25PM +0200, Thierry Reding wrote: > On Wed, Mar 31, 2021 at 06:38:39PM +0200, Thierry Reding wrote: > > On Tue, Mar 30, 2021 at 07:53:32PM +0530, Vinod Koul wrote: > > > On 25-03-21, 17:40, Thierry Reding wrote: > > > > From: JC Kuo <jckuo@nvidia.com> > > > > > > > > This commit adds sleepwalk/wake and suspend/resume interfaces > > > > to Tegra XUSB PHY driver. > > > > > > > > Tegra XUSB host controller driver makes use of sleepwalk functions > > > > to enable/disable sleepwalk circuit which is in always-on partition > > > > and can respond to USB resume signals when controller is not powered. > > > > Sleepwalk can be enabled/disabled for any USB UPHY individually. > > > > > > > > - tegra_xusb_padctl_enable_phy_sleepwalk() > > > > - tegra_xusb_padctl_disable_phy_sleepwalk() > > > > > > > > Tegra XUSB host controller driver makes use of wake functions to > > > > enable/disable/query wake circuit which is in always-on partition > > > > can wake system up when USB resume happens. > > > > Wake circuit can be enabled/disabled for any USB PHY individually. > > > > > > > > - tegra_xusb_padctl_enable_phy_wake() > > > > - tegra_xusb_padctl_disable_phy_wake() > > > > - tegra_xusb_padctl_remote_wake_detected() > > > > > > > > This commit also adds two system suspend stubs that can be used to > > > > save and restore XUSB PADCTL context during system suspend and > > > > resume. > > > > - tegra_xusb_padctl_suspend_noirq() > > > > - tegra_xusb_padctl_resume_noirq() > > > > > > Acked-By: Vinod Koul <vkoul@kernel.org> > > > > Thanks. I didn't see an Acked-by on patches 7-9. Did I miss them or did > > you not get around to that yet? > > Patch 10 is also missing an Acked-by, I think. Hang on, I've mixed these up. Patches 7 and 8 were for soc/tegra and dt-bindings, respectively. Patches 9-11 were for the PHY subsystem, so you may have missed them because they were not contiguous within the series. The reason is that patch 9 depends on patch 7, though in retrospect it might have been clearer to put 7 and 8 before the whole set of the PHY patches. Apologies for that. Could you take a look at 9 through 11? 9 and 11 are pretty big, but it's really just the Tegra210 and Tegra186 specific implementations of the functionality introduced in this patch. I've also fixed up the modular build error that Nathan had pointed out on patch 9. Let me know if you want me to resend that. Thierry
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index a34d304677bb..0aadac678191 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -1273,10 +1273,36 @@ static int tegra_xusb_padctl_remove(struct platform_device *pdev) return err; } +static int tegra_xusb_padctl_suspend_noirq(struct device *dev) +{ + struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev); + + if (padctl->soc && padctl->soc->ops && padctl->soc->ops->suspend_noirq) + return padctl->soc->ops->suspend_noirq(padctl); + + return 0; +} + +static int tegra_xusb_padctl_resume_noirq(struct device *dev) +{ + struct tegra_xusb_padctl *padctl = dev_get_drvdata(dev); + + if (padctl->soc && padctl->soc->ops && padctl->soc->ops->resume_noirq) + return padctl->soc->ops->resume_noirq(padctl); + + return 0; +} + +static const struct dev_pm_ops tegra_xusb_padctl_pm_ops = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_xusb_padctl_suspend_noirq, + tegra_xusb_padctl_resume_noirq) +}; + static struct platform_driver tegra_xusb_padctl_driver = { .driver = { .name = "tegra-xusb-padctl", .of_match_table = tegra_xusb_padctl_of_match, + .pm = &tegra_xusb_padctl_pm_ops, }, .probe = tegra_xusb_padctl_probe, .remove = tegra_xusb_padctl_remove, @@ -1343,6 +1369,62 @@ int tegra_xusb_padctl_hsic_set_idle(struct tegra_xusb_padctl *padctl, } EXPORT_SYMBOL_GPL(tegra_xusb_padctl_hsic_set_idle); +int tegra_xusb_padctl_enable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, struct phy *phy, + enum usb_device_speed speed) +{ + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + + if (lane->pad->ops->enable_phy_sleepwalk) + return lane->pad->ops->enable_phy_sleepwalk(lane, speed); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_enable_phy_sleepwalk); + +int tegra_xusb_padctl_disable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, struct phy *phy) +{ + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + + if (lane->pad->ops->disable_phy_sleepwalk) + return lane->pad->ops->disable_phy_sleepwalk(lane); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_disable_phy_sleepwalk); + +int tegra_xusb_padctl_enable_phy_wake(struct tegra_xusb_padctl *padctl, struct phy *phy) +{ + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + + if (lane->pad->ops->enable_phy_wake) + return lane->pad->ops->enable_phy_wake(lane); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_enable_phy_wake); + +int tegra_xusb_padctl_disable_phy_wake(struct tegra_xusb_padctl *padctl, struct phy *phy) +{ + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + + if (lane->pad->ops->disable_phy_wake) + return lane->pad->ops->disable_phy_wake(lane); + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_disable_phy_wake); + +bool tegra_xusb_padctl_remote_wake_detected(struct tegra_xusb_padctl *padctl, struct phy *phy) +{ + struct tegra_xusb_lane *lane = phy_get_drvdata(phy); + + if (lane->pad->ops->remote_wake_detected) + return lane->pad->ops->remote_wake_detected(lane); + + return false; +} +EXPORT_SYMBOL_GPL(tegra_xusb_padctl_remote_wake_detected); + int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl, unsigned int port, bool enable) { diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index e789d5ff4eb8..034f7a2c28d6 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -11,6 +11,7 @@ #include <linux/mutex.h> #include <linux/workqueue.h> +#include <linux/usb/ch9.h> #include <linux/usb/otg.h> #include <linux/usb/role.h> @@ -132,6 +133,11 @@ struct tegra_xusb_lane_ops { void (*remove)(struct tegra_xusb_lane *lane); void (*iddq_enable)(struct tegra_xusb_lane *lane); void (*iddq_disable)(struct tegra_xusb_lane *lane); + int (*enable_phy_sleepwalk)(struct tegra_xusb_lane *lane, enum usb_device_speed speed); + int (*disable_phy_sleepwalk)(struct tegra_xusb_lane *lane); + int (*enable_phy_wake)(struct tegra_xusb_lane *lane); + int (*disable_phy_wake)(struct tegra_xusb_lane *lane); + bool (*remote_wake_detected)(struct tegra_xusb_lane *lane); }; bool tegra_xusb_lane_check(struct tegra_xusb_lane *lane, const char *function); @@ -396,6 +402,8 @@ struct tegra_xusb_padctl_ops { const struct tegra_xusb_padctl_soc *soc); void (*remove)(struct tegra_xusb_padctl *padctl); + int (*suspend_noirq)(struct tegra_xusb_padctl *padctl); + int (*resume_noirq)(struct tegra_xusb_padctl *padctl); int (*usb3_save_context)(struct tegra_xusb_padctl *padctl, unsigned int index); int (*hsic_set_idle)(struct tegra_xusb_padctl *padctl, diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h index 71d956935405..3a35e74cdc61 100644 --- a/include/linux/phy/tegra/xusb.h +++ b/include/linux/phy/tegra/xusb.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2020, NVIDIA CORPORATION. All rights reserved. */ #ifndef PHY_TEGRA_XUSB_H @@ -8,6 +8,7 @@ struct tegra_xusb_padctl; struct device; +enum usb_device_speed; struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev); void tegra_xusb_padctl_put(struct tegra_xusb_padctl *padctl); @@ -23,4 +24,11 @@ int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl, int tegra_phy_xusb_utmi_port_reset(struct phy *phy); int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl, unsigned int port); +int tegra_xusb_padctl_enable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, struct phy *phy, + enum usb_device_speed speed); +int tegra_xusb_padctl_disable_phy_sleepwalk(struct tegra_xusb_padctl *padctl, struct phy *phy); +int tegra_xusb_padctl_enable_phy_wake(struct tegra_xusb_padctl *padctl, struct phy *phy); +int tegra_xusb_padctl_disable_phy_wake(struct tegra_xusb_padctl *padctl, struct phy *phy); +bool tegra_xusb_padctl_remote_wake_detected(struct tegra_xusb_padctl *padctl, struct phy *phy); + #endif /* PHY_TEGRA_XUSB_H */