ia64/linux-2.6.18-xen.hg

view drivers/acpi/events/evxfevnt.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 *
3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4 *
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2006, R. Byron Moore
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
44 #include <acpi/acpi.h>
45 #include <acpi/acevents.h>
46 #include <acpi/acnamesp.h>
48 #define _COMPONENT ACPI_EVENTS
49 ACPI_MODULE_NAME("evxfevnt")
51 /*******************************************************************************
52 *
53 * FUNCTION: acpi_enable
54 *
55 * PARAMETERS: None
56 *
57 * RETURN: Status
58 *
59 * DESCRIPTION: Transfers the system into ACPI mode.
60 *
61 ******************************************************************************/
62 acpi_status acpi_enable(void)
63 {
64 acpi_status status = AE_OK;
66 ACPI_FUNCTION_TRACE(acpi_enable);
68 /* Make sure we have the FADT */
70 if (!acpi_gbl_FADT) {
71 ACPI_WARNING((AE_INFO, "No FADT information present!"));
72 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
73 }
75 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
76 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
77 "System is already in ACPI mode\n"));
78 } else {
79 /* Transition to ACPI mode */
81 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
82 if (ACPI_FAILURE(status)) {
83 ACPI_ERROR((AE_INFO,
84 "Could not transition to ACPI mode"));
85 return_ACPI_STATUS(status);
86 }
88 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
89 "Transition to ACPI mode successful\n"));
90 }
92 return_ACPI_STATUS(status);
93 }
95 ACPI_EXPORT_SYMBOL(acpi_enable)
97 /*******************************************************************************
98 *
99 * FUNCTION: acpi_disable
100 *
101 * PARAMETERS: None
102 *
103 * RETURN: Status
104 *
105 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
106 *
107 ******************************************************************************/
108 acpi_status acpi_disable(void)
109 {
110 acpi_status status = AE_OK;
112 ACPI_FUNCTION_TRACE(acpi_disable);
114 if (!acpi_gbl_FADT) {
115 ACPI_WARNING((AE_INFO, "No FADT information present!"));
116 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
117 }
119 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
120 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
121 "System is already in legacy (non-ACPI) mode\n"));
122 } else {
123 /* Transition to LEGACY mode */
125 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
127 if (ACPI_FAILURE(status)) {
128 ACPI_ERROR((AE_INFO,
129 "Could not exit ACPI mode to legacy mode"));
130 return_ACPI_STATUS(status);
131 }
133 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
134 }
136 return_ACPI_STATUS(status);
137 }
139 ACPI_EXPORT_SYMBOL(acpi_disable)
141 /*******************************************************************************
142 *
143 * FUNCTION: acpi_enable_event
144 *
145 * PARAMETERS: Event - The fixed eventto be enabled
146 * Flags - Reserved
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Enable an ACPI event (fixed)
151 *
152 ******************************************************************************/
153 acpi_status acpi_enable_event(u32 event, u32 flags)
154 {
155 acpi_status status = AE_OK;
156 u32 value;
158 ACPI_FUNCTION_TRACE(acpi_enable_event);
160 /* Decode the Fixed Event */
162 if (event > ACPI_EVENT_MAX) {
163 return_ACPI_STATUS(AE_BAD_PARAMETER);
164 }
166 /*
167 * Enable the requested fixed event (by writing a one to the
168 * enable register bit)
169 */
170 status =
171 acpi_set_register(acpi_gbl_fixed_event_info[event].
172 enable_register_id, 1, ACPI_MTX_LOCK);
173 if (ACPI_FAILURE(status)) {
174 return_ACPI_STATUS(status);
175 }
177 /* Make sure that the hardware responded */
179 status =
180 acpi_get_register(acpi_gbl_fixed_event_info[event].
181 enable_register_id, &value, ACPI_MTX_LOCK);
182 if (ACPI_FAILURE(status)) {
183 return_ACPI_STATUS(status);
184 }
186 if (value != 1) {
187 ACPI_ERROR((AE_INFO,
188 "Could not enable %s event",
189 acpi_ut_get_event_name(event)));
190 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
191 }
193 return_ACPI_STATUS(status);
194 }
196 ACPI_EXPORT_SYMBOL(acpi_enable_event)
198 /*******************************************************************************
199 *
200 * FUNCTION: acpi_set_gpe_type
201 *
202 * PARAMETERS: gpe_device - Parent GPE Device
203 * gpe_number - GPE level within the GPE block
204 * Type - New GPE type
205 *
206 * RETURN: Status
207 *
208 * DESCRIPTION: Set the type of an individual GPE
209 *
210 ******************************************************************************/
211 acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type)
212 {
213 acpi_status status = AE_OK;
214 struct acpi_gpe_event_info *gpe_event_info;
216 ACPI_FUNCTION_TRACE(acpi_set_gpe_type);
218 /* Ensure that we have a valid GPE number */
220 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
221 if (!gpe_event_info) {
222 status = AE_BAD_PARAMETER;
223 goto unlock_and_exit;
224 }
226 if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
227 return_ACPI_STATUS(AE_OK);
228 }
230 /* Set the new type (will disable GPE if currently enabled) */
232 status = acpi_ev_set_gpe_type(gpe_event_info, type);
234 unlock_and_exit:
235 return_ACPI_STATUS(status);
236 }
238 ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
240 /*******************************************************************************
241 *
242 * FUNCTION: acpi_enable_gpe
243 *
244 * PARAMETERS: gpe_device - Parent GPE Device
245 * gpe_number - GPE level within the GPE block
246 * Flags - Just enable, or also wake enable?
247 * Called from ISR or not
248 *
249 * RETURN: Status
250 *
251 * DESCRIPTION: Enable an ACPI event (general purpose)
252 *
253 ******************************************************************************/
254 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
255 {
256 acpi_status status = AE_OK;
257 struct acpi_gpe_event_info *gpe_event_info;
259 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
261 /* Use semaphore lock if not executing at interrupt level */
263 if (flags & ACPI_NOT_ISR) {
264 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
265 if (ACPI_FAILURE(status)) {
266 return_ACPI_STATUS(status);
267 }
268 }
270 /* Ensure that we have a valid GPE number */
272 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
273 if (!gpe_event_info) {
274 status = AE_BAD_PARAMETER;
275 goto unlock_and_exit;
276 }
278 /* Perform the enable */
280 status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
282 unlock_and_exit:
283 if (flags & ACPI_NOT_ISR) {
284 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
285 }
286 return_ACPI_STATUS(status);
287 }
289 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
291 /*******************************************************************************
292 *
293 * FUNCTION: acpi_disable_gpe
294 *
295 * PARAMETERS: gpe_device - Parent GPE Device
296 * gpe_number - GPE level within the GPE block
297 * Flags - Just disable, or also wake disable?
298 * Called from ISR or not
299 *
300 * RETURN: Status
301 *
302 * DESCRIPTION: Disable an ACPI event (general purpose)
303 *
304 ******************************************************************************/
305 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
306 {
307 acpi_status status = AE_OK;
308 struct acpi_gpe_event_info *gpe_event_info;
310 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
312 /* Use semaphore lock if not executing at interrupt level */
314 if (flags & ACPI_NOT_ISR) {
315 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
316 if (ACPI_FAILURE(status)) {
317 return_ACPI_STATUS(status);
318 }
319 }
321 /* Ensure that we have a valid GPE number */
323 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
324 if (!gpe_event_info) {
325 status = AE_BAD_PARAMETER;
326 goto unlock_and_exit;
327 }
329 status = acpi_ev_disable_gpe(gpe_event_info);
331 unlock_and_exit:
332 if (flags & ACPI_NOT_ISR) {
333 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
334 }
335 return_ACPI_STATUS(status);
336 }
338 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
340 /*******************************************************************************
341 *
342 * FUNCTION: acpi_disable_event
343 *
344 * PARAMETERS: Event - The fixed eventto be enabled
345 * Flags - Reserved
346 *
347 * RETURN: Status
348 *
349 * DESCRIPTION: Disable an ACPI event (fixed)
350 *
351 ******************************************************************************/
352 acpi_status acpi_disable_event(u32 event, u32 flags)
353 {
354 acpi_status status = AE_OK;
355 u32 value;
357 ACPI_FUNCTION_TRACE(acpi_disable_event);
359 /* Decode the Fixed Event */
361 if (event > ACPI_EVENT_MAX) {
362 return_ACPI_STATUS(AE_BAD_PARAMETER);
363 }
365 /*
366 * Disable the requested fixed event (by writing a zero to the
367 * enable register bit)
368 */
369 status =
370 acpi_set_register(acpi_gbl_fixed_event_info[event].
371 enable_register_id, 0, ACPI_MTX_LOCK);
372 if (ACPI_FAILURE(status)) {
373 return_ACPI_STATUS(status);
374 }
376 status =
377 acpi_get_register(acpi_gbl_fixed_event_info[event].
378 enable_register_id, &value, ACPI_MTX_LOCK);
379 if (ACPI_FAILURE(status)) {
380 return_ACPI_STATUS(status);
381 }
383 if (value != 0) {
384 ACPI_ERROR((AE_INFO,
385 "Could not disable %s events",
386 acpi_ut_get_event_name(event)));
387 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
388 }
390 return_ACPI_STATUS(status);
391 }
393 ACPI_EXPORT_SYMBOL(acpi_disable_event)
395 /*******************************************************************************
396 *
397 * FUNCTION: acpi_clear_event
398 *
399 * PARAMETERS: Event - The fixed event to be cleared
400 *
401 * RETURN: Status
402 *
403 * DESCRIPTION: Clear an ACPI event (fixed)
404 *
405 ******************************************************************************/
406 acpi_status acpi_clear_event(u32 event)
407 {
408 acpi_status status = AE_OK;
410 ACPI_FUNCTION_TRACE(acpi_clear_event);
412 /* Decode the Fixed Event */
414 if (event > ACPI_EVENT_MAX) {
415 return_ACPI_STATUS(AE_BAD_PARAMETER);
416 }
418 /*
419 * Clear the requested fixed event (By writing a one to the
420 * status register bit)
421 */
422 status =
423 acpi_set_register(acpi_gbl_fixed_event_info[event].
424 status_register_id, 1, ACPI_MTX_LOCK);
426 return_ACPI_STATUS(status);
427 }
429 ACPI_EXPORT_SYMBOL(acpi_clear_event)
431 /*******************************************************************************
432 *
433 * FUNCTION: acpi_clear_gpe
434 *
435 * PARAMETERS: gpe_device - Parent GPE Device
436 * gpe_number - GPE level within the GPE block
437 * Flags - Called from an ISR or not
438 *
439 * RETURN: Status
440 *
441 * DESCRIPTION: Clear an ACPI event (general purpose)
442 *
443 ******************************************************************************/
444 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
445 {
446 acpi_status status = AE_OK;
447 struct acpi_gpe_event_info *gpe_event_info;
449 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
451 /* Use semaphore lock if not executing at interrupt level */
453 if (flags & ACPI_NOT_ISR) {
454 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
455 if (ACPI_FAILURE(status)) {
456 return_ACPI_STATUS(status);
457 }
458 }
460 /* Ensure that we have a valid GPE number */
462 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
463 if (!gpe_event_info) {
464 status = AE_BAD_PARAMETER;
465 goto unlock_and_exit;
466 }
468 status = acpi_hw_clear_gpe(gpe_event_info);
470 unlock_and_exit:
471 if (flags & ACPI_NOT_ISR) {
472 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
473 }
474 return_ACPI_STATUS(status);
475 }
477 ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
479 #ifdef ACPI_FUTURE_USAGE
480 /*******************************************************************************
481 *
482 * FUNCTION: acpi_get_event_status
483 *
484 * PARAMETERS: Event - The fixed event
485 * event_status - Where the current status of the event will
486 * be returned
487 *
488 * RETURN: Status
489 *
490 * DESCRIPTION: Obtains and returns the current status of the event
491 *
492 ******************************************************************************/
493 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
494 {
495 acpi_status status = AE_OK;
497 ACPI_FUNCTION_TRACE(acpi_get_event_status);
499 if (!event_status) {
500 return_ACPI_STATUS(AE_BAD_PARAMETER);
501 }
503 /* Decode the Fixed Event */
505 if (event > ACPI_EVENT_MAX) {
506 return_ACPI_STATUS(AE_BAD_PARAMETER);
507 }
509 /* Get the status of the requested fixed event */
511 status =
512 acpi_get_register(acpi_gbl_fixed_event_info[event].
513 status_register_id, event_status, ACPI_MTX_LOCK);
515 return_ACPI_STATUS(status);
516 }
518 ACPI_EXPORT_SYMBOL(acpi_get_event_status)
520 /*******************************************************************************
521 *
522 * FUNCTION: acpi_get_gpe_status
523 *
524 * PARAMETERS: gpe_device - Parent GPE Device
525 * gpe_number - GPE level within the GPE block
526 * Flags - Called from an ISR or not
527 * event_status - Where the current status of the event will
528 * be returned
529 *
530 * RETURN: Status
531 *
532 * DESCRIPTION: Get status of an event (general purpose)
533 *
534 ******************************************************************************/
535 acpi_status
536 acpi_get_gpe_status(acpi_handle gpe_device,
537 u32 gpe_number, u32 flags, acpi_event_status * event_status)
538 {
539 acpi_status status = AE_OK;
540 struct acpi_gpe_event_info *gpe_event_info;
542 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
544 /* Use semaphore lock if not executing at interrupt level */
546 if (flags & ACPI_NOT_ISR) {
547 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
548 if (ACPI_FAILURE(status)) {
549 return_ACPI_STATUS(status);
550 }
551 }
553 /* Ensure that we have a valid GPE number */
555 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
556 if (!gpe_event_info) {
557 status = AE_BAD_PARAMETER;
558 goto unlock_and_exit;
559 }
561 /* Obtain status on the requested GPE number */
563 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
565 unlock_and_exit:
566 if (flags & ACPI_NOT_ISR) {
567 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
568 }
569 return_ACPI_STATUS(status);
570 }
572 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
573 #endif /* ACPI_FUTURE_USAGE */
575 /*******************************************************************************
576 *
577 * FUNCTION: acpi_install_gpe_block
578 *
579 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
580 * gpe_block_address - Address and space_iD
581 * register_count - Number of GPE register pairs in the block
582 * interrupt_number - H/W interrupt for the block
583 *
584 * RETURN: Status
585 *
586 * DESCRIPTION: Create and Install a block of GPE registers
587 *
588 ******************************************************************************/
589 acpi_status
590 acpi_install_gpe_block(acpi_handle gpe_device,
591 struct acpi_generic_address *gpe_block_address,
592 u32 register_count, u32 interrupt_number)
593 {
594 acpi_status status;
595 union acpi_operand_object *obj_desc;
596 struct acpi_namespace_node *node;
597 struct acpi_gpe_block_info *gpe_block;
599 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
601 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
602 return_ACPI_STATUS(AE_BAD_PARAMETER);
603 }
605 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
606 if (ACPI_FAILURE(status)) {
607 return (status);
608 }
610 node = acpi_ns_map_handle_to_node(gpe_device);
611 if (!node) {
612 status = AE_BAD_PARAMETER;
613 goto unlock_and_exit;
614 }
616 /*
617 * For user-installed GPE Block Devices, the gpe_block_base_number
618 * is always zero
619 */
620 status =
621 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
622 interrupt_number, &gpe_block);
623 if (ACPI_FAILURE(status)) {
624 goto unlock_and_exit;
625 }
627 /* Run the _PRW methods and enable the GPEs */
629 status = acpi_ev_initialize_gpe_block(node, gpe_block);
630 if (ACPI_FAILURE(status)) {
631 goto unlock_and_exit;
632 }
634 /* Get the device_object attached to the node */
636 obj_desc = acpi_ns_get_attached_object(node);
637 if (!obj_desc) {
639 /* No object, create a new one */
641 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
642 if (!obj_desc) {
643 status = AE_NO_MEMORY;
644 goto unlock_and_exit;
645 }
647 status =
648 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
650 /* Remove local reference to the object */
652 acpi_ut_remove_reference(obj_desc);
654 if (ACPI_FAILURE(status)) {
655 goto unlock_and_exit;
656 }
657 }
659 /* Install the GPE block in the device_object */
661 obj_desc->device.gpe_block = gpe_block;
663 unlock_and_exit:
664 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
665 return_ACPI_STATUS(status);
666 }
668 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
670 /*******************************************************************************
671 *
672 * FUNCTION: acpi_remove_gpe_block
673 *
674 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
675 *
676 * RETURN: Status
677 *
678 * DESCRIPTION: Remove a previously installed block of GPE registers
679 *
680 ******************************************************************************/
681 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
682 {
683 union acpi_operand_object *obj_desc;
684 acpi_status status;
685 struct acpi_namespace_node *node;
687 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
689 if (!gpe_device) {
690 return_ACPI_STATUS(AE_BAD_PARAMETER);
691 }
693 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
694 if (ACPI_FAILURE(status)) {
695 return (status);
696 }
698 node = acpi_ns_map_handle_to_node(gpe_device);
699 if (!node) {
700 status = AE_BAD_PARAMETER;
701 goto unlock_and_exit;
702 }
704 /* Get the device_object attached to the node */
706 obj_desc = acpi_ns_get_attached_object(node);
707 if (!obj_desc || !obj_desc->device.gpe_block) {
708 return_ACPI_STATUS(AE_NULL_OBJECT);
709 }
711 /* Delete the GPE block (but not the device_object) */
713 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
714 if (ACPI_SUCCESS(status)) {
715 obj_desc->device.gpe_block = NULL;
716 }
718 unlock_and_exit:
719 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
720 return_ACPI_STATUS(status);
721 }
723 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)