aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-07-01 16:29:15 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-07-02 08:30:10 -0400
commit632e270e01d8a1ee9e8ea56c83028727f17b1d17 (patch)
tree58cbc127f9f173409f40bbaf27f8ea85c185c52d
parent455716e9b12ba93e93181ac88bef62e4eb5ac66c (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.txt6
-rw-r--r--drivers/base/power/runtime.c9
-rw-r--r--drivers/scsi/scsi_pm.c8
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}