@@ -144,33 +144,83 @@ static int scsi_bus_restore(struct device *dev)
144
144
145
145
#ifdef CONFIG_PM_RUNTIME
146
146
147
+ static int sdev_blk_runtime_suspend (struct scsi_device * sdev ,
148
+ int (* cb )(struct device * ))
149
+ {
150
+ int err ;
151
+
152
+ err = blk_pre_runtime_suspend (sdev -> request_queue );
153
+ if (err )
154
+ return err ;
155
+ if (cb )
156
+ err = cb (& sdev -> sdev_gendev );
157
+ blk_post_runtime_suspend (sdev -> request_queue , err );
158
+
159
+ return err ;
160
+ }
161
+
162
+ static int sdev_runtime_suspend (struct device * dev )
163
+ {
164
+ const struct dev_pm_ops * pm = dev -> driver ? dev -> driver -> pm : NULL ;
165
+ int (* cb )(struct device * ) = pm ? pm -> runtime_suspend : NULL ;
166
+ struct scsi_device * sdev = to_scsi_device (dev );
167
+ int err ;
168
+
169
+ if (sdev -> request_queue -> dev )
170
+ return sdev_blk_runtime_suspend (sdev , cb );
171
+
172
+ err = scsi_dev_type_suspend (dev , cb );
173
+ if (err == - EAGAIN )
174
+ pm_schedule_suspend (dev , jiffies_to_msecs (
175
+ round_jiffies_up_relative (HZ /10 )));
176
+ return err ;
177
+ }
178
+
147
179
static int scsi_runtime_suspend (struct device * dev )
148
180
{
149
181
int err = 0 ;
150
- const struct dev_pm_ops * pm = dev -> driver ? dev -> driver -> pm : NULL ;
151
182
152
183
dev_dbg (dev , "scsi_runtime_suspend\n" );
153
- if (scsi_is_sdev_device (dev )) {
154
- err = scsi_dev_type_suspend (dev ,
155
- pm ? pm -> runtime_suspend : NULL );
156
- if (err == - EAGAIN )
157
- pm_schedule_suspend (dev , jiffies_to_msecs (
158
- round_jiffies_up_relative (HZ /10 )));
159
- }
184
+ if (scsi_is_sdev_device (dev ))
185
+ err = sdev_runtime_suspend (dev );
160
186
161
187
/* Insert hooks here for targets, hosts, and transport classes */
162
188
163
189
return err ;
164
190
}
165
191
166
- static int scsi_runtime_resume (struct device * dev )
192
+ static int sdev_blk_runtime_resume (struct scsi_device * sdev ,
193
+ int (* cb )(struct device * ))
167
194
{
168
195
int err = 0 ;
196
+
197
+ blk_pre_runtime_resume (sdev -> request_queue );
198
+ if (cb )
199
+ err = cb (& sdev -> sdev_gendev );
200
+ blk_post_runtime_resume (sdev -> request_queue , err );
201
+
202
+ return err ;
203
+ }
204
+
205
+ static int sdev_runtime_resume (struct device * dev )
206
+ {
207
+ struct scsi_device * sdev = to_scsi_device (dev );
169
208
const struct dev_pm_ops * pm = dev -> driver ? dev -> driver -> pm : NULL ;
209
+ int (* cb )(struct device * ) = pm ? pm -> runtime_resume : NULL ;
210
+
211
+ if (sdev -> request_queue -> dev )
212
+ return sdev_blk_runtime_resume (sdev , cb );
213
+ else
214
+ return scsi_dev_type_resume (dev , cb );
215
+ }
216
+
217
+ static int scsi_runtime_resume (struct device * dev )
218
+ {
219
+ int err = 0 ;
170
220
171
221
dev_dbg (dev , "scsi_runtime_resume\n" );
172
222
if (scsi_is_sdev_device (dev ))
173
- err = scsi_dev_type_resume (dev , pm ? pm -> runtime_resume : NULL );
223
+ err = sdev_runtime_resume (dev );
174
224
175
225
/* Insert hooks here for targets, hosts, and transport classes */
176
226
@@ -185,10 +235,18 @@ static int scsi_runtime_idle(struct device *dev)
185
235
186
236
/* Insert hooks here for targets, hosts, and transport classes */
187
237
188
- if (scsi_is_sdev_device (dev ))
189
- err = pm_schedule_suspend (dev , 100 );
190
- else
238
+ if (scsi_is_sdev_device (dev )) {
239
+ struct scsi_device * sdev = to_scsi_device (dev );
240
+
241
+ if (sdev -> request_queue -> dev ) {
242
+ pm_runtime_mark_last_busy (dev );
243
+ err = pm_runtime_autosuspend (dev );
244
+ } else {
245
+ err = pm_runtime_suspend (dev );
246
+ }
247
+ } else {
191
248
err = pm_runtime_suspend (dev );
249
+ }
192
250
return err ;
193
251
}
194
252
0 commit comments