195b482a8SLen Brown /****************************************************************************** 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable 495b482a8SLen Brown * 595b482a8SLen Brown *****************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 8fbb7a2dcSBob Moore * Copyright (C) 2000 - 2014, Intel Corp. 995b482a8SLen Brown * All rights reserved. 1095b482a8SLen Brown * 1195b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 1295b482a8SLen Brown * modification, are permitted provided that the following conditions 1395b482a8SLen Brown * are met: 1495b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 1595b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 1695b482a8SLen Brown * without modification. 1795b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1895b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 1995b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 2095b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 2195b482a8SLen Brown * binary redistribution. 2295b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 2395b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 2495b482a8SLen Brown * from this software without specific prior written permission. 2595b482a8SLen Brown * 2695b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 2795b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 2895b482a8SLen Brown * Software Foundation. 2995b482a8SLen Brown * 3095b482a8SLen Brown * NO WARRANTY 3195b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3295b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3395b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3495b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3595b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3695b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3795b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3895b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3995b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4095b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4195b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 4295b482a8SLen Brown */ 4395b482a8SLen Brown 44839e928fSLv Zheng #define EXPORT_ACPI_INTERFACES 45839e928fSLv Zheng 4695b482a8SLen Brown #include <acpi/acpi.h> 47e2f7a777SLen Brown #include "accommon.h" 48e2f7a777SLen Brown #include "actables.h" 4995b482a8SLen Brown 5095b482a8SLen Brown #define _COMPONENT ACPI_EVENTS 5195b482a8SLen Brown ACPI_MODULE_NAME("evxfevnt") 5295b482a8SLen Brown 5333620c54SBob Moore #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 5495b482a8SLen Brown /******************************************************************************* 5595b482a8SLen Brown * 5695b482a8SLen Brown * FUNCTION: acpi_enable 5795b482a8SLen Brown * 5895b482a8SLen Brown * PARAMETERS: None 5995b482a8SLen Brown * 6095b482a8SLen Brown * RETURN: Status 6195b482a8SLen Brown * 6295b482a8SLen Brown * DESCRIPTION: Transfers the system into ACPI mode. 6395b482a8SLen Brown * 6495b482a8SLen Brown ******************************************************************************/ 6595b482a8SLen Brown acpi_status acpi_enable(void) 6695b482a8SLen Brown { 67b430acbdSLen Brown acpi_status status; 683d695839SLen Brown int retry; 6995b482a8SLen Brown 7095b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_enable); 7195b482a8SLen Brown 7295b482a8SLen Brown /* ACPI tables must be present */ 7395b482a8SLen Brown 7495b482a8SLen Brown if (!acpi_tb_tables_loaded()) { 7595b482a8SLen Brown return_ACPI_STATUS(AE_NO_ACPI_TABLES); 7695b482a8SLen Brown } 7795b482a8SLen Brown 78c39660b2SBob Moore /* If the Hardware Reduced flag is set, machine is always in acpi mode */ 79c39660b2SBob Moore 80c39660b2SBob Moore if (acpi_gbl_reduced_hardware) { 81c39660b2SBob Moore return_ACPI_STATUS(AE_OK); 82c39660b2SBob Moore } 83c39660b2SBob Moore 8495b482a8SLen Brown /* Check current mode */ 8595b482a8SLen Brown 8695b482a8SLen Brown if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 8795b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INIT, 8895b482a8SLen Brown "System is already in ACPI mode\n")); 89b430acbdSLen Brown return_ACPI_STATUS(AE_OK); 90b430acbdSLen Brown } 91b430acbdSLen Brown 9295b482a8SLen Brown /* Transition to ACPI mode */ 9395b482a8SLen Brown 9495b482a8SLen Brown status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); 9595b482a8SLen Brown if (ACPI_FAILURE(status)) { 9695b482a8SLen Brown ACPI_ERROR((AE_INFO, 9795b482a8SLen Brown "Could not transition to ACPI mode")); 9895b482a8SLen Brown return_ACPI_STATUS(status); 9995b482a8SLen Brown } 10095b482a8SLen Brown 101b430acbdSLen Brown /* Sanity check that transition succeeded */ 102b430acbdSLen Brown 1033d695839SLen Brown for (retry = 0; retry < 30000; ++retry) { 1043d695839SLen Brown if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 1053d695839SLen Brown if (retry != 0) 1063d695839SLen Brown ACPI_WARNING((AE_INFO, 1073d695839SLen Brown "Platform took > %d00 usec to enter ACPI mode", retry)); 1083d695839SLen Brown return_ACPI_STATUS(AE_OK); 1093d695839SLen Brown } 1103d695839SLen Brown acpi_os_stall(100); /* 100 usec */ 11195b482a8SLen Brown } 11295b482a8SLen Brown 1133d695839SLen Brown ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode")); 1143d695839SLen Brown return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 11595b482a8SLen Brown } 11695b482a8SLen Brown 11795b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable) 11895b482a8SLen Brown 11995b482a8SLen Brown /******************************************************************************* 12095b482a8SLen Brown * 12195b482a8SLen Brown * FUNCTION: acpi_disable 12295b482a8SLen Brown * 12395b482a8SLen Brown * PARAMETERS: None 12495b482a8SLen Brown * 12595b482a8SLen Brown * RETURN: Status 12695b482a8SLen Brown * 12795b482a8SLen Brown * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. 12895b482a8SLen Brown * 12995b482a8SLen Brown ******************************************************************************/ 13095b482a8SLen Brown acpi_status acpi_disable(void) 13195b482a8SLen Brown { 13295b482a8SLen Brown acpi_status status = AE_OK; 13395b482a8SLen Brown 13495b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_disable); 13595b482a8SLen Brown 136c39660b2SBob Moore /* If the Hardware Reduced flag is set, machine is always in acpi mode */ 137c39660b2SBob Moore 138c39660b2SBob Moore if (acpi_gbl_reduced_hardware) { 139c39660b2SBob Moore return_ACPI_STATUS(AE_OK); 140c39660b2SBob Moore } 141c39660b2SBob Moore 14295b482a8SLen Brown if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { 14395b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INIT, 14495b482a8SLen Brown "System is already in legacy (non-ACPI) mode\n")); 14595b482a8SLen Brown } else { 14695b482a8SLen Brown /* Transition to LEGACY mode */ 14795b482a8SLen Brown 14895b482a8SLen Brown status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); 14995b482a8SLen Brown 15095b482a8SLen Brown if (ACPI_FAILURE(status)) { 15195b482a8SLen Brown ACPI_ERROR((AE_INFO, 15295b482a8SLen Brown "Could not exit ACPI mode to legacy mode")); 15395b482a8SLen Brown return_ACPI_STATUS(status); 15495b482a8SLen Brown } 15595b482a8SLen Brown 15695b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); 15795b482a8SLen Brown } 15895b482a8SLen Brown 15995b482a8SLen Brown return_ACPI_STATUS(status); 16095b482a8SLen Brown } 16195b482a8SLen Brown 16295b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable) 16395b482a8SLen Brown 16495b482a8SLen Brown /******************************************************************************* 16595b482a8SLen Brown * 16695b482a8SLen Brown * FUNCTION: acpi_enable_event 16795b482a8SLen Brown * 168ba494beeSBob Moore * PARAMETERS: event - The fixed eventto be enabled 169ba494beeSBob Moore * flags - Reserved 17095b482a8SLen Brown * 17195b482a8SLen Brown * RETURN: Status 17295b482a8SLen Brown * 17395b482a8SLen Brown * DESCRIPTION: Enable an ACPI event (fixed) 17495b482a8SLen Brown * 17595b482a8SLen Brown ******************************************************************************/ 17695b482a8SLen Brown acpi_status acpi_enable_event(u32 event, u32 flags) 17795b482a8SLen Brown { 17895b482a8SLen Brown acpi_status status = AE_OK; 17995b482a8SLen Brown u32 value; 18095b482a8SLen Brown 18195b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_enable_event); 18295b482a8SLen Brown 18395b482a8SLen Brown /* Decode the Fixed Event */ 18495b482a8SLen Brown 18595b482a8SLen Brown if (event > ACPI_EVENT_MAX) { 18695b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 18795b482a8SLen Brown } 18895b482a8SLen Brown 18995b482a8SLen Brown /* 19095b482a8SLen Brown * Enable the requested fixed event (by writing a one to the enable 19195b482a8SLen Brown * register bit) 19295b482a8SLen Brown */ 19395b482a8SLen Brown status = 19450ffba1bSBob Moore acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 195768aaaf1SBob Moore enable_register_id, ACPI_ENABLE_EVENT); 19695b482a8SLen Brown if (ACPI_FAILURE(status)) { 19795b482a8SLen Brown return_ACPI_STATUS(status); 19895b482a8SLen Brown } 19995b482a8SLen Brown 20095b482a8SLen Brown /* Make sure that the hardware responded */ 20195b482a8SLen Brown 20295b482a8SLen Brown status = 20350ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 20495b482a8SLen Brown enable_register_id, &value); 20595b482a8SLen Brown if (ACPI_FAILURE(status)) { 20695b482a8SLen Brown return_ACPI_STATUS(status); 20795b482a8SLen Brown } 20895b482a8SLen Brown 20995b482a8SLen Brown if (value != 1) { 21095b482a8SLen Brown ACPI_ERROR((AE_INFO, 21195b482a8SLen Brown "Could not enable %s event", 21295b482a8SLen Brown acpi_ut_get_event_name(event))); 21395b482a8SLen Brown return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 21495b482a8SLen Brown } 21595b482a8SLen Brown 21695b482a8SLen Brown return_ACPI_STATUS(status); 21795b482a8SLen Brown } 21895b482a8SLen Brown 21995b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable_event) 22095b482a8SLen Brown 22195b482a8SLen Brown /******************************************************************************* 22295b482a8SLen Brown * 22395b482a8SLen Brown * FUNCTION: acpi_disable_event 22495b482a8SLen Brown * 22575c8044fSLv Zheng * PARAMETERS: event - The fixed event to be disabled 22675c8044fSLv Zheng * flags - Reserved 22795b482a8SLen Brown * 22895b482a8SLen Brown * RETURN: Status 22995b482a8SLen Brown * 23095b482a8SLen Brown * DESCRIPTION: Disable an ACPI event (fixed) 23195b482a8SLen Brown * 23295b482a8SLen Brown ******************************************************************************/ 23395b482a8SLen Brown acpi_status acpi_disable_event(u32 event, u32 flags) 23495b482a8SLen Brown { 23595b482a8SLen Brown acpi_status status = AE_OK; 23695b482a8SLen Brown u32 value; 23795b482a8SLen Brown 23895b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_disable_event); 23995b482a8SLen Brown 24095b482a8SLen Brown /* Decode the Fixed Event */ 24195b482a8SLen Brown 24295b482a8SLen Brown if (event > ACPI_EVENT_MAX) { 24395b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 24495b482a8SLen Brown } 24595b482a8SLen Brown 24695b482a8SLen Brown /* 24795b482a8SLen Brown * Disable the requested fixed event (by writing a zero to the enable 24895b482a8SLen Brown * register bit) 24995b482a8SLen Brown */ 25095b482a8SLen Brown status = 25150ffba1bSBob Moore acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 252768aaaf1SBob Moore enable_register_id, ACPI_DISABLE_EVENT); 25395b482a8SLen Brown if (ACPI_FAILURE(status)) { 25495b482a8SLen Brown return_ACPI_STATUS(status); 25595b482a8SLen Brown } 25695b482a8SLen Brown 25795b482a8SLen Brown status = 25850ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 25995b482a8SLen Brown enable_register_id, &value); 26095b482a8SLen Brown if (ACPI_FAILURE(status)) { 26195b482a8SLen Brown return_ACPI_STATUS(status); 26295b482a8SLen Brown } 26395b482a8SLen Brown 26495b482a8SLen Brown if (value != 0) { 26595b482a8SLen Brown ACPI_ERROR((AE_INFO, 26695b482a8SLen Brown "Could not disable %s events", 26795b482a8SLen Brown acpi_ut_get_event_name(event))); 26895b482a8SLen Brown return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 26995b482a8SLen Brown } 27095b482a8SLen Brown 27195b482a8SLen Brown return_ACPI_STATUS(status); 27295b482a8SLen Brown } 27395b482a8SLen Brown 27495b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable_event) 27595b482a8SLen Brown 27695b482a8SLen Brown /******************************************************************************* 27795b482a8SLen Brown * 27895b482a8SLen Brown * FUNCTION: acpi_clear_event 27995b482a8SLen Brown * 280ba494beeSBob Moore * PARAMETERS: event - The fixed event to be cleared 28195b482a8SLen Brown * 28295b482a8SLen Brown * RETURN: Status 28395b482a8SLen Brown * 28495b482a8SLen Brown * DESCRIPTION: Clear an ACPI event (fixed) 28595b482a8SLen Brown * 28695b482a8SLen Brown ******************************************************************************/ 28795b482a8SLen Brown acpi_status acpi_clear_event(u32 event) 28895b482a8SLen Brown { 28995b482a8SLen Brown acpi_status status = AE_OK; 29095b482a8SLen Brown 29195b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_clear_event); 29295b482a8SLen Brown 29395b482a8SLen Brown /* Decode the Fixed Event */ 29495b482a8SLen Brown 29595b482a8SLen Brown if (event > ACPI_EVENT_MAX) { 29695b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 29795b482a8SLen Brown } 29895b482a8SLen Brown 29995b482a8SLen Brown /* 30095b482a8SLen Brown * Clear the requested fixed event (By writing a one to the status 30195b482a8SLen Brown * register bit) 30295b482a8SLen Brown */ 30395b482a8SLen Brown status = 30450ffba1bSBob Moore acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 305768aaaf1SBob Moore status_register_id, ACPI_CLEAR_STATUS); 30695b482a8SLen Brown 30795b482a8SLen Brown return_ACPI_STATUS(status); 30895b482a8SLen Brown } 30995b482a8SLen Brown 31095b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_clear_event) 31195b482a8SLen Brown 31295b482a8SLen Brown /******************************************************************************* 31395b482a8SLen Brown * 31495b482a8SLen Brown * FUNCTION: acpi_get_event_status 31595b482a8SLen Brown * 316ba494beeSBob Moore * PARAMETERS: event - The fixed event 31795b482a8SLen Brown * event_status - Where the current status of the event will 31895b482a8SLen Brown * be returned 31995b482a8SLen Brown * 32095b482a8SLen Brown * RETURN: Status 32195b482a8SLen Brown * 32295b482a8SLen Brown * DESCRIPTION: Obtains and returns the current status of the event 32395b482a8SLen Brown * 32495b482a8SLen Brown ******************************************************************************/ 32595b482a8SLen Brown acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) 32695b482a8SLen Brown { 32795b482a8SLen Brown acpi_status status = AE_OK; 32895b482a8SLen Brown u32 value; 32995b482a8SLen Brown 33095b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_get_event_status); 33195b482a8SLen Brown 33295b482a8SLen Brown if (!event_status) { 33395b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 33495b482a8SLen Brown } 33595b482a8SLen Brown 33695b482a8SLen Brown /* Decode the Fixed Event */ 33795b482a8SLen Brown 33895b482a8SLen Brown if (event > ACPI_EVENT_MAX) { 33995b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER); 34095b482a8SLen Brown } 34195b482a8SLen Brown 34295b482a8SLen Brown /* Get the status of the requested fixed event */ 34395b482a8SLen Brown 34495b482a8SLen Brown status = 34550ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 34695b482a8SLen Brown enable_register_id, &value); 34795b482a8SLen Brown if (ACPI_FAILURE(status)) 34895b482a8SLen Brown return_ACPI_STATUS(status); 34995b482a8SLen Brown 35095b482a8SLen Brown *event_status = value; 35195b482a8SLen Brown 35295b482a8SLen Brown status = 35350ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 35495b482a8SLen Brown status_register_id, &value); 35595b482a8SLen Brown if (ACPI_FAILURE(status)) 35695b482a8SLen Brown return_ACPI_STATUS(status); 35795b482a8SLen Brown 35895b482a8SLen Brown if (value) 35995b482a8SLen Brown *event_status |= ACPI_EVENT_FLAG_SET; 36095b482a8SLen Brown 36195b482a8SLen Brown if (acpi_gbl_fixed_event_handlers[event].handler) 36295b482a8SLen Brown *event_status |= ACPI_EVENT_FLAG_HANDLE; 36395b482a8SLen Brown 36495b482a8SLen Brown return_ACPI_STATUS(status); 36595b482a8SLen Brown } 36695b482a8SLen Brown 36795b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_get_event_status) 36833620c54SBob Moore #endif /* !ACPI_REDUCED_HARDWARE */ 369