]> git.saurik.com Git - apple/xnu.git/blob - iokit/IOKit/IOServicePM.h
2b48bb3379c26ff311b6e9dc8281b0bce5c71734
[apple/xnu.git] / iokit / IOKit / IOServicePM.h
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 extern "C" {
24 #include <kern/thread_call.h>
25 }
26
27 #include <libkern/c++/OSObject.h>
28 #include <IOKit/IOLocks.h>
29 class IOPMinformee;
30 class IOPMinformeeList;
31 class IOPMchangeNoteList;
32 class IOPMpmChild;
33 class IOWorkLoop;
34 class IOCommandQueue;
35 class IOCommandGate;
36 class IOTimerEventSource;
37 class IOPlatformExpert;
38
39 #include <IOKit/pwr_mgt/IOPM.h>
40
41
42 /*!
43 @defined ACK_TIMER_PERIOD
44 @discussion When an IOService is waiting for acknowledgement to a power state change
45 notification from an interested driver or the controlling driver its ack timer is ticking every tenth of a second.
46 (100000000 nanoseconds are one tenth of a second).
47 */
48 #define ACK_TIMER_PERIOD 100000000
49
50
51
52 /*!
53 @class IOPMpriv : public OSObject
54 @abstract Private power management private instance variables for IOService objects.
55 */
56 class IOPMpriv : public OSObject
57 {
58 friend class IOService;
59
60 OSDeclareDefaultStructors(IOPMpriv)
61
62 public:
63
64 /*! @field we_are_root TRUE if this device is the root power domain */
65 bool we_are_root;
66
67 /*! @field interestedDrivers list of interested drivers */
68 IOPMinformeeList * interestedDrivers;
69
70 /*! @field children list of power domain children */
71 IOPMinformeeList * children;
72
73 /*! @field changeList list of pending power state changes */
74 IOPMchangeNoteList * changeList;
75
76 /*! @field driver_timer timeout on waiting for controlling driver to acknowledgeSetPowerState */
77 IOReturn driver_timer;
78
79 /*! @field ackTimer */
80 thread_call_t ackTimer;
81
82 /*! @field settleTimer */
83 thread_call_t settleTimer;
84
85 /*! @field machine_state state number of state machine processing current change note */
86 unsigned long machine_state;
87
88 /*! @field settle_time settle timer after changing power state */
89 unsigned long settle_time;
90
91 /*! @field head_note ordinal of change note currently being processed */
92 long head_note;
93
94 /*! @field head_note_flags copy of flags field in change note currently being processed*/
95 unsigned long head_note_flags;
96
97 /*! @field head_note_state copy of newStateNumberfield in change note currently being processed */
98 unsigned long head_note_state;
99
100 /*! @field head_note_outputFlags outputPowerCharacter field from change note currently being processed */
101 unsigned long head_note_outputFlags;
102
103 /*! @field head_note_domainState power domain flags from parent... (only on parent change) */
104 unsigned long head_note_domainState;
105
106 /*! @field head_note_parent pointer to initiating parent... (only on parent change) */
107 IOPowerConnection * head_note_parent;
108
109 /*! @field head_note_capabilityFlags copy of capabilityFlags field in change note currently being processed */
110 unsigned long head_note_capabilityFlags;
111
112 /*! @field head_note_pendingAcks number of acks we are waiting for during notification */
113 unsigned long head_note_pendingAcks;
114
115 /*! @field our_lock used to control access to head_note_pendingAcks and driver_timer */
116 IOLock * our_lock;
117
118 /*! @field flags_lock used to control access to response flags array */
119 IOLock * flags_lock;
120
121 /*! @field initial_change true forces first state to be broadcast even if it isn't a change */
122 bool initial_change;
123
124 /*! @field need_to_become_usable someone called makeUsable before we had a controlling driver */
125 bool need_to_become_usable;
126
127 /*! @field device_overrides state changes are made based only on subclass's desire */
128 bool device_overrides;
129
130 /*! @field clampOn domain is clamped on till first child registers */
131 bool clampOn;
132
133 /*! @field owner points to object which made this struct. Used for debug output only */
134 IOService * owner;
135
136 /*! @field activityLock used to protect activity flag */
137 IOLock * activityLock;
138
139 /*! @field timerEventSrc an idle timer */
140 IOTimerEventSource * timerEventSrc;
141
142 /*! @field idle_timer_period its period in seconds */
143 unsigned long idle_timer_period;
144
145 /*! @field clampTimerEventSrc timer for clamping power on */
146 IOTimerEventSource * clampTimerEventSrc;
147
148 /*! @field device_active true: there has been device activity since last idle timer expiration */
149 bool device_active;
150
151 /*! @field device_active_timestamp time in ticks of last activity */
152 AbsoluteTime device_active_timestamp;
153
154 /*! @field driverDesire
155 This is the power state desired by our controlling driver. It is initialized to myCurrentState and is changed
156 when the controlling driver calls changePowerStateTo. A change in driverDesire may cause a change in ourDesiredPowerState.
157 */
158 unsigned long driverDesire;
159
160
161
162 /*! @field deviceDesire
163 This is the power state desired by a subclassed device object. It is initialized to myCurrentState and is changed
164 when the subclassed object calls changePowerStateToPriv. A change in deviceDesire may cause a change in ourDesiredPowerState.
165 */
166 unsigned long deviceDesire;
167
168
169
170 /*! @field ourDesiredPowerState
171 This is the power state we desire currently. If equal to myCurrentState, we're happy.
172 Otherwise, we're waiting for the parent to raise the power domain to at least this level.
173
174 If this is a power domain, this is the maximum of all our children's desires, driverDesire, and deviceDesire.
175 It increases when:
176 a child asks for more power via requestDomainState,
177 the controlling driver asks for more power via changePowerStateTo
178
179 It decreases when:
180 we lose a child and the child had the highest power need of all our children,
181 the child with the highest power need suggests a lower power domain state,
182 the controlling driver asks for lower power for some reason via changePowerStateTo
183
184 If this is not a power domain, ourDesiredPowerState represents the greater of driverDesire and deviceDesire.
185 It increases when:
186 the controlling driver asks for more power via changePowerStateTo
187 some driver calls makeUsable
188 a subclassed object asks for more power via changePowerStateToPriv
189
190 It decreases when:
191 the controlling driver asks for lower power for some reason via changePowerStateTo
192 a subclassed object asks for lower power for some reason via changePowerStateToPriv
193 */
194 unsigned long ourDesiredPowerState;
195
196
197 /*! @field previousRequest
198 This is a reminder of what our parent thinks our need is. Whenever it changes,
199 we call requestDomainState in the parent to keep it current. It is usually equal to ourDesiredPowerState
200 except while a power change is in progress.
201 */
202 unsigned long previousRequest;
203
204
205 /*! @field askingFor
206 Used by activityTickle so it doesn't try to raise the device to a lower state than
207 what it may have previously requested.
208 */
209 unsigned long askingFor;
210
211
212 /*! @field imminentState
213 Usually the same as myCurrentState, except right after calling powerStateWillChangeTo.
214 */
215 unsigned long imminentState;
216
217 /*! @function serialize
218 Serialize private instance variables for debug output (IORegistryDumper).
219 */
220 virtual bool serialize(OSSerialize *s) const;
221
222 };
223
224
225
226
227 /*!
228 @class IOPMprot : public OSObject
229 @abstract Protected power management instance variables for IOService objects.
230 */
231 class IOPMprot : public OSObject //management
232 {
233 friend class IOService;
234
235 OSDeclareDefaultStructors(IOPMprot)
236
237 public:
238
239 /*! @field ourName from getName(), used in logging */
240 const char * ourName;
241
242 /*! @field thePlatform from getPlatform, used in logging and registering */
243 IOPlatformExpert * thePlatform;
244
245 /*! @field theNumberOfPowerStates the number of states in the array */
246 unsigned long theNumberOfPowerStates; // the number of states in the array
247
248 /*! @field thePowerStates the array */
249 IOPMPowerState thePowerStates[IOPMMaxPowerStates];
250
251 /*! @field theControllingDriver points to the controlling driver */
252 IOService * theControllingDriver;
253
254 /*! @field aggressiveness current value of power management aggressiveness */
255 unsigned long aggressiveness;
256
257 /*! @field current_aggressiveness_values array of aggressiveness values */
258 unsigned long current_aggressiveness_values [kMaxType+1];
259
260 /*! @field current_aggressiveness_validity true for values that are currently valid */
261 bool current_aggressiveness_valid [kMaxType+1];
262
263 /*! @field myCurrentState the ordinal of our current power state */
264 unsigned long myCurrentState;
265
266 /*! @field parentsKnowState true if all our parents know the state of their power domain */
267 bool parentsKnowState;
268
269 /*! @field parentsCurrentPowerFlags logical OR of power flags for the current state of each power domainparent */
270 IOPMPowerFlags parentsCurrentPowerFlags;
271
272 /*! @field maxCapability ordinal of highest state we can achieve in current power domain state */
273 unsigned long maxCapability;
274
275 /*! @field PMworkloop points to the single power management workloop */
276 IOWorkLoop * PMworkloop;
277
278 /*! @field commandQueue used to serialize idle-power-down and busy-power-up */
279 IOCommandQueue * commandQueue;
280
281 /*! @field PMcommandGate used to serialize timer expirations and incoming acknowledgements */
282 IOCommandGate * PMcommandGate;
283
284 /*! @field myCharacterFlags logical OR of all output power character flags in the array */
285 IOPMPowerFlags myCharacterFlags;
286
287 /*! @field serialNumber used to uniquely identify power management notification to apps and clients */
288 UInt16 serialNumber;
289
290 /*! @field responseFlags points to an OSArray which manages responses from notified apps and clients */
291 OSArray* responseFlags;
292
293 /*! @field doNotPowerDown keeps track of any negative responses from notified apps and clients */
294 bool doNotPowerDown;
295
296 /*! @function serialize
297 Serialize protected instance variables for debug output (IORegistryDumper).
298 */
299 virtual bool serialize(OSSerialize *s) const;
300
301 };
302