summaryrefslogtreecommitdiffstats
path: root/Documentation/power/runtime_pm.rst
blob: 0553008b62798a5520b258f057673ccd00a65d02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
==================================================
Runtime Power Management Framework for I/O Devices
==================================================

(C) 2009-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.

(C) 2010 Alan Stern <stern@rowland.harvard.edu>

(C) 2014 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>

1. Introduction
===============

Support for runtime power management (runtime PM) of I/O devices is provided
at the power management core (PM core) level by means of:

* The power management workqueue pm_wq in which bus types and device drivers can
  put their PM-related work items.  It is strongly recommended that pm_wq be
  used for queuing all work items related to runtime PM, because this allows
  them to be synchronized with system-wide power transitions (suspend to RAM,
  hibernation and resume from system sleep states).  pm_wq is declared in
  include/linux/pm_runtime.h and defined in kernel/power/main.c.

* A number of runtime PM fields in the 'power' member of 'struct device' (which
  is of the type 'struct dev_pm_info', defined in include/linux/pm.h) that can
  be used for synchronizing runtime PM operations with one another.

* Three device runtime PM callbacks in 'struct dev_pm_ops' (defined in
  include/linux/pm.h).

* A set of helper functions defined in drivers/base/power/runtime.c that can be
  used for carrying out runtime PM operations in such a way that the
  synchronization between them is taken care of by the PM core.  Bus types and
  device drivers are encouraged to use these functions.

The runtime PM callbacks present in 'struct dev_pm_ops', the device runtime PM
fields of 'struct dev_pm_info' and the core helper functions provided for
runtime PM are described below.

2. Device Runtime PM Callbacks
==============================

There are three device runtime PM callbacks defined in 'struct dev_pm_ops'::

  struct dev_pm_ops {
	...
	int (*runtime_suspend)(struct device *dev);
	int (*runtime_resume)(struct device *dev);
	int (*runtime_idle)(struct device *dev);
	...
  };

The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks
are executed by the PM core for the device's subsystem that may be either of
the following:

  1. PM domain of the device, if the device's PM domain object, dev->pm_domain,
     is present.

  2. Device type of the device, if both dev->type and dev->type->pm are present.

  3. Device class of the device, if both dev->class and dev->class->pm are
     present.

  4. Bus type of the device, if both dev->bus and dev->bus->pm are present.

If the subsystem chosen by applying the above rules doesn't provide the relevant
callback, the PM core will invoke the corresponding driver callback stored in
dev->driver->pm directly (if present).

The PM core always checks which callback to use in the order given above, so the
priority order of callbacks from high to low is: PM domain, device type, class
and bus type.  Moreover, the high-priority one will always take precedence over
a low-priority one.  The PM domain, bus type, device type and class callbacks
are referred to as subsystem-level callbacks in what follows.

By default, the callbacks are always invoked in process context with interrupts
enabled.  However, the pm_runtime_irq_safe() helper function can be used to tell
the PM core that it is safe to run the ->runtime_suspend(), ->runtime_resume()
and ->runtime_idle() callbacks for the given device in atomic context with
interrupts disabled.  This implies that the callback routines in question must
not block or sleep, but it also means that the synchronous helper functions
listed at the end of Section 4 may be used for that device within an interrupt
handler or generally in an atomic context.

The subsystem-level suspend callback, if present, is _entirely_ _responsible_
for handling the suspend of the device as appropriate, which may, but need not
include executing the device driver's own ->runtime_suspend() callback (from the
PM core's point of view it is not necessary to implement a ->runtime_suspend()
callback in a device driver as long as the subsystem-level suspend callback
knows what to do to handle the device).

  * Once the subsystem-level suspend callback (or the driver suspend callback,
    if invoked directly) has completed successfully for the given device, the PM
    core regards the device as suspended, which need not mean that it has been
    put into a low power state.  It is supposed to mean, however, that the
    device will not process data and will not communicate with the CPU(s) and
    RAM until the appropriate resume callback is executed for it.  The runtime
    PM status of a device after successful execution of the suspend callback is
    'suspended'.

  * If the suspend callback returns -EBUSY or -EAGAIN, the device's runtime PM
    status remains 'active', which means that the device _must_ be fully
    operational afterwards.

  * If the suspend callback returns an error code different from -EBUSY and
    -EAGAIN, the PM core regards this as a fatal error and will refuse to run
    the helper functions described in Section 4 for the device until its status
    is directly set to  either 'active', or 'suspended' (the PM core provides
    special helper functions for this purpose).

In particular, if the driver requires remote wakeup capability (i.e. hardware
mechanism allowing the device to request a change of its power state, such as
PCI PME) for proper functioning and device_can_wakeup() returns 'false' for the
device, then ->runtime_suspend() should return -EBUSY.  On the other hand, if
device_can_wakeup() returns 'true' for the device and the device is put into a
low-power state during the execution of the suspend callback, it is expected
that remote wakeup will be enabled for the device.  Generally, remote wakeup
should be enabled for all input devices put into low-power states at run time.

The subsystem-level resume callback, if present, is **entirely responsible** for
handling the resume of the device as appropriate, which may, but need not
include executing the device driver's own ->runtime_resume() callback (from the
PM core's point of view it is not necessary to implement a ->runtime_resume()
callback in a device driver as long as the subsystem-level resume callback knows
what to do to handle the device).

  * Once the subsystem-level resume callback (or the driver resume callback, if
    invoked directly) has completed successfully, the PM core regards the device
    as fully operational, which means that the device _must_ be able to complete
    I/O operations as needed.  The runtime PM status of the device is then
    'active'.

  * If the resume callback returns an error code, the PM core regards this as a
    fatal error and will refuse to run the helper functions described in Section
    4 for the device, until its status is directly set to either 'active', or
    'suspended' (by means of special helper functions provided by the PM core
    for this purpose).

The idle callback (a subsystem-level one, if present, or the driver one) is
executed by the PM core whenever the device appears to be idle, which is
indicated to the PM core by two counters, the device's usage counter and the
counter of 'active' children of the device.

  * If any of these counters is decreased using a helper function provided by
    the PM core and it turns out to be equal to zero, the other counter is
    checked.  If that counter also is equal to zero, the PM core executes the
    idle callback with the device as its argument.

The action performed by the idle callback is totally dependent on the subsystem
(or driver) in question, but the expected and recommended action is to check
if the device can be suspended (i.e. if all of the conditions necessary for
suspending the device are satisfied) and to queue up a suspend request for the
device in that case.  If there is no idle callback, or if the callback returns
0, then the PM core will attempt to carry out a runtime suspend of the device,
also respecting devices configured for autosuspend.  In essence this means a
call to pm_runtime_autosuspend() (do note that drivers needs to update the
device last busy mark, pm_runtime_mark_last_busy(), to control the delay under
this circumstance).  To prevent this (for example, if the callback routine has
started a delayed suspend), the routine must return a non-zero value.  Negative
error return codes are ignored by the PM core.

The helper functions provided by the PM core, described in Section 4, guarantee
that the following constraints are met with respect to runtime PM callbacks for
one device:

(1) The callbacks are mutually exclusive (e.g. it is forbidden to execute
    ->runtime_suspend() in parallel with ->runtime_resume() or with another
    instance of ->runtime_suspend() for the same device) with the exception that
    ->runtime_suspend() or ->runtime_resume() can be executed in parallel with
    ->runtime_idle() (although ->runtime_idle() will not be started while any
    of the other callbacks is being executed for the same device).

(2) ->runtime_idle() and ->runtime_suspend() can only be executed for 'active'
    devices (i.e. the PM core will only execute ->runtime_idle() or
    ->runtime_suspend() for the devices the runtime PM status of which is
    'active').

(3) ->runtime_idle() and ->runtime_suspend() can only be executed for a device
    the usage counter of which is equal to zero _and_ either the counter of
    'active' children of which is equal to zero, or the 'power.ignore_children'
    flag of which is set.

(4) ->runtime_resume() can only be executed for 'suspended' devices  (i.e. the
    PM core will only execute ->runtime_resume() for the devices the runtime
    PM status of which is 'suspended').

Additionally, the helper functions provided by the PM core obey the following
rules:

  * If ->runtime_suspend() is about to be executed or there's a pending request
    to execute it, ->runtime_idle() will not be executed for the same device.

  * A request to execute or to schedule the execution of ->runtime_suspend()
    will cancel any pending requests to execute ->runtime_idle() for the same
    device.

  * If ->runtime_resume() is about to be executed or there's a pending request
    to execute it, the other callbacks will not be executed for the same device.

  * A request to execute ->runtime_resume() will cancel any pending or
    scheduled requests to execute the other callbacks for the same device,
    except for scheduled autosuspends.

3. Runtime PM Device Fields
===========================

The following device runtime PM fields are present in 'struct dev_pm_info', as
defined in include/linux/pm.h:

  `struct timer_list suspend_timer;`
    - timer used for scheduling (delayed) suspend and autosuspend requests

  `unsigned long timer_expires;`
    - timer expiration time, in jiffies (if this is different from zero, the
      timer is running and will expire at that time, otherwise the timer is not
      running)

  `struct work_struct work;`
    - work structure used for queuing up requests (i.e. work items in pm_wq)

  `wait_queue_head_t wait_queue;`
    - wait queue used if any of the helper functions needs to wait for another
      one to complete

  `spinlock_t lock;`
    - lock used for synchronization

  `atomic_t usage_count;`
    - the usage counter of the device

  `atomic_t child_count;`
    - the count of 'active' children of the device

  `unsigned int ignore_children;`
    - if set, the value of child_count is ignored (but still updated)

  `unsigned int disable_depth;`
    - used for disabling the helper functions (they work normally if this is
      equal to zero); the initial value of it is 1 (i.e. runtime PM is
      initially disabled for all devices)

  `int runtime_error;`
    - if set, there was a fatal error (one of the callbacks returned error code
      as described in Section 2), so the helper functions will not work until
      this flag is cleared; this is the error code returned by the failing
      callback

  `unsigned int idle_notification;`
    - if set, ->runtime_idle() is being executed

  `unsigned int request_pending;`
    - if set, there's a pending request (i.e. a work item queued up into pm_wq)

  `enum rpm_request request;`
    - type of request that's pending (valid if request_pending is set)

  `unsigned int deferred_resume;`
    - set if ->runtime_resume() is about to be run while ->runtime_suspend() is
      being executed for that device and it is not practical to wait for the
      suspend to complete; means "start a resume as soon as you've suspended"

  `enum rpm_status runtime_status;`
    - the runtime PM status of the device; this field's initial value is
      RPM_SUSPENDED, which means that each device is initially regarded by the
      PM core as 'suspended', regardless of its real hardware status

  `unsigned int runtime_auto;`
    - if set, indicates that the user space has allowed the device driver to
      power manage the device at run time via the /sys/devices/.../power/control
      `interface;` it may only be modified with the help of the
      pm_runtime_allow() and pm_runtime_forbid() helper functions

  `unsigned int no_callbacks;`
    - indicates that the device does not use the runtime PM callbacks (see
      Section 8); it may be modified only by the pm_runtime_no_callbacks()
      helper function

  `unsigned int irq_safe;`
    - indicates that the ->runtime_suspend() and ->runtime_resume() callbacks
      will be invoked with the spinlock held and interrupts disabled

  `unsigned int use_autosuspend;`
    - indicates that the device's driver supports delayed autosuspend (see
      Section 9); it may be modified only by the
      pm_runtime{_dont}_use_autosuspend() helper functions

  `unsigned int timer_autosuspends;`
    - indicates that the PM core should attempt to carry out an autosuspend
      when the timer expires rather than a normal suspend

  `int autosuspend_delay;`
    - the delay time (in milliseconds) to be used for autosuspend

  `unsigned long last_busy;`
    - the time (in jiffies) when the pm_runtime_mark_last_busy() helper
      function was last called for this device; used in calculating inactivity
      periods for autosuspend

All of the above fields are members of the 'power' member of 'struct device'.

4. Runtime PM Device Helper Functions
=====================================

The following runtime PM helper functions are defined in
drivers/base/power/runtime.c and include/linux/pm_runtime.h:

  `void pm_runtime_init(struct device *dev);`
    - initialize the device runtime PM fields in 'struct dev_pm_info'

  `void pm_runtime_remove(struct device *dev);`
    - make sure that the runtime PM of the device will be disabled after
      removing the device from device hierarchy

  `int pm_runtime_idle(struct device *dev);`
    - execute the subsystem-level idle callback for the device; returns an
      error code on failure, where -EINPROGRESS means that ->runtime_idle() is
      already being executed; if there is no callback or the callback returns 0
      then run pm_runtime_autosuspend(dev) and return its result

  `int pm_runtime_suspend(struct device *dev);`
    - execute the subsystem-level suspend callback for the device; returns 0 on
      success, 1 if the device's runtime PM status was already 'suspended', or
      error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt
      to suspend the device again in future and -EACCES means that
      'power.disable_depth' is different from 0

  `int pm_runtime_autosuspend(struct device *dev);`
    - same as pm_runtime_suspend() except that the autosuspend delay is taken
      `into account;` if pm_runtime_autosuspend_expiration() says the delay has
      not yet expired then an autosuspend is scheduled for the appropriate time
      and 0 is returned

  `int pm_runtime_resume(struct device *dev);`
    - execute the subsystem-level resume callback for the device; returns 0 on
      success, 1 if the device's runtime PM status was already 'active' or
      error code on failure, where -EAGAIN means it may be safe to attempt to
      resume the device again in future, but 'power.runtime_error' should be
      checked additionally, and -EACCES means that 'power.disable_depth' is
      different from 0

  `int pm_request_idle(struct device *dev);`
    - submit a request to execute the subsystem-level idle callback for the
      device (the request is represented by a work item in pm_wq); returns 0 on
      success or error code if the request has not been queued up

  `int pm_request_autosuspend(struct device *dev);`
    - schedule the execution of the subsystem-level suspend callback for the
      device when the autosuspend delay has expired; if the delay has already
      expired then the work item is queued up immediately

  `int pm_schedule_suspend(struct device *dev, unsigned int delay);`
    - schedule the execution of the subsystem-level suspend callback for the
      device in future, where 'delay' is the time to wait before queuing up a
      suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the work
      item is queued up immediately); returns 0 on success, 1 if the device's PM
      runtime status was already 'suspended', or error code if the request
      hasn't been scheduled (or queued up if 'delay' is 0); if the execution of
      ->runtime_suspend() is already scheduled and not yet expired, the new
      value of 'delay' will be used as the time to wait

  `int pm_request_resume(struct device *dev);`
    - submit a request to execute the subsystem-level resume callback for the
      device (the request is represented by a work item in pm_wq); returns 0 on
      success, 1 if the device's runtime PM status was already 'active', or
      error code if the request hasn't been queued up

  `void pm_runtime_get_noresume(struct device *dev);`
    - increment the device's usage counter

  `int pm_runtime_get(struct device *dev);`
    - increment the device's usage counter, run pm_request_resume(dev) and
      return its result

  `int pm_runtime_get_sync(struct device *dev);`
    - increment the device's usage counter, run pm_runtime_resume(dev) and
      return its result

  `int pm_runtime_get_if_in_use(struct device *dev);`
    - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the
      runtime PM status is RPM_ACTIVE and the runtime PM usage counter is
      nonzero, increment the counter and return 1; otherwise return 0 without
      changing the counter

  `int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count);`
    - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the
      runtime PM status is RPM_ACTIVE, and either ign_usage_count is true
      or the device's usage_count is non-zero, increment the counter and
      return 1; otherwise return 0 without changing the counter

  `void pm_runtime_put_noidle(struct device *dev);`
    - decrement the device's usage counter

  `int pm_runtime_put(struct device *dev);`
    - decrement the device's usage counter; if the result is 0 then run
      pm_request_idle(dev) and return its result

  `int pm_runtime_put_autosuspend(struct device *dev);`
    - decrement the device's usage counter; if the result is 0 then run
      pm_request_autosuspend(dev) and return its result

  `int pm_runtime_put_sync(struct device *dev);`
    - decrement the device's usage counter; if the result is 0 then run
      pm_runtime_idle(dev) and return its result

  `int pm_runtime_put_sync_suspend(struct device *dev);`
    - decrement the device's usage counter; if the result is 0 then run
      pm_runtime_suspend(dev) and return its result

  `int pm_runtime_put_sync_autosuspend(struct device *dev);`
    - decrement the device's usage counter; if the result is 0 then run
      pm_runtime_autosuspend(dev) and return its result

  `void pm_runtime_enable(struct device *dev);`
    - decrement the device's 'power.disable_depth' field; if that field is equal
      to zero, the runtime PM helper functions can execute subsystem-level
      callbacks described in Section 2 for the device

  `int pm_runtime_disable(struct device *dev);`
    - increment the device's 'power.disable_depth' field (if the value of that
      field was previously zero, this prevents subsystem-level runtime PM
      callbacks from being run for the device), make sure that all of the
      pending runtime PM operations on the device are either completed or
      canceled; returns 1 if there was a resume request pending and it was
      necessary to execute the subsystem-level resume callback for the device
      to satisfy that request, otherwise 0 is returned

  `int pm_runtime_barrier(struct device *dev);`
    - check if there's a resume request pending for the device and resume it
      (synchronously) in that case, cancel any other pending runtime PM requests
      regarding it