Quoting Sandeep Maheswaram (2020-07-08 12:10:16) > configure interrupts based on hs_phy_flag. Set genpd active wakeup flag Please capitalize the start of a sentence. What is 'hs_phy_flag'? > for usb gdsc if wakeup capable devices are connected. This tells us what is happening in the code but doesn't tell us the important part, i.e. _why_ this patch is important. Why do we need to set the genpd active wakeup flag? Why configure interrupt based on hs_phy_flag, whatever that is. > > Signed-off-by: Sandeep Maheswaram <sanm@xxxxxxxxxxxxxx> > --- > drivers/usb/dwc3/dwc3-qcom.c | 73 ++++++++++++++++++++++++++++++++++---------- > 1 file changed, 57 insertions(+), 16 deletions(-) > > diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c > index 1dfd024..8902670 100644 > --- a/drivers/usb/dwc3/dwc3-qcom.c > +++ b/drivers/usb/dwc3/dwc3-qcom.c > @@ -192,21 +194,34 @@ static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom) > > static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom) > { > + struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); > + > if (qcom->hs_phy_irq) { > disable_irq_wake(qcom->hs_phy_irq); > disable_irq_nosync(qcom->hs_phy_irq); > } > + if (dwc->hs_phy_flags & PHY_MODE_USB_HOST_LS) { > + if (qcom->dp_hs_phy_irq) { > + disable_irq_wake(qcom->dp_hs_phy_irq); > + disable_irq_nosync(qcom->dp_hs_phy_irq); > + } > + } else if (dwc->hs_phy_flags & PHY_MODE_USB_HOST_HS) { > + if (qcom->dm_hs_phy_irq) { > + disable_irq_wake(qcom->dm_hs_phy_irq); > + disable_irq_nosync(qcom->dm_hs_phy_irq); > + } > + } else { > > - if (qcom->dp_hs_phy_irq) { > - disable_irq_wake(qcom->dp_hs_phy_irq); > - disable_irq_nosync(qcom->dp_hs_phy_irq); > - } > + if (qcom->dp_hs_phy_irq) { > + disable_irq_wake(qcom->dp_hs_phy_irq); > + disable_irq_nosync(qcom->dp_hs_phy_irq); > + } > > - if (qcom->dm_hs_phy_irq) { > - disable_irq_wake(qcom->dm_hs_phy_irq); > - disable_irq_nosync(qcom->dm_hs_phy_irq); > + if (qcom->dm_hs_phy_irq) { > + disable_irq_wake(qcom->dm_hs_phy_irq); > + disable_irq_nosync(qcom->dm_hs_phy_irq); > + } > } > - I liked the newline. Please keep it. > if (qcom->ss_phy_irq) { > disable_irq_wake(qcom->ss_phy_irq); > disable_irq_nosync(qcom->ss_phy_irq); > @@ -215,21 +230,34 @@ static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom) > > static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom) > { > + struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); > + > if (qcom->hs_phy_irq) { > enable_irq(qcom->hs_phy_irq); > enable_irq_wake(qcom->hs_phy_irq); > } > + if (dwc->hs_phy_flags & PHY_MODE_USB_HOST_LS) { > + if (qcom->dp_hs_phy_irq) { > + enable_irq(qcom->dp_hs_phy_irq); > + enable_irq_wake(qcom->dp_hs_phy_irq); > + } > + } else if (dwc->hs_phy_flags & PHY_MODE_USB_HOST_HS) { > + if (qcom->dm_hs_phy_irq) { > + enable_irq(qcom->dm_hs_phy_irq); > + enable_irq_wake(qcom->dm_hs_phy_irq); > + } > + } else { > > - if (qcom->dp_hs_phy_irq) { > - enable_irq(qcom->dp_hs_phy_irq); > - enable_irq_wake(qcom->dp_hs_phy_irq); > - } > + if (qcom->dp_hs_phy_irq) { > + enable_irq(qcom->dp_hs_phy_irq); > + enable_irq_wake(qcom->dp_hs_phy_irq); > + } > > - if (qcom->dm_hs_phy_irq) { > - enable_irq(qcom->dm_hs_phy_irq); > - enable_irq_wake(qcom->dm_hs_phy_irq); > + if (qcom->dm_hs_phy_irq) { > + enable_irq(qcom->dm_hs_phy_irq); > + enable_irq_wake(qcom->dm_hs_phy_irq); > + } > } > - > if (qcom->ss_phy_irq) { > enable_irq(qcom->ss_phy_irq); > enable_irq_wake(qcom->ss_phy_irq); Can we use the wakeup irq support code in the kernel here? That would be preferred to having the driver enable and disable irq wake at various times when the irq is enabled and disabled (which is also odd by the way). Why can't we request the irqs and leave them enabled all the time? Also it seems like the binding should have 'wakeup-source' in it (see Documentation/devicetree/bindings/power/wakeup-source.txt for more info). > @@ -240,6 +268,14 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) > { > u32 val; > int i; > + struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); > + struct usb_hcd *hcd = platform_get_drvdata(dwc->xhci); > + struct generic_pm_domain *genpd; > + > + genpd = pd_to_genpd(qcom->dev->pm_domain); > + > + if (genpd && usb_wakeup_enabled_descendants(hcd->self.root_hub)) Feels like a comment would be good to explain why wakeup enabled descendants matters here. > + genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; > > if (qcom->is_suspended) > return 0; > @@ -261,6 +297,11 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom) > { > int ret; > int i; > + struct generic_pm_domain *genpd; > + > + genpd = pd_to_genpd(qcom->dev->pm_domain); This does container_of() so it can't return NULL. > + if (genpd) So this check is wrong? > + genpd->flags &= !GENPD_FLAG_ACTIVE_WAKEUP;