xref: /reactos/drivers/bus/acpi/busmgr/system.c (revision 34593d93)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  *  acpi_system.c - ACPI System Driver ($Revision: 57 $)
3*c2c66affSColin Finck  *
4*c2c66affSColin Finck  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5*c2c66affSColin Finck  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6*c2c66affSColin Finck  *
7*c2c66affSColin Finck  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8*c2c66affSColin Finck  *
9*c2c66affSColin Finck  *  This program is free software; you can redistribute it and/or modify
10*c2c66affSColin Finck  *  it under the terms of the GNU General Public License as published by
11*c2c66affSColin Finck  *  the Free Software Foundation; either version 2 of the License, or (at
12*c2c66affSColin Finck  *  your option) any later version.
13*c2c66affSColin Finck  *
14*c2c66affSColin Finck  *  This program is distributed in the hope that it will be useful, but
15*c2c66affSColin Finck  *  WITHOUT ANY WARRANTY; without even the implied warranty of
16*c2c66affSColin Finck  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17*c2c66affSColin Finck  *  General Public License for more details.
18*c2c66affSColin Finck  *
19*c2c66affSColin Finck  *  You should have received a copy of the GNU General Public License along
20*c2c66affSColin Finck  *  with this program; if not, write to the Free Software Foundation, Inc.,
21*c2c66affSColin Finck  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22*c2c66affSColin Finck  *
23*c2c66affSColin Finck  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24*c2c66affSColin Finck  */
25*c2c66affSColin Finck 
26*c2c66affSColin Finck /* Modified for ReactOS and latest ACPICA
27*c2c66affSColin Finck  * Copyright (C)2009  Samuel Serapion
28*c2c66affSColin Finck  */
29*c2c66affSColin Finck 
30*c2c66affSColin Finck #include <precomp.h>
31*c2c66affSColin Finck 
32*c2c66affSColin Finck #define NDEBUG
33*c2c66affSColin Finck #include <debug.h>
34*c2c66affSColin Finck 
35*c2c66affSColin Finck ACPI_STATUS acpi_system_save_state(UINT32);
36*c2c66affSColin Finck 
37*c2c66affSColin Finck #define _COMPONENT		ACPI_SYSTEM_COMPONENT
38*c2c66affSColin Finck ACPI_MODULE_NAME		("acpi_system")
39*c2c66affSColin Finck 
40*c2c66affSColin Finck #define PREFIX			"ACPI: "
41*c2c66affSColin Finck 
42*c2c66affSColin Finck static int acpi_system_add (struct acpi_device *device);
43*c2c66affSColin Finck static int acpi_system_remove (struct acpi_device *device, int type);
44*c2c66affSColin Finck 
45*c2c66affSColin Finck ACPI_STATUS acpi_suspend (UINT32 state);
46*c2c66affSColin Finck 
47*c2c66affSColin Finck static struct acpi_driver acpi_system_driver = {
48*c2c66affSColin Finck     {0,0},
49*c2c66affSColin Finck     ACPI_SYSTEM_DRIVER_NAME,
50*c2c66affSColin Finck     ACPI_SYSTEM_CLASS,
51*c2c66affSColin Finck     0,
52*c2c66affSColin Finck     0,
53*c2c66affSColin Finck     ACPI_SYSTEM_HID,
54*c2c66affSColin Finck     {acpi_system_add, acpi_system_remove}
55*c2c66affSColin Finck };
56*c2c66affSColin Finck 
57*c2c66affSColin Finck struct acpi_system
58*c2c66affSColin Finck {
59*c2c66affSColin Finck 	ACPI_HANDLE		handle;
60*c2c66affSColin Finck 	UINT8			states[ACPI_S_STATE_COUNT];
61*c2c66affSColin Finck };
62*c2c66affSColin Finck 
63*c2c66affSColin Finck 
64*c2c66affSColin Finck static int
acpi_system_add(struct acpi_device * device)65*c2c66affSColin Finck acpi_system_add (
66*c2c66affSColin Finck 	struct acpi_device	*device)
67*c2c66affSColin Finck {
68*c2c66affSColin Finck 	ACPI_STATUS		status = AE_OK;
69*c2c66affSColin Finck 	struct acpi_system	*system = NULL;
70*c2c66affSColin Finck 	UINT8			i = 0;
71*c2c66affSColin Finck 
72*c2c66affSColin Finck 	ACPI_FUNCTION_TRACE("acpi_system_add");
73*c2c66affSColin Finck 
74*c2c66affSColin Finck 	if (!device)
75*c2c66affSColin Finck 		return_VALUE(-1);
76*c2c66affSColin Finck 
77*c2c66affSColin Finck 	system = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct acpi_system),'IPCA');
78*c2c66affSColin Finck 	if (!system)
79*c2c66affSColin Finck 		return_VALUE(-14);
80*c2c66affSColin Finck 	memset(system, 0, sizeof(struct acpi_system));
81*c2c66affSColin Finck 
82*c2c66affSColin Finck 	system->handle = device->handle;
83*c2c66affSColin Finck 	sprintf(acpi_device_name(device), "%s", ACPI_SYSTEM_DEVICE_NAME);
84*c2c66affSColin Finck 	sprintf(acpi_device_class(device), "%s", ACPI_SYSTEM_CLASS);
85*c2c66affSColin Finck 	acpi_driver_data(device) = system;
86*c2c66affSColin Finck 
87*c2c66affSColin Finck 	DPRINT("%s [%s] (supports",
88*c2c66affSColin Finck 		acpi_device_name(device), acpi_device_bid(device));
89*c2c66affSColin Finck 	for (i=0; i<ACPI_S_STATE_COUNT; i++) {
90*c2c66affSColin Finck 		UINT8 type_a, type_b;
91*c2c66affSColin Finck 		status = AcpiGetSleepTypeData(i, &type_a, &type_b);
92*c2c66affSColin Finck 		switch (i) {
93*c2c66affSColin Finck 		case ACPI_STATE_S4:
94*c2c66affSColin Finck 			if (/*AcpiGbl_FACS->S4bios_f &&*/
95*c2c66affSColin Finck 			    0 != AcpiGbl_FADT.SmiCommand) {
96*c2c66affSColin Finck 				DPRINT(" S4bios\n");
97*c2c66affSColin Finck 				system->states[i] = 1;
98*c2c66affSColin Finck 			}
99*c2c66affSColin Finck 			/* no break */
100*c2c66affSColin Finck 		default:
101*c2c66affSColin Finck 			if (ACPI_SUCCESS(status)) {
102*c2c66affSColin Finck 				system->states[i] = 1;
103*c2c66affSColin Finck 				DPRINT(" S%d", i);
104*c2c66affSColin Finck 			}
105*c2c66affSColin Finck 		}
106*c2c66affSColin Finck 	}
107*c2c66affSColin Finck 
108*c2c66affSColin Finck //#ifdef CONFIG_PM
109*c2c66affSColin Finck //	/* Install the soft-off (S5) handler. */
110*c2c66affSColin Finck //	if (system->states[ACPI_STATE_S5]) {
111*c2c66affSColin Finck //		pm_power_off = acpi_power_off;
112*c2c66affSColin Finck //		register_sysrq_key('o', &sysrq_acpi_poweroff_op);
113*c2c66affSColin Finck //	}
114*c2c66affSColin Finck //#endif
115*c2c66affSColin Finck 
116*c2c66affSColin Finck 	return_VALUE(0);
117*c2c66affSColin Finck }
118*c2c66affSColin Finck 
119*c2c66affSColin Finck static int
acpi_system_remove(struct acpi_device * device,int type)120*c2c66affSColin Finck acpi_system_remove (
121*c2c66affSColin Finck 	struct acpi_device	*device,
122*c2c66affSColin Finck 	int			type)
123*c2c66affSColin Finck {
124*c2c66affSColin Finck 	struct acpi_system	*system = NULL;
125*c2c66affSColin Finck 
126*c2c66affSColin Finck 	ACPI_FUNCTION_TRACE("acpi_system_remove");
127*c2c66affSColin Finck 
128*c2c66affSColin Finck 	if (!device || !acpi_driver_data(device))
129*c2c66affSColin Finck 		return_VALUE(-1);
130*c2c66affSColin Finck 
131*c2c66affSColin Finck 	system = (struct acpi_system *) acpi_driver_data(device);
132*c2c66affSColin Finck 
133*c2c66affSColin Finck //#ifdef CONFIG_PM
134*c2c66affSColin Finck //	/* Remove the soft-off (S5) handler. */
135*c2c66affSColin Finck //	if (system->states[ACPI_STATE_S5]) {
136*c2c66affSColin Finck //		unregister_sysrq_key('o', &sysrq_acpi_poweroff_op);
137*c2c66affSColin Finck //		pm_power_off = NULL;
138*c2c66affSColin Finck //	}
139*c2c66affSColin Finck //#endif
140*c2c66affSColin Finck //
141*c2c66affSColin Finck //
142*c2c66affSColin Finck 	ExFreePoolWithTag(system, 'IPCA');
143*c2c66affSColin Finck 
144*c2c66affSColin Finck 	return 0;
145*c2c66affSColin Finck }
146*c2c66affSColin Finck 
147*c2c66affSColin Finck /**
148*c2c66affSColin Finck  * acpi_system_restore_state - OS-specific restoration of state
149*c2c66affSColin Finck  * @state:	sleep state we're exiting
150*c2c66affSColin Finck  *
151*c2c66affSColin Finck  * Note that if we're coming back from S4, the memory image should have
152*c2c66affSColin Finck  * already been loaded from the disk and is already in place.  (Otherwise how
153*c2c66affSColin Finck  * else would we be here?).
154*c2c66affSColin Finck  */
155*c2c66affSColin Finck ACPI_STATUS
acpi_system_restore_state(UINT32 state)156*c2c66affSColin Finck acpi_system_restore_state(
157*c2c66affSColin Finck 	UINT32			state)
158*c2c66affSColin Finck {
159*c2c66affSColin Finck 	/*
160*c2c66affSColin Finck 	 * We should only be here if we're coming back from STR or STD.
161*c2c66affSColin Finck 	 * And, in the case of the latter, the memory image should have already
162*c2c66affSColin Finck 	 * been loaded from disk.
163*c2c66affSColin Finck 	 */
164*c2c66affSColin Finck 	if (state > ACPI_STATE_S1) {
165*c2c66affSColin Finck 		//acpi_restore_state_mem();
166*c2c66affSColin Finck 
167*c2c66affSColin Finck 		/* Do _early_ resume for irqs.  Required by
168*c2c66affSColin Finck 		 * ACPI specs.
169*c2c66affSColin Finck 		 */
170*c2c66affSColin Finck 		/* TBD: call arch dependant reinitialization of the
171*c2c66affSColin Finck 		 * interrupts.
172*c2c66affSColin Finck 		 */
173*c2c66affSColin Finck #ifdef _X86_
174*c2c66affSColin Finck 		//init_8259A(0);
175*c2c66affSColin Finck #endif
176*c2c66affSColin Finck 		/* wait for power to come back */
177*c2c66affSColin Finck 		KeStallExecutionProcessor(100);
178*c2c66affSColin Finck 
179*c2c66affSColin Finck 	}
180*c2c66affSColin Finck 
181*c2c66affSColin Finck 	/* Be really sure that irqs are disabled. */
182*c2c66affSColin Finck 	//ACPI_DISABLE_IRQS();
183*c2c66affSColin Finck 
184*c2c66affSColin Finck 	/* Wait a little again, just in case... */
185*c2c66affSColin Finck 	KeStallExecutionProcessor(10);
186*c2c66affSColin Finck 
187*c2c66affSColin Finck 	/* enable interrupts once again */
188*c2c66affSColin Finck 	//ACPI_ENABLE_IRQS();
189*c2c66affSColin Finck 
190*c2c66affSColin Finck 	/* turn all the devices back on */
191*c2c66affSColin Finck 	//if (state > ACPI_STATE_S1)
192*c2c66affSColin Finck 		//pm_send_all(PM_RESUME, (void *)0);
193*c2c66affSColin Finck 
194*c2c66affSColin Finck 	return AE_OK;
195*c2c66affSColin Finck }
196*c2c66affSColin Finck 
197*c2c66affSColin Finck 
198*c2c66affSColin Finck /**
199*c2c66affSColin Finck  * acpi_system_save_state - save OS specific state and power down devices
200*c2c66affSColin Finck  * @state:	sleep state we're entering.
201*c2c66affSColin Finck  *
202*c2c66affSColin Finck  * This handles saving all context to memory, and possibly disk.
203*c2c66affSColin Finck  * First, we call to the device driver layer to save device state.
204*c2c66affSColin Finck  * Once we have that, we save whatevery processor and kernel state we
205*c2c66affSColin Finck  * need to memory.
206*c2c66affSColin Finck  * If we're entering S4, we then write the memory image to disk.
207*c2c66affSColin Finck  *
208*c2c66affSColin Finck  * Only then it is safe for us to power down devices, since we may need
209*c2c66affSColin Finck  * the disks and upstream buses to write to.
210*c2c66affSColin Finck  */
211*c2c66affSColin Finck ACPI_STATUS
acpi_system_save_state(UINT32 state)212*c2c66affSColin Finck acpi_system_save_state(
213*c2c66affSColin Finck 	UINT32			state)
214*c2c66affSColin Finck {
215*c2c66affSColin Finck 	int			error = 0;
216*c2c66affSColin Finck 
217*c2c66affSColin Finck 	/* Send notification to devices that they will be suspended.
218*c2c66affSColin Finck 	 * If any device or driver cannot make the transition, either up
219*c2c66affSColin Finck 	 * or down, we'll get an error back.
220*c2c66affSColin Finck 	 */
221*c2c66affSColin Finck 	/*if (state > ACPI_STATE_S1) {
222*c2c66affSColin Finck 		error = pm_send_all(PM_SAVE_STATE, (void *)3);
223*c2c66affSColin Finck 		if (error)
224*c2c66affSColin Finck 			return AE_ERROR;
225*c2c66affSColin Finck 	}*/
226*c2c66affSColin Finck 
227*c2c66affSColin Finck 	//if (state <= ACPI_STATE_S5) {
228*c2c66affSColin Finck 	//	/* Tell devices to stop I/O and actually save their state.
229*c2c66affSColin Finck 	//	 * It is theoretically possible that something could fail,
230*c2c66affSColin Finck 	//	 * so handle that gracefully..
231*c2c66affSColin Finck 	//	 */
232*c2c66affSColin Finck 	//	if (state > ACPI_STATE_S1 && state != ACPI_STATE_S5) {
233*c2c66affSColin Finck 	//		error = pm_send_all(PM_SUSPEND, (void *)3);
234*c2c66affSColin Finck 	//		if (error) {
235*c2c66affSColin Finck 	//			/* Tell devices to restore state if they have
236*c2c66affSColin Finck 	//			 * it saved and to start taking I/O requests.
237*c2c66affSColin Finck 	//			 */
238*c2c66affSColin Finck 	//			pm_send_all(PM_RESUME, (void *)0);
239*c2c66affSColin Finck 	//			return error;
240*c2c66affSColin Finck 	//		}
241*c2c66affSColin Finck 	//	}
242*c2c66affSColin Finck 
243*c2c66affSColin Finck 		/* flush caches */
244*c2c66affSColin Finck 		ACPI_FLUSH_CPU_CACHE();
245*c2c66affSColin Finck 
246*c2c66affSColin Finck 		/* Do arch specific saving of state. */
247*c2c66affSColin Finck 		if (state > ACPI_STATE_S1) {
248*c2c66affSColin Finck 			error = 0;//acpi_save_state_mem();
249*c2c66affSColin Finck 
250*c2c66affSColin Finck 			/* TBD: if no s4bios, write codes for
251*c2c66affSColin Finck 			 * acpi_save_state_disk()...
252*c2c66affSColin Finck 			 */
253*c2c66affSColin Finck #if 0
254*c2c66affSColin Finck 			if (!error && (state == ACPI_STATE_S4))
255*c2c66affSColin Finck 				error = acpi_save_state_disk();
256*c2c66affSColin Finck #endif
257*c2c66affSColin Finck 			/*if (error) {
258*c2c66affSColin Finck 				pm_send_all(PM_RESUME, (void *)0);
259*c2c66affSColin Finck 				return error;
260*c2c66affSColin Finck 			}*/
261*c2c66affSColin Finck 		}
262*c2c66affSColin Finck 	//}
263*c2c66affSColin Finck 	/* disable interrupts
264*c2c66affSColin Finck 	 * Note that acpi_suspend -- our caller -- will do this once we return.
265*c2c66affSColin Finck 	 * But, we want it done early, so we don't get any surprises during
266*c2c66affSColin Finck 	 * the device suspend sequence.
267*c2c66affSColin Finck 	 */
268*c2c66affSColin Finck 	//ACPI_DISABLE_IRQS();
269*c2c66affSColin Finck 
270*c2c66affSColin Finck 	/* Unconditionally turn off devices.
271*c2c66affSColin Finck 	 * Obvious if we enter a sleep state.
272*c2c66affSColin Finck 	 * If entering S5 (soft off), this should put devices in a
273*c2c66affSColin Finck 	 * quiescent state.
274*c2c66affSColin Finck 	 */
275*c2c66affSColin Finck 
276*c2c66affSColin Finck 	//if (state > ACPI_STATE_S1) {
277*c2c66affSColin Finck 	//	error = pm_send_all(PM_SUSPEND, (void *)3);
278*c2c66affSColin Finck 
279*c2c66affSColin Finck 	//	/* We're pretty screwed if we got an error from this.
280*c2c66affSColin Finck 	//	 * We try to recover by simply calling our own restore_state
281*c2c66affSColin Finck 	//	 * function; see above for definition.
282*c2c66affSColin Finck 	//	 *
283*c2c66affSColin Finck 	//	 * If it's S5 though, go through with it anyway..
284*c2c66affSColin Finck 	//	 */
285*c2c66affSColin Finck 	//	if (error && state != ACPI_STATE_S5)
286*c2c66affSColin Finck 	//		acpi_system_restore_state(state);
287*c2c66affSColin Finck 	//}
288*c2c66affSColin Finck 	return error ? AE_ERROR : AE_OK;
289*c2c66affSColin Finck }
290*c2c66affSColin Finck 
291*c2c66affSColin Finck 
292*c2c66affSColin Finck /****************************************************************************
293*c2c66affSColin Finck  *
294*c2c66affSColin Finck  * FUNCTION:    acpi_system_suspend
295*c2c66affSColin Finck  *
296*c2c66affSColin Finck  * PARAMETERS:  %state: Sleep state to enter.
297*c2c66affSColin Finck  *
298*c2c66affSColin Finck  * RETURN:      ACPI_STATUS, whether or not we successfully entered and
299*c2c66affSColin Finck  *              exited sleep.
300*c2c66affSColin Finck  *
301*c2c66affSColin Finck  * DESCRIPTION: Perform OS-specific action to enter sleep state.
302*c2c66affSColin Finck  *              This is the final step in going to sleep, per spec.  If we
303*c2c66affSColin Finck  *              know we're coming back (i.e. not entering S5), we save the
304*c2c66affSColin Finck  *              processor flags. [ We'll have to save and restore them anyway,
305*c2c66affSColin Finck  *              so we use the arch-agnostic save_flags and restore_flags
306*c2c66affSColin Finck  *              here.]  We then set the place to return to in arch-specific
307*c2c66affSColin Finck  *              globals using arch_set_return_point. Finally, we call the
308*c2c66affSColin Finck  *              ACPI function to write the proper values to I/O ports.
309*c2c66affSColin Finck  *
310*c2c66affSColin Finck  ****************************************************************************/
311*c2c66affSColin Finck 
312*c2c66affSColin Finck ACPI_STATUS
acpi_system_suspend(UINT32 state)313*c2c66affSColin Finck acpi_system_suspend(
314*c2c66affSColin Finck 	UINT32		state)
315*c2c66affSColin Finck {
316*c2c66affSColin Finck 	ACPI_STATUS		status = AE_ERROR;
317*c2c66affSColin Finck 	//unsigned long		flags = 0;
318*c2c66affSColin Finck 
319*c2c66affSColin Finck 	//local_irq_save(flags);
320*c2c66affSColin Finck 	/* kernel_fpu_begin(); */
321*c2c66affSColin Finck 
322*c2c66affSColin Finck 	switch (state) {
323*c2c66affSColin Finck 	case ACPI_STATE_S1:
324*c2c66affSColin Finck 	case ACPI_STATE_S5:
325*c2c66affSColin Finck 		//barrier();
326*c2c66affSColin Finck 		status = AcpiEnterSleepState(state);
327*c2c66affSColin Finck 		break;
328*c2c66affSColin Finck 	case ACPI_STATE_S4:
329*c2c66affSColin Finck 		//do_suspend_lowlevel_s4bios(0);
330*c2c66affSColin Finck 		break;
331*c2c66affSColin Finck 	}
332*c2c66affSColin Finck 
333*c2c66affSColin Finck 	/* kernel_fpu_end(); */
334*c2c66affSColin Finck 	//local_irq_restore(flags);
335*c2c66affSColin Finck 
336*c2c66affSColin Finck 	return status;
337*c2c66affSColin Finck }
338*c2c66affSColin Finck 
339*c2c66affSColin Finck 
340*c2c66affSColin Finck 
341*c2c66affSColin Finck /**
342*c2c66affSColin Finck  * acpi_suspend - OS-agnostic system suspend/resume support (S? states)
343*c2c66affSColin Finck  * @state:	state we're entering
344*c2c66affSColin Finck  *
345*c2c66affSColin Finck  */
346*c2c66affSColin Finck ACPI_STATUS
acpi_suspend(UINT32 state)347*c2c66affSColin Finck acpi_suspend (
348*c2c66affSColin Finck 	UINT32			state)
349*c2c66affSColin Finck {
350*c2c66affSColin Finck 	ACPI_STATUS status;
351*c2c66affSColin Finck 
352*c2c66affSColin Finck 	/* only support S1 and S5 on kernel 2.4 */
353*c2c66affSColin Finck 	//if (state != ACPI_STATE_S1 && state != ACPI_STATE_S4
354*c2c66affSColin Finck 	//    && state != ACPI_STATE_S5)
355*c2c66affSColin Finck 	//	return AE_ERROR;
356*c2c66affSColin Finck 
357*c2c66affSColin Finck 
358*c2c66affSColin Finck 	//if (ACPI_STATE_S4 == state) {
359*c2c66affSColin Finck 	//	/* For s4bios, we need a wakeup address. */
360*c2c66affSColin Finck 	//	if (1 == AcpiGbl_FACS->S4bios_f &&
361*c2c66affSColin Finck 	//	    0 != AcpiGbl_FADT->smi_cmd) {
362*c2c66affSColin Finck 	//		if (!acpi_wakeup_address)
363*c2c66affSColin Finck 	//			return AE_ERROR;
364*c2c66affSColin Finck 	//		AcpiSetFirmwareWakingVector((acpi_physical_address) acpi_wakeup_address);
365*c2c66affSColin Finck 	//	} else
366*c2c66affSColin Finck 	//		/* We don't support S4 under 2.4.  Give up */
367*c2c66affSColin Finck 	//		return AE_ERROR;
368*c2c66affSColin Finck 	//}
369*c2c66affSColin Finck 	AcpiEnterSleepStatePrep(state);
370*c2c66affSColin Finck 
371*c2c66affSColin Finck 	status = AcpiEnterSleepState(state);
372*c2c66affSColin Finck 	if (!ACPI_SUCCESS(status) && state != ACPI_STATE_S5)
373*c2c66affSColin Finck 		return status;
374*c2c66affSColin Finck 
375*c2c66affSColin Finck 	/* disable interrupts and flush caches */
376*c2c66affSColin Finck 	_disable();
377*c2c66affSColin Finck 	ACPI_FLUSH_CPU_CACHE();
378*c2c66affSColin Finck 
379*c2c66affSColin Finck 	/* perform OS-specific sleep actions */
380*c2c66affSColin Finck 	status = acpi_system_suspend(state);
381*c2c66affSColin Finck 
382*c2c66affSColin Finck 	/* Even if we failed to go to sleep, all of the devices are in an suspended
383*c2c66affSColin Finck 	 * mode. So, we run these unconditionally to make sure we have a usable system
384*c2c66affSColin Finck 	 * no matter what.
385*c2c66affSColin Finck 	 */
386*c2c66affSColin Finck 	AcpiLeaveSleepState(state);
387*c2c66affSColin Finck 	acpi_system_restore_state(state);
388*c2c66affSColin Finck 
389*c2c66affSColin Finck 	/* make sure interrupts are enabled */
390*c2c66affSColin Finck 	_enable();
391*c2c66affSColin Finck 
392*c2c66affSColin Finck 	/* reset firmware waking vector */
393*c2c66affSColin Finck 	AcpiSetFirmwareWakingVector(0, 0);
394*c2c66affSColin Finck 
395*c2c66affSColin Finck 	return status;
396*c2c66affSColin Finck }
397*c2c66affSColin Finck 
398*c2c66affSColin Finck int
acpi_system_init(void)399*c2c66affSColin Finck acpi_system_init (void)
400*c2c66affSColin Finck {
401*c2c66affSColin Finck 	int			result = 0;
402*c2c66affSColin Finck 
403*c2c66affSColin Finck 	ACPI_FUNCTION_TRACE("acpi_system_init");
404*c2c66affSColin Finck 
405*c2c66affSColin Finck 	result = acpi_bus_register_driver(&acpi_system_driver);
406*c2c66affSColin Finck 	if (result < 0)
407*c2c66affSColin Finck 		return_VALUE(AE_NOT_FOUND);
408*c2c66affSColin Finck 
409*c2c66affSColin Finck 	return_VALUE(0);
410*c2c66affSColin Finck }
411*c2c66affSColin Finck 
412*c2c66affSColin Finck 
413*c2c66affSColin Finck void
acpi_system_exit(void)414*c2c66affSColin Finck acpi_system_exit (void)
415*c2c66affSColin Finck {
416*c2c66affSColin Finck 	ACPI_FUNCTION_TRACE("acpi_system_exit");
417*c2c66affSColin Finck 	acpi_bus_unregister_driver(&acpi_system_driver);
418*c2c66affSColin Finck 	return_VOID;
419*c2c66affSColin Finck }
420*c2c66affSColin Finck 
421