diff options
Diffstat (limited to 'drivers/acpi/acpica/evsci.c')
| -rw-r--r-- | drivers/acpi/acpica/evsci.c | 91 | 
1 files changed, 79 insertions, 12 deletions
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 8dfbaa96e42..29630e30382 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -6,7 +6,7 @@   ******************************************************************************/  /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp.   * All rights reserved.   *   * Redistribution and use in source and binary forms, with or without @@ -48,15 +48,59 @@  #define _COMPONENT          ACPI_EVENTS  ACPI_MODULE_NAME("evsci") - +#if (!ACPI_REDUCED_HARDWARE)	/* Entire module */  /* Local prototypes */  static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context);  /*******************************************************************************   * + * FUNCTION:    acpi_ev_sci_dispatch + * + * PARAMETERS:  None + * + * RETURN:      Status code indicates whether interrupt was handled. + * + * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers. + * + ******************************************************************************/ + +u32 acpi_ev_sci_dispatch(void) +{ +	struct acpi_sci_handler_info *sci_handler; +	acpi_cpu_flags flags; +	u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; + +	ACPI_FUNCTION_NAME(ev_sci_dispatch); + +	/* Are there any host-installed SCI handlers? */ + +	if (!acpi_gbl_sci_handler_list) { +		return (int_status); +	} + +	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + +	/* Invoke all host-installed SCI handlers */ + +	sci_handler = acpi_gbl_sci_handler_list; +	while (sci_handler) { + +		/* Invoke the installed handler (at interrupt level) */ + +		int_status |= sci_handler->address(sci_handler->context); + +		sci_handler = sci_handler->next; +	} + +	acpi_os_release_lock(acpi_gbl_gpe_lock, flags); +	return (int_status); +} + +/******************************************************************************* + *   * FUNCTION:    acpi_ev_sci_xrupt_handler   * - * PARAMETERS:  Context   - Calling Context + * PARAMETERS:  context   - Calling Context   *   * RETURN:      Status code indicates whether interrupt was handled.   * @@ -73,7 +117,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)  	ACPI_FUNCTION_TRACE(ev_sci_xrupt_handler);  	/* -	 * We are guaranteed by the ACPI CA initialization/shutdown code that +	 * We are guaranteed by the ACPICA initialization/shutdown code that  	 * if this interrupt handler is installed, ACPI is enabled.  	 */ @@ -89,6 +133,11 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)  	 */  	interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); +	/* Invoke all host-installed SCI handlers */ + +	interrupt_handled |= acpi_ev_sci_dispatch(); + +	acpi_sci_count++;  	return_UINT32(interrupt_handled);  } @@ -96,7 +145,7 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context)   *   * FUNCTION:    acpi_ev_gpe_xrupt_handler   * - * PARAMETERS:  Context   - Calling Context + * PARAMETERS:  context   - Calling Context   *   * RETURN:      Status code indicates whether interrupt was handled.   * @@ -112,14 +161,13 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context)  	ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler);  	/* -	 * We are guaranteed by the ACPI CA initialization/shutdown code that +	 * We are guaranteed by the ACPICA initialization/shutdown code that  	 * if this interrupt handler is installed, ACPI is enabled.  	 */  	/* GPEs: Check for and dispatch any GPEs that have occurred */  	interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); -  	return_UINT32(interrupt_handled);  } @@ -150,15 +198,15 @@ u32 acpi_ev_install_sci_handler(void)  /******************************************************************************   * - * FUNCTION:    acpi_ev_remove_sci_handler + * FUNCTION:    acpi_ev_remove_all_sci_handlers   *   * PARAMETERS:  none   * - * RETURN:      E_OK if handler uninstalled OK, E_ERROR if handler was not + * RETURN:      AE_OK if handler uninstalled, AE_ERROR if handler was not   *              installed to begin with   *   * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be - *              taken. + *              taken. Remove all host-installed SCI handlers.   *   * Note:  It doesn't seem important to disable all events or set the event   *        enable registers to their original values. The OS should disable @@ -167,11 +215,13 @@ u32 acpi_ev_install_sci_handler(void)   *   ******************************************************************************/ -acpi_status acpi_ev_remove_sci_handler(void) +acpi_status acpi_ev_remove_all_sci_handlers(void)  { +	struct acpi_sci_handler_info *sci_handler; +	acpi_cpu_flags flags;  	acpi_status status; -	ACPI_FUNCTION_TRACE(ev_remove_sci_handler); +	ACPI_FUNCTION_TRACE(ev_remove_all_sci_handlers);  	/* Just let the OS remove the handler and disable the level */ @@ -179,5 +229,22 @@ acpi_status acpi_ev_remove_sci_handler(void)  	    acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,  					     acpi_ev_sci_xrupt_handler); +	if (!acpi_gbl_sci_handler_list) { +		return (status); +	} + +	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + +	/* Free all host-installed SCI handlers */ + +	while (acpi_gbl_sci_handler_list) { +		sci_handler = acpi_gbl_sci_handler_list; +		acpi_gbl_sci_handler_list = sci_handler->next; +		ACPI_FREE(sci_handler); +	} + +	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);  	return_ACPI_STATUS(status);  } + +#endif				/* !ACPI_REDUCED_HARDWARE */  | 
