evevent.c 8.33 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2
/******************************************************************************
 *
3
 * Module Name: evevent - Fixed Event handling and dispatch
Linus Torvalds's avatar
Linus Torvalds committed
4 5 6 7
 *
 *****************************************************************************/

/*
8
 * Copyright (C) 2000 - 2004, R. Byron Moore
9
 * All rights reserved.
Linus Torvalds's avatar
Linus Torvalds committed
10
 *
11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
Linus Torvalds's avatar
Linus Torvalds committed
25
 *
26 27 28
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
Linus Torvalds's avatar
Linus Torvalds committed
29
 *
30 31 32 33 34 35 36 37 38 39 40 41
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
Linus Torvalds's avatar
Linus Torvalds committed
42 43
 */

44 45
#include <acpi/acpi.h>
#include <acpi/acevents.h>
Linus Torvalds's avatar
Linus Torvalds committed
46

Linus Torvalds's avatar
Linus Torvalds committed
47
#define _COMPONENT          ACPI_EVENTS
Andy Grover's avatar
Andy Grover committed
48
	 ACPI_MODULE_NAME    ("evevent")
Linus Torvalds's avatar
Linus Torvalds committed
49 50


Linus Torvalds's avatar
Linus Torvalds committed
51
/*******************************************************************************
Linus Torvalds's avatar
Linus Torvalds committed
52
 *
53
 * FUNCTION:    acpi_ev_initialize_events
Linus Torvalds's avatar
Linus Torvalds committed
54 55 56 57 58
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
Andy Grover's avatar
Andy Grover committed
59
 * DESCRIPTION: Initialize global data structures for events.
Linus Torvalds's avatar
Linus Torvalds committed
60
 *
Linus Torvalds's avatar
Linus Torvalds committed
61
 ******************************************************************************/
Linus Torvalds's avatar
Linus Torvalds committed
62

Linus Torvalds's avatar
Linus Torvalds committed
63
acpi_status
64
acpi_ev_initialize_events (
Linus Torvalds's avatar
Linus Torvalds committed
65 66
	void)
{
67
	acpi_status                     status;
Linus Torvalds's avatar
Linus Torvalds committed
68 69


70
	ACPI_FUNCTION_TRACE ("ev_initialize_events");
Linus Torvalds's avatar
Linus Torvalds committed
71 72


Linus Torvalds's avatar
Linus Torvalds committed
73
	/* Make sure we have ACPI tables */
Linus Torvalds's avatar
Linus Torvalds committed
74 75

	if (!acpi_gbl_DSDT) {
Linus Torvalds's avatar
Linus Torvalds committed
76 77
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!\n"));
		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
Linus Torvalds's avatar
Linus Torvalds committed
78 79 80
	}

	/*
81 82 83
	 * Initialize the Fixed and General Purpose Events. This is
	 * done prior to enabling SCIs to prevent interrupts from
	 * occurring before handers are installed.
Linus Torvalds's avatar
Linus Torvalds committed
84 85 86
	 */
	status = acpi_ev_fixed_event_initialize ();
	if (ACPI_FAILURE (status)) {
87
		ACPI_REPORT_ERROR ((
Andy Grover's avatar
Andy Grover committed
88 89
				"Unable to initialize fixed events, %s\n",
				acpi_format_exception (status)));
Linus Torvalds's avatar
Linus Torvalds committed
90
		return_ACPI_STATUS (status);
Linus Torvalds's avatar
Linus Torvalds committed
91 92 93 94
	}

	status = acpi_ev_gpe_initialize ();
	if (ACPI_FAILURE (status)) {
95
		ACPI_REPORT_ERROR ((
Andy Grover's avatar
Andy Grover committed
96 97
				"Unable to initialize general purpose events, %s\n",
				acpi_format_exception (status)));
Linus Torvalds's avatar
Linus Torvalds committed
98
		return_ACPI_STATUS (status);
Linus Torvalds's avatar
Linus Torvalds committed
99 100
	}

Andy Grover's avatar
Andy Grover committed
101 102 103 104 105 106
	return_ACPI_STATUS (status);
}


/*******************************************************************************
 *
107
 * FUNCTION:    acpi_ev_install_xrupt_handlers
Andy Grover's avatar
Andy Grover committed
108 109 110 111 112
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
Andy Grover's avatar
Andy Grover committed
113
 * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
Andy Grover's avatar
Andy Grover committed
114 115 116 117
 *
 ******************************************************************************/

acpi_status
118
acpi_ev_install_xrupt_handlers (
Andy Grover's avatar
Andy Grover committed
119 120
	void)
{
121
	acpi_status                     status;
Andy Grover's avatar
Andy Grover committed
122 123


124
	ACPI_FUNCTION_TRACE ("ev_install_xrupt_handlers");
Andy Grover's avatar
Andy Grover committed
125 126


Linus Torvalds's avatar
Linus Torvalds committed
127 128 129 130
	/* Install the SCI handler */

	status = acpi_ev_install_sci_handler ();
	if (ACPI_FAILURE (status)) {
131
		ACPI_REPORT_ERROR ((
Andy Grover's avatar
Andy Grover committed
132 133
				"Unable to install System Control Interrupt Handler, %s\n",
				acpi_format_exception (status)));
Linus Torvalds's avatar
Linus Torvalds committed
134
		return_ACPI_STATUS (status);
Linus Torvalds's avatar
Linus Torvalds committed
135 136 137 138 139 140
	}

	/* Install the handler for the Global Lock */

	status = acpi_ev_init_global_lock_handler ();
	if (ACPI_FAILURE (status)) {
141
		ACPI_REPORT_ERROR ((
Andy Grover's avatar
Andy Grover committed
142 143
				"Unable to initialize Global Lock handler, %s\n",
				acpi_format_exception (status)));
Linus Torvalds's avatar
Linus Torvalds committed
144
		return_ACPI_STATUS (status);
Linus Torvalds's avatar
Linus Torvalds committed
145 146
	}

Andy Grover's avatar
Andy Grover committed
147
	acpi_gbl_events_initialized = TRUE;
Linus Torvalds's avatar
Linus Torvalds committed
148
	return_ACPI_STATUS (status);
Linus Torvalds's avatar
Linus Torvalds committed
149 150 151
}


Linus Torvalds's avatar
Linus Torvalds committed
152
/*******************************************************************************
Linus Torvalds's avatar
Linus Torvalds committed
153
 *
154
 * FUNCTION:    acpi_ev_fixed_event_initialize
Linus Torvalds's avatar
Linus Torvalds committed
155 156 157 158 159
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
Andy Grover's avatar
Andy Grover committed
160
 * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
Linus Torvalds's avatar
Linus Torvalds committed
161 162 163
 *
 ******************************************************************************/

Linus Torvalds's avatar
Linus Torvalds committed
164
acpi_status
Andy Grover's avatar
Andy Grover committed
165 166
acpi_ev_fixed_event_initialize (
	void)
Linus Torvalds's avatar
Linus Torvalds committed
167
{
168 169
	acpi_native_uint                i;
	acpi_status                     status;
Linus Torvalds's avatar
Linus Torvalds committed
170 171


Andy Grover's avatar
Andy Grover committed
172 173 174 175
	/*
	 * Initialize the structure that keeps track of fixed event handlers
	 * and enable the fixed events.
	 */
Linus Torvalds's avatar
Linus Torvalds committed
176
	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
Linus Torvalds's avatar
Linus Torvalds committed
177 178 179
		acpi_gbl_fixed_event_handlers[i].handler = NULL;
		acpi_gbl_fixed_event_handlers[i].context = NULL;

Andy Grover's avatar
Andy Grover committed
180 181 182
		/* Enable the fixed event */

		if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
183
			status = acpi_set_register (acpi_gbl_fixed_event_info[i].enable_register_id,
Andy Grover's avatar
Andy Grover committed
184
					 0, ACPI_MTX_LOCK);
185 186 187
			if (ACPI_FAILURE (status)) {
				return (status);
			}
Andy Grover's avatar
Andy Grover committed
188 189
		}
	}
Linus Torvalds's avatar
Linus Torvalds committed
190 191 192 193 194

	return (AE_OK);
}


Linus Torvalds's avatar
Linus Torvalds committed
195
/*******************************************************************************
Linus Torvalds's avatar
Linus Torvalds committed
196
 *
197
 * FUNCTION:    acpi_ev_fixed_event_detect
Linus Torvalds's avatar
Linus Torvalds committed
198 199 200 201 202 203 204 205 206 207
 *
 * PARAMETERS:  None
 *
 * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
 *
 * DESCRIPTION: Checks the PM status register for fixed events
 *
 ******************************************************************************/

u32
Andy Grover's avatar
Andy Grover committed
208 209
acpi_ev_fixed_event_detect (
	void)
Linus Torvalds's avatar
Linus Torvalds committed
210
{
211 212 213 214
	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
	u32                             fixed_status;
	u32                             fixed_enable;
	acpi_native_uint                i;
Linus Torvalds's avatar
Linus Torvalds committed
215

Linus Torvalds's avatar
Linus Torvalds committed
216

217
	ACPI_FUNCTION_NAME ("ev_fixed_event_detect");
Linus Torvalds's avatar
Linus Torvalds committed
218 219


Linus Torvalds's avatar
Linus Torvalds committed
220 221
	/*
	 * Read the fixed feature status and enable registers, as all the cases
222
	 * depend on their values.  Ignore errors here.
Linus Torvalds's avatar
Linus Torvalds committed
223
	 */
224 225
	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, &fixed_status);
	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
Linus Torvalds's avatar
Linus Torvalds committed
226

Linus Torvalds's avatar
Linus Torvalds committed
227
	ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
228
		"Fixed Event Block: Enable %08X Status %08X\n",
229
		fixed_enable, fixed_status));
Linus Torvalds's avatar
Linus Torvalds committed
230

Andy Grover's avatar
Andy Grover committed
231 232 233 234 235
	/*
	 * Check for all possible Fixed Events and dispatch those that are active
	 */
	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
		/* Both the status and enable bits must be on for this event */
Linus Torvalds's avatar
Linus Torvalds committed
236

237 238
		if ((fixed_status & acpi_gbl_fixed_event_info[i].status_bit_mask) &&
			(fixed_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) {
Andy Grover's avatar
Andy Grover committed
239
			/* Found an active (signalled) event */
Linus Torvalds's avatar
Linus Torvalds committed
240

241
			int_status |= acpi_ev_fixed_event_dispatch ((u32) i);
Andy Grover's avatar
Andy Grover committed
242
		}
Linus Torvalds's avatar
Linus Torvalds committed
243 244 245 246 247 248
	}

	return (int_status);
}


Linus Torvalds's avatar
Linus Torvalds committed
249
/*******************************************************************************
Linus Torvalds's avatar
Linus Torvalds committed
250
 *
251
 * FUNCTION:    acpi_ev_fixed_event_dispatch
Linus Torvalds's avatar
Linus Torvalds committed
252 253 254 255 256 257 258 259 260 261 262 263
 *
 * PARAMETERS:  Event               - Event type
 *
 * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
 *
 * DESCRIPTION: Clears the status bit for the requested event, calls the
 *              handler that previously registered for the event.
 *
 ******************************************************************************/

u32
acpi_ev_fixed_event_dispatch (
264
	u32                             event)
Linus Torvalds's avatar
Linus Torvalds committed
265
{
Linus Torvalds's avatar
Linus Torvalds committed
266 267


Andy Grover's avatar
Andy Grover committed
268
	ACPI_FUNCTION_ENTRY ();
Linus Torvalds's avatar
Linus Torvalds committed
269

Linus Torvalds's avatar
Linus Torvalds committed
270 271 272

	/* Clear the status bit */

273
	(void) acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
Andy Grover's avatar
Andy Grover committed
274
			 1, ACPI_MTX_DO_NOT_LOCK);
Linus Torvalds's avatar
Linus Torvalds committed
275 276 277 278 279 280

	/*
	 * Make sure we've got a handler.  If not, report an error.
	 * The event is disabled to prevent further interrupts.
	 */
	if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
281
		(void) acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
Andy Grover's avatar
Andy Grover committed
282
				0, ACPI_MTX_DO_NOT_LOCK);
Linus Torvalds's avatar
Linus Torvalds committed
283

Andy Grover's avatar
Andy Grover committed
284
		ACPI_REPORT_ERROR (
285
			("No installed handler for fixed event [%08X]\n",
Linus Torvalds's avatar
Linus Torvalds committed
286 287
			event));

Andy Grover's avatar
Andy Grover committed
288
		return (ACPI_INTERRUPT_NOT_HANDLED);
Linus Torvalds's avatar
Linus Torvalds committed
289 290
	}

Andy Grover's avatar
Andy Grover committed
291
	/* Invoke the Fixed Event handler */
Linus Torvalds's avatar
Linus Torvalds committed
292 293 294 295 296 297

	return ((acpi_gbl_fixed_event_handlers[event].handler)(
			  acpi_gbl_fixed_event_handlers[event].context));
}