xref: /openbmc/linux/drivers/scsi/scsi_pm.c (revision 1a59d1b8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *	scsi_pm.c	Copyright (C) 2010 Alan Stern
4  *
5  *	SCSI dynamic Power Management
6  *		Initial version: Alan Stern <stern@rowland.harvard.edu>
7  */
8 
9 #include <linux/pm_runtime.h>
10 #include <linux/export.h>
11 #include <linux/async.h>
12 #include <linux/blk-pm.h>
13 
14 #include <scsi/scsi.h>
15 #include <scsi/scsi_device.h>
16 #include <scsi/scsi_driver.h>
17 #include <scsi/scsi_host.h>
18 
19 #include "scsi_priv.h"
20 
21 #ifdef CONFIG_PM_SLEEP
22 
23 static int do_scsi_suspend(struct device *dev, const struct dev_pm_ops *pm)
24 {
25 	return pm && pm->suspend ? pm->suspend(dev) : 0;
26 }
27 
28 static int do_scsi_freeze(struct device *dev, const struct dev_pm_ops *pm)
29 {
30 	return pm && pm->freeze ? pm->freeze(dev) : 0;
31 }
32 
33 static int do_scsi_poweroff(struct device *dev, const struct dev_pm_ops *pm)
34 {
35 	return pm && pm->poweroff ? pm->poweroff(dev) : 0;
36 }
37 
38 static int do_scsi_resume(struct device *dev, const struct dev_pm_ops *pm)
39 {
40 	return pm && pm->resume ? pm->resume(dev) : 0;
41 }
42 
43 static int do_scsi_thaw(struct device *dev, const struct dev_pm_ops *pm)
44 {
45 	return pm && pm->thaw ? pm->thaw(dev) : 0;
46 }
47 
48 static int do_scsi_restore(struct device *dev, const struct dev_pm_ops *pm)
49 {
50 	return pm && pm->restore ? pm->restore(dev) : 0;
51 }
52 
53 static int scsi_dev_type_suspend(struct device *dev,
54 		int (*cb)(struct device *, const struct dev_pm_ops *))
55 {
56 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
57 	int err;
58 
59 	/* flush pending in-flight resume operations, suspend is synchronous */
60 	async_synchronize_full_domain(&scsi_sd_pm_domain);
61 
62 	err = scsi_device_quiesce(to_scsi_device(dev));
63 	if (err == 0) {
64 		err = cb(dev, pm);
65 		if (err)
66 			scsi_device_resume(to_scsi_device(dev));
67 	}
68 	dev_dbg(dev, "scsi suspend: %d\n", err);
69 	return err;
70 }
71 
72 static int scsi_dev_type_resume(struct device *dev,
73 		int (*cb)(struct device *, const struct dev_pm_ops *))
74 {
75 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
76 	int err = 0;
77 
78 	err = cb(dev, pm);
79 	scsi_device_resume(to_scsi_device(dev));
80 	dev_dbg(dev, "scsi resume: %d\n", err);
81 
82 	if (err == 0) {
83 		pm_runtime_disable(dev);
84 		err = pm_runtime_set_active(dev);
85 		pm_runtime_enable(dev);
86 
87 		/*
88 		 * Forcibly set runtime PM status of request queue to "active"
89 		 * to make sure we can again get requests from the queue
90 		 * (see also blk_pm_peek_request()).
91 		 *
92 		 * The resume hook will correct runtime PM status of the disk.
93 		 */
94 		if (!err && scsi_is_sdev_device(dev)) {
95 			struct scsi_device *sdev = to_scsi_device(dev);
96 
97 			if (sdev->request_queue->dev)
98 				blk_set_runtime_active(sdev->request_queue);
99 		}
100 	}
101 
102 	return err;
103 }
104 
105 static int
106 scsi_bus_suspend_common(struct device *dev,
107 		int (*cb)(struct device *, const struct dev_pm_ops *))
108 {
109 	int err = 0;
110 
111 	if (scsi_is_sdev_device(dev)) {
112 		/*
113 		 * All the high-level SCSI drivers that implement runtime
114 		 * PM treat runtime suspend, system suspend, and system
115 		 * hibernate nearly identically. In all cases the requirements
116 		 * for runtime suspension are stricter.
117 		 */
118 		if (pm_runtime_suspended(dev))
119 			return 0;
120 
121 		err = scsi_dev_type_suspend(dev, cb);
122 	}
123 
124 	return err;
125 }
126 
127 static void async_sdev_resume(void *dev, async_cookie_t cookie)
128 {
129 	scsi_dev_type_resume(dev, do_scsi_resume);
130 }
131 
132 static void async_sdev_thaw(void *dev, async_cookie_t cookie)
133 {
134 	scsi_dev_type_resume(dev, do_scsi_thaw);
135 }
136 
137 static void async_sdev_restore(void *dev, async_cookie_t cookie)
138 {
139 	scsi_dev_type_resume(dev, do_scsi_restore);
140 }
141 
142 static int scsi_bus_resume_common(struct device *dev,
143 		int (*cb)(struct device *, const struct dev_pm_ops *))
144 {
145 	async_func_t fn;
146 
147 	if (!scsi_is_sdev_device(dev))
148 		fn = NULL;
149 	else if (cb == do_scsi_resume)
150 		fn = async_sdev_resume;
151 	else if (cb == do_scsi_thaw)
152 		fn = async_sdev_thaw;
153 	else if (cb == do_scsi_restore)
154 		fn = async_sdev_restore;
155 	else
156 		fn = NULL;
157 
158 	if (fn) {
159 		async_schedule_domain(fn, dev, &scsi_sd_pm_domain);
160 
161 		/*
162 		 * If a user has disabled async probing a likely reason
163 		 * is due to a storage enclosure that does not inject
164 		 * staggered spin-ups.  For safety, make resume
165 		 * synchronous as well in that case.
166 		 */
167 		if (strncmp(scsi_scan_type, "async", 5) != 0)
168 			async_synchronize_full_domain(&scsi_sd_pm_domain);
169 	} else {
170 		pm_runtime_disable(dev);
171 		pm_runtime_set_active(dev);
172 		pm_runtime_enable(dev);
173 	}
174 	return 0;
175 }
176 
177 static int scsi_bus_prepare(struct device *dev)
178 {
179 	if (scsi_is_sdev_device(dev)) {
180 		/* sd probing uses async_schedule.  Wait until it finishes. */
181 		async_synchronize_full_domain(&scsi_sd_probe_domain);
182 
183 	} else if (scsi_is_host_device(dev)) {
184 		/* Wait until async scanning is finished */
185 		scsi_complete_async_scans();
186 	}
187 	return 0;
188 }
189 
190 static int scsi_bus_suspend(struct device *dev)
191 {
192 	return scsi_bus_suspend_common(dev, do_scsi_suspend);
193 }
194 
195 static int scsi_bus_resume(struct device *dev)
196 {
197 	return scsi_bus_resume_common(dev, do_scsi_resume);
198 }
199 
200 static int scsi_bus_freeze(struct device *dev)
201 {
202 	return scsi_bus_suspend_common(dev, do_scsi_freeze);
203 }
204 
205 static int scsi_bus_thaw(struct device *dev)
206 {
207 	return scsi_bus_resume_common(dev, do_scsi_thaw);
208 }
209 
210 static int scsi_bus_poweroff(struct device *dev)
211 {
212 	return scsi_bus_suspend_common(dev, do_scsi_poweroff);
213 }
214 
215 static int scsi_bus_restore(struct device *dev)
216 {
217 	return scsi_bus_resume_common(dev, do_scsi_restore);
218 }
219 
220 #else /* CONFIG_PM_SLEEP */
221 
222 #define scsi_bus_prepare		NULL
223 #define scsi_bus_suspend		NULL
224 #define scsi_bus_resume			NULL
225 #define scsi_bus_freeze			NULL
226 #define scsi_bus_thaw			NULL
227 #define scsi_bus_poweroff		NULL
228 #define scsi_bus_restore		NULL
229 
230 #endif /* CONFIG_PM_SLEEP */
231 
232 static int sdev_runtime_suspend(struct device *dev)
233 {
234 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
235 	struct scsi_device *sdev = to_scsi_device(dev);
236 	int err = 0;
237 
238 	err = blk_pre_runtime_suspend(sdev->request_queue);
239 	if (err)
240 		return err;
241 	if (pm && pm->runtime_suspend)
242 		err = pm->runtime_suspend(dev);
243 	blk_post_runtime_suspend(sdev->request_queue, err);
244 
245 	return err;
246 }
247 
248 static int scsi_runtime_suspend(struct device *dev)
249 {
250 	int err = 0;
251 
252 	dev_dbg(dev, "scsi_runtime_suspend\n");
253 	if (scsi_is_sdev_device(dev))
254 		err = sdev_runtime_suspend(dev);
255 
256 	/* Insert hooks here for targets, hosts, and transport classes */
257 
258 	return err;
259 }
260 
261 static int sdev_runtime_resume(struct device *dev)
262 {
263 	struct scsi_device *sdev = to_scsi_device(dev);
264 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
265 	int err = 0;
266 
267 	blk_pre_runtime_resume(sdev->request_queue);
268 	if (pm && pm->runtime_resume)
269 		err = pm->runtime_resume(dev);
270 	blk_post_runtime_resume(sdev->request_queue, err);
271 
272 	return err;
273 }
274 
275 static int scsi_runtime_resume(struct device *dev)
276 {
277 	int err = 0;
278 
279 	dev_dbg(dev, "scsi_runtime_resume\n");
280 	if (scsi_is_sdev_device(dev))
281 		err = sdev_runtime_resume(dev);
282 
283 	/* Insert hooks here for targets, hosts, and transport classes */
284 
285 	return err;
286 }
287 
288 static int scsi_runtime_idle(struct device *dev)
289 {
290 	dev_dbg(dev, "scsi_runtime_idle\n");
291 
292 	/* Insert hooks here for targets, hosts, and transport classes */
293 
294 	if (scsi_is_sdev_device(dev)) {
295 		pm_runtime_mark_last_busy(dev);
296 		pm_runtime_autosuspend(dev);
297 		return -EBUSY;
298 	}
299 
300 	return 0;
301 }
302 
303 int scsi_autopm_get_device(struct scsi_device *sdev)
304 {
305 	int	err;
306 
307 	err = pm_runtime_get_sync(&sdev->sdev_gendev);
308 	if (err < 0 && err !=-EACCES)
309 		pm_runtime_put_sync(&sdev->sdev_gendev);
310 	else
311 		err = 0;
312 	return err;
313 }
314 EXPORT_SYMBOL_GPL(scsi_autopm_get_device);
315 
316 void scsi_autopm_put_device(struct scsi_device *sdev)
317 {
318 	pm_runtime_put_sync(&sdev->sdev_gendev);
319 }
320 EXPORT_SYMBOL_GPL(scsi_autopm_put_device);
321 
322 void scsi_autopm_get_target(struct scsi_target *starget)
323 {
324 	pm_runtime_get_sync(&starget->dev);
325 }
326 
327 void scsi_autopm_put_target(struct scsi_target *starget)
328 {
329 	pm_runtime_put_sync(&starget->dev);
330 }
331 
332 int scsi_autopm_get_host(struct Scsi_Host *shost)
333 {
334 	int	err;
335 
336 	err = pm_runtime_get_sync(&shost->shost_gendev);
337 	if (err < 0 && err !=-EACCES)
338 		pm_runtime_put_sync(&shost->shost_gendev);
339 	else
340 		err = 0;
341 	return err;
342 }
343 
344 void scsi_autopm_put_host(struct Scsi_Host *shost)
345 {
346 	pm_runtime_put_sync(&shost->shost_gendev);
347 }
348 
349 const struct dev_pm_ops scsi_bus_pm_ops = {
350 	.prepare =		scsi_bus_prepare,
351 	.suspend =		scsi_bus_suspend,
352 	.resume =		scsi_bus_resume,
353 	.freeze =		scsi_bus_freeze,
354 	.thaw =			scsi_bus_thaw,
355 	.poweroff =		scsi_bus_poweroff,
356 	.restore =		scsi_bus_restore,
357 	.runtime_suspend =	scsi_runtime_suspend,
358 	.runtime_resume =	scsi_runtime_resume,
359 	.runtime_idle =		scsi_runtime_idle,
360 };
361