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 24#include <IOKit/assert.h> 25#include <IOKit/IOLib.h> 26#include <IOKit/IOKitKeys.h> 27#include <IOKit/IOPlatformExpert.h> 28#include <IOKit/pwr_mgt/RootDomain.h> 29#include <IOKit/IOTimerEventSource.h> 30#include <IOKit/IOUserClient.h> 31#include <IOKit/IOHibernatePrivate.h> 32 33#include <IOKit/graphics/IOGraphicsPrivate.h> 34#include <IOKit/graphics/IOGraphicsTypesPrivate.h> 35 36#include "IODisplayWrangler.h" 37 38/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 39 40enum { 41 kIODisplayWranglerNumPowerStates = kIODisplayNumPowerStates + 1, 42 kIODisplayWranglerMaxPowerState = kIODisplayWranglerNumPowerStates - 1, 43}; 44 45enum 46{ 47 // seconds 48 kDimInterval = 15, 49 kAnnoyanceWithin = 20, 50 kMaxAnnoyanceInterval = 10 * 60, 51}; 52 53/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 54 55#undef super 56#define super IOService 57 58OSDefineMetaClassAndStructors(IODisplayConnect, IOService) 59 60bool IODisplayConnect::initWithConnection( IOIndex _connection ) 61{ 62 char name[ 12 ]; 63 64 if (!super::init()) 65 return (false); 66 67 connection = _connection; 68 69 snprintf( name, sizeof(name), "display%d", (int)connection); 70 71 setName( name); 72 73 return (true); 74} 75 76IOFramebuffer * IODisplayConnect::getFramebuffer( void ) 77{ 78 return ((IOFramebuffer *) getProvider()); 79} 80 81IOIndex IODisplayConnect::getConnection( void ) 82{ 83 return (connection); 84} 85 86IOReturn IODisplayConnect::getAttributeForConnection( IOSelect selector, uintptr_t * value ) 87{ 88 if (!getProvider()) 89 return (kIOReturnNotReady); 90 return ((IOFramebuffer *) getProvider())->getAttributeForConnection(connection, selector, value); 91} 92 93IOReturn IODisplayConnect::setAttributeForConnection( IOSelect selector, uintptr_t value ) 94{ 95 if (!getProvider()) 96 return (kIOReturnNotReady); 97 return ((IOFramebuffer *) getProvider())->setAttributeForConnection(connection, selector, value); 98} 99 100// joinPMtree 101// 102// The policy-maker in the display driver calls here when initializing. 103// We attach it into the power management hierarchy as a child of our 104// frame buffer. 105 106void IODisplayConnect::joinPMtree ( IOService * driver ) 107{ 108 getProvider()->addPowerChild(driver); 109} 110 111/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 112 113#define super IOService 114OSDefineMetaClassAndStructors(IODisplayWrangler, IOService); 115 116IODisplayWrangler * gIODisplayWrangler; 117 118/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 119 120bool IODisplayWrangler::serverStart(void) 121{ 122 mach_timespec_t timeout = { 120, 0 }; 123 124 if (!gIODisplayWrangler) 125 waitForService(serviceMatching("IODisplayWrangler"), &timeout); 126 127 if (gIODisplayWrangler) 128 { 129 gIODisplayWrangler->fOpen = true; 130 if (gIODisplayWrangler->fMinutesToDim) gIODisplayWrangler->setIdleTimerPeriod(60); 131 gIODisplayWrangler->activityTickle(0, 0); 132 } 133 134 return (gIODisplayWrangler != 0); 135} 136 137bool IODisplayWrangler::start( IOService * provider ) 138{ 139 OSObject * notify; 140 141 if (!super::start(provider)) 142 return (false); 143 144 assert( gIODisplayWrangler == 0 ); 145 146 setProperty(kIOUserClientClassKey, "IOAccelerationUserClient"); 147 148 fMatchingLock = IOLockAlloc(); 149 fFramebuffers = OSSet::withCapacity( 1 ); 150 fDisplays = OSSet::withCapacity( 1 ); 151 152 clock_interval_to_absolutetime_interval(kDimInterval, kSecondScale, &fDimInterval); 153 154 assert( fMatchingLock && fFramebuffers && fDisplays ); 155 156 notify = addMatchingNotification( gIOPublishNotification, 157 serviceMatching("IODisplay"), _displayHandler, 158 this, fDisplays ); 159 assert( notify ); 160 161 notify = addMatchingNotification( gIOPublishNotification, 162 serviceMatching("IODisplayConnect"), _displayConnectHandler, 163 this, 0, 50000 ); 164 assert( notify ); 165 166 gIODisplayWrangler = this; 167 168 // initialize power managment 169 gIODisplayWrangler->initForPM(); 170 getPMRootDomain()->publishFeature("AdaptiveDimming"); 171 172 return (true); 173} 174 175bool IODisplayWrangler::_displayHandler( void * target, void * ref, 176 IOService * newService, IONotifier * notifier ) 177{ 178 return (((IODisplayWrangler *)target)->displayHandler((OSSet *) ref, 179 (IODisplay *) newService)); 180} 181 182bool IODisplayWrangler::_displayConnectHandler( void * target, void * ref, 183 IOService * newService, IONotifier * notifier ) 184{ 185 return (((IODisplayWrangler *)target)->displayConnectHandler(ref, 186 (IODisplayConnect *) newService)); 187} 188 189bool IODisplayWrangler::displayHandler( OSSet * set, 190 IODisplay * newDisplay ) 191{ 192 assert( OSDynamicCast( IODisplay, newDisplay )); 193 194 IOTakeLock( fMatchingLock ); 195 196 set->setObject( newDisplay ); 197 198 IOUnlock( fMatchingLock ); 199 200 return (true); 201} 202 203bool IODisplayWrangler::displayConnectHandler( void * /* ref */, 204 IODisplayConnect * connect ) 205{ 206 SInt32 score = 50000; 207 OSIterator * iter; 208 IODisplay * display; 209 bool found = false; 210 211 assert( OSDynamicCast( IODisplayConnect, connect )); 212 213 IOTakeLock( fMatchingLock ); 214 215 iter = OSCollectionIterator::withCollection( fDisplays ); 216 if (iter) 217 { 218 while (!found && (display = (IODisplay *) iter->getNextObject())) 219 { 220 if (display->getConnection()) 221 continue; 222 223 do 224 { 225 if (!display->attach(connect)) 226 continue; 227 found = ((display->probe( connect, &score )) 228 && (display->start( connect ))); 229 if (!found) 230 display->detach( connect ); 231 } 232 while (false); 233 } 234 iter->release(); 235 } 236 237 IOUnlock( fMatchingLock ); 238 239 return (true); 240} 241 242bool IODisplayWrangler::makeDisplayConnects( IOFramebuffer * fb ) 243{ 244 IODisplayConnect * connect; 245 IOItemCount i; 246 247 for (i = 0; i < 1 /*fb->getConnectionCount()*/; i++) 248 { 249 connect = new IODisplayConnect; 250 if (0 == connect) 251 continue; 252 253 if ((connect->initWithConnection(i)) 254 && (connect->attach(fb))) 255 { 256 connect->registerService( kIOServiceSynchronous ); 257 } 258 connect->release(); 259 } 260 261 return (true); 262} 263 264void IODisplayWrangler::destroyDisplayConnects( IOFramebuffer * fb ) 265{ 266 OSIterator * iter; 267 OSObject * next; 268 IODisplayConnect * connect; 269 IODisplay * display; 270 271 fb->removeProperty(kIOFBBuiltInKey); 272 273 iter = fb->getClientIterator(); 274 if (iter) 275 { 276 while ((next = iter->getNextObject())) 277 { 278 if ((connect = OSDynamicCast(IODisplayConnect, next))) 279 { 280 if (connect->isInactive()) 281 continue; 282 display = OSDynamicCast( IODisplay, connect->getClient()); 283 if (display) 284 { 285 gIODisplayWrangler->fDisplays->removeObject( display ); 286 display->PMstop(); 287 } 288 connect->terminate( kIOServiceSynchronous ); 289 } 290 } 291 iter->release(); 292 } 293} 294 295void IODisplayWrangler::activityChange( IOFramebuffer * fb ) 296{ 297 DEBG1("W", " activityChange\n"); 298 gIODisplayWrangler->activityTickle(0,0); 299} 300 301IODisplayConnect * IODisplayWrangler::getDisplayConnect( 302 IOFramebuffer * fb, IOIndex connect ) 303{ 304 OSIterator * iter; 305 OSObject * next; 306 IODisplayConnect * connection = 0; 307 308 iter = fb->getClientIterator(); 309 if (iter) 310 { 311 while ((next = iter->getNextObject())) 312 { 313 connection = OSDynamicCast( IODisplayConnect, next); 314 if (connection) 315 { 316 if (connection->isInactive()) 317 continue; 318 if (0 == (connect--)) 319 break; 320 } 321 } 322 iter->release(); 323 } 324 return (connection); 325} 326 327IOReturn IODisplayWrangler::getConnectFlagsForDisplayMode( 328 IODisplayConnect * connect, 329 IODisplayModeID mode, UInt32 * flags ) 330{ 331 IOReturn err = kIOReturnUnsupported; 332 IODisplay * display; 333 334 display = OSDynamicCast( IODisplay, connect->getClient()); 335 if (display) 336 err = display->getConnectFlagsForDisplayMode( mode, flags ); 337 else 338 { 339 err = connect->getFramebuffer()->connectFlags( 340 connect->getConnection(), mode, flags ); 341 } 342 343 return (err); 344} 345 346IOReturn IODisplayWrangler::getFlagsForDisplayMode( 347 IOFramebuffer * fb, 348 IODisplayModeID mode, UInt32 * flags ) 349{ 350 IODisplayConnect * connect; 351 352 // should look at all connections 353 connect = gIODisplayWrangler->getDisplayConnect( fb, 0 ); 354 if (!connect) 355 return (fb->connectFlags(0, mode, flags)); 356 357 return (gIODisplayWrangler-> 358 getConnectFlagsForDisplayMode(connect, mode, flags)); 359} 360 361/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 362 363static IOPMPowerState ourPowerStates[kIODisplayWranglerNumPowerStates] = { 364 // version, 365 // capabilityFlags, outputPowerCharacter, inputPowerRequirement, 366 { 1, 0, 0, 0, 0,0,0,0,0,0,0,0 }, 367 { 1, 0, 0, IOPMPowerOn, 0,0,0,0,0,0,0,0 }, 368 { 1, 0, 0, IOPMPowerOn, 0,0,0,0,0,0,0,0 }, 369 { 1, IOPMDeviceUsable | kIOPMPreventIdleSleep, 0, IOPMPowerOn, 0,0,0,0,0,0,0,0 }, 370 { 1, IOPMDeviceUsable | kIOPMPreventIdleSleep, 0, IOPMPowerOn, 0,0,0,0,0,0,0,0 } 371 // staticPower, unbudgetedPower, powerToAttain, timeToAttain, settleUpTime, 372 // timeToLower, settleDownTime, powerDomainBudget 373 }; 374 375 376/* 377 This is the Power Management policy-maker for the displays. It senses when 378 the display is idle and lowers power accordingly. It raises power back up 379 when the display becomes un-idle. 380 381 It senses idleness with a combination of an idle timer and the "activityTickle" 382 method call. "activityTickle" is called by objects which sense keyboard activity, 383 mouse activity, or other button activity (display contrast, display brightness, 384 PCMCIA eject). The method sets a "displayInUse" flag. When the timer expires, 385 this flag is checked. If it is on, the display is judged "in use". The flag is 386 cleared and the timer is restarted. 387 388 If the flag is off when the timer expires, then there has been no user activity 389 since the last timer expiration, and the display is judged idle and its power is 390 lowered. 391 392 The period of the timer is a function of the current value of Power Management 393 aggressiveness. As that factor varies from 1 to 999, the timer period varies 394 from 1004 seconds to 6 seconds. Above 1000, the system is in a very aggressive 395 power management condition, and the timer period is 5 seconds. (In this case, 396 the display dims between five and ten seconds after the last user activity). 397 398 This driver calls the drivers for each display and has them move their display 399 between various power states. When the display is idle, its power is dropped 400 state by state until it is in the lowest state. When it becomes un-idle it is 401 powered back up to the state where it was last being used. 402 403 In times of very high power management aggressiveness, the display will not be 404 operated above the lowest power state which is marked "usable". 405 406 When Power Management is turned off (aggressiveness = 0), the display is never 407 judged idle and never dimmed. 408 409 We register with Power Management only so that we can be informed of changes in 410 the Power Management aggressiveness factor. We don't really have a device with 411 power states so we implement the absolute minimum. The display drivers themselves 412 are part of the Power Management hierarchy under their respective frame buffers. 413*/ 414 415/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 416// initForPM 417// 418 419void IODisplayWrangler::initForPM(void ) 420{ 421 // initialize superclass variables 422 PMinit(); 423 424 // attach into the power management hierarchy 425 joinPMtree( this ); 426 427 // register ourselves with policy-maker (us) 428 registerPowerDriver( this, ourPowerStates, kIODisplayWranglerNumPowerStates ); 429 makeUsable(); 430 431 // HID system is waiting for this 432 registerService(); 433} 434 435unsigned long IODisplayWrangler::initialPowerStateForDomainState( IOPMPowerFlags domainState ) 436{ 437 if (domainState & IOPMPowerOn) 438 return (kIODisplayWranglerMaxPowerState); 439 else 440 return (0); 441} 442 443/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 444// setAggressiveness 445// 446// We are informed by our power domain parent of a new level of "power management 447// aggressiveness" which we use as a factor in our judgement of when we are idle. 448// This change implies a change in our idle timer period, so restart that timer. 449// timer. 450 451IOReturn IODisplayWrangler::setAggressiveness( unsigned long type, unsigned long newLevel ) 452{ 453 switch (type) 454 { 455 456 case kIOFBCaptureAggressiveness: 457 458 if (fDimCaptured && !newLevel) 459 activityTickle(0,0); 460 461 fDimCaptured = (0 != newLevel); 462 setProperty("DimCaptured", fDimCaptured); 463 464 /* fall thru */ 465 466 case kPMMinutesToDim: 467 // minutes to dim received 468 if (kPMMinutesToDim == type) 469 { 470 // Display will always dim at least kMinDimTime seconds before 471 // display sleep kicks in. 472 fMinutesToDim = newLevel; 473 clock_interval_to_absolutetime_interval(fMinutesToDim * 60, kSecondScale, &fOffInterval[0]); 474 475 uint32_t annoyedInterval = fMinutesToDim * 60 * 2; 476 if (annoyedInterval > kMaxAnnoyanceInterval) annoyedInterval = kMaxAnnoyanceInterval; 477 if (annoyedInterval < (fMinutesToDim * 60)) annoyedInterval = (fMinutesToDim * 60); 478 clock_interval_to_absolutetime_interval(annoyedInterval, kSecondScale, &fOffInterval[1]); 479 AbsoluteTime_to_scalar(&fSettingsChanged) = mach_absolute_time(); 480 481 DEBG2("W", " fMinutesToDim %ld, annoyed %d\n", newLevel, annoyedInterval); 482 } 483 484 newLevel = fDimCaptured ? 0 : fMinutesToDim; 485 if (newLevel == 0) 486 { 487 // pm turned off while idle? 488 if (getPowerState() < kIODisplayWranglerMaxPowerState) 489 { 490 // yes, bring displays up again 491// activityTickle(0,0); 492 changePowerStateToPriv( kIODisplayWranglerMaxPowerState ); 493 } 494 } 495 setIdleTimerPeriod(newLevel * 30); 496 break; 497 498 default: 499 break; 500 } 501 super::setAggressiveness(type, newLevel); 502 return (IOPMNoErr); 503} 504 505 506/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 507// setPowerState 508// 509// The vanilla policy-maker in the superclass is changing our power state. 510// If it's down, inform the displays to lower one state, too. If it's up, 511// the idle displays are made usable. 512 513IOReturn IODisplayWrangler::setPowerState( unsigned long powerStateOrdinal, IOService * whatDevice ) 514{ 515 fPendingPowerState = powerStateOrdinal; 516 517 DEBG2("W", " (%ld), pwr %d open %d\n", 518 powerStateOrdinal, gIOGraphicsSystemPower, fOpen); 519 520 if (powerStateOrdinal == 0) 521 { 522 // system is going to sleep 523 // keep displays off on wake till UI brings them up 524 changePowerStateToPriv(0); 525 return (IOPMNoErr); 526 } 527 528 if (!gIOGraphicsSystemPower || !fOpen) 529 return (IOPMNoErr); 530 else if (powerStateOrdinal < getPowerState()) 531 { 532 // HI is idle, drop power 533 if (kIODisplayWranglerMaxPowerState == getPowerState()) 534 { 535 clock_interval_to_deadline(kAnnoyanceWithin, kSecondScale, &fAnnoyanceUntil); 536 } 537 538 if (powerStateOrdinal < 3) fAnnoyed = false; 539 540 IOFramebuffer::updateDisplaysPowerState(); 541 } 542 else if (powerStateOrdinal == kIODisplayWranglerMaxPowerState) 543 { 544 // there is activity, raise power 545 IOFramebuffer::updateDisplaysPowerState(); 546 547 start_PM_idle_timer(); 548 } 549 return (IOPMNoErr); 550} 551 552unsigned long IODisplayWrangler::getDisplaysPowerState(void) 553{ 554 unsigned long state = gIODisplayWrangler 555 ? gIODisplayWrangler->fPendingPowerState 556 : kIODisplayWranglerMaxPowerState; 557 return (state); 558} 559 560/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 561// nextIdleTimeout 562// 563// Virtual member function of IOService 564// overridden here to provide custom power-down behavior for dimming displays. 565// - Transition from 4->3 (to dim on built-in LCDs) 566// - Transition from 3->2 (to full display sleep on all machines) 567// will occur at exactly N minutes from last user activity, where N 568// is the value chosen by the user and set via setAggressiveness(). 569 570SInt32 IODisplayWrangler::nextIdleTimeout( 571 AbsoluteTime currentTime, 572 AbsoluteTime lastActivity, 573 unsigned int powerState) 574{ 575 AbsoluteTime deadline; 576 uint64_t delayNS = 0; 577 SInt32 delaySecs = 0; 578 579 if (!fOpen) 580 { 581 enum { kWindowServerStartTime = 24 * 60 * 60 }; 582 return (kWindowServerStartTime); 583 } 584 585 if (CMP_ABSOLUTETIME(&fSettingsChanged, &lastActivity) > 0) lastActivity = fSettingsChanged; 586 587 switch (fPendingPowerState) 588 { 589 case 4: 590 // The system is currently in its 'on' state 591 case 3: 592 // The system is currently in its 'dim' state 593 // The transition into the next 'display sleep' state must occur 594 // fMinutesToDim after last UI activity 595 deadline = lastActivity; 596 ADD_ABSOLUTETIME(&deadline, &fOffInterval[fAnnoyed]); 597 if (4 == fPendingPowerState) SUB_ABSOLUTETIME(&deadline, &fDimInterval); 598 if (CMP_ABSOLUTETIME(&deadline, ¤tTime) > 0) 599 { 600 SUB_ABSOLUTETIME(&deadline, ¤tTime); 601 absolutetime_to_nanoseconds(deadline, &delayNS); 602 delaySecs = delayNS / kSecondScale; 603 } 604 break; 605 606 case 2: 607 case 1: 608 delaySecs = fMinutesToDim * 30; 609 break; 610 case 0: 611 default: 612 // error 613 delaySecs = 60; 614 break; 615 } 616 617 DEBG2("W", " %ld, %d, annoyed %d, now %lld, last %lld\n", 618 fPendingPowerState, (int) delaySecs, fAnnoyed, 619 AbsoluteTime_to_scalar(¤tTime), 620 AbsoluteTime_to_scalar(&lastActivity)); 621 622 if (!delaySecs) delaySecs = 1; 623 624 return (delaySecs); 625} 626 627/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 628// activityTickle 629// 630// This is called by the HID system and calls the superclass in turn. 631 632bool IODisplayWrangler::activityTickle( unsigned long x, unsigned long y ) 633{ 634 AbsoluteTime now; 635 636 if (!fOpen) 637 return (true); 638 639 AbsoluteTime_to_scalar(&now) = mach_absolute_time(); 640 if (AbsoluteTime_to_scalar(&fIdleUntil)) 641 { 642 if (CMP_ABSOLUTETIME(&now, &fIdleUntil) < 0) 643 return (true); 644 AbsoluteTime_to_scalar(&fIdleUntil) = 0; 645 } 646 647 // Record if this was an annoyance. 648 if (AbsoluteTime_to_scalar(&fAnnoyanceUntil)) 649 { 650 DEBG2("W", " now %lld, annoyed until %lld\n", 651 AbsoluteTime_to_scalar(&now), 652 AbsoluteTime_to_scalar(&fAnnoyanceUntil)); 653 654 if (CMP_ABSOLUTETIME(&now, &fAnnoyanceUntil) < 0) 655 fAnnoyed = true; 656 AbsoluteTime_to_scalar(&fAnnoyanceUntil) = 0; 657 } 658 659 if (super::activityTickle(kIOPMSuperclassPolicy1, 660 kIODisplayWranglerMaxPowerState) ) 661 { 662 return (true); 663 } 664 665 getPMRootDomain()->wakeFromDoze(); 666 667 return (false); 668} 669 670OSObject * IODisplayWrangler::copyProperty( const char * aKey ) const 671{ 672 if (!strcmp(aKey, kIOGraphicsPrefsKey)) 673 return (IOFramebuffer::copyPreferences()); 674 return (super::copyProperty(aKey)); 675} 676 677IOReturn IODisplayWrangler::setProperties( OSObject * properties ) 678{ 679 OSDictionary * dict; 680 OSDictionary * prefs; 681 OSObject * obj; 682 OSNumber * num; 683 uint32_t idleFor = 0; 684 enum { kIODisplayRequestDefaultIdleFor = 1000, 685 kIODisplayRequestMaxIdleFor = 15000 }; 686 687 if (!(dict = OSDynamicCast(OSDictionary, properties))) 688 return (kIOReturnBadArgument); 689 690 if ((prefs = OSDynamicCast(OSDictionary, 691 dict->getObject(kIOGraphicsPrefsKey)))) 692 { 693 return (IOFramebuffer::setPreferences(this, prefs)); 694 } 695 696 obj = dict->getObject(kIORequestIdleKey); 697 if (kOSBooleanTrue == obj) 698 { 699 idleFor = kIODisplayRequestDefaultIdleFor; 700 } 701 else if (kOSBooleanFalse == obj) 702 { 703 AbsoluteTime_to_scalar(&fIdleUntil) = 0; 704 activityTickle(0, 0); 705 } 706 else if ((num = OSDynamicCast(OSNumber, obj))) 707 { 708 idleFor = num->unsigned32BitValue(); 709 if (idleFor > kIODisplayRequestMaxIdleFor) 710 idleFor = kIODisplayRequestMaxIdleFor; 711 } 712 713 if (idleFor) 714 { 715 DEBG1("W", " idleFor(%d)\n", idleFor); 716 717 clock_interval_to_deadline(idleFor, kMillisecondScale, &fIdleUntil); 718 if (getPowerState() > 1) 719 changePowerStateToPriv(1); 720 return (kIOReturnSuccess); 721 } 722 723 return (kIOReturnSuccess); 724} 725