xref: /netbsd-src/sys/dev/acpi/acpi_ec.c (revision 10ad5ffa714ce1a679dcc9dd8159648df2d67b5a)
1 /*	$NetBSD: acpi_ec.c,v 1.56 2009/07/06 00:54:00 alc Exp $	*/
2 
3 /*-
4  * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  * The ACPI Embedded Controller (EC) driver serves two different purposes:
34  * - read and write access from ASL, e.g. to read battery state
35  * - notification of ASL of System Control Interrupts.
36  *
37  * Access to the EC is serialised by sc_access_mtx and optionally the
38  * ACPI global mutex.  Both locks are held until the request is fulfilled.
39  * All access to the softc has to hold sc_mtx to serialise against the GPE
40  * handler and the callout.  sc_mtx is also used for wakeup conditions.
41  *
42  * SCIs are processed in a kernel thread. Handling gets a bit complicated
43  * by the lock order (sc_mtx must be acquired after sc_access_mtx and the
44  * ACPI global mutex).
45  *
46  * Read and write requests spin around for a short time as many requests
47  * can be handled instantly by the EC.  During normal processing interrupt
48  * mode is used exclusively.  At boot and resume time interrupts are not
49  * working and the handlers just busy loop.
50  *
51  * A callout is scheduled to compensate for missing interrupts on some
52  * hardware.  If the EC doesn't process a request for 5s, it is most likely
53  * in a wedged state.  No method to reset the EC is currently known.
54  *
55  * Special care has to be taken to not poll the EC in a busy loop without
56  * delay.  This can prevent processing of Power Button events. At least some
57  * Lenovo Thinkpads seem to be implement the Power Button Override in the EC
58  * and the only option to recover on those models is to cut off all power.
59  */
60 
61 #include <sys/cdefs.h>
62 __KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.56 2009/07/06 00:54:00 alc Exp $");
63 
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/condvar.h>
67 #include <sys/device.h>
68 #include <sys/kernel.h>
69 #include <sys/kthread.h>
70 #include <sys/mutex.h>
71 
72 #include <sys/bus.h>
73 
74 #include <dev/acpi/acpivar.h>
75 #include <dev/acpi/acpi_ecvar.h>
76 
77 /* Maximum time to wait for global ACPI lock in ms */
78 #define	EC_LOCK_TIMEOUT		5
79 
80 /* Maximum time to poll for completion of a command  in ms */
81 #define	EC_POLL_TIMEOUT		5
82 
83 /* Maximum time to give a single EC command in s */
84 #define EC_CMD_TIMEOUT		10
85 
86 /* From ACPI 3.0b, chapter 12.3 */
87 #define EC_COMMAND_READ		0x80
88 #define	EC_COMMAND_WRITE	0x81
89 #define	EC_COMMAND_BURST_EN	0x82
90 #define	EC_COMMAND_BURST_DIS	0x83
91 #define	EC_COMMAND_QUERY	0x84
92 
93 /* From ACPI 3.0b, chapter 12.2.1 */
94 #define	EC_STATUS_OBF		0x01
95 #define	EC_STATUS_IBF		0x02
96 #define	EC_STATUS_CMD		0x08
97 #define	EC_STATUS_BURST		0x10
98 #define	EC_STATUS_SCI		0x20
99 #define	EC_STATUS_SMI		0x40
100 
101 static const char *ec_hid[] = {
102 	"PNP0C09",
103 	NULL,
104 };
105 
106 enum ec_state_t {
107 	EC_STATE_QUERY,
108 	EC_STATE_QUERY_VAL,
109 	EC_STATE_READ,
110 	EC_STATE_READ_ADDR,
111 	EC_STATE_READ_VAL,
112 	EC_STATE_WRITE,
113 	EC_STATE_WRITE_ADDR,
114 	EC_STATE_WRITE_VAL,
115 	EC_STATE_FREE
116 };
117 
118 struct acpiec_softc {
119 	ACPI_HANDLE sc_ech;
120 
121 	ACPI_HANDLE sc_gpeh;
122 	UINT8 sc_gpebit;
123 
124 	bus_space_tag_t sc_data_st;
125 	bus_space_handle_t sc_data_sh;
126 
127 	bus_space_tag_t sc_csr_st;
128 	bus_space_handle_t sc_csr_sh;
129 
130 	bool sc_need_global_lock;
131 	UINT32 sc_global_lock;
132 
133 	kmutex_t sc_mtx, sc_access_mtx;
134 	kcondvar_t sc_cv, sc_cv_sci;
135 	enum ec_state_t sc_state;
136 	bool sc_got_sci;
137 	callout_t sc_pseudo_intr;
138 
139 	uint8_t sc_cur_addr, sc_cur_val;
140 };
141 
142 static int acpiecdt_match(device_t, cfdata_t, void *);
143 static void acpiecdt_attach(device_t, device_t, void *);
144 
145 static int acpiec_match(device_t, cfdata_t, void *);
146 static void acpiec_attach(device_t, device_t, void *);
147 
148 static void acpiec_common_attach(device_t, device_t, ACPI_HANDLE,
149     bus_addr_t, bus_addr_t, ACPI_HANDLE, uint8_t);
150 
151 static bool acpiec_suspend(device_t PMF_FN_PROTO);
152 static bool acpiec_resume(device_t PMF_FN_PROTO);
153 static bool acpiec_shutdown(device_t, int);
154 
155 static bool acpiec_parse_gpe_package(device_t, ACPI_HANDLE,
156     ACPI_HANDLE *, uint8_t *);
157 
158 static void acpiec_callout(void *);
159 static void acpiec_gpe_query(void *);
160 static UINT32 acpiec_gpe_handler(void *);
161 static ACPI_STATUS acpiec_space_setup(ACPI_HANDLE, UINT32, void *, void **);
162 static ACPI_STATUS acpiec_space_handler(UINT32, ACPI_PHYSICAL_ADDRESS,
163     UINT32, ACPI_INTEGER *, void *, void *);
164 
165 static void acpiec_gpe_state_machine(device_t);
166 
167 CFATTACH_DECL_NEW(acpiec, sizeof(struct acpiec_softc),
168     acpiec_match, acpiec_attach, NULL, NULL);
169 
170 CFATTACH_DECL_NEW(acpiecdt, sizeof(struct acpiec_softc),
171     acpiecdt_match, acpiecdt_attach, NULL, NULL);
172 
173 static device_t ec_singleton = NULL;
174 static bool acpiec_cold = false;
175 
176 static bool
177 acpiecdt_find(device_t parent, ACPI_HANDLE *ec_handle,
178     bus_addr_t *cmd_reg, bus_addr_t *data_reg, uint8_t *gpebit)
179 {
180 	ACPI_TABLE_ECDT *ecdt;
181 	ACPI_STATUS rv;
182 
183 	rv = AcpiGetTable(ACPI_SIG_ECDT, 1, (ACPI_TABLE_HEADER **)&ecdt);
184 	if (ACPI_FAILURE(rv))
185 		return false;
186 
187 	if (ecdt->Control.BitWidth != 8 || ecdt->Data.BitWidth != 8) {
188 		aprint_error_dev(parent,
189 		    "ECDT register width invalid (%d/%d)\n",
190 		    ecdt->Control.BitWidth, ecdt->Data.BitWidth);
191 		return false;
192 	}
193 
194 	rv = AcpiGetHandle(ACPI_ROOT_OBJECT, ecdt->Id, ec_handle);
195 	if (ACPI_FAILURE(rv)) {
196 		aprint_error_dev(parent,
197 		    "failed to look up EC object %s: %s\n",
198 		    ecdt->Id, AcpiFormatException(rv));
199 		return false;
200 	}
201 
202 	*cmd_reg = ecdt->Control.Address;
203 	*data_reg = ecdt->Data.Address;
204 	*gpebit = ecdt->Gpe;
205 
206 	return true;
207 }
208 
209 static int
210 acpiecdt_match(device_t parent, cfdata_t match, void *aux)
211 {
212 	ACPI_HANDLE ec_handle;
213 	bus_addr_t cmd_reg, data_reg;
214 	uint8_t gpebit;
215 
216 	if (acpiecdt_find(parent, &ec_handle, &cmd_reg, &data_reg, &gpebit))
217 		return 1;
218 	else
219 		return 0;
220 }
221 
222 static void
223 acpiecdt_attach(device_t parent, device_t self, void *aux)
224 {
225 	ACPI_HANDLE ec_handle;
226 	bus_addr_t cmd_reg, data_reg;
227 	uint8_t gpebit;
228 
229 	if (!acpiecdt_find(parent, &ec_handle, &cmd_reg, &data_reg, &gpebit))
230 		panic("ECDT disappeared");
231 
232 	aprint_naive("\n");
233 	aprint_normal(": ACPI Embedded Controller via ECDT\n");
234 
235 	acpiec_common_attach(parent, self, ec_handle, cmd_reg, data_reg,
236 	    NULL, gpebit);
237 }
238 
239 static int
240 acpiec_match(device_t parent, cfdata_t match, void *aux)
241 {
242 	struct acpi_attach_args *aa = aux;
243 
244 	if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE)
245 		return 0;
246 
247 	return acpi_match_hid(aa->aa_node->ad_devinfo, ec_hid);
248 }
249 
250 static void
251 acpiec_attach(device_t parent, device_t self, void *aux)
252 {
253 	struct acpi_attach_args *aa = aux;
254 	struct acpi_resources ec_res;
255 	struct acpi_io *io0, *io1;
256 	ACPI_HANDLE gpe_handle;
257 	uint8_t gpebit;
258 	ACPI_STATUS rv;
259 
260 	if (ec_singleton != NULL) {
261 		aprint_naive(": using %s\n", device_xname(ec_singleton));
262 		aprint_normal(": using %s\n", device_xname(ec_singleton));
263 		if (!pmf_device_register(self, NULL, NULL))
264 			aprint_error_dev(self, "couldn't establish power handler\n");
265 		return;
266 	}
267 
268 	if (!acpiec_parse_gpe_package(self, aa->aa_node->ad_handle,
269 				      &gpe_handle, &gpebit))
270 		return;
271 
272 	rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS",
273 	    &ec_res, &acpi_resource_parse_ops_default);
274 	if (rv != AE_OK) {
275 		aprint_error_dev(self, "resource parsing failed: %s\n",
276 		    AcpiFormatException(rv));
277 		return;
278 	}
279 
280 	if ((io0 = acpi_res_io(&ec_res, 0)) == NULL) {
281 		aprint_error_dev(self, "no data register resource\n");
282 		goto free_res;
283 	}
284 	if ((io1 = acpi_res_io(&ec_res, 1)) == NULL) {
285 		aprint_error_dev(self, "no CSR register resource\n");
286 		goto free_res;
287 	}
288 
289 	acpiec_common_attach(parent, self, aa->aa_node->ad_handle,
290 	    io1->ar_base, io0->ar_base, gpe_handle, gpebit);
291 
292 free_res:
293 	acpi_resource_cleanup(&ec_res);
294 }
295 
296 static void
297 acpiec_common_attach(device_t parent, device_t self,
298     ACPI_HANDLE ec_handle, bus_addr_t cmd_reg, bus_addr_t data_reg,
299     ACPI_HANDLE gpe_handle, uint8_t gpebit)
300 {
301 	struct acpiec_softc *sc = device_private(self);
302 	ACPI_STATUS rv;
303 	ACPI_INTEGER val;
304 
305 	sc->sc_ech = ec_handle;
306 	sc->sc_gpeh = gpe_handle;
307 	sc->sc_gpebit = gpebit;
308 
309 	sc->sc_state = EC_STATE_FREE;
310 	mutex_init(&sc->sc_mtx, MUTEX_DRIVER, IPL_TTY);
311 	mutex_init(&sc->sc_access_mtx, MUTEX_DEFAULT, IPL_NONE);
312 	cv_init(&sc->sc_cv, "eccv");
313 	cv_init(&sc->sc_cv_sci, "ecsci");
314 
315 	if (bus_space_map(sc->sc_data_st, data_reg, 1, 0,
316 	    &sc->sc_data_sh) != 0) {
317 		aprint_error_dev(self, "unable to map data register\n");
318 		return;
319 	}
320 
321 	if (bus_space_map(sc->sc_csr_st, cmd_reg, 1, 0, &sc->sc_csr_sh) != 0) {
322 		aprint_error_dev(self, "unable to map CSR register\n");
323 		goto post_data_map;
324 	}
325 
326 	rv = acpi_eval_integer(sc->sc_ech, "_GLK", &val);
327 	if (rv == AE_OK) {
328 		sc->sc_need_global_lock = val != 0;
329 	} else if (rv != AE_NOT_FOUND) {
330 		aprint_error_dev(self, "unable to evaluate _GLK: %s\n",
331 		    AcpiFormatException(rv));
332 		goto post_csr_map;
333 	} else {
334 		sc->sc_need_global_lock = false;
335 	}
336 	if (sc->sc_need_global_lock)
337 		aprint_normal_dev(self, "using global ACPI lock\n");
338 
339 	callout_init(&sc->sc_pseudo_intr, CALLOUT_MPSAFE);
340 	callout_setfunc(&sc->sc_pseudo_intr, acpiec_callout, self);
341 
342 	rv = AcpiInstallAddressSpaceHandler(sc->sc_ech, ACPI_ADR_SPACE_EC,
343 	    acpiec_space_handler, acpiec_space_setup, self);
344 	if (rv != AE_OK) {
345 		aprint_error_dev(self,
346 		    "unable to install address space handler: %s\n",
347 		    AcpiFormatException(rv));
348 		goto post_csr_map;
349 	}
350 
351 	rv = AcpiInstallGpeHandler(sc->sc_gpeh, sc->sc_gpebit,
352 	    ACPI_GPE_EDGE_TRIGGERED, acpiec_gpe_handler, self);
353 	if (rv != AE_OK) {
354 		aprint_error_dev(self, "unable to install GPE handler: %s\n",
355 		    AcpiFormatException(rv));
356 		goto post_csr_map;
357 	}
358 
359 	rv = AcpiSetGpeType(sc->sc_gpeh, sc->sc_gpebit, ACPI_GPE_TYPE_RUNTIME);
360 	if (rv != AE_OK) {
361 		aprint_error_dev(self, "unable to set GPE type: %s\n",
362 		    AcpiFormatException(rv));
363 		goto post_csr_map;
364 	}
365 
366 	rv = AcpiEnableGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_ISR);
367 	if (rv != AE_OK) {
368 		aprint_error_dev(self, "unable to enable GPE: %s\n",
369 		    AcpiFormatException(rv));
370 		goto post_csr_map;
371 	}
372 
373 	if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, acpiec_gpe_query,
374 		           self, NULL, "acpiec sci thread")) {
375 		aprint_error_dev(self, "unable to create query kthread\n");
376 		goto post_csr_map;
377 	}
378 
379 	ec_singleton = self;
380 
381 	if (!pmf_device_register1(self, acpiec_suspend, acpiec_resume,
382 	    acpiec_shutdown))
383 		aprint_error_dev(self, "couldn't establish power handler\n");
384 
385 	return;
386 
387 post_csr_map:
388 	(void)AcpiRemoveGpeHandler(sc->sc_gpeh, sc->sc_gpebit,
389 	    acpiec_gpe_handler);
390 	(void)AcpiRemoveAddressSpaceHandler(sc->sc_ech,
391 	    ACPI_ADR_SPACE_EC, acpiec_space_handler);
392 	bus_space_unmap(sc->sc_csr_st, sc->sc_csr_sh, 1);
393 post_data_map:
394 	bus_space_unmap(sc->sc_data_st, sc->sc_data_sh, 1);
395 }
396 
397 static bool
398 acpiec_suspend(device_t dv PMF_FN_ARGS)
399 {
400 	acpiec_cold = true;
401 
402 	return true;
403 }
404 
405 static bool
406 acpiec_resume(device_t dv PMF_FN_ARGS)
407 {
408 	acpiec_cold = false;
409 
410 	return true;
411 }
412 
413 static bool
414 acpiec_shutdown(device_t dv, int how)
415 {
416 
417 	acpiec_cold = true;
418 	return true;
419 }
420 
421 static bool
422 acpiec_parse_gpe_package(device_t self, ACPI_HANDLE ec_handle,
423     ACPI_HANDLE *gpe_handle, uint8_t *gpebit)
424 {
425 	ACPI_BUFFER buf;
426 	ACPI_OBJECT *p, *c;
427 	ACPI_STATUS rv;
428 
429 	rv = acpi_eval_struct(ec_handle, "_GPE", &buf);
430 	if (rv != AE_OK) {
431 		aprint_error_dev(self, "unable to evaluate _GPE: %s\n",
432 		    AcpiFormatException(rv));
433 		return false;
434 	}
435 
436 	p = buf.Pointer;
437 
438 	if (p->Type == ACPI_TYPE_INTEGER) {
439 		*gpe_handle = NULL;
440 		*gpebit = p->Integer.Value;
441 		AcpiOsFree(p);
442 		return true;
443 	}
444 
445 	if (p->Type != ACPI_TYPE_PACKAGE) {
446 		aprint_error_dev(self, "_GPE is neither integer nor package\n");
447 		AcpiOsFree(p);
448 		return false;
449 	}
450 
451 	if (p->Package.Count != 2) {
452 		aprint_error_dev(self, "_GPE package does not contain 2 elements\n");
453 		AcpiOsFree(p);
454 		return false;
455 	}
456 
457 	c = &p->Package.Elements[0];
458 	switch (c->Type) {
459 	case ACPI_TYPE_LOCAL_REFERENCE:
460 	case ACPI_TYPE_ANY:
461 		*gpe_handle = c->Reference.Handle;
462 		break;
463 	case ACPI_TYPE_STRING:
464 		/* XXX should be using real scope here */
465 		rv = AcpiGetHandle(NULL, p->String.Pointer, gpe_handle);
466 		if (rv != AE_OK) {
467 			aprint_error_dev(self,
468 			    "_GPE device reference unresolvable\n");
469 			AcpiOsFree(p);
470 			return false;
471 		}
472 		break;
473 	default:
474 		aprint_error_dev(self, "_GPE device reference incorrect\n");
475 		AcpiOsFree(p);
476 		return false;
477 	}
478 	c = &p->Package.Elements[1];
479 	if (c->Type != ACPI_TYPE_INTEGER) {
480 		aprint_error_dev(self,
481 		    "_GPE package needs integer as 2nd field\n");
482 		AcpiOsFree(p);
483 		return false;
484 	}
485 	*gpebit = c->Integer.Value;
486 	AcpiOsFree(p);
487 	return true;
488 }
489 
490 static uint8_t
491 acpiec_read_data(struct acpiec_softc *sc)
492 {
493 	return bus_space_read_1(sc->sc_data_st, sc->sc_data_sh, 0);
494 }
495 
496 static void
497 acpiec_write_data(struct acpiec_softc *sc, uint8_t val)
498 {
499 	bus_space_write_1(sc->sc_data_st, sc->sc_data_sh, 0, val);
500 }
501 
502 static uint8_t
503 acpiec_read_status(struct acpiec_softc *sc)
504 {
505 	return bus_space_read_1(sc->sc_csr_st, sc->sc_csr_sh, 0);
506 }
507 
508 static void
509 acpiec_write_command(struct acpiec_softc *sc, uint8_t cmd)
510 {
511 	bus_space_write_1(sc->sc_csr_st, sc->sc_csr_sh, 0, cmd);
512 }
513 
514 static ACPI_STATUS
515 acpiec_space_setup(ACPI_HANDLE region, UINT32 func, void *arg,
516     void **region_arg)
517 {
518 	if (func == ACPI_REGION_DEACTIVATE)
519 		*region_arg = NULL;
520 	else
521 		*region_arg = arg;
522 
523 	return AE_OK;
524 }
525 
526 static void
527 acpiec_lock(device_t dv)
528 {
529 	struct acpiec_softc *sc = device_private(dv);
530 	ACPI_STATUS rv;
531 
532 	mutex_enter(&sc->sc_access_mtx);
533 
534 	if (sc->sc_need_global_lock) {
535 		rv = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT, &sc->sc_global_lock);
536 		if (rv != AE_OK) {
537 			aprint_error_dev(dv, "failed to acquire global lock: %s\n",
538 			    AcpiFormatException(rv));
539 			return;
540 		}
541 	}
542 }
543 
544 static void
545 acpiec_unlock(device_t dv)
546 {
547 	struct acpiec_softc *sc = device_private(dv);
548 	ACPI_STATUS rv;
549 
550 	if (sc->sc_need_global_lock) {
551 		rv = AcpiReleaseGlobalLock(sc->sc_global_lock);
552 		if (rv != AE_OK) {
553 			aprint_error_dev(dv, "failed to release global lock: %s\n",
554 			    AcpiFormatException(rv));
555 		}
556 	}
557 	mutex_exit(&sc->sc_access_mtx);
558 }
559 
560 static ACPI_STATUS
561 acpiec_read(device_t dv, uint8_t addr, uint8_t *val)
562 {
563 	struct acpiec_softc *sc = device_private(dv);
564 	int i, timeo = 1000 * EC_CMD_TIMEOUT;
565 
566 	acpiec_lock(dv);
567 	mutex_enter(&sc->sc_mtx);
568 
569 	sc->sc_cur_addr = addr;
570 	sc->sc_state = EC_STATE_READ;
571 
572 	for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
573 		acpiec_gpe_state_machine(dv);
574 		if (sc->sc_state == EC_STATE_FREE)
575 			goto done;
576 		delay(1);
577 	}
578 
579 	if (cold || acpiec_cold) {
580 		while (sc->sc_state != EC_STATE_FREE && timeo-- > 0) {
581 			delay(1000);
582 			acpiec_gpe_state_machine(dv);
583 		}
584 		if (sc->sc_state != EC_STATE_FREE) {
585 			mutex_exit(&sc->sc_mtx);
586 			AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR);
587 			acpiec_unlock(dv);
588 			aprint_error_dev(dv, "command timed out, state %d\n",
589 			    sc->sc_state);
590 			return AE_ERROR;
591 		}
592 	} else if (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) {
593 		mutex_exit(&sc->sc_mtx);
594 		AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR);
595 		acpiec_unlock(dv);
596 		aprint_error_dev(dv, "command takes over %d sec...\n", EC_CMD_TIMEOUT);
597 		return AE_ERROR;
598 	}
599 
600 done:
601 	*val = sc->sc_cur_val;
602 
603 	mutex_exit(&sc->sc_mtx);
604 	acpiec_unlock(dv);
605 	return AE_OK;
606 }
607 
608 static ACPI_STATUS
609 acpiec_write(device_t dv, uint8_t addr, uint8_t val)
610 {
611 	struct acpiec_softc *sc = device_private(dv);
612 	int i, timeo = 1000 * EC_CMD_TIMEOUT;
613 
614 	acpiec_lock(dv);
615 	mutex_enter(&sc->sc_mtx);
616 
617 	sc->sc_cur_addr = addr;
618 	sc->sc_cur_val = val;
619 	sc->sc_state = EC_STATE_WRITE;
620 
621 	for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
622 		acpiec_gpe_state_machine(dv);
623 		if (sc->sc_state == EC_STATE_FREE)
624 			goto done;
625 		delay(1);
626 	}
627 
628 	if (cold || acpiec_cold) {
629 		while (sc->sc_state != EC_STATE_FREE && timeo-- > 0) {
630 			delay(1000);
631 			acpiec_gpe_state_machine(dv);
632 		}
633 		if (sc->sc_state != EC_STATE_FREE) {
634 			mutex_exit(&sc->sc_mtx);
635 			AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR);
636 			acpiec_unlock(dv);
637 			aprint_error_dev(dv, "command timed out, state %d\n",
638 			    sc->sc_state);
639 			return AE_ERROR;
640 		}
641 	} else if (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) {
642 		mutex_exit(&sc->sc_mtx);
643 		AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR);
644 		acpiec_unlock(dv);
645 		aprint_error_dev(dv, "command takes over %d sec...\n", EC_CMD_TIMEOUT);
646 		return AE_ERROR;
647 	}
648 
649 done:
650 	mutex_exit(&sc->sc_mtx);
651 	acpiec_unlock(dv);
652 	return AE_OK;
653 }
654 
655 static ACPI_STATUS
656 acpiec_space_handler(UINT32 func, ACPI_PHYSICAL_ADDRESS paddr,
657     UINT32 width, ACPI_INTEGER *value, void *arg, void *region_arg)
658 {
659 	device_t dv;
660 	struct acpiec_softc *sc;
661 	ACPI_STATUS rv;
662 	uint8_t addr, reg;
663 	unsigned int i;
664 
665 	if (paddr > 0xff || width % 8 != 0 || value == NULL || arg == NULL ||
666 	    paddr + width / 8 > 0xff)
667 		return AE_BAD_PARAMETER;
668 
669 	addr = paddr;
670 	dv = arg;
671 	sc = device_private(dv);
672 
673 	rv = AE_OK;
674 
675 	switch (func) {
676 	case ACPI_READ:
677 		*value = 0;
678 		for (i = 0; i < width; i += 8, ++addr) {
679 			rv = acpiec_read(dv, addr, &reg);
680 			if (rv != AE_OK)
681 				break;
682 			*value |= (ACPI_INTEGER)reg << i;
683 		}
684 		break;
685 	case ACPI_WRITE:
686 		for (i = 0; i < width; i += 8, ++addr) {
687 			reg = (*value >>i) & 0xff;
688 			rv = acpiec_write(dv, addr, reg);
689 			if (rv != AE_OK)
690 				break;
691 		}
692 		break;
693 	default:
694 		aprint_error("%s: invalid Address Space function called: %x\n",
695 		    device_xname(dv), (unsigned int)func);
696 		return AE_BAD_PARAMETER;
697 	}
698 
699 	return rv;
700 }
701 
702 static void
703 acpiec_gpe_query(void *arg)
704 {
705 	device_t dv = arg;
706 	struct acpiec_softc *sc = device_private(dv);
707 	uint8_t reg;
708 	char qxx[5];
709 	ACPI_STATUS rv;
710 	int i;
711 
712 loop:
713 	mutex_enter(&sc->sc_mtx);
714 
715 	if (sc->sc_got_sci == false)
716 		cv_wait(&sc->sc_cv_sci, &sc->sc_mtx);
717 	mutex_exit(&sc->sc_mtx);
718 
719 	acpiec_lock(dv);
720 	mutex_enter(&sc->sc_mtx);
721 
722 	/* The Query command can always be issued, so be defensive here. */
723 	sc->sc_got_sci = false;
724 	sc->sc_state = EC_STATE_QUERY;
725 
726 	for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
727 		acpiec_gpe_state_machine(dv);
728 		if (sc->sc_state == EC_STATE_FREE)
729 			goto done;
730 		delay(1);
731 	}
732 
733 	cv_wait(&sc->sc_cv, &sc->sc_mtx);
734 
735 done:
736 	reg = sc->sc_cur_val;
737 
738 	mutex_exit(&sc->sc_mtx);
739 	acpiec_unlock(dv);
740 
741 	if (reg == 0)
742 		goto loop; /* Spurious query result */
743 
744 	/*
745 	 * Evaluate _Qxx to respond to the controller.
746 	 */
747 	snprintf(qxx, sizeof(qxx), "_Q%02X", (unsigned int)reg);
748 	rv = AcpiEvaluateObject(sc->sc_ech, qxx, NULL, NULL);
749 	if (rv != AE_OK && rv != AE_NOT_FOUND) {
750 		aprint_error("%s: GPE query method %s failed: %s",
751 		    device_xname(dv), qxx, AcpiFormatException(rv));
752 	}
753 
754 	goto loop;
755 }
756 
757 static void
758 acpiec_gpe_state_machine(device_t dv)
759 {
760 	struct acpiec_softc *sc = device_private(dv);
761 	uint8_t reg;
762 
763 	reg = acpiec_read_status(sc);
764 
765 	if (reg & EC_STATUS_SCI)
766 		sc->sc_got_sci = true;
767 
768 	switch (sc->sc_state) {
769 	case EC_STATE_QUERY:
770 		if ((reg & EC_STATUS_IBF) != 0)
771 			break; /* Nothing of interest here. */
772 		acpiec_write_command(sc, EC_COMMAND_QUERY);
773 		sc->sc_state = EC_STATE_QUERY_VAL;
774 		break;
775 
776 	case EC_STATE_QUERY_VAL:
777 		if ((reg & EC_STATUS_OBF) == 0)
778 			break; /* Nothing of interest here. */
779 
780 		sc->sc_cur_val = acpiec_read_data(sc);
781 		sc->sc_state = EC_STATE_FREE;
782 
783 		cv_signal(&sc->sc_cv);
784 		break;
785 
786 	case EC_STATE_READ:
787 		if ((reg & EC_STATUS_IBF) != 0)
788 			break; /* Nothing of interest here. */
789 
790 		acpiec_write_command(sc, EC_COMMAND_READ);
791 		sc->sc_state = EC_STATE_READ_ADDR;
792 		break;
793 
794 	case EC_STATE_READ_ADDR:
795 		if ((reg & EC_STATUS_IBF) != 0)
796 			break; /* Nothing of interest here. */
797 
798 		acpiec_write_data(sc, sc->sc_cur_addr);
799 		sc->sc_state = EC_STATE_READ_VAL;
800 		break;
801 
802 	case EC_STATE_READ_VAL:
803 		if ((reg & EC_STATUS_OBF) == 0)
804 			break; /* Nothing of interest here. */
805 		sc->sc_cur_val = acpiec_read_data(sc);
806 		sc->sc_state = EC_STATE_FREE;
807 
808 		cv_signal(&sc->sc_cv);
809 		break;
810 
811 	case EC_STATE_WRITE:
812 		if ((reg & EC_STATUS_IBF) != 0)
813 			break; /* Nothing of interest here. */
814 
815 		acpiec_write_command(sc, EC_COMMAND_WRITE);
816 		sc->sc_state = EC_STATE_WRITE_ADDR;
817 		break;
818 
819 	case EC_STATE_WRITE_ADDR:
820 		if ((reg & EC_STATUS_IBF) != 0)
821 			break; /* Nothing of interest here. */
822 		acpiec_write_data(sc, sc->sc_cur_addr);
823 		sc->sc_state = EC_STATE_WRITE_VAL;
824 		break;
825 
826 	case EC_STATE_WRITE_VAL:
827 		if ((reg & EC_STATUS_IBF) != 0)
828 			break; /* Nothing of interest here. */
829 		sc->sc_state = EC_STATE_FREE;
830 		cv_signal(&sc->sc_cv);
831 
832 		acpiec_write_data(sc, sc->sc_cur_val);
833 		break;
834 
835 	case EC_STATE_FREE:
836 		if (sc->sc_got_sci)
837 			cv_signal(&sc->sc_cv_sci);
838 		break;
839 	default:
840 		panic("invalid state");
841 	}
842 
843 	if (sc->sc_state != EC_STATE_FREE)
844 		callout_schedule(&sc->sc_pseudo_intr, 1);
845 }
846 
847 static void
848 acpiec_callout(void *arg)
849 {
850 	device_t dv = arg;
851 	struct acpiec_softc *sc = device_private(dv);
852 
853 	AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_NOT_ISR);
854 
855 	mutex_enter(&sc->sc_mtx);
856 	acpiec_gpe_state_machine(dv);
857 	mutex_exit(&sc->sc_mtx);
858 }
859 
860 static UINT32
861 acpiec_gpe_handler(void *arg)
862 {
863 	device_t dv = arg;
864 	struct acpiec_softc *sc = device_private(dv);
865 
866 	AcpiClearGpe(sc->sc_gpeh, sc->sc_gpebit, ACPI_ISR);
867 
868 	mutex_enter(&sc->sc_mtx);
869 	acpiec_gpe_state_machine(dv);
870 	mutex_exit(&sc->sc_mtx);
871 
872 	return 0;
873 }
874 
875 ACPI_STATUS
876 acpiec_bus_read(device_t dv, u_int addr, ACPI_INTEGER *val, int width)
877 {
878 	return acpiec_space_handler(ACPI_READ, addr, width * 8, val, dv, NULL);
879 }
880 
881 ACPI_STATUS
882 acpiec_bus_write(device_t dv, u_int addr, ACPI_INTEGER val, int width)
883 {
884 	return acpiec_space_handler(ACPI_WRITE, addr, width * 8, &val, dv, NULL);
885 }
886 
887 ACPI_HANDLE
888 acpiec_get_handle(device_t dv)
889 {
890 	struct acpiec_softc *sc = device_private(dv);
891 
892 	return sc->sc_ech;
893 }
894