summaryrefslogtreecommitdiff
path: root/drivers/usb/host/ehci-platform.c
diff options
context:
space:
mode:
authorWu Liang feng <wulf@rock-chips.com>2014-12-24 13:22:19 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-09 23:25:54 +0300
commit314b41b16a71ee824f55e2791fcb92997672da37 (patch)
treea9df21d88f343ee33f85b093a535fcb8780ebe98 /drivers/usb/host/ehci-platform.c
parent96e418543d27212d73f2fec76490f833baa27e3b (diff)
downloadlinux-314b41b16a71ee824f55e2791fcb92997672da37.tar.xz
USB: ehci-platform: Support ehci reset after resume quirk
The Rockchip rk3288 EHCI controller doesn't properly detect the case when a device is removed during suspend. Specifically, when usb resume from suspend, the EHCI controller maintaining the USB state (FLAG_CF is 1, Current Connect Status is 1), but a USB device (like a USB camera on rk3288) may have been disconnected actually. Let's add a quirk to force ehci to go into the usb_root_hub_lost_power() path and reset after resume. This should generally reset the whole controller and all ports and initialize everything cleanly again, and bring the devices back up. As part of this, rename the "hibernation" paramter of ehci_resume() to force_reset since hibernation is simply another case where we can't trust the autodetected status and need to force a reset of devices. Signed-off-by: Wu Liang feng <wulf@rock-chips.com> Reviewed-by: Julius Werner <jwerner@google.com> Reviewed-by: Doug Anderson <dianders@google.com> Reviewed-by: Tomasz Figa <tfiga@google.com> Reviewed-by: Pawel Osciak <posciak@google.com> Reviewed-by: Sonny Rao <sonnyrao@google.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Doug Anderson <dianders@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-platform.c')
-rw-r--r--drivers/usb/host/ehci-platform.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 8557803e6154..db5c29edf6db 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -185,6 +185,10 @@ static int ehci_platform_probe(struct platform_device *dev)
if (of_property_read_bool(dev->dev.of_node, "big-endian"))
ehci->big_endian_mmio = ehci->big_endian_desc = 1;
+ if (of_property_read_bool(dev->dev.of_node,
+ "needs-reset-on-resume"))
+ pdata->reset_on_resume = 1;
+
priv->phy = devm_phy_get(&dev->dev, "usb");
if (IS_ERR(priv->phy)) {
err = PTR_ERR(priv->phy);
@@ -340,7 +344,7 @@ static int ehci_platform_resume(struct device *dev)
return err;
}
- ehci_resume(hcd, false);
+ ehci_resume(hcd, pdata->reset_on_resume);
return 0;
}
#endif /* CONFIG_PM_SLEEP */