aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_pm.c62
-rw-r--r--drivers/scsi/sr.c37
2 files changed, 29 insertions, 70 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
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 119d67f9c47e..40d85929aefe 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -161,14 +161,10 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
161 goto out; 161 goto out;
162 cd = scsi_cd(disk); 162 cd = scsi_cd(disk);
163 kref_get(&cd->kref); 163 kref_get(&cd->kref);
164 if (scsi_device_get(cd->device)) 164 if (scsi_device_get(cd->device)) {
165 goto out_put; 165 kref_put(&cd->kref, sr_kref_release);
166 if (!scsi_autopm_get_device(cd->device)) 166 cd = NULL;
167 goto out; 167 }
168
169 out_put:
170 kref_put(&cd->kref, sr_kref_release);
171 cd = NULL;
172 out: 168 out:
173 mutex_unlock(&sr_ref_mutex); 169 mutex_unlock(&sr_ref_mutex);
174 return cd; 170 return cd;
@@ -180,7 +176,6 @@ static void scsi_cd_put(struct scsi_cd *cd)
180 176
181 mutex_lock(&sr_ref_mutex); 177 mutex_lock(&sr_ref_mutex);
182 kref_put(&cd->kref, sr_kref_release); 178 kref_put(&cd->kref, sr_kref_release);
183 scsi_autopm_put_device(sdev);
184 scsi_device_put(sdev); 179 scsi_device_put(sdev);
185 mutex_unlock(&sr_ref_mutex); 180 mutex_unlock(&sr_ref_mutex);
186} 181}
@@ -558,8 +553,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
558 void __user *argp = (void __user *)arg; 553 void __user *argp = (void __user *)arg;
559 int ret; 554 int ret;
560 555
561 scsi_autopm_get_device(cd->device);
562
563 mutex_lock(&sr_mutex); 556 mutex_lock(&sr_mutex);
564 557
565 /* 558 /*
@@ -591,7 +584,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
591 584
592out: 585out:
593 mutex_unlock(&sr_mutex); 586 mutex_unlock(&sr_mutex);
594 scsi_autopm_put_device(cd->device);
595 return ret; 587 return ret;
596} 588}
597 589
@@ -599,17 +591,11 @@ static unsigned int sr_block_check_events(struct gendisk *disk,
599 unsigned int clearing) 591 unsigned int clearing)
600{ 592{
601 struct scsi_cd *cd = scsi_cd(disk); 593 struct scsi_cd *cd = scsi_cd(disk);
602 unsigned int ret;
603 594
604 if (atomic_read(&cd->device->disk_events_disable_depth) == 0) { 595 if (atomic_read(&cd->device->disk_events_disable_depth))
605 scsi_autopm_get_device(cd->device); 596 return 0;
606 ret = cdrom_check_events(&cd->cdi, clearing);
607 scsi_autopm_put_device(cd->device);
608 } else {
609 ret = 0;
610 }
611 597
612 return ret; 598 return cdrom_check_events(&cd->cdi, clearing);
613} 599}
614 600
615static int sr_block_revalidate_disk(struct gendisk *disk) 601static int sr_block_revalidate_disk(struct gendisk *disk)
@@ -617,8 +603,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
617 struct scsi_cd *cd = scsi_cd(disk); 603 struct scsi_cd *cd = scsi_cd(disk);
618 struct scsi_sense_hdr sshdr; 604 struct scsi_sense_hdr sshdr;
619 605
620 scsi_autopm_get_device(cd->device);
621
622 /* if the unit is not ready, nothing more to do */ 606 /* if the unit is not ready, nothing more to do */
623 if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) 607 if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
624 goto out; 608 goto out;
@@ -626,7 +610,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
626 sr_cd_check(&cd->cdi); 610 sr_cd_check(&cd->cdi);
627 get_sectorsize(cd); 611 get_sectorsize(cd);
628out: 612out:
629 scsi_autopm_put_device(cd->device);
630 return 0; 613 return 0;
631} 614}
632 615
@@ -747,6 +730,12 @@ static int sr_probe(struct device *dev)
747 if (register_cdrom(&cd->cdi)) 730 if (register_cdrom(&cd->cdi))
748 goto fail_put; 731 goto fail_put;
749 732
733 /*
734 * Initialize block layer runtime PM stuffs before the
735 * periodic event checking request gets started in add_disk.
736 */
737 blk_pm_runtime_init(sdev->request_queue, dev);
738
750 dev_set_drvdata(dev, cd); 739 dev_set_drvdata(dev, cd);
751 disk->flags |= GENHD_FL_REMOVABLE; 740 disk->flags |= GENHD_FL_REMOVABLE;
752 add_disk(disk); 741 add_disk(disk);