1/***************************************************************************** 2 * 3 * Module Name: ecgpe.c 4 * $Revision: 1.1.1.1 $ 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000, 2001 Andrew Grover 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26 27#include <acpi.h> 28#include "ec.h" 29 30#define _COMPONENT ACPI_EC 31 MODULE_NAME ("ecgpe") 32 33 34/**************************************************************************** 35 * 36 * FUNCTION: ec_query_handler 37 * 38 * PARAMETERS: 39 * 40 * RETURN: 41 * 42 * DESCRIPTION: 43 * 44 ****************************************************************************/ 45 46void 47ec_query_handler ( 48 void *context) 49{ 50 EC_CONTEXT *ec = (EC_CONTEXT*)context; 51 static char object_name[5] = {'_','Q','0','0','\0'}; 52 const char hex[] = {'0','1','2','3','4','5','6','7','8', 53 '9','A','B','C','D','E','F'}; 54 55 FUNCTION_TRACE("ec_query_handler"); 56 57 if (!ec) { 58 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); 59 return_VOID; 60 } 61 62 /* 63 * Evaluate _Qxx: 64 * -------------- 65 * Evaluate corresponding _Qxx method. Note that a zero query value 66 * indicates a spurious EC_SCI (no such thing as _Q00). 67 */ 68 object_name[2] = hex[((ec->query_data >> 4) & 0x0F)]; 69 object_name[3] = hex[(ec->query_data & 0x0F)]; 70 71 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Evaluating [%s] for ec [%02x].\n", object_name, ec->device_handle)); 72 73 bm_evaluate_object(ec->acpi_handle, object_name, NULL, NULL); 74 75 return_VOID; 76} 77 78 79/**************************************************************************** 80 * 81 * FUNCTION: ec_gpe_handler 82 * 83 * PARAMETERS: 84 * 85 * RETURN: 86 * 87 * DESCRIPTION: 88 * 89 ****************************************************************************/ 90 91void 92ec_gpe_handler ( 93 void *context) 94{ 95 acpi_status status = AE_OK; 96 EC_CONTEXT *ec = (EC_CONTEXT*)context; 97 EC_STATUS ec_status = 0; 98 99 FUNCTION_TRACE("ec_gpe_handler"); 100 101 if (!ec) { 102 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); 103 return_VOID; 104 } 105 106 /* TBD: synchronize w/ transaction (ectransx). */ 107 108 /* 109 * EC_SCI? 110 * ------- 111 * Check the EC_SCI bit to see if this is an EC_SCI event. If not (e.g. 112 * OBF/IBE) just return, as we already poll to detect these events. 113 */ 114 acpi_os_read_port(ec->status_port, &ec_status, 8); 115 if (!(ec_status & EC_FLAG_SCI)) { 116 return_VOID; 117 } 118 119 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "EC_SCI event detected on ec [%02x] - running query.\n", ec->device_handle)); 120 121 /* 122 * Run Query: 123 * ---------- 124 * Query the EC to find out which _Qxx method we need to evaluate. 125 * Note that successful completion of the query causes the EC_SCI 126 * bit to be cleared (and thus clearing the interrupt source). 127 */ 128 status = ec_io_write(ec, ec->command_port, EC_COMMAND_QUERY, 129 EC_EVENT_OUTPUT_BUFFER_FULL); 130 if (ACPI_FAILURE(status)) { 131 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to send 'query command' to EC.\n")); 132 return_VOID; 133 } 134 135 status = ec_io_read(ec, ec->data_port, &(ec->query_data), 136 EC_EVENT_NONE); 137 if (ACPI_FAILURE(status)) { 138 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Error reading query data.\n")); 139 return_VOID; 140 } 141 142 /* TBD: un-synchronize w/ transaction (ectransx). */ 143 144 /* 145 * Spurious EC_SCI? 146 * ---------------- 147 */ 148 if (!ec->query_data) { 149 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Spurious EC SCI detected.\n")); 150 return_VOID; 151 } 152 153 /* 154 * Defer _Qxx Execution: 155 * --------------------- 156 * Can't evaluate this method now 'cause we're at interrupt-level. 157 */ 158 status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, 159 ec_query_handler, ec); 160 if (ACPI_FAILURE(status)) { 161 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to defer _Qxx method evaluation.\n")); 162 return_VOID; 163 } 164 165 return_VOID; 166} 167 168 169/**************************************************************************** 170 * 171 * FUNCTION: ec_install_gpe_handler 172 * 173 * PARAMETERS: 174 * 175 * RETURN: 176 * 177 * DESCRIPTION: 178 * 179 ****************************************************************************/ 180 181acpi_status 182ec_install_gpe_handler ( 183 EC_CONTEXT *ec) 184{ 185 acpi_status status = AE_OK; 186 187 FUNCTION_TRACE("ec_install_gpe_handler"); 188 189 if (!ec) { 190 return_ACPI_STATUS(AE_BAD_PARAMETER); 191 } 192 193 /* 194 * Evaluate _GPE: 195 * -------------- 196 * Evaluate the "_GPE" object (required) to find out which GPE bit 197 * is used by this EC to signal events (SCIs). 198 */ 199 status = bm_evaluate_simple_integer(ec->acpi_handle, 200 "_GPE", &(ec->gpe_bit)); 201 if (ACPI_FAILURE(status)) { 202 return_ACPI_STATUS(status); 203 } 204 205 /* 206 * Install GPE Handler: 207 * -------------------- 208 * Install a handler for this EC's GPE bit. 209 */ 210 status = acpi_install_gpe_handler(ec->gpe_bit, ACPI_EVENT_EDGE_TRIGGERED, 211 &ec_gpe_handler, ec); 212 if (ACPI_FAILURE(status)) { 213 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "acpi_install_gpe_handler() failed for GPE bit [%02x] with status [%08x].\n", ec->gpe_bit, status)); 214 ec->gpe_bit = EC_GPE_UNKNOWN; 215 return_ACPI_STATUS(status); 216 } 217 218 return_ACPI_STATUS(status); 219} 220 221 222/**************************************************************************** 223 * 224 * FUNCTION: ec_remove_gpe_handler 225 * 226 * PARAMETERS: 227 * 228 * RETURN: 229 * 230 * DESCRIPTION: 231 * 232 ****************************************************************************/ 233 234acpi_status 235ec_remove_gpe_handler ( 236 EC_CONTEXT *ec) 237{ 238 acpi_status status = AE_OK; 239 240 FUNCTION_TRACE("ec_remove_gpe_handler"); 241 242 if (!ec) { 243 return_ACPI_STATUS(AE_BAD_PARAMETER); 244 } 245 246 status = acpi_remove_gpe_handler(ec->gpe_bit, &ec_gpe_handler); 247 248 return_ACPI_STATUS(status); 249} 250