1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28#ifndef _IOKIT_ROOTDOMAIN_H
29#define _IOKIT_ROOTDOMAIN_H
30
31#include <IOKit/IOService.h>
32#include <IOKit/pwr_mgt/IOPM.h>
33
34class IOPMPowerStateQueue;
35class RootDomainUserClient;
36
37enum {
38    kRootDomainSleepNotSupported	= 0x00000000,
39    kRootDomainSleepSupported 		= 0x00000001,
40    kFrameBufferDeepSleepSupported	= 0x00000002,
41    kPCICantSleep			= 0x00000004
42};
43
44
45
46/*
47 *IOPMrootDomain registry property keys
48 */
49#define kRootDomainSupportedFeatures        "Supported Features"
50#define kRootDomainSleepReasonKey           "Last Sleep Reason"
51#define kRootDomainSleepOptionsKey          "Last Sleep Options"
52#define kIOPMRootDomainPowerStatusKey       "Power Status"
53
54/*
55 * Possible sleep reasons found under kRootDomainSleepReasonsKey
56 */
57#define kIOPMClamshellSleepKey              "Clamshell Sleep"
58#define kIOPMPowerButtonSleepKey            "Power Button Sleep"
59#define kIOPMSoftwareSleepKey               "Software Sleep"
60#define kIOPMOSSwitchHibernationKey         "OS Switch Sleep"
61#define kIOPMIdleSleepKey                   "Idle Sleep"
62#define kIOPMLowPowerSleepKey               "Low Power Sleep"
63#define kIOPMThermalEmergencySleepKey       "Thermal Emergency Sleep"
64
65/*
66 * String constants for communication with PM CPU
67 */
68#define kIOPMRootDomainLidCloseCString      "LidClose"
69#define kIOPMRootDomainBatPowerCString      "BatPower"
70
71// Supported Feature bitfields for IOPMrootDomain::publishFeature()
72enum {
73    kIOPMSupportedOnAC = 1<<0,
74    kIOPMSupportedOnBatt = 1<<1,
75    kIOPMSupportedOnUPS = 1<<2
76};
77
78typedef IOReturn (*IOPMSettingControllerCallback) \
79                    (OSObject *target, const OSSymbol *type, \
80                     OSObject *val, uintptr_t refcon);
81
82extern "C"
83{
84    IONotifier * registerSleepWakeInterest(
85               IOServiceInterestHandler, void *, void * = 0);
86
87    IONotifier * registerPrioritySleepWakeInterest(
88                IOServiceInterestHandler handler,
89                void * self, void * ref = 0);
90
91    IOReturn acknowledgeSleepWakeNotification(void * );
92
93    IOReturn vetoSleepWakeNotification(void * PMrefcon);
94
95    IOReturn rootDomainRestart ( void );
96
97    IOReturn rootDomainShutdown ( void );
98}
99
100#define IOPM_ROOTDOMAIN_REV		2
101
102class IOPMrootDomain: public IOService
103{
104OSDeclareDefaultStructors(IOPMrootDomain)
105
106public:
107
108    class IOService * wrangler;			// we tickle the wrangler on button presses, etc
109
110    static IOPMrootDomain * construct( void );
111    virtual bool start( IOService * provider );
112    virtual IOReturn setAggressiveness ( unsigned long, unsigned long );
113    virtual IOReturn youAreRoot ( void );
114
115    virtual IOReturn sleepSystem ( void );
116    IOReturn sleepSystemOptions ( OSDictionary *options );
117
118    virtual IOReturn setProperties ( OSObject * );
119    IOReturn shutdownSystem ( void );
120    IOReturn restartSystem ( void );
121
122/*! @function systemPowerEventOccurred
123    @abstract Other drivers may inform IOPMrootDomain of system PM events
124    @discussion systemPowerEventOccurred is a richer alternative to receivePowerNotification()
125        Only Apple-owned kexts should have reason to call systemPowerEventOccurred.
126    @param event An OSSymbol describing the type of power event.
127    @param value A 32-bit integer value associated with the event.
128    @param shouldUpdate indicates whether the root domain should send a notification
129        to interested parties. Pass false if you're calling systemPowerEventOccurred
130        several times in succession; and pass true only on the last invocatino.
131    @result kIOReturnSuccess on success */
132    IOReturn systemPowerEventOccurred(const OSSymbol *event,
133                                    uint32_t intValue);
134    IOReturn systemPowerEventOccurred(const OSSymbol *event,
135                                    OSObject *value);
136
137    virtual IOReturn receivePowerNotification (UInt32 msg);
138    virtual void setSleepSupported( IOOptionBits flags );
139    virtual IOOptionBits getSleepSupported();
140    virtual IOReturn requestPowerDomainState ( IOPMPowerFlags, IOPowerConnection *, unsigned long );
141    virtual void handleSleepTimerExpiration ( void );
142    void stopIgnoringClamshellEventsDuringWakeup ( void );
143    void wakeFromDoze( void );
144    void broadcast_it (unsigned long, unsigned long );
145
146    // KEXT driver announces support of power management feature
147    void publishFeature( const char *feature );
148
149    // KEXT driver announces support of power management feature
150    // And specifies power sources with kIOPMSupportedOn{AC/Batt/UPS} bitfield.
151    // Returns a unique uint32_t identifier for later removing support for this
152    // feature.
153    // NULL is acceptable for uniqueFeatureID for kexts without plans to unload.
154    void publishFeature( const char *feature,
155                            uint32_t supportedWhere,
156                            uint32_t *uniqueFeatureID);
157
158    // KEXT driver announces removal of a previously published power management
159    // feature. Pass 'uniqueFeatureID' returned from publishFeature()
160    IOReturn removePublishedFeature( uint32_t removeFeatureID );
161
162    void unIdleDevice( IOService *, unsigned long );
163    void announcePowerSourceChange( void );
164
165    // Override of these methods for logging purposes.
166    virtual IOReturn changePowerStateTo ( unsigned long ordinal );
167    virtual IOReturn changePowerStateToPriv ( unsigned long ordinal );
168
169/*! @function copyPMSetting
170    @abstract Copy the current value for a PM setting. Returns OSNumber or
171        OSData depending on the setting.
172    @param whichSetting Name of the desired setting.
173    @result OSObject *value if valid, NULL otherwise. */
174    OSObject *copyPMSetting(OSSymbol *whichSetting);
175
176/*! @function registerPMSettingController
177    @abstract Register for callbacks on changes to certain PM settings.
178    @param settings NULL terminated array of C strings, each string for a PM
179        setting that the caller is interested in and wants to get callbacks for.
180    @param callout C function ptr or member function cast as such.
181    @param target The target of the callback, usually 'this'
182    @param refcon Will be passed to caller in callback; for caller's use.
183    @param handle Caller should keep the OSObject * returned here. If non-NULL,
184        handle will have a retain count of 1 on return. To deregister, pass to
185        unregisterPMSettingController()
186    @result kIOReturnSuccess on success. */
187    IOReturn registerPMSettingController(
188                                 const OSSymbol *settings[],
189                                 IOPMSettingControllerCallback callout,
190                                 OSObject   *target,
191                                 uintptr_t  refcon,
192                                 OSObject   **handle);    // out param
193
194/*! @function registerPMSettingController
195    @abstract Register for callbacks on changes to certain PM settings.
196    @param settings NULL terminated array of C strings, each string for a PM
197        setting that the caller is interested in and wants to get callbacks for.
198    @param supportedPowerSources bitfield indicating which power sources these
199        settings are supported for (kIOPMSupportedOnAC, etc.)
200    @param callout C function ptr or member function cast as such.
201    @param target The target of the callback, usually 'this'
202    @param refcon Will be passed to caller in callback; for caller's use.
203    @param handle Caller should keep the OSObject * returned here. If non-NULL,
204        handle will have a retain count of 1 on return. To deregister, pass to
205        unregisterPMSettingController()
206    @result kIOReturnSuccess on success. */
207    IOReturn registerPMSettingController(
208                                 const OSSymbol *settings[],
209                                 uint32_t   supportedPowerSources,
210                                 IOPMSettingControllerCallback callout,
211                                 OSObject   *target,
212                                 uintptr_t  refcon,
213                                 OSObject   **handle);    // out param
214
215/*! @function acknowledgeSystemWillShutdown
216    @abstract Handle callbacks from IOService::systemWillShutdown().
217    @param The IOService sender of the callback. */
218	void acknowledgeSystemWillShutdown( IOService * from );
219
220/*! @function handlePlatformHaltRestart
221    @abstract Handle platform halt and restart notifications.
222    @param kPEHaltCPU or kPERestartCPU. */
223	void handlePlatformHaltRestart( UInt32 pe_type );
224
225private:
226
227    // Points to our parent
228    class IORootParent * patriarch;
229
230    // Pref: idle time before idle sleep
231    long		sleepSlider;
232    long		idleSeconds;
233    uint64_t		autoWakeStart;
234    uint64_t		autoWakeEnd;
235
236    // Pref: longest of other idle times (disk and display)
237    long		longestNonSleepSlider;
238
239    // Difference between sleepSlider and longestNonSleepSlider
240    long		extraSleepDelay;
241
242    // Used to wait between say display idle and system idle
243    thread_call_t	extraSleepTimer;
244
245    // Used to ignore clamshell close events while we're waking from sleep
246    thread_call_t   clamshellWakeupIgnore;
247
248	// IOPMrootDomain internal sleep call
249    IOReturn 	privateSleepSystem ( const char *sleepReason );
250
251
252    virtual void powerChangeDone ( unsigned long );
253    virtual void command_received ( void *, void * , void * , void *);
254    virtual bool tellChangeDown ( unsigned long stateNum);
255    virtual bool askChangeDown ( unsigned long stateNum);
256    virtual void tellChangeUp ( unsigned long );
257    virtual void tellNoChangeDown ( unsigned long );
258    void reportUserInput ( void );
259    static IOReturn sysPowerDownHandler( void * target, void * refCon,
260                                    UInt32 messageType, IOService * service,
261                                    void * messageArgument, vm_size_t argSize );
262
263    static IOReturn displayWranglerNotification( void * target, void * refCon,
264                                    UInt32 messageType, IOService * service,
265                                    void * messageArgument, vm_size_t argSize );
266
267    static bool displayWranglerPublished( void * target, void * refCon,
268                                    IOService * newService);
269
270    static bool batteryPublished( void * target, void * refCon,
271                                    IOService * resourceService );
272
273    void adjustPowerState ( void );
274    void setQuickSpinDownTimeout ( void );
275    void restoreUserSpinDownTimeout ( void );
276
277    bool shouldSleepOnClamshellClosed (void );
278    void sendClientClamshellNotification ( void );
279
280    // Inform PMCPU of changes to state like lid, AC vs. battery
281    void informCPUStateChange( uint32_t type, uint32_t value );
282
283    IOLock                  *featuresDictLock;  // guards supportedFeatures
284    IOPMPowerStateQueue     *pmPowerStateQueue;
285    unsigned int user_spindown;       // User's selected disk spindown value
286
287    unsigned int systemBooting:1;
288    unsigned int systemShutdown:1;
289    unsigned int ignoringClamshell:1;
290    unsigned int allowSleep:1;
291    unsigned int sleepIsSupported:1;
292    unsigned int canSleep:1;
293    unsigned int idleSleepPending:1;
294    unsigned int sleepASAP:1;
295    unsigned int desktopMode:1;
296    unsigned int userDisabledAllSleep:1;
297
298    unsigned int acAdaptorConnect:1;
299    unsigned int ignoringClamshellDuringWakeup:1;
300    unsigned int clamshellIsClosed:1;
301    unsigned int clamshellExists:1;
302
303    OSArray         *allowedPMSettings;
304
305    // Settings controller info
306    IORecursiveLock        *settingsCtrlLock;
307    OSDictionary           *settingsCallbacks;
308    OSDictionary           *fPMSettingsDict;
309    IOReturn setPMSetting(const OSSymbol *, OSObject *);
310
311    thread_call_t           diskSyncCalloutEntry;
312    IONotifier              *_batteryPublishNotifier;
313    IONotifier              *_displayWranglerNotifier;
314
315    // Info for communicating system state changes to PMCPU
316    int32_t                idxPMCPUClamshell;
317    int32_t                idxPMCPULimitedPower;
318
319    struct ExpansionData {
320    };
321    ExpansionData   *_reserved;
322    IOOptionBits platformSleepSupport;
323
324    friend class PMSettingObject;
325};
326
327class IORootParent: public IOService
328{
329OSDeclareDefaultStructors(IORootParent)
330
331private:
332    unsigned long mostRecentChange;
333
334public:
335
336    virtual IOReturn changePowerStateToPriv ( unsigned long ordinal );
337
338    bool start ( IOService * nub );
339    void shutDownSystem ( void );
340    void restartSystem ( void );
341    void sleepSystem ( void );
342    void dozeSystem ( void );
343    void sleepToDoze ( void );
344    void wakeSystem ( void );
345};
346
347
348#endif /*  _IOKIT_ROOTDOMAIN_H */
349