XenevaOS
Loading...
Searching...
No Matches
pm.h
Go to the documentation of this file.
1#ifndef __LINUX_PM_H__
2#define __LINUX_PM_H__
3
4/*
5 * DCL <linux/pm.h> -- pm_sleep_ptr(), and nothing else.
6 *
7 * mainline's header is ~37 KB of suspend/resume types, dpm_list, PM message
8 * bits and the dev_pm_info layout. DCL has no suspend path: there is no
9 * freezer, no dpm_suspend(), nothing that walks a driver's ->freeze. So the
10 * whole surface that a ported source actually names is one macro, and
11 * pretending the rest exists would be worse than it being absent.
12 *
13 * The macro's job upstream:
14 *
15 * #define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr))
16 *
17 * -- i.e. the driver's .freeze/.restore callbacks compile away to NULL when
18 * the kernel was built without suspend support, which is why virtio-rng.c can
19 * name virtrng_freeze and virtrng_restore unconditionally.
20 *
21 * ### DCL spells the same result differently, and the spelling matters
22 *
23 * The obvious translations both fail:
24 *
25 * - `#define pm_sleep_ptr(_ptr) (_ptr)` keeps the pointer, so .freeze/.restore
26 * get wired to functions nothing calls -- correct by accident, but it is
27 * not what the macro means.
28 * - `#define pm_sleep_ptr(_ptr) NULL` is the right *value* but drops the
29 * token `_ptr` entirely, so virtrng_freeze and virtrng_restore become two
30 * static functions with no reference anywhere: -Wunused-function on every
31 * build. It also cannot be typed -- assigning `((void*)0)` to a function
32 * pointer only compiles because we do not pass -pedantic.
33 *
34 * `((__typeof__(&_ptr))0)` does all three at once: it references `_ptr` (the
35 * function counts as used, no warning), the cast yields a null pointer of
36 * exactly the callee's function-pointer type (no type-mismatch warning, no
37 * reliance on -Wno-pedantic), and `cast-of-0-to-pointer` is a null pointer
38 * constant, so it is a legal constant expression for the static initialiser
39 * it appears in. A comma-operator spelling, e.g. `((void)sizeof(&(_ptr)),
40 * NULL)`, would be rejected: initialisers at file scope need a constant
41 * expression and the comma operator is not one.
42 */
43
44#define pm_sleep_ptr(_ptr) (_ptr)
45
46/*
47 * struct dev_pm_ops + SET_SYSTEM_SLEEP_PM_OPS() -- the PCI driver's power
48 * half that bochs.c brings in:
49 *
50 * static const struct dev_pm_ops bochs_pm_ops = {
51 * SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend, bochs_pm_resume)
52 * };
53 * ...
54 * static struct pci_driver bochs_pci_driver = {
55 * ...
56 * .driver.pm = &bochs_pm_ops,
57 * };
58 *
59 * The callbacks themselves sit behind `#ifdef CONFIG_PM_SLEEP` in the
60 * driver, and CONFIG_PM_SLEEP is undefined here for the reason pm_sleep_ptr
61 * above records -- there is no suspend path. So mainline's #else arm is the
62 * one that has to exist: an empty expansion that names neither function,
63 * because both were compiled out. A non-empty expansion would reference two
64 * functions that do not exist.
65 *
66 * The struct is correspondingly empty: a zero-member dev_pm_ops is exactly
67 * what a driver with no compiled-in PM callbacks points at. If a suspend
68 * path ever lands, the members arrive with it and this macro grows mainline's
69 * populated arm -- nothing else in the tree names either today.
70 */
71struct dev_pm_ops {
72 int (*prepare)(struct device*);
73 void (*complete)(struct device*);
74 int (*suspend)(struct device*);
75 int (*resume)(struct device*);
76 int (*freeze)(struct device*);
77 int (*thaw)(struct device*);
78 int (*poweroff)(struct device*);
79 int (*restore)(struct device*);
80 int (*suspend_late)(struct device*);
81 int (*resume_early)(struct device*);
82 int (*freeze_late)(struct device*);
83 int (*thaw_early)(struct device*);
84 int (*poweroff_late)(struct device*);
85 int (*restore_early)(struct device*);
86 int (*suspend_noirq)(struct device*);
87 int (*resume_noirq)(struct device*);
88 int (*freeze_noirq)(struct device*);
89 int (*thaw_noirq)(struct device*);
90 int (*poweroff_noirq)(struct device*);
91 int (*restore_noirq)(struct device*);
92 int (*runtime_suspend)(struct device*);
93 int (*runtime_resume)(struct device*);
94 int (*runtime_idle)(struct device*);
95};
96
97#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
98
99#endif /* __LINUX_PM_H__ */
Definition pm.h:71
int(* resume_early)(struct device *)
Definition pm.h:81
int(* poweroff)(struct device *)
Definition pm.h:78
int(* restore_early)(struct device *)
Definition pm.h:85
int(* resume)(struct device *)
Definition pm.h:75
int(* freeze_noirq)(struct device *)
Definition pm.h:88
int(* resume_noirq)(struct device *)
Definition pm.h:87
int(* runtime_suspend)(struct device *)
Definition pm.h:92
int(* suspend_noirq)(struct device *)
Definition pm.h:86
int(* suspend_late)(struct device *)
Definition pm.h:80
int(* runtime_resume)(struct device *)
Definition pm.h:93
int(* restore_noirq)(struct device *)
Definition pm.h:91
int(* thaw)(struct device *)
Definition pm.h:77
int(* freeze)(struct device *)
Definition pm.h:76
int(* runtime_idle)(struct device *)
Definition pm.h:94
void(* complete)(struct device *)
Definition pm.h:73
int(* poweroff_late)(struct device *)
Definition pm.h:84
int(* restore)(struct device *)
Definition pm.h:79
int(* freeze_late)(struct device *)
Definition pm.h:82
int(* suspend)(struct device *)
Definition pm.h:74
int(* thaw_early)(struct device *)
Definition pm.h:83
int(* poweroff_noirq)(struct device *)
Definition pm.h:90
int(* thaw_noirq)(struct device *)
Definition pm.h:89
int(* prepare)(struct device *)
Definition pm.h:72
Definition fs.h:255