PM / Runtime: Return special error code if runtime PM is disabled

Some callers of pm_runtime_get_sync() and other runtime PM helper
functions, scsi_autopm_get_host() and scsi_autopm_get_device() in
particular, need to distinguish error codes returned when runtime PM
is disabled (i.e. power.disable_depth is nonzero for the given
device) from error codes returned in other situations.  For this
reason, make the runtime PM helper functions return -EACCES when
power.disable_depth is nonzero and ensure that this error code
won't be returned by them in any other circumstances.  Modify
scsi_autopm_get_host() and scsi_autopm_get_device() to check the
error code returned by pm_runtime_get_sync() and ignore -EACCES.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
This commit is contained in:
Rafael J. Wysocki 2011-07-01 22:29:15 +02:00
Родитель 455716e9b1
Коммит 632e270e01
3 изменённых файлов: 13 добавлений и 10 удалений

Просмотреть файл

@ -291,7 +291,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
- execute the subsystem-level suspend callback for the device; returns 0 on - execute the subsystem-level suspend callback for the device; returns 0 on
success, 1 if the device's run-time PM status was already 'suspended', or success, 1 if the device's run-time PM status was already 'suspended', or
error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt
to suspend the device again in future to suspend the device again in future and -EACCES means that
'power.disable_depth' is different from 0
int pm_runtime_autosuspend(struct device *dev); int pm_runtime_autosuspend(struct device *dev);
- same as pm_runtime_suspend() except that the autosuspend delay is taken - same as pm_runtime_suspend() except that the autosuspend delay is taken
@ -304,7 +305,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
success, 1 if the device's run-time PM status was already 'active' or success, 1 if the device's run-time PM status was already 'active' or
error code on failure, where -EAGAIN means it may be safe to attempt to error code on failure, where -EAGAIN means it may be safe to attempt to
resume the device again in future, but 'power.runtime_error' should be resume the device again in future, but 'power.runtime_error' should be
checked additionally checked additionally, and -EACCES means that 'power.disable_depth' is
different from 0
int pm_request_idle(struct device *dev); int pm_request_idle(struct device *dev);
- submit a request to execute the subsystem-level idle callback for the - submit a request to execute the subsystem-level idle callback for the

Просмотреть файл

@ -135,8 +135,9 @@ static int rpm_check_suspend_allowed(struct device *dev)
if (dev->power.runtime_error) if (dev->power.runtime_error)
retval = -EINVAL; retval = -EINVAL;
else if (atomic_read(&dev->power.usage_count) > 0 else if (dev->power.disable_depth > 0)
|| dev->power.disable_depth > 0) retval = -EACCES;
else if (atomic_read(&dev->power.usage_count) > 0)
retval = -EAGAIN; retval = -EAGAIN;
else if (!pm_children_suspended(dev)) else if (!pm_children_suspended(dev))
retval = -EBUSY; retval = -EBUSY;
@ -262,7 +263,7 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
spin_lock_irq(&dev->power.lock); spin_lock_irq(&dev->power.lock);
} }
dev->power.runtime_error = retval; dev->power.runtime_error = retval;
return retval; return retval != -EACCES ? retval : -EIO;
} }
/** /**
@ -458,7 +459,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
if (dev->power.runtime_error) if (dev->power.runtime_error)
retval = -EINVAL; retval = -EINVAL;
else if (dev->power.disable_depth > 0) else if (dev->power.disable_depth > 0)
retval = -EAGAIN; retval = -EACCES;
if (retval) if (retval)
goto out; goto out;

Просмотреть файл

@ -144,9 +144,9 @@ int scsi_autopm_get_device(struct scsi_device *sdev)
int err; int err;
err = pm_runtime_get_sync(&sdev->sdev_gendev); err = pm_runtime_get_sync(&sdev->sdev_gendev);
if (err < 0) if (err < 0 && err !=-EACCES)
pm_runtime_put_sync(&sdev->sdev_gendev); pm_runtime_put_sync(&sdev->sdev_gendev);
else if (err > 0) else
err = 0; err = 0;
return err; return err;
} }
@ -173,9 +173,9 @@ int scsi_autopm_get_host(struct Scsi_Host *shost)
int err; int err;
err = pm_runtime_get_sync(&shost->shost_gendev); err = pm_runtime_get_sync(&shost->shost_gendev);
if (err < 0) if (err < 0 && err !=-EACCES)
pm_runtime_put_sync(&shost->shost_gendev); pm_runtime_put_sync(&shost->shost_gendev);
else if (err > 0) else
err = 0; err = 0;
return err; return err;
} }