Sandeep Maheswaram <sanm@xxxxxxxxxxxxxx> writes: > Avoiding phy powerdown in host mode so that it can be wake up by devices. > Set usb controller wakeup capable when wakeup capable devices are > connected to the host. > > Signed-off-by: Sandeep Maheswaram <sanm@xxxxxxxxxxxxxx> > --- > drivers/usb/dwc3/core.c | 47 ++++++++++++++++++++++++++----- > drivers/usb/dwc3/core.h | 1 + > drivers/usb/dwc3/dwc3-qcom.c | 66 +++++++++++++++++++++++++++++++++----------- > 3 files changed, 91 insertions(+), 23 deletions(-) > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index 25c686a7..8370350 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -31,15 +31,19 @@ > #include <linux/usb/gadget.h> > #include <linux/usb/of.h> > #include <linux/usb/otg.h> > +#include <linux/usb/hcd.h> > > #include "core.h" > #include "gadget.h" > #include "io.h" > > #include "debug.h" > +#include "../host/xhci.h" nope > #define DWC3_DEFAULT_AUTOSUSPEND_DELAY 5000 /* ms */ > > +bool need_phy_for_wakeup; nope > + > /** > * dwc3_get_dr_mode - Validates and sets dr_mode > * @dwc: pointer to our context structure > @@ -1627,10 +1631,36 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc) > return ret; > } > > +static void dwc3_set_phy_speed_flags(struct dwc3 *dwc) > +{ > + > + int i, num_ports; > + u32 reg; > + struct usb_hcd *hcd = platform_get_drvdata(dwc->xhci); > + struct xhci_hcd *xhci_hcd = hcd_to_xhci(hcd); > + > + dwc->hs_phy_flags &= ~(PHY_MODE_USB_HOST_HS | PHY_MODE_USB_HOST_LS); > + > + reg = readl(&xhci_hcd->cap_regs->hcs_params1); > + > + num_ports = HCS_MAX_PORTS(reg); > + for (i = 0; i < num_ports; i++) { > + reg = readl(&xhci_hcd->op_regs->port_status_base + i*0x10); > + if (reg & PORT_PE) { > + if (DEV_HIGHSPEED(reg) || DEV_FULLSPEED(reg)) > + dwc->hs_phy_flags |= PHY_MODE_USB_HOST_HS; > + else if (DEV_LOWSPEED(reg)) > + dwc->hs_phy_flags |= PHY_MODE_USB_HOST_LS; > + } > + } > + phy_set_mode(dwc->usb2_generic_phy, dwc->hs_phy_flags); XHCI already supports PHY framework, no? > static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) > { > unsigned long flags; > u32 reg; > + struct usb_hcd *hcd = platform_get_drvdata(dwc->xhci); > > switch (dwc->current_dr_role) { > case DWC3_GCTL_PRTCAP_DEVICE: > @@ -1643,9 +1673,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) > dwc3_core_exit(dwc); > break; > case DWC3_GCTL_PRTCAP_HOST: > + dwc3_set_phy_speed_flags(dwc); > if (!PMSG_IS_AUTO(msg)) { > - dwc3_core_exit(dwc); > - break; > + if (usb_wakeup_enabled_descendants(hcd->self.root_hub)) > + need_phy_for_wakeup = true; should be done in xhci-plat > @@ -1705,11 +1736,13 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) > break; > case DWC3_GCTL_PRTCAP_HOST: > if (!PMSG_IS_AUTO(msg)) { > - ret = dwc3_core_init_for_resume(dwc); > - if (ret) > - return ret; > - dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); > - break; > + if (!need_phy_for_wakeup) { > + ret = dwc3_core_init_for_resume(dwc); > + if (ret) > + return ret; > + dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); > + break; why? -- balbi
Attachment:
signature.asc
Description: PGP signature