diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-07-01 16:29:15 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-07-02 08:30:10 -0400 |
commit | 632e270e01d8a1ee9e8ea56c83028727f17b1d17 (patch) | |
tree | 58cbc127f9f173409f40bbaf27f8ea85c185c52d | |
parent | 455716e9b12ba93e93181ac88bef62e4eb5ac66c (diff) |
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>
-rw-r--r-- | Documentation/power/runtime_pm.txt | 6 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 9 | ||||
-rw-r--r-- | drivers/scsi/scsi_pm.c | 8 |
3 files changed, 13 insertions, 10 deletions
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 513c52ef5a42..0ec3d610fc9a 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt | |||
@@ -291,7 +291,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
291 | - execute the subsystem-level suspend callback for the device; returns 0 on | 291 | - execute the subsystem-level suspend callback for the device; returns 0 on |
292 | success, 1 if the device's run-time PM status was already 'suspended', or | 292 | success, 1 if the device's run-time PM status was already 'suspended', or |
293 | error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt | 293 | error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt |
294 | to suspend the device again in future | 294 | to suspend the device again in future and -EACCES means that |
295 | 'power.disable_depth' is different from 0 | ||
295 | 296 | ||
296 | int pm_runtime_autosuspend(struct device *dev); | 297 | int pm_runtime_autosuspend(struct device *dev); |
297 | - same as pm_runtime_suspend() except that the autosuspend delay is taken | 298 | - 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: | |||
304 | success, 1 if the device's run-time PM status was already 'active' or | 305 | success, 1 if the device's run-time PM status was already 'active' or |
305 | error code on failure, where -EAGAIN means it may be safe to attempt to | 306 | error code on failure, where -EAGAIN means it may be safe to attempt to |
306 | resume the device again in future, but 'power.runtime_error' should be | 307 | resume the device again in future, but 'power.runtime_error' should be |
307 | checked additionally | 308 | checked additionally, and -EACCES means that 'power.disable_depth' is |
309 | different from 0 | ||
308 | 310 | ||
309 | int pm_request_idle(struct device *dev); | 311 | int pm_request_idle(struct device *dev); |
310 | - submit a request to execute the subsystem-level idle callback for the | 312 | - submit a request to execute the subsystem-level idle callback for the |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 5f5c4236f006..ee99025be6b3 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -135,8 +135,9 @@ static int rpm_check_suspend_allowed(struct device *dev) | |||
135 | 135 | ||
136 | if (dev->power.runtime_error) | 136 | if (dev->power.runtime_error) |
137 | retval = -EINVAL; | 137 | retval = -EINVAL; |
138 | else if (atomic_read(&dev->power.usage_count) > 0 | 138 | else if (dev->power.disable_depth > 0) |
139 | || dev->power.disable_depth > 0) | 139 | retval = -EACCES; |
140 | else if (atomic_read(&dev->power.usage_count) > 0) | ||
140 | retval = -EAGAIN; | 141 | retval = -EAGAIN; |
141 | else if (!pm_children_suspended(dev)) | 142 | else if (!pm_children_suspended(dev)) |
142 | retval = -EBUSY; | 143 | retval = -EBUSY; |
@@ -262,7 +263,7 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev) | |||
262 | spin_lock_irq(&dev->power.lock); | 263 | spin_lock_irq(&dev->power.lock); |
263 | } | 264 | } |
264 | dev->power.runtime_error = retval; | 265 | dev->power.runtime_error = retval; |
265 | return retval; | 266 | return retval != -EACCES ? retval : -EIO; |
266 | } | 267 | } |
267 | 268 | ||
268 | /** | 269 | /** |
@@ -458,7 +459,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
458 | if (dev->power.runtime_error) | 459 | if (dev->power.runtime_error) |
459 | retval = -EINVAL; | 460 | retval = -EINVAL; |
460 | else if (dev->power.disable_depth > 0) | 461 | else if (dev->power.disable_depth > 0) |
461 | retval = -EAGAIN; | 462 | retval = -EACCES; |
462 | if (retval) | 463 | if (retval) |
463 | goto out; | 464 | goto out; |
464 | 465 | ||
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index d70e91ae60af..d82a023a9015 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c | |||
@@ -144,9 +144,9 @@ int scsi_autopm_get_device(struct scsi_device *sdev) | |||
144 | int err; | 144 | int err; |
145 | 145 | ||
146 | err = pm_runtime_get_sync(&sdev->sdev_gendev); | 146 | err = pm_runtime_get_sync(&sdev->sdev_gendev); |
147 | if (err < 0) | 147 | if (err < 0 && err !=-EACCES) |
148 | pm_runtime_put_sync(&sdev->sdev_gendev); | 148 | pm_runtime_put_sync(&sdev->sdev_gendev); |
149 | else if (err > 0) | 149 | else |
150 | err = 0; | 150 | err = 0; |
151 | return err; | 151 | return err; |
152 | } | 152 | } |
@@ -173,9 +173,9 @@ int scsi_autopm_get_host(struct Scsi_Host *shost) | |||
173 | int err; | 173 | int err; |
174 | 174 | ||
175 | err = pm_runtime_get_sync(&shost->shost_gendev); | 175 | err = pm_runtime_get_sync(&shost->shost_gendev); |
176 | if (err < 0) | 176 | if (err < 0 && err !=-EACCES) |
177 | pm_runtime_put_sync(&shost->shost_gendev); | 177 | pm_runtime_put_sync(&shost->shost_gendev); |
178 | else if (err > 0) | 178 | else |
179 | err = 0; | 179 | err = 0; |
180 | return err; | 180 | return err; |
181 | } | 181 | } |