aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_pm.c')
-rw-r--r--drivers/scsi/scsi_pm.c62
1 files changed, 16 insertions, 46 deletions
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index af4c050ce6e4..001e9ceda4c3 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -16,6 +16,8 @@
16 16
17#include "scsi_priv.h" 17#include "scsi_priv.h"
18 18
19#ifdef CONFIG_PM_SLEEP
20
19static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *)) 21static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *))
20{ 22{
21 int err; 23 int err;
@@ -43,8 +45,6 @@ static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *))
43 return err; 45 return err;
44} 46}
45 47
46#ifdef CONFIG_PM_SLEEP
47
48static int 48static int
49scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *)) 49scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
50{ 50{
@@ -145,38 +145,22 @@ static int scsi_bus_restore(struct device *dev)
145 145
146#ifdef CONFIG_PM_RUNTIME 146#ifdef CONFIG_PM_RUNTIME
147 147
148static int sdev_blk_runtime_suspend(struct scsi_device *sdev, 148static int sdev_runtime_suspend(struct device *dev)
149 int (*cb)(struct device *))
150{ 149{
150 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
151 struct scsi_device *sdev = to_scsi_device(dev);
151 int err; 152 int err;
152 153
153 err = blk_pre_runtime_suspend(sdev->request_queue); 154 err = blk_pre_runtime_suspend(sdev->request_queue);
154 if (err) 155 if (err)
155 return err; 156 return err;
156 if (cb) 157 if (pm && pm->runtime_suspend)
157 err = cb(&sdev->sdev_gendev); 158 err = pm->runtime_suspend(dev);
158 blk_post_runtime_suspend(sdev->request_queue, err); 159 blk_post_runtime_suspend(sdev->request_queue, err);
159 160
160 return err; 161 return err;
161} 162}
162 163
163static int sdev_runtime_suspend(struct device *dev)
164{
165 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
166 int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL;
167 struct scsi_device *sdev = to_scsi_device(dev);
168 int err;
169
170 if (sdev->request_queue->dev)
171 return sdev_blk_runtime_suspend(sdev, cb);
172
173 err = scsi_dev_type_suspend(dev, cb);
174 if (err == -EAGAIN)
175 pm_schedule_suspend(dev, jiffies_to_msecs(
176 round_jiffies_up_relative(HZ/10)));
177 return err;
178}
179
180static int scsi_runtime_suspend(struct device *dev) 164static int scsi_runtime_suspend(struct device *dev)
181{ 165{
182 int err = 0; 166 int err = 0;
@@ -190,31 +174,20 @@ static int scsi_runtime_suspend(struct device *dev)
190 return err; 174 return err;
191} 175}
192 176
193static int sdev_blk_runtime_resume(struct scsi_device *sdev, 177static int sdev_runtime_resume(struct device *dev)
194 int (*cb)(struct device *))
195{ 178{
179 struct scsi_device *sdev = to_scsi_device(dev);
180 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
196 int err = 0; 181 int err = 0;
197 182
198 blk_pre_runtime_resume(sdev->request_queue); 183 blk_pre_runtime_resume(sdev->request_queue);
199 if (cb) 184 if (pm && pm->runtime_resume)
200 err = cb(&sdev->sdev_gendev); 185 err = pm->runtime_resume(dev);
201 blk_post_runtime_resume(sdev->request_queue, err); 186 blk_post_runtime_resume(sdev->request_queue, err);
202 187
203 return err; 188 return err;
204} 189}
205 190
206static int sdev_runtime_resume(struct device *dev)
207{
208 struct scsi_device *sdev = to_scsi_device(dev);
209 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
210 int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL;
211
212 if (sdev->request_queue->dev)
213 return sdev_blk_runtime_resume(sdev, cb);
214 else
215 return scsi_dev_type_resume(dev, cb);
216}
217
218static int scsi_runtime_resume(struct device *dev) 191static int scsi_runtime_resume(struct device *dev)
219{ 192{
220 int err = 0; 193 int err = 0;
@@ -235,14 +208,11 @@ static int scsi_runtime_idle(struct device *dev)
235 /* Insert hooks here for targets, hosts, and transport classes */ 208 /* Insert hooks here for targets, hosts, and transport classes */
236 209
237 if (scsi_is_sdev_device(dev)) { 210 if (scsi_is_sdev_device(dev)) {
238 struct scsi_device *sdev = to_scsi_device(dev); 211 pm_runtime_mark_last_busy(dev);
239 212 pm_runtime_autosuspend(dev);
240 if (sdev->request_queue->dev) { 213 return -EBUSY;
241 pm_runtime_mark_last_busy(dev);
242 pm_runtime_autosuspend(dev);
243 return -EBUSY;
244 }
245 } 214 }
215
246 return 0; 216 return 0;
247} 217}
248 218