You forgot to Cc the linux-usb mailing list.

On Mon, Mar 25, 2013 at 04:21:42PM +0800, Lan Tianyu wrote:
> This patch is to add usb port system pm support. Add
> usb port's system suspend/resume callbacks and call
> usb_port_runtime_resume/suspend() to power off these
> ports whose pm qos NO_POWER_OFF flag is not set, system
> wakeup is disabled and persist is enalbed.
> 
> During system pm, usb port should be powered off after
> dev being suspended and powered on before dev being
> resumed. Decause usb ports and devs enable async suspend,
> call device_pm_wait_for_dev() in the usb_port_system_suspend()
> and usb_port_resume() to keeping the order.
> 
> Usb_port_system_suspend() ignores EAGAIN from usb_port_runtime_suspend().
> Because EAGAIN is caused by pm qos NO_POWER_OFF setting. This is
> not an error for usb port system pm.
> 
> If usb port was already powered off by runtime pm with
> port_dev->power_is_on being false, usb_port_system_suspend()
> returns directly.
> 
> If usb port was not powered off during system suspend with
> port_dev->power_is_on being true, usb_port_system_resume()
> returns directly.
> 
> Signed-off-by: Lan Tianyu <tianyu....@intel.com>
> ---
>  drivers/usb/core/hub.c  |    4 ++++
>  drivers/usb/core/port.c |   48 
> +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 52 insertions(+)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 5480352..09948b6 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -3146,6 +3146,10 @@ int usb_port_resume(struct usb_device *udev, 
> pm_message_t msg)
>       int             status;
>       u16             portchange, portstatus;
>  
> +     /* Wait for usb port system resume finishing */
> +     if (!PMSG_IS_AUTO(msg))
> +             device_pm_wait_for_dev(&udev->dev, &port_dev->dev);
> +
>       if (port_dev->did_runtime_put) {
>               status = pm_runtime_get_sync(&port_dev->dev);
>               port_dev->did_runtime_put = false;
> diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
> index 797f9d5..553cab3 100644
> --- a/drivers/usb/core/port.c
> +++ b/drivers/usb/core/port.c
> @@ -136,9 +136,57 @@ static int usb_port_runtime_suspend(struct device *dev)
>       usb_autopm_put_interface(intf);
>       return retval;
>  }
> +#else
> +static int usb_port_runtime_suspend(struct device *dev) { return 0; }
> +static int usb_port_runtime_resume(struct device *dev) { return 0; }
>  #endif
>  
> +static int usb_port_system_suspend(struct device *dev)
> +{
> +     struct usb_port *port_dev = to_usb_port(dev);
> +     int retval;
> +
> +     if (!port_dev->power_is_on)
> +             return 0;
> +
> +     if (port_dev->child) {
> +             struct usb_device *udev = port_dev->child;
> +
> +             /*
> +              * usb port can't be powered off when dev's system
> +              * wakeup is enabled or persist is disabled.
> +              */
> +             if (device_may_wakeup(&udev->dev)
> +                             || !udev->persist_enabled)
> +                     return 0;
> +
> +             /*
> +              * usb port should be powered off after usb dev
> +              * being suspended.
> +              */
> +             device_pm_wait_for_dev(dev, &port_dev->child->dev);
> +     }
> +
> +     retval = usb_port_runtime_suspend(dev);
> +     if (retval < 0 && retval != -EAGAIN)
> +             return retval;
> +
> +     return 0;
> +}
> +
> +static int usb_port_system_resume(struct device *dev)
> +{
> +     struct usb_port *port_dev = to_usb_port(dev);
> +
> +     if (port_dev->power_is_on)
> +             return 0;
> +
> +     return usb_port_runtime_resume(dev);
> +}
> +
>  static const struct dev_pm_ops usb_port_pm_ops = {
> +     .suspend =      usb_port_system_suspend,
> +     .resume =       usb_port_system_resume,
>  #ifdef CONFIG_USB_SUSPEND
>       .runtime_suspend =      usb_port_runtime_suspend,
>       .runtime_resume =       usb_port_runtime_resume,
> -- 
> 1.7.9.5
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to