Re: [PATCH] usb: Add usb port system pm support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.lan@xxxxxxxxx>
> ---
>  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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux