diff options
Diffstat (limited to 'drivers/scsi/scsi_pm.c')
| -rw-r--r-- | drivers/scsi/scsi_pm.c | 62 |
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 | |||
| 19 | static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *)) | 21 | static 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 | |||
| 48 | static int | 48 | static int |
| 49 | scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *)) | 49 | scsi_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 | ||
| 148 | static int sdev_blk_runtime_suspend(struct scsi_device *sdev, | 148 | static 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 | ||
| 163 | static 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 | |||
| 180 | static int scsi_runtime_suspend(struct device *dev) | 164 | static 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 | ||
| 193 | static int sdev_blk_runtime_resume(struct scsi_device *sdev, | 177 | static 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 | ||
| 206 | static 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 | |||
| 218 | static int scsi_runtime_resume(struct device *dev) | 191 | static 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 | ||
