Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23f8fe7c authored by Hemant Kumar's avatar Hemant Kumar
Browse files

usb: xhci: Power up/down SS phy upon bus suspend/resume



In case HS device is connected SS phy needs to be powered
up before bus goes to U3 state. Similarly SS phy needs to be
powered down after bus goes to U0 state. Otherwise remote
wake up is resulting into link does not transition to U0 and
stay into RESUME state.

Change-Id: Ieb328618ffb9cb74a4f4c129e4609e9ec200e55b
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 5f5def1a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/gfp.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include <linux/usb/phy.h>

#include "xhci.h"
#include "xhci-trace.h"
@@ -945,6 +946,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
			spin_lock_irqsave(&xhci->lock, flags);

			if (time_left) {
				usb_phy_powerdown(hcd->usb3_phy);
				slot_id = xhci_find_slot_id_by_port(hcd,
						xhci, wIndex + 1);
				if (!slot_id) {
@@ -1310,6 +1312,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
			/* unlock to execute stop endpoint commands */
			spin_unlock_irqrestore(&xhci->lock, flags);
			xhci_stop_device(xhci, slot_id, 1);
			usb_phy_powerup(hcd->usb3_phy);
			spin_lock_irqsave(&xhci->lock, flags);

			xhci_set_link_state(xhci, port_array, wIndex, XDEV_U3);
@@ -1515,6 +1518,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
				spin_lock_irqsave(&xhci->lock, flags);
				xhci_set_link_state(xhci, port_array, wIndex,
							XDEV_U0);
				usb_phy_powerdown(hcd->usb3_phy);
				clear_bit(wIndex, &bus_state->resuming_ports);
			}
			bus_state->port_c_suspend |= 1 << wIndex;
+11 −1
Original line number Diff line number Diff line
@@ -347,7 +347,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
	if (device_property_read_u32(&pdev->dev, "usb-core-id", &xhci->core_id))
		xhci->core_id = -EINVAL;

	hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
	hcd->usb_phy = devm_usb_get_phy_by_phandle(pdev->dev.parent, "usb-phy",
			0);
	if (IS_ERR(hcd->usb_phy)) {
		ret = PTR_ERR(hcd->usb_phy);
		if (ret == -EPROBE_DEFER)
@@ -359,6 +360,15 @@ static int xhci_plat_probe(struct platform_device *pdev)
			goto put_usb3_hcd;
	}

	hcd->usb3_phy = devm_usb_get_phy_by_phandle(pdev->dev.parent, "usb-phy",
			1);
	if (IS_ERR(hcd->usb3_phy)) {
		ret = PTR_ERR(hcd->usb3_phy);
		if (ret == -EPROBE_DEFER)
			goto put_usb3_hcd;
		hcd->usb3_phy = NULL;
	}

	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
	if (ret)
		goto disable_usb_phy;
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ struct usb_hcd {
	 * other external phys should be software-transparent
	 */
	struct usb_phy		*usb_phy;
	struct usb_phy		*usb3_phy;
	struct phy		*phy;

	/* Flags that need to be manipulated atomically because they can