On Wed, 12 Jun 2013, Alan Stern wrote: > On Wed, 12 Jun 2013, Manjunath Goudar wrote: > > > Suspend scenario in case of ohci-at91 glue was not properly > > handled as it was not suspending generic part of ohci controller. > > Calling explicitly the ohci_suspend()routine in ohci_hcd_at91_drv_suspend() > > will ensure proper handling of suspend scenario. > > > diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c > > index fb2f127..28400a7 100644 > > --- a/drivers/usb/host/ohci-at91.c > > +++ b/drivers/usb/host/ohci-at91.c > > @@ -619,8 +619,12 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) > > { > > struct usb_hcd *hcd = platform_get_drvdata(pdev); > > struct ohci_hcd *ohci = hcd_to_ohci(hcd); > > + bool do_wakeup = device_may_wakeup(&pdev->dev); > > + int ret; > > > > - if (device_may_wakeup(&pdev->dev)) > > + ret = ohci_suspend(hcd, do_wakeup); > > + > > + if (do_wakeup) > > enable_irq_wake(hcd->irq); > > > > /* > > @@ -637,7 +641,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) > > at91_stop_clock(); > > } > > > > - return 0; > > + return ret; > > If ohci_suspend() fails, we should return right away. Don't execute > the enable_irq_wake() and all the other stuff. Actually, the situation is more complicated. In order to handle races with remote wakeup, the logic we need is more like this: Index: usb-3.10/drivers/usb/host/ohci-at91.c =================================================================== --- usb-3.10.orig/drivers/usb/host/ohci-at91.c +++ usb-3.10/drivers/usb/host/ohci-at91.c @@ -674,8 +674,18 @@ ohci_hcd_at91_drv_suspend(struct platfor { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_hcd *ohci = hcd_to_ohci(hcd); + bool do_wakeup = device_may_wakeup(&pdev->dev); + int ret; - if (device_may_wakeup(&pdev->dev)) + ret = ohci_suspend(hcd, do_wakeup); + if (ret == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) { + ohci_resume(hcd, false); + ret = -EBUSY; + } + if (ret) + return ret; + + if (do_wakeup) enable_irq_wake(hcd->irq); /* @@ -692,7 +702,7 @@ ohci_hcd_at91_drv_suspend(struct platfor at91_stop_clock(); } - return 0; + return ret; } static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) The same is true for all the other drivers. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html