- First, all interested parties are notified of the change via their powerStateWillChangeTo method. If they all don't
- acknowledge via return code, then we have to wait. If they do, or when they finally all acknowledge via our
- acknowledgePowerChange method, then we can continue. We call the controlling driver, instructing it to change to
- the new state. Then we wait for power to settle. If there is no settling-time, or after it has passed, we notify
- interested parties again, this time via their powerStateDidChangeTo methods. When they have all acked, we're done.
- If we lowered power and don't need the power domain to be in its current power state, we suggest to the parent that
- it lower the power domain state.
-
- This is how a change to a lower power domain state initiated by the parent is handled:
- First, we figure out what power state we will be in when the new domain state is reached. Then all interested parties are
- notified that we are moving to that new state. When they have acknowledged, we call the controlling driver to assume
- that state and we wait for power to settle. Then we acknowledge our preparedness to our parent. When all its interested
- parties have acknowledged, it lowers power and then notifies its interested parties again. When we get this call, we notify
- our interested parties that the power state has changed, and when they have all acknowledged, we're done.
-
- This is how a change to a higher power domain state initiated by the parent is handled:
- We figure out what power state we will be in when the new domain state is reached. If it is different from our current
- state we acknowledge the parent. When all the parent's interested parties have acknowledged, it raises power in the
-domain and waits for power to settle. Then it notifies everyone that the new state has been reached. When we get this call,
- we call the controlling driver, instructing it to assume the new state, and wait for power to settle. Then we notify our interested
- parties. When they all acknowledge we are done.
-
- In either of the two cases above, it is possible that we will not be changing state even though the domain is. Examples:
- A change to a lower domain state may not affect us because we are already in a low enough state, and
- We will not take advantage of a change to a higher domain state, because we have no need of the higher power.
- In such a case, there is nothing to do but acknowledge the parent. So when the parent calls our powerDomainWillChange
- method, and we decide that we will not be changing state, we merely acknowledge the parent, via return code, and wait.
- When the parent subsequently calls powerStateDidChange, we acknowledge again via return code, and the change is complete.
-
- Power state changes are processed in a state machine, and since there are four varieties of power state changes, there are
- four major paths through the state machine:
-
- The fourth is nearly trivial. In this path, the parent is changing the domain state, but we are not changing the device state.
- The change starts when the parent calls powerDomainWillChange. All we do is acknowledge the parent.
-When the parent calls powerStateDidChange, we acknowledge the parent again, and we're done.
-
- The first is fairly simple. It starts when a power domain child calls requestPowerDomainState and we decide to change power states
- to accomodate the child, or if our power-controlling driver calls changePowerStateTo, or if some other driver which is using our
- device calls makeUsable, or if a subclassed object calls changePowerStateToPriv. These are all power changes initiated by us, not
- forced upon us by the parent. We start by notifying interested parties. If they all acknowledge via return code, we can go
- on to state "OurChangeSetPowerState". Otherwise, we start the ack timer and wait for the stragglers to acknowlege by calling
- acknowledgePowerChange. We move on to state "OurChangeSetPowerState" when all the stragglers have acknowledged,
- or when the ack timer expires on all those which didn't acknowledge. In "OurChangeSetPowerState" we call the power-controlling
- driver to change the power state of the hardware. If it returns saying it has done so, we go on to state "OurChangeWaitForPowerSettle".
- Otherwise, we have to wait for it, so we set the ack timer and wait. When it calls acknowledgeSetPowerState, or when the
- ack timer expires, we go on. In "OurChangeWaitForPowerSettle", we look in the power state array to see if there is any settle time required
- when changing from our current state to the new state. If not, we go right away to "OurChangeNotifyInterestedDriversDidChange". Otherwise, we
- set the settle timer and wait. When it expires, we move on. In "OurChangeNotifyInterestedDriversDidChange" state, we notify all our interested parties
- via their powerStateDidChange methods that we have finished changing power state. If they all acknowledge via return
- code, we move on to "OurChangeFinish". Otherwise we set the ack timer and wait. When they have all acknowledged, or
- when the ack timer has expired for those that didn't, we move on to "OurChangeFinish", where we remove the used
- change note from the head of the queue and start the next one if one exists.
-
- Parent-initiated changes are more complex in the state machine. First, power going up and power going down are handled
- differently, so they have different paths throught the state machine. Second, we can acknowledge the parent's notification
- in two different ways, so each of the parent paths is really two.
-
- When the parent calls our powerDomainWillChange method, notifying us that it will lower power in the domain, we decide
- what state that will put our device in. Then we embark on the state machine path "IOPMParentDownSetPowerState_Immediate"
- and "kIOPM_ParentDownWaitForPowerSettleAndNotifyDidChange_Immediate", in which we notify interested parties of the upcoming change, instruct our driver to make
- the change, check for settle time, and notify interested parties of the completed change. If we get to the end of this path without
- stalling due to an interested party which didn't acknowledge via return code, due to the controlling driver not able to change
- state right away, or due to a non-zero settling time, then we return IOPMAckImplied to the parent, and we're done with the change.
- If we do stall in any of those states, we return IOPMWillAckLater to the parent and enter the parallel path "kIOPM_ParentDownSetPowerState_Delayed"
- "kIOPM_ParentDownWaitForPowerSettle_Delayed", and "kIOPM_ParentDownNotifyDidChangeAndAcknowledgeChange_Delayed", where we continue with the same processing, except that at the end we
- acknowledge the parent explicitly via acknowledgePowerChange, and we're done with the change.
-Then when the parent calls us at powerStateDidChange we acknowledging via return code, because we have already made
- the power change. In any case, when we are done we remove the used change note from the head of the queue and start on the next one.
-
- The case of the parent raising power in the domain is handled similarly in that there are parallel paths, one for no-stall
- that ends in implicit acknowleging the parent, and one that has stalled at least once that ends in explicit acknowledging
- the parent. This case is different, though in that our device changes state in the second half, after the parent calls
- powerStateDidChange rather than before, as in the power-lowering case.
-
- When the parent calls our powerDomainWillChange method, notifying us that it will raise power in the domain, we acknowledge
- via return code, because there's really nothing we can do until the power is actually raised in the domain.
- When the parent calls us at powerStateDidChange, we start by notifying our interested parties. If they all acknowledge via return code,
- we go on to" kIOPM_ParentUpSetPowerState_Immediate" to instruct the driver to raise its power level. After that, we check for any
- necessary settling time in "IOPMParentUpWaitForSettleTime_Immediate", and we notify all interested parties that power has changed
- in "IOPMParentUpNotifyInterestedDriversDidChange_Immediate". If none of these operations stall, we acknowledge the parent via return code, release
- the change note, and start the next, if there is one. If one of them does stall, we enter the parallel path "kIOPM_ParentUpSetPowerState_Delayed",
- "kIOPM_ParentUpWaitForSettleTime_Delayed", "kIOPM_ParentUpNotifyInterestedDriversDidChange_Delayed", and "kIOPM_ParentUpAcknowledgePowerChange_Delayed", which ends with
- our explicit acknowledgement to the parent.
-
-*/
-
-
-const char priv_key[ ] = "Power Management private data";
-const char prot_key[ ] = "Power Management protected data";
+ -> First, all interested parties are notified of the change via their
+ powerStateWillChangeTo method. If they all don't acknowledge via return
+ code, then we have to wait. If they do, or when they finally all
+ acknowledge via our acknowledgePowerChange method, then we can continue.
+ -> We call the controlling driver, instructing it to change to the new state
+ -> Then we wait for power to settle. If there is no settling-time, or after
+ it has passed,
+ -> we notify interested parties again, this time via their
+ powerStateDidChangeTo methods.
+ -> When they have all acked, we're done.
+ If we lowered power and don't need the power domain to be in its current power
+ state, we suggest to the parent that it lower the power domain state.
+
+ == PowerDomainDownInitiated ==
+How a change to a lower power domain state initiated by the parent is handled:
+ -> First, we figure out what power state we will be in when the new domain
+ state is reached.
+ -> Then all interested parties are notified that we are moving to that new
+ state.
+ -> When they have acknowledged, we call the controlling driver to assume
+ that state and we wait for power to settle.
+ -> Then we acknowledge our preparedness to our parent. When all its
+ interested parties have acknowledged,
+ -> it lowers power and then notifies its interested parties again.
+ -> When we get this call, we notify our interested parties that the power
+ state has changed, and when they have all acknowledged, we're done.
+
+ == PowerDomainUpInitiated ==
+How a change to a higher power domain state initiated by the parent is handled:
+ -> We figure out what power state we will be in when the new domain state is
+ reached.
+ -> If it is different from our current state we acknowledge the parent.
+ -> When all the parent's interested parties have acknowledged, it raises
+ power in the domain and waits for power to settle.
+ -> Then it notifies everyone that the new state has been reached.
+ -> When we get this call, we call the controlling driver, instructing it to
+ assume the new state, and wait for power to settle.
+ -> Then we notify our interested parties. When they all acknowledge we are
+ done.
+
+ In either of the two power domain state cases above, it is possible that we
+ will not be changing state even though the domain is.
+ Examples:
+ * A change to a lower domain state may not affect us because we are already
+ in a low enough state,
+ * We will not take advantage of a change to a higher domain state, because
+ we have no need of the higher power. In such cases, there is nothing to
+ do but acknowledge the parent. So when the parent calls our
+ powerDomainWillChange method, and we decide that we will not be changing
+ state, we merely acknowledge the parent, via return code, and wait.
+ When the parent subsequently calls powerStateDidChange, we acknowledge again
+ via return code, and the change is complete.
+
+ == 4 Paths Through State Machine ==
+ Power state changes are processed in a state machine, and since there are four
+ varieties of power state changes, there are four major paths through the state
+ machine.
+
+ == 5. No Need To change ==
+ The fourth is nearly trivial. In this path, the parent is changing the domain
+ state, but we are not changing the device state. The change starts when the
+ parent calls powerDomainWillChange. All we do is acknowledge the parent. When
+ the parent calls powerStateDidChange, we acknowledge the parent again, and
+ we're done.
+
+ == 1. OurChange Down == XXX gvdl
+ The first is fairly simple. It starts:
+ * when a power domain child calls requestPowerDomainState and we decide to
+ change power states to accomodate the child,
+ * or if our power-controlling driver calls changePowerStateTo,
+ * or if some other driver which is using our device calls makeUsable,
+ * or if a subclassed object calls changePowerStateToPriv.
+ These are all power changes initiated by us, not forced upon us by the parent.
+
+ -> We start by notifying interested parties.
+ -> If they all acknowledge via return code, we can go on to state
+ "msSetPowerState".
+ -> Otherwise, we start the ack timer and wait for the stragglers to
+ acknowlege by calling acknowledgePowerChange.
+ -> We move on to state "msSetPowerState" when all the
+ stragglers have acknowledged, or when the ack timer expires on
+ all those which didn't acknowledge.
+ In "msSetPowerState" we call the power-controlling driver to change the
+ power state of the hardware.
+ -> If it returns saying it has done so, we go on to state
+ "msWaitForPowerSettle".
+ -> Otherwise, we have to wait for it, so we set the ack timer and wait.
+ -> When it calls acknowledgeSetPowerState, or when the ack timer
+ expires, we go on.
+ In "msWaitForPowerSettle", we look in the power state array to see if
+ there is any settle time required when changing from our current state to the
+ new state.
+ -> If not, we go right away to "msNotifyInterestedDriversDidChange".
+ -> Otherwise, we set the settle timer and wait. When it expires, we move on.
+ In "msNotifyInterestedDriversDidChange" state, we notify all our
+ interested parties via their powerStateDidChange methods that we have finished
+ changing power state.
+ -> If they all acknowledge via return code, we move on to "msFinish".
+ -> Otherwise we set the ack timer and wait. When they have all
+ acknowledged, or when the ack timer has expired for those that didn't,
+ we move on to "msFinish".
+ In "msFinish" we remove the used change note from the head of the queue
+ and start the next one if one exists.
+
+ == 2. Parent Change Down ==
+ Start at Stage 2 of OurChange Down XXX gvdl
+
+ == 3. Change Up ==
+ Start at Stage 4 of OurChange Down XXX gvdl
+
+Note all parent requested changes need to acknowledge the power has changed to the parent when done.
+ */