2 * Copyright (c) 2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _IOKIT_IOSERVICEPMPRIVATE_H
30 #define _IOKIT_IOSERVICEPMPRIVATE_H
32 #include <IOKit/IOCommand.h>
33 #include <IOKit/IOEventSource.h>
35 //******************************************************************************
37 //******************************************************************************
41 kIOPMRequestTypeInvalid
= 0x00,
42 kIOPMRequestTypePMStop
= 0x01,
43 kIOPMRequestTypeAddPowerChild1
= 0x02,
44 kIOPMRequestTypeAddPowerChild2
= 0x03,
45 kIOPMRequestTypeAddPowerChild3
= 0x04,
46 kIOPMRequestTypeRegisterPowerDriver
= 0x05,
47 kIOPMRequestTypeAdjustPowerState
= 0x06,
48 kIOPMRequestTypePowerDomainWillChange
= 0x07,
49 kIOPMRequestTypePowerDomainDidChange
= 0x08,
50 kIOPMRequestTypePowerOverrideOnPriv
= 0x09,
51 kIOPMRequestTypePowerOverrideOffPriv
= 0x0A,
52 kIOPMRequestTypeActivityTickle
= 0x0B,
53 kIOPMRequestTypeRequestPowerState
= 0x0C,
54 kIOPMRequestTypeSynchronizePowerTree
= 0x0D,
55 kIOPMRequestTypeRequestPowerStateOverride
= 0x0E,
56 kIOPMRequestTypeSetIdleTimerPeriod
= 0x0F,
59 kIOPMRequestTypeReplyStart
= 0x80,
60 kIOPMRequestTypeAckPowerChange
= 0x81,
61 kIOPMRequestTypeAckSetPowerState
= 0x82,
62 kIOPMRequestTypeAllowPowerChange
= 0x83,
63 kIOPMRequestTypeCancelPowerChange
= 0x84,
64 kIOPMRequestTypeInterestChanged
= 0x85,
65 kIOPMRequestTypeIdleCancel
= 0x86,
66 kIOPMRequestTypeChildNotifyDelayCancel
= 0x87
69 //******************************************************************************
70 // PM actions - For root domain only
71 //******************************************************************************
76 (*IOPMActionPowerChangeStart
)(
79 IOPMActions
* actions
,
81 uint32_t * changeFlags
);
84 (*IOPMActionPowerChangeDone
)(
87 IOPMActions
* actions
,
89 uint32_t changeFlags
);
92 (*IOPMActionPowerChangeOverride
)(
95 IOPMActions
* actions
,
96 unsigned long * powerState
,
97 uint32_t * changeFlags
);
100 (*IOPMActionActivityTickle
)(
103 IOPMActions
* actions
);
108 IOPMActionPowerChangeStart actionPowerChangeStart
;
109 IOPMActionPowerChangeDone actionPowerChangeDone
;
110 IOPMActionPowerChangeOverride actionPowerChangeOverride
;
111 IOPMActionActivityTickle actionActivityTickle
;
114 //******************************************************************************
117 kIOPMEventClassSystemEvent
= 0x00,
118 kIOPMEventClassDriverEvent
= 0x1
121 class PMEventDetails
: public OSObject
123 OSDeclareDefaultStructors( PMEventDetails
);
124 friend class IOServicePM
;
125 friend class IOPMrootDomain
;
126 friend class IOPMTimeline
;
128 static PMEventDetails
*eventDetails(uint32_t type
,
129 const char *ownerName
,
130 uintptr_t ownerUnique
,
131 const char *interestName
,
135 uint32_t elapsedTimeUS
);
137 static PMEventDetails
*eventDetails(uint32_t type
,
142 uint8_t eventClassifier
;
144 const char *ownerName
;
145 uintptr_t ownerUnique
;
146 const char *interestName
;
150 uint32_t elapsedTimeUS
;
156 // Internal concise representation of IOPMPowerState
159 IOPMPowerFlags capabilityFlags
;
160 IOPMPowerFlags outputPowerFlags
;
161 IOPMPowerFlags inputPowerFlags
;
162 uint32_t staticPower
;
163 uint32_t settleUpTime
;
164 uint32_t settleDownTime
;
167 //******************************************************************************
169 //******************************************************************************
171 class IOServicePM
: public OSObject
173 friend class IOService
;
174 friend class IOPMWorkQueue
;
176 OSDeclareDefaultStructors( IOServicePM
)
179 // Link IOServicePM objects on IOPMWorkQueue.
180 queue_chain_t WorkChain
;
182 // Queue of IOPMRequest objects.
183 queue_head_t RequestHead
;
185 // IOService creator and owner.
188 // List of interested drivers (protected by PMLock).
189 IOPMinformeeList
* InterestedDrivers
;
191 // How long to wait for controlling driver to acknowledge.
192 IOReturn DriverTimer
;
194 // Current power management machine state.
195 uint32_t MachineState
;
197 thread_call_t AckTimer
;
198 thread_call_t SettleTimer
;
199 thread_call_t IdleTimer
;
201 // Settle time after changing power state.
202 uint32_t SettleTimeUS
;
204 // The flags describing current change note.
205 IOPMPowerChangeFlags HeadNoteChangeFlags
;
207 // The new power state number being changed to.
208 IOPMPowerStateIndex HeadNotePowerState
;
210 // Points to the entry in the power state array.
211 IOPMPSEntry
* HeadNotePowerArrayEntry
;
213 // Power flags supplied by all parents (domain).
214 IOPMPowerFlags HeadNoteDomainFlags
;
216 // Power flags supplied by domain accounting for parent changes.
217 IOPMPowerFlags HeadNoteDomainTargetFlags
;
219 // Connection attached to the changing parent.
220 IOPowerConnection
* HeadNoteParentConnection
;
222 // Power flags supplied by the changing parent.
223 IOPMPowerFlags HeadNoteParentFlags
;
225 // Number of acks still outstanding.
226 uint32_t HeadNotePendingAcks
;
231 unsigned int InitialPowerChange
:1;
232 unsigned int InitialSetPowerState
:1;
233 unsigned int DeviceOverrideEnabled
:1;
234 unsigned int DeviceWasActive
:1;
235 unsigned int DoNotPowerDown
:1;
236 unsigned int ParentsKnowState
:1;
237 unsigned int StrictTreeOrder
:1;
238 unsigned int IdleTimerStopped
:1;
239 unsigned int AdjustPowerScheduled
:1;
240 unsigned int IsPreChange
:1;
241 unsigned int DriverCallBusy
:1;
242 unsigned int PCDFunctionOverride
:1;
244 // Time of last device activity.
245 AbsoluteTime DeviceActiveTimestamp
;
247 // Used to protect activity flag.
248 IOLock
* ActivityLock
;
250 // Idle timer's period in seconds.
251 unsigned long IdleTimerPeriod
;
252 unsigned long IdleTimerMinPowerState
;
253 AbsoluteTime IdleTimerStartTime
;
255 // Power state desired by a subclassed device object.
256 IOPMPowerStateIndex DeviceDesire
;
258 // This is the power state we desire currently.
259 IOPMPowerStateIndex DesiredPowerState
;
261 // This is what our parent thinks our need is.
262 IOPMPowerFlags PreviousRequestPowerFlags
;
264 // Cache result from getName(), used in logging.
267 // Number of power states in the power array.
268 IOPMPowerStateIndex NumberOfPowerStates
;
270 // Power state array.
271 IOPMPSEntry
* PowerStates
;
273 // The controlling driver.
274 IOService
* ControllingDriver
;
276 // Our current power state.
277 IOPMPowerStateIndex CurrentPowerState
;
279 // Logical OR of power flags for each power domain parent.
280 IOPMPowerFlags ParentsCurrentPowerFlags
;
282 // The highest power state we can achieve in current power domain.
283 IOPMPowerStateIndex MaxPowerState
;
285 // Logical OR of all output power character flags in the array.
286 IOPMPowerFlags OutputPowerCharacterFlags
;
288 // OSArray which manages responses from notified apps and clients.
289 OSArray
* ResponseArray
;
290 OSArray
* NotifyClientArray
;
292 // Used to uniquely identify power management notification to apps and clients.
295 // Used to communicate desired function to tellClientsWithResponse().
296 // This is used because it avoids changing the signatures of the affected virtual methods.
297 int OutOfBandParameter
;
299 AbsoluteTime DriverCallStartTime
;
300 IOPMPowerFlags CurrentCapabilityFlags
;
301 long ActivityTicklePowerState
;
302 unsigned long CurrentPowerConsumption
;
303 IOPMPowerStateIndex TempClampPowerState
;
304 OSArray
* NotifyChildArray
;
305 OSDictionary
* PowerClients
;
306 thread_call_t DriverCallEntry
;
307 void * DriverCallParamPtr
;
308 IOItemCount DriverCallParamCount
;
309 IOItemCount DriverCallParamSlots
;
310 uint32_t DriverCallReason
;
311 uint32_t OutOfBandMessage
;
312 uint32_t TempClampCount
;
313 uint32_t OverrideMaxPowerState
;
314 uint32_t ActivityTickleCount
;
316 uint32_t SavedMachineState
;
317 uint32_t RootDomainState
;
319 // Protected by PMLock - BEGIN
322 uint32_t PMDriverCallWait
: 1;
325 queue_head_t PMDriverCallQueue
;
326 OSSet
* InsertInterestSet
;
327 OSSet
* RemoveInterestSet
;
328 // Protected by PMLock - END
334 IOPMActions PMActions
;
336 // Serialize IOServicePM state for debug output.
337 IOReturn
gatedSerialize( OSSerialize
* s
);
338 virtual bool serialize( OSSerialize
* s
) const;
341 #define fOwner pwrMgt->Owner
342 #define fInterestedDrivers pwrMgt->InterestedDrivers
343 #define fDriverTimer pwrMgt->DriverTimer
344 #define fMachineState pwrMgt->MachineState
345 #define fAckTimer pwrMgt->AckTimer
346 #define fSettleTimer pwrMgt->SettleTimer
347 #define fIdleTimer pwrMgt->IdleTimer
348 #define fSettleTimeUS pwrMgt->SettleTimeUS
349 #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags
350 #define fHeadNotePowerState pwrMgt->HeadNotePowerState
351 #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry
352 #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags
353 #define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags
354 #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection
355 #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags
356 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks
357 #define fPMLock pwrMgt->PMLock
358 #define fInitialPowerChange pwrMgt->InitialPowerChange
359 #define fInitialSetPowerState pwrMgt->InitialSetPowerState
360 #define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled
361 #define fDeviceWasActive pwrMgt->DeviceWasActive
362 #define fDoNotPowerDown pwrMgt->DoNotPowerDown
363 #define fParentsKnowState pwrMgt->ParentsKnowState
364 #define fStrictTreeOrder pwrMgt->StrictTreeOrder
365 #define fIdleTimerStopped pwrMgt->IdleTimerStopped
366 #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled
367 #define fIsPreChange pwrMgt->IsPreChange
368 #define fDriverCallBusy pwrMgt->DriverCallBusy
369 #define fPCDFunctionOverride pwrMgt->PCDFunctionOverride
370 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp
371 #define fActivityLock pwrMgt->ActivityLock
372 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod
373 #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState
374 #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime
375 #define fDeviceDesire pwrMgt->DeviceDesire
376 #define fDesiredPowerState pwrMgt->DesiredPowerState
377 #define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags
378 #define fName pwrMgt->Name
379 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates
380 #define fPowerStates pwrMgt->PowerStates
381 #define fControllingDriver pwrMgt->ControllingDriver
382 #define fCurrentPowerState pwrMgt->CurrentPowerState
383 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags
384 #define fMaxPowerState pwrMgt->MaxPowerState
385 #define fOutputPowerCharacterFlags pwrMgt->OutputPowerCharacterFlags
386 #define fResponseArray pwrMgt->ResponseArray
387 #define fNotifyClientArray pwrMgt->NotifyClientArray
388 #define fSerialNumber pwrMgt->SerialNumber
389 #define fOutOfBandParameter pwrMgt->OutOfBandParameter
390 #define fDriverCallStartTime pwrMgt->DriverCallStartTime
391 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags
392 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState
393 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption
394 #define fTempClampPowerState pwrMgt->TempClampPowerState
395 #define fNotifyChildArray pwrMgt->NotifyChildArray
396 #define fPowerClients pwrMgt->PowerClients
397 #define fDriverCallEntry pwrMgt->DriverCallEntry
398 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr
399 #define fDriverCallParamCount pwrMgt->DriverCallParamCount
400 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots
401 #define fDriverCallReason pwrMgt->DriverCallReason
402 #define fOutOfBandMessage pwrMgt->OutOfBandMessage
403 #define fTempClampCount pwrMgt->TempClampCount
404 #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState
405 #define fActivityTickleCount pwrMgt->ActivityTickleCount
406 #define fWaitReason pwrMgt->WaitReason
407 #define fSavedMachineState pwrMgt->SavedMachineState
408 #define fRootDomainState pwrMgt->RootDomainState
409 #define fLockedFlags pwrMgt->LockedFlags
410 #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue
411 #define fInsertInterestSet pwrMgt->InsertInterestSet
412 #define fRemoveInterestSet pwrMgt->RemoveInterestSet
413 #define fPMVars pwrMgt->PMVars
414 #define fPMActions pwrMgt->PMActions
417 When an IOService is waiting for acknowledgement to a power change
418 notification from an interested driver or the controlling driver,
419 the ack timer is ticking every tenth of a second.
420 (100000000 nanoseconds are one tenth of a second).
422 #define ACK_TIMER_PERIOD 100000000
424 // Max wait time in microseconds for kernel priority and capability clients
425 // with async message handlers to acknowledge.
427 #define kPriorityClientMaxWait (90 * 1000 * 1000)
428 #define kCapabilityClientMaxWait (240 * 1000 * 1000)
430 // Attributes describing a power state change.
431 // See IOPMPowerChangeFlags data type.
433 #define kIOPMParentInitiated 0x0001 // this power change initiated by our parent
434 #define kIOPMSelfInitiated 0x0002 // this power change initiated by this device
435 #define kIOPMNotDone 0x0004 // we couldn't make this change
436 #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo
437 #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo
438 #define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power
439 #define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires
440 #define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase
441 #define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync
442 #define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree
443 #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages
444 #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake
445 #define kIOPMPowerSuppressed 0x1000 // power suppressed for dark wake
448 kDriverCallInformPreChange
,
449 kDriverCallInformPostChange
,
450 kDriverCallSetPowerState
453 struct DriverCallParam
{
458 // values of OutOfBandParameter
462 kNotifyCapabilityChangeApps
,
463 kNotifyCapabilityChangePriority
466 typedef bool (*IOPMMessageFilter
)(
467 void * target
, void * object
, void * arg1
, void * arg2
, void * arg3
);
469 // used for applyToInterested
470 struct IOPMInterestContext
{
471 OSArray
* responseArray
;
472 OSArray
* notifyClients
;
473 uint16_t serialNumber
;
475 uint8_t enableTracing
;
476 uint32_t maxTimeRequested
;
477 uint32_t messageType
;
480 IOPMPowerStateIndex stateNumber
;
481 IOPMPowerFlags stateFlags
;
482 IOPMPowerChangeFlags changeFlags
;
483 const char * errorLog
;
484 IOPMMessageFilter messageFilter
;
487 // assertPMDriverCall() options
489 kIOPMADC_NoInactiveCheck
= 1
492 //******************************************************************************
493 // PM Statistics & Diagnostics
494 //******************************************************************************
496 extern const OSSymbol
*gIOPMStatsApplicationResponseTimedOut
;
497 extern const OSSymbol
*gIOPMStatsApplicationResponseCancel
;
498 extern const OSSymbol
*gIOPMStatsApplicationResponseSlow
;
500 //******************************************************************************
502 //******************************************************************************
504 typedef void (*IOPMCompletionAction
)(void * target
, void * param
, IOReturn status
);
506 class IOPMRequest
: public IOCommand
508 OSDeclareDefaultStructors( IOPMRequest
)
511 IOService
* fTarget
; // request target
512 IOPMRequest
* fRequestNext
; // the next request in the chain
513 IOPMRequest
* fRequestRoot
; // the root request in the issue tree
514 IOItemCount fWorkWaitCount
; // execution blocked if non-zero
515 IOItemCount fFreeWaitCount
; // completion blocked if non-zero
516 uint32_t fType
; // request type
518 IOPMCompletionAction fCompletionAction
;
519 void * fCompletionTarget
;
520 void * fCompletionParam
;
521 IOReturn fCompletionStatus
;
528 inline bool isWorkBlocked( void ) const
530 return (fWorkWaitCount
!= 0);
533 inline bool isFreeBlocked( void ) const
535 return (fFreeWaitCount
!= 0);
538 inline IOPMRequest
* getNextRequest( void ) const
543 inline IOPMRequest
* getRootRequest( void ) const
545 if (fRequestRoot
) return fRequestRoot
;
546 if (fCompletionAction
) return (IOPMRequest
*) this;
550 inline uint32_t getType( void ) const
555 inline bool isReplyType( void ) const
557 return (fType
> kIOPMRequestTypeReplyStart
);
560 inline IOService
* getTarget( void ) const
565 inline bool isCompletionInstalled( void )
567 return (fCompletionAction
!= 0);
570 inline void installCompletionAction(
571 IOPMCompletionAction action
,
575 fCompletionAction
= action
;
576 fCompletionTarget
= target
;
577 fCompletionParam
= param
;
580 static IOPMRequest
* create( void );
581 bool init( IOService
* owner
, IOOptionBits type
);
583 bool attachNextRequest( IOPMRequest
* next
);
584 bool detachNextRequest( void );
585 bool attachRootRequest( IOPMRequest
* root
);
586 bool detachRootRequest( void );
589 //******************************************************************************
591 //******************************************************************************
593 class IOPMRequestQueue
: public IOEventSource
595 OSDeclareDefaultStructors( IOPMRequestQueue
)
598 typedef bool (*Action
)( IOService
*, IOPMRequest
*, IOPMRequestQueue
* );
604 virtual bool checkForWork( void );
605 virtual void free( void );
606 virtual bool init( IOService
* inOwner
, Action inAction
);
609 static IOPMRequestQueue
* create( IOService
* inOwner
, Action inAction
);
610 void queuePMRequest( IOPMRequest
* request
);
611 void queuePMRequestChain( IOPMRequest
** requests
, IOItemCount count
);
614 //******************************************************************************
616 //******************************************************************************
618 #define WORK_QUEUE_STATS 1
620 class IOPMWorkQueue
: public IOEventSource
622 OSDeclareDefaultStructors( IOPMWorkQueue
)
625 typedef bool (*Action
)( IOService
*, IOPMRequest
*, IOPMWorkQueue
* );
628 uint64_t fStatCheckForWork
;
629 uint64_t fStatScanEntries
;
630 uint64_t fStatQueueEmpty
;
631 uint64_t fStatNoWorkDone
;
635 queue_head_t fWorkQueue
;
637 Action fRetireAction
;
638 uint32_t fQueueLength
;
639 uint32_t fConsumerCount
;
640 volatile uint32_t fProducerCount
;
642 virtual bool checkForWork( void );
643 virtual bool init( IOService
* inOwner
, Action work
, Action retire
);
644 bool checkRequestQueue( queue_head_t
* queue
, bool * empty
);
647 static IOPMWorkQueue
* create( IOService
* inOwner
, Action work
, Action retire
);
648 bool queuePMRequest( IOPMRequest
* request
, IOServicePM
* pwrMgt
);
649 void signalWorkAvailable( void );
650 void incrementProducerCount( void );
653 //******************************************************************************
654 // IOPMCompletionQueue
655 //******************************************************************************
657 class IOPMCompletionQueue
: public IOEventSource
659 OSDeclareDefaultStructors( IOPMCompletionQueue
)
662 typedef bool (*Action
)( IOService
*, IOPMRequest
*, IOPMCompletionQueue
* );
667 virtual bool checkForWork( void );
668 virtual bool init( IOService
* inOwner
, Action inAction
);
671 static IOPMCompletionQueue
* create( IOService
* inOwner
, Action inAction
);
672 bool queuePMRequest( IOPMRequest
* request
);
675 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */