X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..593a1d5fd87cdf5b46dd5fcb84467b432cea0f91:/iokit/Kernel/IOPMrootDomain.cpp diff --git a/iokit/Kernel/IOPMrootDomain.cpp b/iokit/Kernel/IOPMrootDomain.cpp index 9af5919f4..1ff71887b 100644 --- a/iokit/Kernel/IOPMrootDomain.cpp +++ b/iokit/Kernel/IOPMrootDomain.cpp @@ -329,7 +329,7 @@ static UInt32 computeDeltaTimeMS( const AbsoluteTime * startTime ) // expert informs us we are the root. // ********************************************************************************** -#define kRootDomainSettingsCount 14 +#define kRootDomainSettingsCount 16 static SYSCTL_STRUCT(_kern, OID_AUTO, sleeptime, CTLFLAG_RD | CTLFLAG_NOAUTO | CTLFLAG_KERN, @@ -363,7 +363,9 @@ bool IOPMrootDomain::start ( IOService * nub ) OSSymbol::withCString(kIOPMSettingWakeOnACChangeKey), OSSymbol::withCString(kIOPMSettingTimeZoneOffsetKey), OSSymbol::withCString(kIOPMSettingDisplaySleepUsesDimKey), - OSSymbol::withCString(kIOPMSettingMobileMotionModuleKey) + OSSymbol::withCString(kIOPMSettingMobileMotionModuleKey), + OSSymbol::withCString(kIOPMSettingGraphicsSwitchKey), + OSSymbol::withCString(kIOPMStateConsoleShutdown) }; @@ -1076,6 +1078,9 @@ void IOPMrootDomain::powerChangeDone ( unsigned long previousState ) // re-enable this timer for next sleep idleSleepPending = false; gSleepOrShutdownPending = 0; + + // Invalidate prior activity tickles to allow wake from doze. + if (wrangler) wrangler->changePowerStateTo(0); break; case RESTART_STATE: @@ -1653,12 +1658,87 @@ void IOPMrootDomain::informCPUStateChange( #endif __i386__ } +//****************************************************************************** +// systemPowerEventOccurred +// +// The power controller is notifying us of a hardware-related power management +// event that we must handle. +// +// systemPowerEventOccurred covers the same functionality that receivePowerNotification +// does; it simply provides a richer API for conveying more information. +//****************************************************************************** +IOReturn IOPMrootDomain::systemPowerEventOccurred( + const OSSymbol *event, + uint32_t intValue) +{ + IOReturn attempt = kIOReturnSuccess; + OSNumber *newNumber = NULL; + + if (!event) + return kIOReturnBadArgument; + + newNumber = OSNumber::withNumber(intValue, 8*sizeof(intValue)); + if (!newNumber) + return kIOReturnInternalError; + + attempt = systemPowerEventOccurred(event, (OSObject *)newNumber); + + newNumber->release(); + + return attempt; +} + +IOReturn IOPMrootDomain::systemPowerEventOccurred( + const OSSymbol *event, + OSObject *value) +{ + OSDictionary *thermalsDict = NULL; + bool shouldUpdate = true; + + if (!event || !value) + return kIOReturnBadArgument; + + // LOCK + // We reuse featuresDict Lock because it already exists and guards + // the very infrequently used publish/remove feature mechanism; so there's zero rsk + // of stepping on that lock. + if (featuresDictLock) IOLockLock(featuresDictLock); + + thermalsDict = (OSDictionary *)getProperty(kIOPMRootDomainPowerStatusKey); + + if (thermalsDict && OSDynamicCast(OSDictionary, thermalsDict)) { + thermalsDict = OSDictionary::withDictionary(thermalsDict); + } else { + thermalsDict = OSDictionary::withCapacity(1); + } + + if (!thermalsDict) { + shouldUpdate = false; + goto exit; + } + + thermalsDict->setObject (event, value); + + setProperty (kIOPMRootDomainPowerStatusKey, thermalsDict); + + thermalsDict->release(); + +exit: + // UNLOCK + if (featuresDictLock) IOLockUnlock(featuresDictLock); + + if (shouldUpdate) + messageClients (kIOPMMessageSystemPowerEventOccurred, (void *)NULL); + + return kIOReturnSuccess; +} + //****************************************************************************** // receivePowerNotification // // The power controller is notifying us of a hardware-related power management -// event that we must handle. This is a result of an 'environment' interrupt from +// event that we must handle. This may be a result of an 'environment' interrupt from // the power mgt micro. //****************************************************************************** @@ -2227,12 +2307,30 @@ void IOPMrootDomain::tellChangeUp ( unsigned long stateNum) { if ( stateNum == ON_STATE ) { -#if HIBERNATION // Direct callout into OSMetaClass so it can disable kmod unloads // during sleep/wake to prevent deadlocks. OSMetaClassSystemSleepOrWake( kIOMessageSystemHasPoweredOn ); - IOHibernateSystemPostWake(); + if (getPowerState() == ON_STATE) + { + // this is a quick wake from aborted sleep + if (idleSeconds && !wrangler) + { + AbsoluteTime deadline; + sleepASAP = false; + // stay awake for at least idleSeconds + clock_interval_to_deadline(idleSeconds, kSecondScale, &deadline); + thread_call_enter_delayed(extraSleepTimer, deadline); + // this gets turned off when we sleep again + idleSleepPending = true; + } + tellClients(kIOMessageSystemWillPowerOn); + } +#if HIBERNATION + else + { + IOHibernateSystemPostWake(); + } #endif return tellClients(kIOMessageSystemHasPoweredOn); }