ia64/linux-2.6.18-xen.hg

view drivers/acpi/bus.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /*
2 * acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
3 *
4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/ioport.h>
28 #include <linux/kernel.h>
29 #include <linux/list.h>
30 #include <linux/sched.h>
31 #include <linux/pm.h>
32 #include <linux/pm_legacy.h>
33 #include <linux/device.h>
34 #include <linux/proc_fs.h>
35 #ifdef CONFIG_X86
36 #include <asm/mpspec.h>
37 #endif
38 #include <acpi/acpi_bus.h>
39 #include <acpi/acpi_drivers.h>
41 #define _COMPONENT ACPI_BUS_COMPONENT
42 ACPI_MODULE_NAME("acpi_bus")
43 #ifdef CONFIG_X86
44 extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
45 #endif
47 struct fadt_descriptor acpi_fadt;
48 EXPORT_SYMBOL(acpi_fadt);
50 struct acpi_device *acpi_root;
51 struct proc_dir_entry *acpi_root_dir;
52 EXPORT_SYMBOL(acpi_root_dir);
54 #define STRUCT_TO_INT(s) (*((int*)&s))
56 /* --------------------------------------------------------------------------
57 Device Management
58 -------------------------------------------------------------------------- */
60 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
61 {
62 acpi_status status = AE_OK;
65 if (!device)
66 return -EINVAL;
68 /* TBD: Support fixed-feature devices */
70 status = acpi_get_data(handle, acpi_bus_data_handler, (void **)device);
71 if (ACPI_FAILURE(status) || !*device) {
72 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n",
73 handle));
74 return -ENODEV;
75 }
77 return 0;
78 }
80 EXPORT_SYMBOL(acpi_bus_get_device);
82 int acpi_bus_get_status(struct acpi_device *device)
83 {
84 acpi_status status = AE_OK;
85 unsigned long sta = 0;
88 if (!device)
89 return -EINVAL;
91 /*
92 * Evaluate _STA if present.
93 */
94 if (device->flags.dynamic_status) {
95 status =
96 acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
97 if (ACPI_FAILURE(status))
98 return -ENODEV;
99 STRUCT_TO_INT(device->status) = (int)sta;
100 }
102 /*
103 * Otherwise we assume the status of our parent (unless we don't
104 * have one, in which case status is implied).
105 */
106 else if (device->parent)
107 device->status = device->parent->status;
108 else
109 STRUCT_TO_INT(device->status) = 0x0F;
111 if (device->status.functional && !device->status.present) {
112 printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
113 "functional but not present; setting present\n",
114 device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
115 device->status.present = 1;
116 }
118 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
119 device->pnp.bus_id,
120 (u32) STRUCT_TO_INT(device->status)));
122 return 0;
123 }
125 EXPORT_SYMBOL(acpi_bus_get_status);
127 /* --------------------------------------------------------------------------
128 Power Management
129 -------------------------------------------------------------------------- */
131 int acpi_bus_get_power(acpi_handle handle, int *state)
132 {
133 int result = 0;
134 acpi_status status = 0;
135 struct acpi_device *device = NULL;
136 unsigned long psc = 0;
139 result = acpi_bus_get_device(handle, &device);
140 if (result)
141 return result;
143 *state = ACPI_STATE_UNKNOWN;
145 if (!device->flags.power_manageable) {
146 /* TBD: Non-recursive algorithm for walking up hierarchy */
147 if (device->parent)
148 *state = device->parent->power.state;
149 else
150 *state = ACPI_STATE_D0;
151 } else {
152 /*
153 * Get the device's power state either directly (via _PSC) or
154 * indirectly (via power resources).
155 */
156 if (device->power.flags.explicit_get) {
157 status = acpi_evaluate_integer(device->handle, "_PSC",
158 NULL, &psc);
159 if (ACPI_FAILURE(status))
160 return -ENODEV;
161 device->power.state = (int)psc;
162 } else if (device->power.flags.power_resources) {
163 result = acpi_power_get_inferred_state(device);
164 if (result)
165 return result;
166 }
168 *state = device->power.state;
169 }
171 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
172 device->pnp.bus_id, device->power.state));
174 return 0;
175 }
177 EXPORT_SYMBOL(acpi_bus_get_power);
179 int acpi_bus_set_power(acpi_handle handle, int state)
180 {
181 int result = 0;
182 acpi_status status = AE_OK;
183 struct acpi_device *device = NULL;
184 char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
187 result = acpi_bus_get_device(handle, &device);
188 if (result)
189 return result;
191 if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
192 return -EINVAL;
194 /* Make sure this is a valid target state */
196 if (!device->flags.power_manageable) {
197 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
198 device->kobj.name));
199 return -ENODEV;
200 }
201 /*
202 * Get device's current power state if it's unknown
203 * This means device power state isn't initialized or previous setting failed
204 */
205 if (!device->flags.force_power_state) {
206 if (device->power.state == ACPI_STATE_UNKNOWN)
207 acpi_bus_get_power(device->handle, &device->power.state);
208 if (state == device->power.state) {
209 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
210 state));
211 return 0;
212 }
213 }
214 if (!device->power.states[state].flags.valid) {
215 printk(KERN_WARNING PREFIX "Device does not support D%d\n", state);
216 return -ENODEV;
217 }
218 if (device->parent && (state < device->parent->power.state)) {
219 printk(KERN_WARNING PREFIX
220 "Cannot set device to a higher-powered"
221 " state than parent\n");
222 return -ENODEV;
223 }
225 /*
226 * Transition Power
227 * ----------------
228 * On transitions to a high-powered state we first apply power (via
229 * power resources) then evalute _PSx. Conversly for transitions to
230 * a lower-powered state.
231 */
232 if (state < device->power.state) {
233 if (device->power.flags.power_resources) {
234 result = acpi_power_transition(device, state);
235 if (result)
236 goto end;
237 }
238 if (device->power.states[state].flags.explicit_set) {
239 status = acpi_evaluate_object(device->handle,
240 object_name, NULL, NULL);
241 if (ACPI_FAILURE(status)) {
242 result = -ENODEV;
243 goto end;
244 }
245 }
246 } else {
247 if (device->power.states[state].flags.explicit_set) {
248 status = acpi_evaluate_object(device->handle,
249 object_name, NULL, NULL);
250 if (ACPI_FAILURE(status)) {
251 result = -ENODEV;
252 goto end;
253 }
254 }
255 if (device->power.flags.power_resources) {
256 result = acpi_power_transition(device, state);
257 if (result)
258 goto end;
259 }
260 }
262 end:
263 if (result)
264 printk(KERN_WARNING PREFIX
265 "Transitioning device [%s] to D%d\n",
266 device->pnp.bus_id, state);
267 else
268 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
269 "Device [%s] transitioned to D%d\n",
270 device->pnp.bus_id, state));
272 return result;
273 }
275 EXPORT_SYMBOL(acpi_bus_set_power);
277 /* --------------------------------------------------------------------------
278 Event Management
279 -------------------------------------------------------------------------- */
281 static DEFINE_SPINLOCK(acpi_bus_event_lock);
283 LIST_HEAD(acpi_bus_event_list);
284 DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
286 extern int event_is_open;
288 int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
289 {
290 struct acpi_bus_event *event = NULL;
291 unsigned long flags = 0;
294 if (!device)
295 return -EINVAL;
297 /* drop event on the floor if no one's listening */
298 if (!event_is_open)
299 return 0;
301 event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
302 if (!event)
303 return -ENOMEM;
305 strcpy(event->device_class, device->pnp.device_class);
306 strcpy(event->bus_id, device->pnp.bus_id);
307 event->type = type;
308 event->data = data;
310 spin_lock_irqsave(&acpi_bus_event_lock, flags);
311 list_add_tail(&event->node, &acpi_bus_event_list);
312 spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
314 wake_up_interruptible(&acpi_bus_event_queue);
316 return 0;
317 }
319 EXPORT_SYMBOL(acpi_bus_generate_event);
321 int acpi_bus_receive_event(struct acpi_bus_event *event)
322 {
323 unsigned long flags = 0;
324 struct acpi_bus_event *entry = NULL;
326 DECLARE_WAITQUEUE(wait, current);
329 if (!event)
330 return -EINVAL;
332 if (list_empty(&acpi_bus_event_list)) {
334 set_current_state(TASK_INTERRUPTIBLE);
335 add_wait_queue(&acpi_bus_event_queue, &wait);
337 if (list_empty(&acpi_bus_event_list))
338 schedule();
340 remove_wait_queue(&acpi_bus_event_queue, &wait);
341 set_current_state(TASK_RUNNING);
343 if (signal_pending(current))
344 return -ERESTARTSYS;
345 }
347 spin_lock_irqsave(&acpi_bus_event_lock, flags);
348 entry =
349 list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
350 if (entry)
351 list_del(&entry->node);
352 spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
354 if (!entry)
355 return -ENODEV;
357 memcpy(event, entry, sizeof(struct acpi_bus_event));
359 kfree(entry);
361 return 0;
362 }
364 EXPORT_SYMBOL(acpi_bus_receive_event);
366 /* --------------------------------------------------------------------------
367 Notification Handling
368 -------------------------------------------------------------------------- */
370 static int
371 acpi_bus_check_device(struct acpi_device *device, int *status_changed)
372 {
373 acpi_status status = 0;
374 struct acpi_device_status old_status;
377 if (!device)
378 return -EINVAL;
380 if (status_changed)
381 *status_changed = 0;
383 old_status = device->status;
385 /*
386 * Make sure this device's parent is present before we go about
387 * messing with the device.
388 */
389 if (device->parent && !device->parent->status.present) {
390 device->status = device->parent->status;
391 if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) {
392 if (status_changed)
393 *status_changed = 1;
394 }
395 return 0;
396 }
398 status = acpi_bus_get_status(device);
399 if (ACPI_FAILURE(status))
400 return -ENODEV;
402 if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status))
403 return 0;
405 if (status_changed)
406 *status_changed = 1;
408 /*
409 * Device Insertion/Removal
410 */
411 if ((device->status.present) && !(old_status.present)) {
412 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
413 /* TBD: Handle device insertion */
414 } else if (!(device->status.present) && (old_status.present)) {
415 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n"));
416 /* TBD: Handle device removal */
417 }
419 return 0;
420 }
422 static int acpi_bus_check_scope(struct acpi_device *device)
423 {
424 int result = 0;
425 int status_changed = 0;
428 if (!device)
429 return -EINVAL;
431 /* Status Change? */
432 result = acpi_bus_check_device(device, &status_changed);
433 if (result)
434 return result;
436 if (!status_changed)
437 return 0;
439 /*
440 * TBD: Enumerate child devices within this device's scope and
441 * run acpi_bus_check_device()'s on them.
442 */
444 return 0;
445 }
447 /**
448 * acpi_bus_notify
449 * ---------------
450 * Callback for all 'system-level' device notifications (values 0x00-0x7F).
451 */
452 static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
453 {
454 int result = 0;
455 struct acpi_device *device = NULL;
458 if (acpi_bus_get_device(handle, &device))
459 return;
461 switch (type) {
463 case ACPI_NOTIFY_BUS_CHECK:
464 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
465 "Received BUS CHECK notification for device [%s]\n",
466 device->pnp.bus_id));
467 result = acpi_bus_check_scope(device);
468 /*
469 * TBD: We'll need to outsource certain events to non-ACPI
470 * drivers via the device manager (device.c).
471 */
472 break;
474 case ACPI_NOTIFY_DEVICE_CHECK:
475 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
476 "Received DEVICE CHECK notification for device [%s]\n",
477 device->pnp.bus_id));
478 result = acpi_bus_check_device(device, NULL);
479 /*
480 * TBD: We'll need to outsource certain events to non-ACPI
481 * drivers via the device manager (device.c).
482 */
483 break;
485 case ACPI_NOTIFY_DEVICE_WAKE:
486 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
487 "Received DEVICE WAKE notification for device [%s]\n",
488 device->pnp.bus_id));
489 /* TBD */
490 break;
492 case ACPI_NOTIFY_EJECT_REQUEST:
493 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
494 "Received EJECT REQUEST notification for device [%s]\n",
495 device->pnp.bus_id));
496 /* TBD */
497 break;
499 case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
500 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
501 "Received DEVICE CHECK LIGHT notification for device [%s]\n",
502 device->pnp.bus_id));
503 /* TBD: Exactly what does 'light' mean? */
504 break;
506 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
507 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
508 "Received FREQUENCY MISMATCH notification for device [%s]\n",
509 device->pnp.bus_id));
510 /* TBD */
511 break;
513 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
514 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
515 "Received BUS MODE MISMATCH notification for device [%s]\n",
516 device->pnp.bus_id));
517 /* TBD */
518 break;
520 case ACPI_NOTIFY_POWER_FAULT:
521 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
522 "Received POWER FAULT notification for device [%s]\n",
523 device->pnp.bus_id));
524 /* TBD */
525 break;
527 default:
528 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
529 "Received unknown/unsupported notification [%08x]\n",
530 type));
531 break;
532 }
534 return;
535 }
537 /* --------------------------------------------------------------------------
538 Initialization/Cleanup
539 -------------------------------------------------------------------------- */
541 static int __init acpi_bus_init_irq(void)
542 {
543 acpi_status status = AE_OK;
544 union acpi_object arg = { ACPI_TYPE_INTEGER };
545 struct acpi_object_list arg_list = { 1, &arg };
546 char *message = NULL;
549 /*
550 * Let the system know what interrupt model we are using by
551 * evaluating the \_PIC object, if exists.
552 */
554 switch (acpi_irq_model) {
555 case ACPI_IRQ_MODEL_PIC:
556 message = "PIC";
557 break;
558 case ACPI_IRQ_MODEL_IOAPIC:
559 message = "IOAPIC";
560 break;
561 case ACPI_IRQ_MODEL_IOSAPIC:
562 message = "IOSAPIC";
563 break;
564 default:
565 printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n");
566 return -ENODEV;
567 }
569 printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message);
571 arg.integer.value = acpi_irq_model;
573 status = acpi_evaluate_object(NULL, "\\_PIC", &arg_list, NULL);
574 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
575 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
576 return -ENODEV;
577 }
579 return 0;
580 }
582 void __init acpi_early_init(void)
583 {
584 acpi_status status = AE_OK;
585 struct acpi_buffer buffer = { sizeof(acpi_fadt), &acpi_fadt };
588 if (acpi_disabled)
589 return;
591 printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
593 /* enable workarounds, unless strict ACPI spec. compliance */
594 if (!acpi_strict)
595 acpi_gbl_enable_interpreter_slack = TRUE;
597 status = acpi_initialize_subsystem();
598 if (ACPI_FAILURE(status)) {
599 printk(KERN_ERR PREFIX
600 "Unable to initialize the ACPI Interpreter\n");
601 goto error0;
602 }
604 status = acpi_load_tables();
605 if (ACPI_FAILURE(status)) {
606 printk(KERN_ERR PREFIX
607 "Unable to load the System Description Tables\n");
608 goto error0;
609 }
611 /*
612 * Get a separate copy of the FADT for use by other drivers.
613 */
614 status = acpi_get_table(ACPI_TABLE_ID_FADT, 1, &buffer);
615 if (ACPI_FAILURE(status)) {
616 printk(KERN_ERR PREFIX "Unable to get the FADT\n");
617 goto error0;
618 }
619 #ifdef CONFIG_X86
620 if (!acpi_ioapic) {
621 extern acpi_interrupt_flags acpi_sci_flags;
623 /* compatible (0) means level (3) */
624 if (acpi_sci_flags.trigger == 0)
625 acpi_sci_flags.trigger = 3;
627 /* Set PIC-mode SCI trigger type */
628 acpi_pic_sci_set_trigger(acpi_fadt.sci_int,
629 acpi_sci_flags.trigger);
630 } else {
631 extern int acpi_sci_override_gsi;
632 /*
633 * now that acpi_fadt is initialized,
634 * update it with result from INT_SRC_OVR parsing
635 */
636 acpi_fadt.sci_int = acpi_sci_override_gsi;
637 }
638 #endif
640 status =
641 acpi_enable_subsystem(~
642 (ACPI_NO_HARDWARE_INIT |
643 ACPI_NO_ACPI_ENABLE));
644 if (ACPI_FAILURE(status)) {
645 printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
646 goto error0;
647 }
649 return;
651 error0:
652 disable_acpi();
653 return;
654 }
656 static int __init acpi_bus_init(void)
657 {
658 int result = 0;
659 acpi_status status = AE_OK;
660 extern acpi_status acpi_os_initialize1(void);
663 status = acpi_os_initialize1();
665 status =
666 acpi_enable_subsystem(ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE);
667 if (ACPI_FAILURE(status)) {
668 printk(KERN_ERR PREFIX
669 "Unable to start the ACPI Interpreter\n");
670 goto error1;
671 }
673 if (ACPI_FAILURE(status)) {
674 printk(KERN_ERR PREFIX
675 "Unable to initialize ACPI OS objects\n");
676 goto error1;
677 }
678 #ifdef CONFIG_ACPI_EC
679 /*
680 * ACPI 2.0 requires the EC driver to be loaded and work before
681 * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
682 * is called).
683 *
684 * This is accomplished by looking for the ECDT table, and getting
685 * the EC parameters out of that.
686 */
687 status = acpi_ec_ecdt_probe();
688 /* Ignore result. Not having an ECDT is not fatal. */
689 #endif
691 status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
692 if (ACPI_FAILURE(status)) {
693 printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
694 goto error1;
695 }
697 printk(KERN_INFO PREFIX "Interpreter enabled\n");
699 /*
700 * Get the system interrupt model and evaluate \_PIC.
701 */
702 result = acpi_bus_init_irq();
703 if (result)
704 goto error1;
706 /*
707 * Register the for all standard device notifications.
708 */
709 status =
710 acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
711 &acpi_bus_notify, NULL);
712 if (ACPI_FAILURE(status)) {
713 printk(KERN_ERR PREFIX
714 "Unable to register for device notifications\n");
715 goto error1;
716 }
718 /*
719 * Create the top ACPI proc directory
720 */
721 acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
723 return 0;
725 /* Mimic structured exception handling */
726 error1:
727 acpi_terminate();
728 return -ENODEV;
729 }
731 decl_subsys(acpi, NULL, NULL);
733 static int __init acpi_init(void)
734 {
735 int result = 0;
738 if (acpi_disabled) {
739 printk(KERN_INFO PREFIX "Interpreter disabled.\n");
740 return -ENODEV;
741 }
743 result = firmware_register(&acpi_subsys);
744 if (result < 0)
745 printk(KERN_WARNING "%s: firmware_register error: %d\n",
746 __FUNCTION__, result);
748 result = acpi_bus_init();
750 if (!result) {
751 #ifdef CONFIG_PM_LEGACY
752 if (!PM_IS_ACTIVE())
753 pm_active = 1;
754 else {
755 printk(KERN_INFO PREFIX
756 "APM is already active, exiting\n");
757 disable_acpi();
758 result = -ENODEV;
759 }
760 #endif
761 } else
762 disable_acpi();
764 return result;
765 }
767 subsys_initcall(acpi_init);