Re: [PATCH v3 4/5] pm: use callbacks from dev_pm_ops for scsi devices

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

 



On Friday 12 of October 2012 14:59:37 Aaron Lu wrote:
> Use of pm_message_t is deprecated and device driver is not supposed
> to use that. This patch tries to migrate the SCSI bus level pm callbacks
> to call device's pm callbacks defined in its driver's dev_pm_ops.

Well, as Yoda had said: “Do or do not... there is no try.” ;-)

The patch looks OK, though.

> This is achieved by finding out which device pm callback should be used
> in bus callback function, and then pass that callback function pointer
> as a param to the scsi_bus_{suspend,resume}_common routine, which will
> further pass that callback to scsi_dev_type_{suspend,resume} after
> proper handling.
> 
> The special case for freeze in scsi_bus_suspend_common is not necessary
> since there is no high level SCSI driver has implemented freeze, so no
> need to runtime resume the device if it is in runtime suspended state
> for system freeze, just return like the system suspend/hibernate case.
> 
> Since only sd has implemented drv->suspend/drv->resume, and I'll update
> sd driver to use the new callbacks in the following patch, there is no
> need to fallback to call drv->suspend/drv->resume if dev_pm_ops is NULL.
> 
> Signed-off-by: Aaron Lu <aaron.lu@xxxxxxxxx>
> ---
>  drivers/scsi/scsi_pm.c | 85 ++++++++++++++++++++++++++++++--------------------
>  1 file changed, 52 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
> index 9923b26..6e70a16 100644
> --- a/drivers/scsi/scsi_pm.c
> +++ b/drivers/scsi/scsi_pm.c
> @@ -16,16 +16,14 @@
>  
>  #include "scsi_priv.h"
>  
> -static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg)
> +static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *))
>  {
> -	struct device_driver *drv;
>  	int err;
>  
>  	err = scsi_device_quiesce(to_scsi_device(dev));
>  	if (err == 0) {
> -		drv = dev->driver;
> -		if (drv && drv->suspend) {
> -			err = drv->suspend(dev, msg);
> +		if (cb) {
> +			err = cb(dev);
>  			if (err)
>  				scsi_device_resume(to_scsi_device(dev));
>  		}
> @@ -34,14 +32,12 @@ static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg)
>  	return err;
>  }
>  
> -static int scsi_dev_type_resume(struct device *dev)
> +static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *))
>  {
> -	struct device_driver *drv;
>  	int err = 0;
>  
> -	drv = dev->driver;
> -	if (drv && drv->resume)
> -		err = drv->resume(dev);
> +	if (cb)
> +		err = cb(dev);
>  	scsi_device_resume(to_scsi_device(dev));
>  	dev_dbg(dev, "scsi resume: %d\n", err);
>  	return err;
> @@ -49,35 +45,33 @@ static int scsi_dev_type_resume(struct device *dev)
>  
>  #ifdef CONFIG_PM_SLEEP
>  
> -static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
> +static int
> +scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
>  {
>  	int err = 0;
>  
>  	if (scsi_is_sdev_device(dev)) {
>  		/*
> -		 * sd is the only high-level SCSI driver to implement runtime
> -		 * PM, and sd treats runtime suspend, system suspend, and
> -		 * system hibernate identically (but not system freeze).
> +		 * All the high-level SCSI drivers that implement runtime
> +		 * PM treat runtime suspend, system suspend, and system
> +		 * hibernate identically.
>  		 */
> -		if (pm_runtime_suspended(dev)) {
> -			if (msg.event == PM_EVENT_SUSPEND ||
> -			    msg.event == PM_EVENT_HIBERNATE)
> -				return 0;	/* already suspended */
> +		if (pm_runtime_suspended(dev))
> +			return 0;
>  
> -			/* wake up device so that FREEZE will succeed */
> -			pm_runtime_resume(dev);
> -		}
> -		err = scsi_dev_type_suspend(dev, msg);
> +		err = scsi_dev_type_suspend(dev, cb);
>  	}
> +
>  	return err;
>  }
>  
> -static int scsi_bus_resume_common(struct device *dev)
> +static int
> +scsi_bus_resume_common(struct device *dev, int (*cb)(struct device *))
>  {
>  	int err = 0;
>  
>  	if (scsi_is_sdev_device(dev))
> -		err = scsi_dev_type_resume(dev);
> +		err = scsi_dev_type_resume(dev, cb);
>  
>  	if (err == 0) {
>  		pm_runtime_disable(dev);
> @@ -102,26 +96,49 @@ static int scsi_bus_prepare(struct device *dev)
>  
>  static int scsi_bus_suspend(struct device *dev)
>  {
> -	return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	return scsi_bus_suspend_common(dev, pm ? pm->suspend : NULL);
> +}
> +
> +static int scsi_bus_resume(struct device *dev)
> +{
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	return scsi_bus_resume_common(dev, pm ? pm->resume : NULL);
>  }
>  
>  static int scsi_bus_freeze(struct device *dev)
>  {
> -	return scsi_bus_suspend_common(dev, PMSG_FREEZE);
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	return scsi_bus_suspend_common(dev, pm ? pm->freeze : NULL);
> +}
> +
> +static int scsi_bus_thaw(struct device *dev)
> +{
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	return scsi_bus_resume_common(dev, pm ? pm->thaw : NULL);
>  }
>  
>  static int scsi_bus_poweroff(struct device *dev)
>  {
> -	return scsi_bus_suspend_common(dev, PMSG_HIBERNATE);
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	return scsi_bus_suspend_common(dev, pm ? pm->poweroff : NULL);
> +}
> +
> +static int scsi_bus_restore(struct device *dev)
> +{
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	return scsi_bus_resume_common(dev, pm ? pm->restore : NULL);
>  }
>  
>  #else /* CONFIG_PM_SLEEP */
>  
> -#define scsi_bus_resume_common		NULL
>  #define scsi_bus_prepare		NULL
>  #define scsi_bus_suspend		NULL
> +#define scsi_bus_resume			NULL
>  #define scsi_bus_freeze			NULL
> +#define scsi_bus_thaw			NULL
>  #define scsi_bus_poweroff		NULL
> +#define scsi_bus_restore		NULL
>  
>  #endif /* CONFIG_PM_SLEEP */
>  
> @@ -130,10 +147,11 @@ static int scsi_bus_poweroff(struct device *dev)
>  static int scsi_runtime_suspend(struct device *dev)
>  {
>  	int err = 0;
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>  
>  	dev_dbg(dev, "scsi_runtime_suspend\n");
>  	if (scsi_is_sdev_device(dev)) {
> -		err = scsi_dev_type_suspend(dev, PMSG_AUTO_SUSPEND);
> +		err = scsi_dev_type_suspend(dev, pm ? pm->runtime_suspend : NULL);
>  		if (err == -EAGAIN)
>  			pm_schedule_suspend(dev, jiffies_to_msecs(
>  				round_jiffies_up_relative(HZ/10)));
> @@ -147,10 +165,11 @@ static int scsi_runtime_suspend(struct device *dev)
>  static int scsi_runtime_resume(struct device *dev)
>  {
>  	int err = 0;
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>  
>  	dev_dbg(dev, "scsi_runtime_resume\n");
>  	if (scsi_is_sdev_device(dev))
> -		err = scsi_dev_type_resume(dev);
> +		err = scsi_dev_type_resume(dev, pm ? pm->runtime_resume : NULL);
>  
>  	/* Insert hooks here for targets, hosts, and transport classes */
>  
> @@ -229,11 +248,11 @@ void scsi_autopm_put_host(struct Scsi_Host *shost)
>  const struct dev_pm_ops scsi_bus_pm_ops = {
>  	.prepare =		scsi_bus_prepare,
>  	.suspend =		scsi_bus_suspend,
> -	.resume =		scsi_bus_resume_common,
> +	.resume =		scsi_bus_resume,
>  	.freeze =		scsi_bus_freeze,
> -	.thaw =			scsi_bus_resume_common,
> +	.thaw =			scsi_bus_thaw,
>  	.poweroff =		scsi_bus_poweroff,
> -	.restore =		scsi_bus_resume_common,
> +	.restore =		scsi_bus_restore,
>  	.runtime_suspend =	scsi_runtime_suspend,
>  	.runtime_resume =	scsi_runtime_resume,
>  	.runtime_idle =		scsi_runtime_idle,
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux