Sun Jul 30 12:01:54 2023 UTC ()
Pull up following revision(s) (requested by riastradh in ticket #259):

	sys/dev/acpi/acpi_ec.c: revision 1.102
	sys/dev/acpi/acpi_ec.c: revision 1.103
	sys/dev/acpi/acpi_ec.c: revision 1.104
	sys/dev/acpi/acpi_ec.c: revision 1.105
	sys/dev/acpi/acpi_ec.c: revision 1.106
	sys/dev/acpi/acpi_ec.c: revision 1.107
	sys/dev/acpi/acpi_ec.c: revision 1.108
	sys/dev/acpi/acpi_ec.c: revision 1.90
	sys/dev/acpi/acpi_ec.c: revision 1.91
	sys/dev/acpi/acpi_ec.c: revision 1.92
	sys/dev/acpi/acpi_ec.c: revision 1.93
	sys/dev/acpi/acpi_ec.c: revision 1.94
	sys/dev/acpi/files.acpi: revision 1.128
	sys/dev/acpi/acpi_ec.c: revision 1.95
	sys/dev/acpi/acpi_ec.c: revision 1.96
	sys/dev/acpi/acpi_ec.c: revision 1.97
	sys/arch/amd64/conf/ALL: revision 1.179
	sys/dev/acpi/acpi_ec.c: revision 1.98
	sys/dev/acpi/acpi_ec.c: revision 1.99
	sys/dev/acpi/acpi_ec.c: revision 1.87
	sys/dev/acpi/acpi_ec.c: revision 1.88
	sys/dev/acpi/acpi_ec.c: revision 1.89
	sys/arch/i386/conf/ALL: revision 1.511
	sys/dev/acpi/acpi_ec.c: revision 1.100
	sys/dev/acpi/acpi_ec.c: revision 1.101

acpiec(4): Record device_t self.

Not used yet, to be used soon for device_printf and to allow making
some of the internal functions a little more type-safe later.
acpiec(4): New ACPIEC_DEBUG option.

Value is bit mask of debug messages to enable.

Enable in x86/ALL kernels.

No functional change intended when the option is off.

acpiec(4): Clarify lock order and sprinkle lock assertions.
No functional change intended.

acpiec(4): Sprinkle comments.
Note where this code is abusing cv_wait and needs a loop to handle
spurious wakeups.
No functional change intended.

acpiec(4): Assert state is free when we start a transaction.
No functional change intended.

acpiec(4): Set sc_got_sci only when a transaction is over.

Before, when the acpiec thread noticed an SCI had been requested and
entered acpiec_gpe_state_machine to send the query command, it would
see the SCI is still requested -- because it had yet to acknowledge
it by setting the query command! -- and think the EC was asking for a
_second_ SCI.

So once the first SCI transaction was over, it would start a second
one, even though the EC hadn't asked for another -- and this would
wedge on some ECs.

Now, acpiec_gpe_state_machine waits to see what state we transition
to before taking the SCI bit to mean we need to notify the acpiec
thread to handle another query.

That way, when the acpiec thread enters acpiec_gpe_state_machine with
EC_STATE_QUERY, it can send the query command first, with the side
effect of clearing the SCI bit in subsequent reads of the status
register, and it won't think another SCI has been requested until it
returns to EC_STATE_FREE and sees the SCI bit set again in the status
register.

Possibly relevant PRs:
PR kern/53135
PR kern/52763
PR kern/57162

acpiec(4): Fix cv_wait loop around sc->sc_got_sci.

That is, make it actually loop as required, so it gracefully handles
spurious wakeups instead of barging into invalid states.

acpiec(4): Fix interrupt wait loop in acpiec_gpe_query thread.

acpiec(4): Fix cv_timedwait abuse in acpiec_read/write.

acpiec(4): Don't touch sc->sc_state outside sc->sc_mtx.

acpiec(4): Merge returns in acpiec_read/write.
No functional change intended.

acpiec(4): Factor wait logic out.
No functional change intended.

acpiec(4): Pass softc, not device_t, to acpiec_gpe_state_machine.
Simpler, type-safer.
No functional change intended.

acpiec(4): Pass softc, not device_t, to acpiec_callout.
Simpler.
No functional change intended.

acpiec(4): Pass softc, not device_t, to acpiec_gpe_handler.
Simpler.
No functional change intended.

acpiec(4): Pass softc, not device_t, to acpiec_lock/unlock.
Simpler, type-safer.
No functional change intended.

acpiec(4): Pass softc, not device_t, to acpiec_read/write.
Simpler, type-safer.
No functional change intended.

acpiec(4): Pass softc, not device_t, to acpiec_gpe_query thread.
Simpler.
No functional change intended.

acpiec(4): Pass softc, not device_t, to acpiec_space_handler.
Better to keep the device_t isolated to public interfaces.  Simpler
internally this way.
No functional change intended.

acpiec(4): Factor out if (state == FREE) cv_signal(sc_cv).

In principle this could have a functional change, but at worst, it is
to signal more wakeups than needed, which should always be safe.
acpiec(4): Take a lock around acpiec_cold updates.

Otherwise we race with readers -- probably harmlessly, but let's
avoid the appearance of problems.
XXX Maybe acpiec_suspend and acpiec_shutdown should interrupt
transactions and force them to fail promptly?
XXX This looks bad because acpiec_cold is global and sc->sc_mtx
doesn't look like it's global, but we expect to have only one
acpiec(4) device anyway from what I understand.  Maybe we should move
acpiec_cold into the softc?

acpiec(4): One more debug message about read/write polling timeout.


(martin)
diff -r1.174 -r1.174.4.1 src/sys/arch/amd64/conf/ALL
diff -r1.503 -r1.503.4.1 src/sys/arch/i386/conf/ALL
diff -r1.86 -r1.86.4.1 src/sys/dev/acpi/acpi_ec.c
diff -r1.126 -r1.126.4.1 src/sys/dev/acpi/files.acpi

cvs diff -r1.174 -r1.174.4.1 src/sys/arch/amd64/conf/ALL (expand / switch to unified diff)

--- src/sys/arch/amd64/conf/ALL 2022/09/24 11:05:17 1.174
+++ src/sys/arch/amd64/conf/ALL 2023/07/30 12:01:54 1.174.4.1
@@ -1,33 +1,33 @@ @@ -1,33 +1,33 @@
1# $NetBSD: ALL,v 1.174 2022/09/24 11:05:17 riastradh Exp $ 1# $NetBSD: ALL,v 1.174.4.1 2023/07/30 12:01:54 martin Exp $
2# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp 2# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
3# 3#
4# ALL machine description file 4# ALL machine description file
5# 5#
6# This machine description includes all devices and options and it is 6# This machine description includes all devices and options and it is
7# used to compile-test the source and does not necessarily produce a 7# used to compile-test the source and does not necessarily produce a
8# bootable or useful kernel. 8# bootable or useful kernel.
9# 9#
10# For further information on hardware support for this architecture, see 10# For further information on hardware support for this architecture, see
11# the intro(4) man page. For further information about kernel options 11# the intro(4) man page. For further information about kernel options
12# for this architecture, see the options(4) man page. For an explanation 12# for this architecture, see the options(4) man page. For an explanation
13# of each device driver in this file see the section 4 man page for the 13# of each device driver in this file see the section 4 man page for the
14# device. 14# device.
15 15
16include "arch/amd64/conf/std.amd64" 16include "arch/amd64/conf/std.amd64"
17 17
18options INCLUDE_CONFIG_FILE # embed config file in kernel binary 18options INCLUDE_CONFIG_FILE # embed config file in kernel binary
19 19
20#ident "ALL-$Revision: 1.174 $" 20#ident "ALL-$Revision: 1.174.4.1 $"
21 21
22maxusers 64 # estimated number of users 22maxusers 64 # estimated number of users
23 23
24makeoptions USE_SSP=yes 24makeoptions USE_SSP=yes
25 25
26# CPU-related options. 26# CPU-related options.
27options USER_LDT # User-settable LDT, used by Wine 27options USER_LDT # User-settable LDT, used by Wine
28options X86EMU # 386 Real Mode emulator 28options X86EMU # 386 Real Mode emulator
29#options PAE # PAE mode (36 bits physical addressing) 29#options PAE # PAE mode (36 bits physical addressing)
30makeoptions SPECTRE_V2_GCC_MITIGATION=1 # GCC Spectre variant 2 30makeoptions SPECTRE_V2_GCC_MITIGATION=1 # GCC Spectre variant 2
31 # migitation 31 # migitation
32options PCPU_IDT # Per CPU IDT 32options PCPU_IDT # Per CPU IDT
33 33
@@ -356,26 +356,27 @@ options PCI_ADDR_FIXUP # fixup PCI I/O @@ -356,26 +356,27 @@ options PCI_ADDR_FIXUP # fixup PCI I/O
356options ACPI_ACTIVATE_DEV # If set, activate inactive devices 356options ACPI_ACTIVATE_DEV # If set, activate inactive devices
357options VGA_POST # in-kernel support for VGA POST 357options VGA_POST # in-kernel support for VGA POST
358 358
359acpi0 at mainbus0 359acpi0 at mainbus0
360 360
361# ACPI devices 361# ACPI devices
362apm* at acpi? # ACPI apm emulation 362apm* at acpi? # ACPI apm emulation
363acpiacad* at acpi? # ACPI AC Adapter 363acpiacad* at acpi? # ACPI AC Adapter
364acpibat* at acpi? # ACPI Battery 364acpibat* at acpi? # ACPI Battery
365acpibut* at acpi? # ACPI Button 365acpibut* at acpi? # ACPI Button
366acpidalb* at acpi? # ACPI Direct Application Launch Button 366acpidalb* at acpi? # ACPI Direct Application Launch Button
367acpiec* at acpi? # ACPI Embedded Controller (late) 367acpiec* at acpi? # ACPI Embedded Controller (late)
368acpiecdt* at acpi? # ACPI Embedded Controller (early) 368acpiecdt* at acpi? # ACPI Embedded Controller (early)
 369options ACPIEC_DEBUG=-1
369acpifan* at acpi? # ACPI Fan 370acpifan* at acpi? # ACPI Fan
370acpilid* at acpi? # ACPI Lid Switch 371acpilid* at acpi? # ACPI Lid Switch
371acpipmtr* at acpi? # ACPI Power Meter (experimental) 372acpipmtr* at acpi? # ACPI Power Meter (experimental)
372# XXX Do not enable this in a real kernel unless you also disable any 373# XXX Do not enable this in a real kernel unless you also disable any
373# XXX "native" i2c controller. Otherwise you'll have two accessors to 374# XXX "native" i2c controller. Otherwise you'll have two accessors to
374# XXX the same bus, and bad things (tm) will happen! 375# XXX the same bus, and bad things (tm) will happen!
375acpismbus* at acpi? # ACPI SMBus CMI (experimental) 376acpismbus* at acpi? # ACPI SMBus CMI (experimental)
376acpitz* at acpi? # ACPI Thermal Zone 377acpitz* at acpi? # ACPI Thermal Zone
377acpivga* at acpi? # ACPI Display Adapter 378acpivga* at acpi? # ACPI Display Adapter
378acpiout* at acpivga? # ACPI Display Output Device 379acpiout* at acpivga? # ACPI Display Output Device
379acpiwdrt* at acpi? # ACPI Watchdog Resource Table 380acpiwdrt* at acpi? # ACPI Watchdog Resource Table
380acpiwmi* at acpi? # ACPI WMI Mapper 381acpiwmi* at acpi? # ACPI WMI Mapper
381 382

cvs diff -r1.503 -r1.503.4.1 src/sys/arch/i386/conf/ALL (expand / switch to unified diff)

--- src/sys/arch/i386/conf/ALL 2022/09/24 11:05:17 1.503
+++ src/sys/arch/i386/conf/ALL 2023/07/30 12:01:54 1.503.4.1
@@ -1,33 +1,33 @@ @@ -1,33 +1,33 @@
1# $NetBSD: ALL,v 1.503 2022/09/24 11:05:17 riastradh Exp $ 1# $NetBSD: ALL,v 1.503.4.1 2023/07/30 12:01:54 martin Exp $
2# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp 2# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
3# 3#
4# ALL machine description file 4# ALL machine description file
5# 5#
6# This machine description includes all devices and options and it is 6# This machine description includes all devices and options and it is
7# used to compile-test the source and does not necessarily produce a 7# used to compile-test the source and does not necessarily produce a
8# bootable or useful kernel. 8# bootable or useful kernel.
9# 9#
10# For further information on hardware support for this architecture, see 10# For further information on hardware support for this architecture, see
11# the intro(4) man page. For further information about kernel options 11# the intro(4) man page. For further information about kernel options
12# for this architecture, see the options(4) man page. For an explanation 12# for this architecture, see the options(4) man page. For an explanation
13# of each device driver in this file see the section 4 man page for the 13# of each device driver in this file see the section 4 man page for the
14# device. 14# device.
15 15
16include "arch/i386/conf/std.i386" 16include "arch/i386/conf/std.i386"
17 17
18options INCLUDE_CONFIG_FILE # embed config file in kernel binary 18options INCLUDE_CONFIG_FILE # embed config file in kernel binary
19 19
20#ident "ALL-$Revision: 1.503 $" 20#ident "ALL-$Revision: 1.503.4.1 $"
21 21
22maxusers 64 # estimated number of users 22maxusers 64 # estimated number of users
23 23
24makeoptions USE_SSP=yes 24makeoptions USE_SSP=yes
25 25
26# CPU-related options. 26# CPU-related options.
27options USER_LDT # user-settable LDT; used by WINE 27options USER_LDT # user-settable LDT; used by WINE
28options X86EMU # 386 Real Mode emulator 28options X86EMU # 386 Real Mode emulator
29options PAE # PAE mode (36 bits physical addressing) 29options PAE # PAE mode (36 bits physical addressing)
30makeoptions SPECTRE_V2_GCC_MITIGATION=1 # GCC Spectre variant 2 30makeoptions SPECTRE_V2_GCC_MITIGATION=1 # GCC Spectre variant 2
31 # migitation 31 # migitation
32options PCPU_IDT # Per CPU IDT 32options PCPU_IDT # Per CPU IDT
33 33
@@ -343,26 +343,27 @@ options ACPI_SCANPCI # find PCI roots u @@ -343,26 +343,27 @@ options ACPI_SCANPCI # find PCI roots u
343 343
344acpi0 at mainbus0 344acpi0 at mainbus0
345 345
346options ACPI_ACTIVATE_DEV # If set, activate inactive devices 346options ACPI_ACTIVATE_DEV # If set, activate inactive devices
347 347
348# ACPI devices 348# ACPI devices
349apm* at acpi? # ACPI apm emulation 349apm* at acpi? # ACPI apm emulation
350acpiacad* at acpi? # ACPI AC Adapter 350acpiacad* at acpi? # ACPI AC Adapter
351acpibat* at acpi? # ACPI Battery 351acpibat* at acpi? # ACPI Battery
352acpibut* at acpi? # ACPI Button 352acpibut* at acpi? # ACPI Button
353acpidalb* at acpi? # ACPI Direct Application Launch Button 353acpidalb* at acpi? # ACPI Direct Application Launch Button
354acpiec* at acpi? # ACPI Embedded Controller (late) 354acpiec* at acpi? # ACPI Embedded Controller (late)
355acpiecdt* at acpi? # ACPI Embedded Controller (early) 355acpiecdt* at acpi? # ACPI Embedded Controller (early)
 356options ACPIEC_DEBUG=-1
356acpifan* at acpi? # ACPI Fan 357acpifan* at acpi? # ACPI Fan
357acpilid* at acpi? # ACPI Lid Switch 358acpilid* at acpi? # ACPI Lid Switch
358acpipmtr* at acpi? # ACPI Power Meter (experimental) 359acpipmtr* at acpi? # ACPI Power Meter (experimental)
359# XXX Do not enable this in a real kernel unless you also disable any 360# XXX Do not enable this in a real kernel unless you also disable any
360# XXX "native" i2c controller. Otherwise you'll have two accessors to 361# XXX "native" i2c controller. Otherwise you'll have two accessors to
361# XXX the same bus, and bad things (tm) will happen! 362# XXX the same bus, and bad things (tm) will happen!
362acpismbus* at acpi? # ACPI SMBus CMI (experimental) 363acpismbus* at acpi? # ACPI SMBus CMI (experimental)
363acpitz* at acpi? # ACPI Thermal Zone 364acpitz* at acpi? # ACPI Thermal Zone
364acpivga* at acpi? # ACPI Display Adapter 365acpivga* at acpi? # ACPI Display Adapter
365acpiout* at acpivga? # ACPI Display Output Device 366acpiout* at acpivga? # ACPI Display Output Device
366acpiwdrt* at acpi? # ACPI Watchdog Resource Table 367acpiwdrt* at acpi? # ACPI Watchdog Resource Table
367acpiwmi* at acpi? # ACPI WMI Mapper 368acpiwmi* at acpi? # ACPI WMI Mapper
368 369

cvs diff -r1.86 -r1.86.4.1 src/sys/dev/acpi/acpi_ec.c (expand / switch to unified diff)

--- src/sys/dev/acpi/acpi_ec.c 2021/12/31 17:22:25 1.86
+++ src/sys/dev/acpi/acpi_ec.c 2023/07/30 12:01:53 1.86.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: acpi_ec.c,v 1.86 2021/12/31 17:22:25 riastradh Exp $ */ 1/* $NetBSD: acpi_ec.c,v 1.86.4.1 2023/07/30 12:01:53 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>. 4 * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in 14 * notice, this list of conditions and the following disclaimer in
@@ -24,52 +24,54 @@ @@ -24,52 +24,54 @@
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 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 28 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * The ACPI Embedded Controller (EC) driver serves two different purposes: 33 * The ACPI Embedded Controller (EC) driver serves two different purposes:
34 * - read and write access from ASL, e.g. to read battery state 34 * - read and write access from ASL, e.g. to read battery state
35 * - notification of ASL of System Control Interrupts. 35 * - notification of ASL of System Control Interrupts.
36 * 36 *
37 * Access to the EC is serialised by sc_access_mtx and optionally the 37 * Lock order:
38 * ACPI global mutex. Both locks are held until the request is fulfilled. 38 * sc_access_mtx (serializes EC transactions -- read, write, or SCI)
39 * All access to the softc has to hold sc_mtx to serialise against the GPE 39 * -> ACPI global lock (excludes other ACPI access during EC transaction)
40 * handler and the callout. sc_mtx is also used for wakeup conditions. 40 * -> sc_mtx (serializes state machine transitions and waits)
41 * 41 *
42 * SCIs are processed in a kernel thread. Handling gets a bit complicated 42 * SCIs are processed in a kernel thread.
43 * by the lock order (sc_mtx must be acquired after sc_access_mtx and the 
44 * ACPI global mutex). 
45 * 43 *
46 * Read and write requests spin around for a short time as many requests 44 * 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 45 * can be handled instantly by the EC. During normal processing interrupt
48 * mode is used exclusively. At boot and resume time interrupts are not 46 * mode is used exclusively. At boot and resume time interrupts are not
49 * working and the handlers just busy loop. 47 * working and the handlers just busy loop.
50 * 48 *
51 * A callout is scheduled to compensate for missing interrupts on some 49 * 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 50 * 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. 51 * in a wedged state. No method to reset the EC is currently known.
54 * 52 *
55 * Special care has to be taken to not poll the EC in a busy loop without 53 * 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 54 * 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 55 * 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. 56 * and the only option to recover on those models is to cut off all power.
59 */ 57 */
60 58
61#include <sys/cdefs.h> 59#include <sys/cdefs.h>
62__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.86 2021/12/31 17:22:25 riastradh Exp $"); 60__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.86.4.1 2023/07/30 12:01:53 martin Exp $");
 61
 62#ifdef _KERNEL_OPT
 63#include "opt_acpi_ec.h"
 64#endif
63 65
64#include <sys/param.h> 66#include <sys/param.h>
65#include <sys/callout.h> 67#include <sys/callout.h>
66#include <sys/condvar.h> 68#include <sys/condvar.h>
67#include <sys/device.h> 69#include <sys/device.h>
68#include <sys/kernel.h> 70#include <sys/kernel.h>
69#include <sys/kthread.h> 71#include <sys/kthread.h>
70#include <sys/mutex.h> 72#include <sys/mutex.h>
71#include <sys/systm.h> 73#include <sys/systm.h>
72 74
73#include <dev/acpi/acpireg.h> 75#include <dev/acpi/acpireg.h>
74#include <dev/acpi/acpivar.h> 76#include <dev/acpi/acpivar.h>
75#include <dev/acpi/acpi_ecvar.h> 77#include <dev/acpi/acpi_ecvar.h>
@@ -91,92 +93,159 @@ ACPI_MODULE_NAME ("acpi_ec") @@ -91,92 +93,159 @@ ACPI_MODULE_NAME ("acpi_ec")
91#define EC_COMMAND_WRITE 0x81 93#define EC_COMMAND_WRITE 0x81
92#define EC_COMMAND_BURST_EN 0x82 94#define EC_COMMAND_BURST_EN 0x82
93#define EC_COMMAND_BURST_DIS 0x83 95#define EC_COMMAND_BURST_DIS 0x83
94#define EC_COMMAND_QUERY 0x84 96#define EC_COMMAND_QUERY 0x84
95 97
96/* From ACPI 3.0b, chapter 12.2.1 */ 98/* From ACPI 3.0b, chapter 12.2.1 */
97#define EC_STATUS_OBF 0x01 99#define EC_STATUS_OBF 0x01
98#define EC_STATUS_IBF 0x02 100#define EC_STATUS_IBF 0x02
99#define EC_STATUS_CMD 0x08 101#define EC_STATUS_CMD 0x08
100#define EC_STATUS_BURST 0x10 102#define EC_STATUS_BURST 0x10
101#define EC_STATUS_SCI 0x20 103#define EC_STATUS_SCI 0x20
102#define EC_STATUS_SMI 0x40 104#define EC_STATUS_SMI 0x40
103 105
 106#define EC_STATUS_FMT \
 107 "\x10\10IGN7\7SMI\6SCI\5BURST\4CMD\3IGN2\2IBF\1OBF"
 108
104static const struct device_compatible_entry compat_data[] = { 109static const struct device_compatible_entry compat_data[] = {
105 { .compat = "PNP0C09" }, 110 { .compat = "PNP0C09" },
106 DEVICE_COMPAT_EOL 111 DEVICE_COMPAT_EOL
107}; 112};
108 113
 114#define EC_STATE_ENUM(F) \
 115 F(EC_STATE_QUERY, "QUERY") \
 116 F(EC_STATE_QUERY_VAL, "QUERY_VAL") \
 117 F(EC_STATE_READ, "READ") \
 118 F(EC_STATE_READ_ADDR, "READ_ADDR") \
 119 F(EC_STATE_READ_VAL, "READ_VAL") \
 120 F(EC_STATE_WRITE, "WRITE") \
 121 F(EC_STATE_WRITE_ADDR, "WRITE_ADDR") \
 122 F(EC_STATE_WRITE_VAL, "WRITE_VAL") \
 123 F(EC_STATE_FREE, "FREE") \
 124
109enum ec_state_t { 125enum ec_state_t {
110 EC_STATE_QUERY, 126#define F(N, S) N,
111 EC_STATE_QUERY_VAL, 127 EC_STATE_ENUM(F)
112 EC_STATE_READ, 128#undef F
113 EC_STATE_READ_ADDR, 129};
114 EC_STATE_READ_VAL, 130
115 EC_STATE_WRITE, 131#ifdef ACPIEC_DEBUG
116 EC_STATE_WRITE_ADDR, 132static const char *const acpiec_state_names[] = {
117 EC_STATE_WRITE_VAL, 133#define F(N, S) [N] = S,
118 EC_STATE_FREE 134 EC_STATE_ENUM(F)
 135#undef F
119}; 136};
 137#endif
120 138
121struct acpiec_softc { 139struct acpiec_softc {
 140 device_t sc_dev;
 141
122 ACPI_HANDLE sc_ech; 142 ACPI_HANDLE sc_ech;
123 143
124 ACPI_HANDLE sc_gpeh; 144 ACPI_HANDLE sc_gpeh;
125 uint8_t sc_gpebit; 145 uint8_t sc_gpebit;
126 146
127 bus_space_tag_t sc_data_st; 147 bus_space_tag_t sc_data_st;
128 bus_space_handle_t sc_data_sh; 148 bus_space_handle_t sc_data_sh;
129 149
130 bus_space_tag_t sc_csr_st; 150 bus_space_tag_t sc_csr_st;
131 bus_space_handle_t sc_csr_sh; 151 bus_space_handle_t sc_csr_sh;
132 152
133 bool sc_need_global_lock; 153 bool sc_need_global_lock;
134 uint32_t sc_global_lock; 154 uint32_t sc_global_lock;
135 155
136 kmutex_t sc_mtx, sc_access_mtx; 156 kmutex_t sc_mtx, sc_access_mtx;
137 kcondvar_t sc_cv, sc_cv_sci; 157 kcondvar_t sc_cv, sc_cv_sci;
138 enum ec_state_t sc_state; 158 enum ec_state_t sc_state;
139 bool sc_got_sci; 159 bool sc_got_sci;
140 callout_t sc_pseudo_intr; 160 callout_t sc_pseudo_intr;
141 161
142 uint8_t sc_cur_addr, sc_cur_val; 162 uint8_t sc_cur_addr, sc_cur_val;
143}; 163};
144 164
 165#ifdef ACPIEC_DEBUG
 166
 167#define ACPIEC_DEBUG_ENUM(F) \
 168 F(ACPIEC_DEBUG_REG, "REG") \
 169 F(ACPIEC_DEBUG_RW, "RW") \
 170 F(ACPIEC_DEBUG_QUERY, "QUERY") \
 171 F(ACPIEC_DEBUG_TRANSITION, "TRANSITION") \
 172 F(ACPIEC_DEBUG_INTR, "INTR") \
 173
 174enum {
 175#define F(N, S) N,
 176 ACPIEC_DEBUG_ENUM(F)
 177#undef F
 178};
 179
 180static const char *const acpiec_debug_names[] = {
 181#define F(N, S) [N] = S,
 182 ACPIEC_DEBUG_ENUM(F)
 183#undef F
 184};
 185
 186int acpiec_debug = ACPIEC_DEBUG;
 187
 188#define DPRINTF(n, sc, fmt, ...) do \
 189{ \
 190 if (acpiec_debug & __BIT(n)) { \
 191 char dprintbuf[16]; \
 192 const char *state; \
 193 \
 194 /* paranoia */ \
 195 if ((sc)->sc_state < __arraycount(acpiec_state_names)) { \
 196 state = acpiec_state_names[(sc)->sc_state]; \
 197 } else { \
 198 snprintf(dprintbuf, sizeof(dprintbuf), "0x%x", \
 199 (sc)->sc_state); \
 200 state = dprintbuf; \
 201 } \
 202 \
 203 device_printf((sc)->sc_dev, "(%s) [%s] "fmt, \
 204 acpiec_debug_names[n], state, ##__VA_ARGS__); \
 205 } \
 206} while (0)
 207
 208#else
 209
 210#define DPRINTF(n, sc, fmt, ...) __nothing
 211
 212#endif
 213
145static int acpiecdt_match(device_t, cfdata_t, void *); 214static int acpiecdt_match(device_t, cfdata_t, void *);
146static void acpiecdt_attach(device_t, device_t, void *); 215static void acpiecdt_attach(device_t, device_t, void *);
147 216
148static int acpiec_match(device_t, cfdata_t, void *); 217static int acpiec_match(device_t, cfdata_t, void *);
149static void acpiec_attach(device_t, device_t, void *); 218static void acpiec_attach(device_t, device_t, void *);
150 219
151static void acpiec_common_attach(device_t, device_t, ACPI_HANDLE, 220static void acpiec_common_attach(device_t, device_t, ACPI_HANDLE,
152 bus_space_tag_t, bus_addr_t, bus_space_tag_t, bus_addr_t, 221 bus_space_tag_t, bus_addr_t, bus_space_tag_t, bus_addr_t,
153 ACPI_HANDLE, uint8_t); 222 ACPI_HANDLE, uint8_t);
154 223
155static bool acpiec_suspend(device_t, const pmf_qual_t *); 224static bool acpiec_suspend(device_t, const pmf_qual_t *);
156static bool acpiec_resume(device_t, const pmf_qual_t *); 225static bool acpiec_resume(device_t, const pmf_qual_t *);
157static bool acpiec_shutdown(device_t, int); 226static bool acpiec_shutdown(device_t, int);
158 227
159static bool acpiec_parse_gpe_package(device_t, ACPI_HANDLE, 228static bool acpiec_parse_gpe_package(device_t, ACPI_HANDLE,
160 ACPI_HANDLE *, uint8_t *); 229 ACPI_HANDLE *, uint8_t *);
161 230
162static void acpiec_callout(void *); 231static void acpiec_callout(void *);
163static void acpiec_gpe_query(void *); 232static void acpiec_gpe_query(void *);
164static uint32_t acpiec_gpe_handler(ACPI_HANDLE, uint32_t, void *); 233static uint32_t acpiec_gpe_handler(ACPI_HANDLE, uint32_t, void *);
165static ACPI_STATUS acpiec_space_setup(ACPI_HANDLE, uint32_t, void *, void **); 234static ACPI_STATUS acpiec_space_setup(ACPI_HANDLE, uint32_t, void *, void **);
166static ACPI_STATUS acpiec_space_handler(uint32_t, ACPI_PHYSICAL_ADDRESS, 235static ACPI_STATUS acpiec_space_handler(uint32_t, ACPI_PHYSICAL_ADDRESS,
167 uint32_t, ACPI_INTEGER *, void *, void *); 236 uint32_t, ACPI_INTEGER *, void *, void *);
168 237
169static void acpiec_gpe_state_machine(device_t); 238static void acpiec_gpe_state_machine(struct acpiec_softc *);
170 239
171CFATTACH_DECL_NEW(acpiec, sizeof(struct acpiec_softc), 240CFATTACH_DECL_NEW(acpiec, sizeof(struct acpiec_softc),
172 acpiec_match, acpiec_attach, NULL, NULL); 241 acpiec_match, acpiec_attach, NULL, NULL);
173 242
174CFATTACH_DECL_NEW(acpiecdt, sizeof(struct acpiec_softc), 243CFATTACH_DECL_NEW(acpiecdt, sizeof(struct acpiec_softc),
175 acpiecdt_match, acpiecdt_attach, NULL, NULL); 244 acpiecdt_match, acpiecdt_attach, NULL, NULL);
176 245
177static device_t ec_singleton = NULL; 246static device_t ec_singleton = NULL;
178static bool acpiec_cold = false; 247static bool acpiec_cold = false;
179 248
180static bool 249static bool
181acpiecdt_find(device_t parent, ACPI_HANDLE *ec_handle, 250acpiecdt_find(device_t parent, ACPI_HANDLE *ec_handle,
182 bus_addr_t *cmd_reg, bus_addr_t *data_reg, uint8_t *gpebit) 251 bus_addr_t *cmd_reg, bus_addr_t *data_reg, uint8_t *gpebit)
@@ -303,26 +372,28 @@ fail0: if (!pmf_device_register(self, NU @@ -303,26 +372,28 @@ fail0: if (!pmf_device_register(self, NU
303 aprint_error_dev(self, "couldn't establish power handler\n"); 372 aprint_error_dev(self, "couldn't establish power handler\n");
304} 373}
305 374
306static void 375static void
307acpiec_common_attach(device_t parent, device_t self, 376acpiec_common_attach(device_t parent, device_t self,
308 ACPI_HANDLE ec_handle, bus_space_tag_t cmdt, bus_addr_t cmd_reg, 377 ACPI_HANDLE ec_handle, bus_space_tag_t cmdt, bus_addr_t cmd_reg,
309 bus_space_tag_t datat, bus_addr_t data_reg, 378 bus_space_tag_t datat, bus_addr_t data_reg,
310 ACPI_HANDLE gpe_handle, uint8_t gpebit) 379 ACPI_HANDLE gpe_handle, uint8_t gpebit)
311{ 380{
312 struct acpiec_softc *sc = device_private(self); 381 struct acpiec_softc *sc = device_private(self);
313 ACPI_STATUS rv; 382 ACPI_STATUS rv;
314 ACPI_INTEGER val; 383 ACPI_INTEGER val;
315 384
 385 sc->sc_dev = self;
 386
316 sc->sc_csr_st = cmdt; 387 sc->sc_csr_st = cmdt;
317 sc->sc_data_st = datat; 388 sc->sc_data_st = datat;
318 389
319 sc->sc_ech = ec_handle; 390 sc->sc_ech = ec_handle;
320 sc->sc_gpeh = gpe_handle; 391 sc->sc_gpeh = gpe_handle;
321 sc->sc_gpebit = gpebit; 392 sc->sc_gpebit = gpebit;
322 393
323 sc->sc_state = EC_STATE_FREE; 394 sc->sc_state = EC_STATE_FREE;
324 mutex_init(&sc->sc_mtx, MUTEX_DRIVER, IPL_TTY); 395 mutex_init(&sc->sc_mtx, MUTEX_DRIVER, IPL_TTY);
325 mutex_init(&sc->sc_access_mtx, MUTEX_DEFAULT, IPL_NONE); 396 mutex_init(&sc->sc_access_mtx, MUTEX_DEFAULT, IPL_NONE);
326 cv_init(&sc->sc_cv, "eccv"); 397 cv_init(&sc->sc_cv, "eccv");
327 cv_init(&sc->sc_cv_sci, "ecsci"); 398 cv_init(&sc->sc_cv_sci, "ecsci");
328 399
@@ -341,54 +412,54 @@ acpiec_common_attach(device_t parent, de @@ -341,54 +412,54 @@ acpiec_common_attach(device_t parent, de
341 if (rv == AE_OK) { 412 if (rv == AE_OK) {
342 sc->sc_need_global_lock = val != 0; 413 sc->sc_need_global_lock = val != 0;
343 } else if (rv != AE_NOT_FOUND) { 414 } else if (rv != AE_NOT_FOUND) {
344 aprint_error_dev(self, "unable to evaluate _GLK: %s\n", 415 aprint_error_dev(self, "unable to evaluate _GLK: %s\n",
345 AcpiFormatException(rv)); 416 AcpiFormatException(rv));
346 goto post_csr_map; 417 goto post_csr_map;
347 } else { 418 } else {
348 sc->sc_need_global_lock = false; 419 sc->sc_need_global_lock = false;
349 } 420 }
350 if (sc->sc_need_global_lock) 421 if (sc->sc_need_global_lock)
351 aprint_normal_dev(self, "using global ACPI lock\n"); 422 aprint_normal_dev(self, "using global ACPI lock\n");
352 423
353 callout_init(&sc->sc_pseudo_intr, CALLOUT_MPSAFE); 424 callout_init(&sc->sc_pseudo_intr, CALLOUT_MPSAFE);
354 callout_setfunc(&sc->sc_pseudo_intr, acpiec_callout, self); 425 callout_setfunc(&sc->sc_pseudo_intr, acpiec_callout, sc);
355 426
356 rv = AcpiInstallAddressSpaceHandler(sc->sc_ech, ACPI_ADR_SPACE_EC, 427 rv = AcpiInstallAddressSpaceHandler(sc->sc_ech, ACPI_ADR_SPACE_EC,
357 acpiec_space_handler, acpiec_space_setup, self); 428 acpiec_space_handler, acpiec_space_setup, sc);
358 if (rv != AE_OK) { 429 if (rv != AE_OK) {
359 aprint_error_dev(self, 430 aprint_error_dev(self,
360 "unable to install address space handler: %s\n", 431 "unable to install address space handler: %s\n",
361 AcpiFormatException(rv)); 432 AcpiFormatException(rv));
362 goto post_csr_map; 433 goto post_csr_map;
363 } 434 }
364 435
365 rv = AcpiInstallGpeHandler(sc->sc_gpeh, sc->sc_gpebit, 436 rv = AcpiInstallGpeHandler(sc->sc_gpeh, sc->sc_gpebit,
366 ACPI_GPE_EDGE_TRIGGERED, acpiec_gpe_handler, self); 437 ACPI_GPE_EDGE_TRIGGERED, acpiec_gpe_handler, sc);
367 if (rv != AE_OK) { 438 if (rv != AE_OK) {
368 aprint_error_dev(self, "unable to install GPE handler: %s\n", 439 aprint_error_dev(self, "unable to install GPE handler: %s\n",
369 AcpiFormatException(rv)); 440 AcpiFormatException(rv));
370 goto post_csr_map; 441 goto post_csr_map;
371 } 442 }
372 443
373 rv = AcpiEnableGpe(sc->sc_gpeh, sc->sc_gpebit); 444 rv = AcpiEnableGpe(sc->sc_gpeh, sc->sc_gpebit);
374 if (rv != AE_OK) { 445 if (rv != AE_OK) {
375 aprint_error_dev(self, "unable to enable GPE: %s\n", 446 aprint_error_dev(self, "unable to enable GPE: %s\n",
376 AcpiFormatException(rv)); 447 AcpiFormatException(rv));
377 goto post_csr_map; 448 goto post_csr_map;
378 } 449 }
379 450
380 if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, acpiec_gpe_query, 451 if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, acpiec_gpe_query,
381 self, NULL, "acpiec sci thread")) { 452 sc, NULL, "acpiec sci thread")) {
382 aprint_error_dev(self, "unable to create query kthread\n"); 453 aprint_error_dev(self, "unable to create query kthread\n");
383 goto post_csr_map; 454 goto post_csr_map;
384 } 455 }
385 456
386 ec_singleton = self; 457 ec_singleton = self;
387 458
388 if (!pmf_device_register1(self, acpiec_suspend, acpiec_resume, 459 if (!pmf_device_register1(self, acpiec_suspend, acpiec_resume,
389 acpiec_shutdown)) 460 acpiec_shutdown))
390 aprint_error_dev(self, "couldn't establish power handler\n"); 461 aprint_error_dev(self, "couldn't establish power handler\n");
391 462
392 return; 463 return;
393 464
394post_csr_map: 465post_csr_map:
@@ -396,46 +467,68 @@ post_csr_map: @@ -396,46 +467,68 @@ post_csr_map:
396 acpiec_gpe_handler); 467 acpiec_gpe_handler);
397 (void)AcpiRemoveAddressSpaceHandler(sc->sc_ech, 468 (void)AcpiRemoveAddressSpaceHandler(sc->sc_ech,
398 ACPI_ADR_SPACE_EC, acpiec_space_handler); 469 ACPI_ADR_SPACE_EC, acpiec_space_handler);
399 bus_space_unmap(sc->sc_csr_st, sc->sc_csr_sh, 1); 470 bus_space_unmap(sc->sc_csr_st, sc->sc_csr_sh, 1);
400post_data_map: 471post_data_map:
401 bus_space_unmap(sc->sc_data_st, sc->sc_data_sh, 1); 472 bus_space_unmap(sc->sc_data_st, sc->sc_data_sh, 1);
402 if (!pmf_device_register(self, NULL, NULL)) 473 if (!pmf_device_register(self, NULL, NULL))
403 aprint_error_dev(self, "couldn't establish power handler\n"); 474 aprint_error_dev(self, "couldn't establish power handler\n");
404} 475}
405 476
406static bool 477static bool
407acpiec_suspend(device_t dv, const pmf_qual_t *qual) 478acpiec_suspend(device_t dv, const pmf_qual_t *qual)
408{ 479{
 480 struct acpiec_softc *sc = device_private(dv);
409 481
 482 /*
 483 * XXX This looks bad because acpiec_cold is global and
 484 * sc->sc_mtx doesn't look like it's global, but we can have
 485 * only one acpiec(4) device anyway. Maybe acpiec_cold should
 486 * live in the softc to make this look less bad?
 487 *
 488 * XXX Should this block read/write/query transactions until
 489 * resume?
 490 *
 491 * XXX Should this interrupt existing transactions to make them
 492 * fail promptly or restart on resume?
 493 */
 494 mutex_enter(&sc->sc_mtx);
410 acpiec_cold = true; 495 acpiec_cold = true;
 496 mutex_exit(&sc->sc_mtx);
411 497
412 return true; 498 return true;
413} 499}
414 500
415static bool 501static bool
416acpiec_resume(device_t dv, const pmf_qual_t *qual) 502acpiec_resume(device_t dv, const pmf_qual_t *qual)
417{ 503{
 504 struct acpiec_softc *sc = device_private(dv);
418 505
 506 mutex_enter(&sc->sc_mtx);
419 acpiec_cold = false; 507 acpiec_cold = false;
 508 mutex_exit(&sc->sc_mtx);
420 509
421 return true; 510 return true;
422} 511}
423 512
424static bool 513static bool
425acpiec_shutdown(device_t dv, int how) 514acpiec_shutdown(device_t dv, int how)
426{ 515{
 516 struct acpiec_softc *sc = device_private(dv);
427 517
 518 mutex_enter(&sc->sc_mtx);
428 acpiec_cold = true; 519 acpiec_cold = true;
 520 mutex_exit(&sc->sc_mtx);
 521
429 return true; 522 return true;
430} 523}
431 524
432static bool 525static bool
433acpiec_parse_gpe_package(device_t self, ACPI_HANDLE ec_handle, 526acpiec_parse_gpe_package(device_t self, ACPI_HANDLE ec_handle,
434 ACPI_HANDLE *gpe_handle, uint8_t *gpebit) 527 ACPI_HANDLE *gpe_handle, uint8_t *gpebit)
435{ 528{
436 ACPI_BUFFER buf; 529 ACPI_BUFFER buf;
437 ACPI_OBJECT *p, *c; 530 ACPI_OBJECT *p, *c;
438 ACPI_STATUS rv; 531 ACPI_STATUS rv;
439 532
440 rv = acpi_eval_struct(ec_handle, "_GPE", &buf); 533 rv = acpi_eval_struct(ec_handle, "_GPE", &buf);
441 if (rv != AE_OK) { 534 if (rv != AE_OK) {
@@ -481,197 +574,244 @@ acpiec_parse_gpe_package(device_t self,  @@ -481,197 +574,244 @@ acpiec_parse_gpe_package(device_t self,
481 aprint_error_dev(self, 574 aprint_error_dev(self,
482 "_GPE package needs integer as 2nd field\n"); 575 "_GPE package needs integer as 2nd field\n");
483 ACPI_FREE(p); 576 ACPI_FREE(p);
484 return false; 577 return false;
485 } 578 }
486 *gpebit = c->Integer.Value; 579 *gpebit = c->Integer.Value;
487 ACPI_FREE(p); 580 ACPI_FREE(p);
488 return true; 581 return true;
489} 582}
490 583
491static uint8_t 584static uint8_t
492acpiec_read_data(struct acpiec_softc *sc) 585acpiec_read_data(struct acpiec_softc *sc)
493{ 586{
494 return bus_space_read_1(sc->sc_data_st, sc->sc_data_sh, 0); 587 uint8_t x;
 588
 589 KASSERT(mutex_owned(&sc->sc_mtx));
 590
 591 x = bus_space_read_1(sc->sc_data_st, sc->sc_data_sh, 0);
 592 DPRINTF(ACPIEC_DEBUG_REG, sc, "read data=0x%"PRIx8"\n", x);
 593
 594 return x;
495} 595}
496 596
497static void 597static void
498acpiec_write_data(struct acpiec_softc *sc, uint8_t val) 598acpiec_write_data(struct acpiec_softc *sc, uint8_t val)
499{ 599{
 600
 601 KASSERT(mutex_owned(&sc->sc_mtx));
 602
 603 DPRINTF(ACPIEC_DEBUG_REG, sc, "write data=0x%"PRIx8"\n", val);
500 bus_space_write_1(sc->sc_data_st, sc->sc_data_sh, 0, val); 604 bus_space_write_1(sc->sc_data_st, sc->sc_data_sh, 0, val);
501} 605}
502 606
503static uint8_t 607static uint8_t
504acpiec_read_status(struct acpiec_softc *sc) 608acpiec_read_status(struct acpiec_softc *sc)
505{ 609{
506 return bus_space_read_1(sc->sc_csr_st, sc->sc_csr_sh, 0); 610 uint8_t x;
 611
 612 KASSERT(mutex_owned(&sc->sc_mtx));
 613
 614 x = bus_space_read_1(sc->sc_csr_st, sc->sc_csr_sh, 0);
 615 DPRINTF(ACPIEC_DEBUG_REG, sc, "read status=0x%"PRIx8"\n", x);
 616
 617 return x;
507} 618}
508 619
509static void 620static void
510acpiec_write_command(struct acpiec_softc *sc, uint8_t cmd) 621acpiec_write_command(struct acpiec_softc *sc, uint8_t cmd)
511{ 622{
 623
 624 KASSERT(mutex_owned(&sc->sc_mtx));
 625
 626 DPRINTF(ACPIEC_DEBUG_REG, sc, "write command=0x%"PRIx8"\n", cmd);
512 bus_space_write_1(sc->sc_csr_st, sc->sc_csr_sh, 0, cmd); 627 bus_space_write_1(sc->sc_csr_st, sc->sc_csr_sh, 0, cmd);
513} 628}
514 629
515static ACPI_STATUS 630static ACPI_STATUS
516acpiec_space_setup(ACPI_HANDLE region, uint32_t func, void *arg, 631acpiec_space_setup(ACPI_HANDLE region, uint32_t func, void *arg,
517 void **region_arg) 632 void **region_arg)
518{ 633{
519 634
520 if (func == ACPI_REGION_DEACTIVATE) 635 if (func == ACPI_REGION_DEACTIVATE)
521 *region_arg = NULL; 636 *region_arg = NULL;
522 else 637 else
523 *region_arg = arg; 638 *region_arg = arg;
524 639
525 return AE_OK; 640 return AE_OK;
526} 641}
527 642
528static void 643static void
529acpiec_lock(device_t dv) 644acpiec_lock(struct acpiec_softc *sc)
530{ 645{
531 struct acpiec_softc *sc = device_private(dv); 
532 ACPI_STATUS rv; 646 ACPI_STATUS rv;
533 647
534 mutex_enter(&sc->sc_access_mtx); 648 mutex_enter(&sc->sc_access_mtx);
535 649
536 if (sc->sc_need_global_lock) { 650 if (sc->sc_need_global_lock) {
537 rv = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT, 651 rv = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT,
538 &sc->sc_global_lock); 652 &sc->sc_global_lock);
539 if (rv != AE_OK) { 653 if (rv != AE_OK) {
540 aprint_error_dev(dv, 654 aprint_error_dev(sc->sc_dev,
541 "failed to acquire global lock: %s\n", 655 "failed to acquire global lock: %s\n",
542 AcpiFormatException(rv)); 656 AcpiFormatException(rv));
543 return; 657 return;
544 } 658 }
545 } 659 }
546} 660}
547 661
548static void 662static void
549acpiec_unlock(device_t dv) 663acpiec_unlock(struct acpiec_softc *sc)
550{ 664{
551 struct acpiec_softc *sc = device_private(dv); 
552 ACPI_STATUS rv; 665 ACPI_STATUS rv;
553 666
554 if (sc->sc_need_global_lock) { 667 if (sc->sc_need_global_lock) {
555 rv = AcpiReleaseGlobalLock(sc->sc_global_lock); 668 rv = AcpiReleaseGlobalLock(sc->sc_global_lock);
556 if (rv != AE_OK) { 669 if (rv != AE_OK) {
557 aprint_error_dev(dv, 670 aprint_error_dev(sc->sc_dev,
558 "failed to release global lock: %s\n", 671 "failed to release global lock: %s\n",
559 AcpiFormatException(rv)); 672 AcpiFormatException(rv));
560 } 673 }
561 } 674 }
562 mutex_exit(&sc->sc_access_mtx); 675 mutex_exit(&sc->sc_access_mtx);
563} 676}
564 677
565static ACPI_STATUS 678static ACPI_STATUS
566acpiec_read(device_t dv, uint8_t addr, uint8_t *val) 679acpiec_wait_timeout(struct acpiec_softc *sc)
567{ 680{
568 struct acpiec_softc *sc = device_private(dv); 681 device_t dv = sc->sc_dev;
569 int i, timeo = 1000 * EC_CMD_TIMEOUT; 682 int i;
570 
571 acpiec_lock(dv); 
572 mutex_enter(&sc->sc_mtx); 
573 
574 sc->sc_cur_addr = addr; 
575 sc->sc_state = EC_STATE_READ; 
576 683
577 for (i = 0; i < EC_POLL_TIMEOUT; ++i) { 684 for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
578 acpiec_gpe_state_machine(dv); 685 acpiec_gpe_state_machine(sc);
579 if (sc->sc_state == EC_STATE_FREE) 686 if (sc->sc_state == EC_STATE_FREE)
580 goto done; 687 return AE_OK;
581 delay(1); 688 delay(1);
582 } 689 }
583 690
 691 DPRINTF(ACPIEC_DEBUG_RW, sc, "SCI polling timeout\n");
584 if (cold || acpiec_cold) { 692 if (cold || acpiec_cold) {
 693 int timeo = 1000 * EC_CMD_TIMEOUT;
 694
585 while (sc->sc_state != EC_STATE_FREE && timeo-- > 0) { 695 while (sc->sc_state != EC_STATE_FREE && timeo-- > 0) {
586 delay(1000); 696 delay(1000);
587 acpiec_gpe_state_machine(dv); 697 acpiec_gpe_state_machine(sc);
588 } 698 }
589 if (sc->sc_state != EC_STATE_FREE) { 699 if (sc->sc_state != EC_STATE_FREE) {
590 mutex_exit(&sc->sc_mtx); 
591 acpiec_unlock(dv); 
592 aprint_error_dev(dv, "command timed out, state %d\n", 700 aprint_error_dev(dv, "command timed out, state %d\n",
593 sc->sc_state); 701 sc->sc_state);
594 return AE_ERROR; 702 return AE_ERROR;
595 } 703 }
596 } else if (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) { 704 } else {
597 mutex_exit(&sc->sc_mtx); 705 const unsigned deadline = getticks() + EC_CMD_TIMEOUT*hz;
598 acpiec_unlock(dv); 706 unsigned delta;
599 aprint_error_dev(dv, 707
600 "command takes over %d sec...\n", EC_CMD_TIMEOUT); 708 while (sc->sc_state != EC_STATE_FREE &&
601 return AE_ERROR; 709 (delta = deadline - getticks()) < INT_MAX)
 710 (void)cv_timedwait(&sc->sc_cv, &sc->sc_mtx, delta);
 711 if (sc->sc_state != EC_STATE_FREE) {
 712 aprint_error_dev(dv,
 713 "command takes over %d sec...\n",
 714 EC_CMD_TIMEOUT);
 715 return AE_ERROR;
 716 }
602 } 717 }
603 718
604done: 719 return AE_OK;
 720}
 721
 722static ACPI_STATUS
 723acpiec_read(struct acpiec_softc *sc, uint8_t addr, uint8_t *val)
 724{
 725 ACPI_STATUS rv;
 726
 727 acpiec_lock(sc);
 728 mutex_enter(&sc->sc_mtx);
 729
 730 DPRINTF(ACPIEC_DEBUG_RW, sc,
 731 "pid %ld %s, lid %ld%s%s: read addr 0x%"PRIx8"\n",
 732 (long)curproc->p_pid, curproc->p_comm,
 733 (long)curlwp->l_lid, curlwp->l_name ? " " : "",
 734 curlwp->l_name ? curlwp->l_name : "",
 735 addr);
 736
 737 KASSERT(sc->sc_state == EC_STATE_FREE);
 738
 739 sc->sc_cur_addr = addr;
 740 sc->sc_state = EC_STATE_READ;
 741
 742 rv = acpiec_wait_timeout(sc);
 743 if (ACPI_FAILURE(rv))
 744 goto out;
 745
 746 DPRINTF(ACPIEC_DEBUG_RW, sc,
 747 "pid %ld %s, lid %ld%s%s: read addr 0x%"PRIx8": 0x%"PRIx8"\n",
 748 (long)curproc->p_pid, curproc->p_comm,
 749 (long)curlwp->l_lid, curlwp->l_name ? " " : "",
 750 curlwp->l_name ? curlwp->l_name : "",
 751 addr, sc->sc_cur_val);
 752
605 *val = sc->sc_cur_val; 753 *val = sc->sc_cur_val;
606 754
607 mutex_exit(&sc->sc_mtx); 755out: mutex_exit(&sc->sc_mtx);
608 acpiec_unlock(dv); 756 acpiec_unlock(sc);
609 return AE_OK; 757 return rv;
610} 758}
611 759
612static ACPI_STATUS 760static ACPI_STATUS
613acpiec_write(device_t dv, uint8_t addr, uint8_t val) 761acpiec_write(struct acpiec_softc *sc, uint8_t addr, uint8_t val)
614{ 762{
615 struct acpiec_softc *sc = device_private(dv); 763 ACPI_STATUS rv;
616 int i, timeo = 1000 * EC_CMD_TIMEOUT; 
617 764
618 acpiec_lock(dv); 765 acpiec_lock(sc);
619 mutex_enter(&sc->sc_mtx); 766 mutex_enter(&sc->sc_mtx);
620 767
 768 DPRINTF(ACPIEC_DEBUG_RW, sc,
 769 "pid %ld %s, lid %ld%s%s write addr 0x%"PRIx8": 0x%"PRIx8"\n",
 770 (long)curproc->p_pid, curproc->p_comm,
 771 (long)curlwp->l_lid, curlwp->l_name ? " " : "",
 772 curlwp->l_name ? curlwp->l_name : "",
 773 addr, val);
 774
 775 KASSERT(sc->sc_state == EC_STATE_FREE);
 776
621 sc->sc_cur_addr = addr; 777 sc->sc_cur_addr = addr;
622 sc->sc_cur_val = val; 778 sc->sc_cur_val = val;
623 sc->sc_state = EC_STATE_WRITE; 779 sc->sc_state = EC_STATE_WRITE;
624 780
625 for (i = 0; i < EC_POLL_TIMEOUT; ++i) { 781 rv = acpiec_wait_timeout(sc);
626 acpiec_gpe_state_machine(dv); 782 if (ACPI_FAILURE(rv))
627 if (sc->sc_state == EC_STATE_FREE) 783 goto out;
628 goto done; 
629 delay(1); 
630 } 
631 784
632 if (cold || acpiec_cold) { 785 DPRINTF(ACPIEC_DEBUG_RW, sc,
633 while (sc->sc_state != EC_STATE_FREE && timeo-- > 0) { 786 "pid %ld %s, lid %ld%s%s: write addr 0x%"PRIx8": 0x%"PRIx8
634 delay(1000); 787 " done\n",
635 acpiec_gpe_state_machine(dv); 788 (long)curproc->p_pid, curproc->p_comm,
636 } 789 (long)curlwp->l_lid, curlwp->l_name ? " " : "",
637 if (sc->sc_state != EC_STATE_FREE) { 790 curlwp->l_name ? curlwp->l_name : "",
638 mutex_exit(&sc->sc_mtx); 791 addr, val);
639 acpiec_unlock(dv); 
640 aprint_error_dev(dv, "command timed out, state %d\n", 
641 sc->sc_state); 
642 return AE_ERROR; 
643 } 
644 } else if (cv_timedwait(&sc->sc_cv, &sc->sc_mtx, EC_CMD_TIMEOUT * hz)) { 
645 mutex_exit(&sc->sc_mtx); 
646 acpiec_unlock(dv); 
647 aprint_error_dev(dv, 
648 "command takes over %d sec...\n", EC_CMD_TIMEOUT); 
649 return AE_ERROR; 
650 } 
651 792
652done: 793out: mutex_exit(&sc->sc_mtx);
653 mutex_exit(&sc->sc_mtx); 794 acpiec_unlock(sc);
654 acpiec_unlock(dv); 795 return rv;
655 return AE_OK; 
656} 796}
657 797
658/* 798/*
659 * acpiec_space_handler(func, paddr, bitwidth, value, arg, region_arg) 799 * acpiec_space_handler(func, paddr, bitwidth, value, arg, region_arg)
660 * 800 *
661 * Transfer bitwidth/8 bytes of data between paddr and *value: 801 * Transfer bitwidth/8 bytes of data between paddr and *value:
662 * from paddr to *value when func is ACPI_READ, and the other way 802 * from paddr to *value when func is ACPI_READ, and the other way
663 * when func is ACPI_WRITE. arg is the acpiec(4) or acpiecdt(4) 803 * when func is ACPI_WRITE. arg is the acpiec_softc pointer.
664 * device. region_arg is ignored (XXX why? determined by 804 * region_arg is ignored (XXX why? determined by
665 * acpiec_space_setup but never used by anything that I can see). 805 * acpiec_space_setup but never used by anything that I can see).
666 * 806 *
667 * The caller always provides storage at *value large enough for 807 * The caller always provides storage at *value large enough for
668 * an ACPI_INTEGER object, i.e., a 64-bit integer. However, 808 * an ACPI_INTEGER object, i.e., a 64-bit integer. However,
669 * bitwidth may be larger; in this case the caller provides larger 809 * bitwidth may be larger; in this case the caller provides larger
670 * storage at *value, e.g. 128 bits as documented in 810 * storage at *value, e.g. 128 bits as documented in
671 * <https://gnats.netbsd.org/55206>. 811 * <https://gnats.netbsd.org/55206>.
672 * 812 *
673 * On reads, this fully initializes one ACPI_INTEGER's worth of 813 * On reads, this fully initializes one ACPI_INTEGER's worth of
674 * data at *value, even if bitwidth < 64. The integer is 814 * data at *value, even if bitwidth < 64. The integer is
675 * interpreted in host byte order; in other words, bytes of data 815 * interpreted in host byte order; in other words, bytes of data
676 * are transferred in order between paddr and (uint8_t *)value. 816 * are transferred in order between paddr and (uint8_t *)value.
677 * The transfer is not atomic; it may go byte-by-byte. 817 * The transfer is not atomic; it may go byte-by-byte.
@@ -681,247 +821,298 @@ done: @@ -681,247 +821,298 @@ done:
681 * in the low-order bits of the result. A big-endian system could 821 * in the low-order bits of the result. A big-endian system could
682 * read a 64-bit integer in big-endian (and it did for a while!), 822 * read a 64-bit integer in big-endian (and it did for a while!),
683 * but what should it do for larger reads? Unclear! 823 * but what should it do for larger reads? Unclear!
684 * 824 *
685 * XXX It's not clear whether the object at *value is always 825 * XXX It's not clear whether the object at *value is always
686 * _aligned_ adequately for an ACPI_INTEGER object. Currently it 826 * _aligned_ adequately for an ACPI_INTEGER object. Currently it
687 * always is as long as malloc, used by AcpiOsAllocate, returns 827 * always is as long as malloc, used by AcpiOsAllocate, returns
688 * 64-bit-aligned data. 828 * 64-bit-aligned data.
689 */ 829 */
690static ACPI_STATUS 830static ACPI_STATUS
691acpiec_space_handler(uint32_t func, ACPI_PHYSICAL_ADDRESS paddr, 831acpiec_space_handler(uint32_t func, ACPI_PHYSICAL_ADDRESS paddr,
692 uint32_t width, ACPI_INTEGER *value, void *arg, void *region_arg) 832 uint32_t width, ACPI_INTEGER *value, void *arg, void *region_arg)
693{ 833{
694 device_t dv; 834 struct acpiec_softc *sc = arg;
695 ACPI_STATUS rv; 835 ACPI_STATUS rv;
696 uint8_t addr, *buf; 836 uint8_t addr, *buf;
697 unsigned int i; 837 unsigned int i;
698 838
699 if (paddr > 0xff || width % 8 != 0 || 839 if (paddr > 0xff || width % 8 != 0 ||
700 value == NULL || arg == NULL || paddr + width / 8 > 0x100) 840 value == NULL || arg == NULL || paddr + width / 8 > 0x100)
701 return AE_BAD_PARAMETER; 841 return AE_BAD_PARAMETER;
702 842
703 addr = paddr; 843 addr = paddr;
704 dv = arg; 
705 buf = (uint8_t *)value; 844 buf = (uint8_t *)value;
706 845
707 rv = AE_OK; 846 rv = AE_OK;
708 847
709 switch (func) { 848 switch (func) {
710 case ACPI_READ: 849 case ACPI_READ:
711 for (i = 0; i < width; i += 8, ++addr, ++buf) { 850 for (i = 0; i < width; i += 8, ++addr, ++buf) {
712 rv = acpiec_read(dv, addr, buf); 851 rv = acpiec_read(sc, addr, buf);
713 if (rv != AE_OK) 852 if (rv != AE_OK)
714 break; 853 break;
715 } 854 }
716 /* 855 /*
717 * Make sure to fully initialize at least an 856 * Make sure to fully initialize at least an
718 * ACPI_INTEGER-sized object. 857 * ACPI_INTEGER-sized object.
719 */ 858 */
720 for (; i < sizeof(*value)*8; i += 8, ++buf) 859 for (; i < sizeof(*value)*8; i += 8, ++buf)
721 *buf = 0; 860 *buf = 0;
722 break; 861 break;
723 case ACPI_WRITE: 862 case ACPI_WRITE:
724 for (i = 0; i < width; i += 8, ++addr, ++buf) { 863 for (i = 0; i < width; i += 8, ++addr, ++buf) {
725 rv = acpiec_write(dv, addr, *buf); 864 rv = acpiec_write(sc, addr, *buf);
726 if (rv != AE_OK) 865 if (rv != AE_OK)
727 break; 866 break;
728 } 867 }
729 break; 868 break;
730 default: 869 default:
731 aprint_error("%s: invalid Address Space function called: %x\n", 870 aprint_error_dev(sc->sc_dev,
732 device_xname(dv), (unsigned int)func); 871 "invalid Address Space function called: %x\n",
 872 (unsigned int)func);
733 return AE_BAD_PARAMETER; 873 return AE_BAD_PARAMETER;
734 } 874 }
735 875
736 return rv; 876 return rv;
737} 877}
738 878
739static void 879static void
 880acpiec_wait(struct acpiec_softc *sc)
 881{
 882 int i;
 883
 884 /*
 885 * First, attempt to get the query by polling.
 886 */
 887 for (i = 0; i < EC_POLL_TIMEOUT; ++i) {
 888 acpiec_gpe_state_machine(sc);
 889 if (sc->sc_state == EC_STATE_FREE)
 890 return;
 891 delay(1);
 892 }
 893
 894 /*
 895 * Polling timed out. Try waiting for interrupts -- either GPE
 896 * interrupts, or periodic callouts in case GPE interrupts are
 897 * broken.
 898 */
 899 DPRINTF(ACPIEC_DEBUG_QUERY, sc, "SCI polling timeout\n");
 900 while (sc->sc_state != EC_STATE_FREE)
 901 cv_wait(&sc->sc_cv, &sc->sc_mtx);
 902}
 903
 904static void
740acpiec_gpe_query(void *arg) 905acpiec_gpe_query(void *arg)
741{ 906{
742 device_t dv = arg; 907 struct acpiec_softc *sc = arg;
743 struct acpiec_softc *sc = device_private(dv); 
744 uint8_t reg; 908 uint8_t reg;
745 char qxx[5]; 909 char qxx[5];
746 ACPI_STATUS rv; 910 ACPI_STATUS rv;
747 int i; 
748 911
749loop: 912loop:
 913 /*
 914 * Wait until the EC sends an SCI requesting a query.
 915 */
750 mutex_enter(&sc->sc_mtx); 916 mutex_enter(&sc->sc_mtx);
751 917 while (!sc->sc_got_sci)
752 if (sc->sc_got_sci == false) 
753 cv_wait(&sc->sc_cv_sci, &sc->sc_mtx); 918 cv_wait(&sc->sc_cv_sci, &sc->sc_mtx);
 919 DPRINTF(ACPIEC_DEBUG_QUERY, sc, "SCI query requested\n");
754 mutex_exit(&sc->sc_mtx); 920 mutex_exit(&sc->sc_mtx);
755 921
756 acpiec_lock(dv); 922 /*
 923 * EC wants to submit a query to us. Exclude concurrent reads
 924 * and writes while we handle it.
 925 */
 926 acpiec_lock(sc);
757 mutex_enter(&sc->sc_mtx); 927 mutex_enter(&sc->sc_mtx);
758 928
 929 DPRINTF(ACPIEC_DEBUG_QUERY, sc, "SCI query\n");
 930
 931 KASSERT(sc->sc_state == EC_STATE_FREE);
 932
759 /* The Query command can always be issued, so be defensive here. */ 933 /* The Query command can always be issued, so be defensive here. */
 934 KASSERT(sc->sc_got_sci);
760 sc->sc_got_sci = false; 935 sc->sc_got_sci = false;
761 sc->sc_state = EC_STATE_QUERY; 936 sc->sc_state = EC_STATE_QUERY;
762 937
763 for (i = 0; i < EC_POLL_TIMEOUT; ++i) { 938 acpiec_wait(sc);
764 acpiec_gpe_state_machine(dv); 
765 if (sc->sc_state == EC_STATE_FREE) 
766 goto done; 
767 delay(1); 
768 } 
769 
770 cv_wait(&sc->sc_cv, &sc->sc_mtx); 
771 939
772done: 
773 reg = sc->sc_cur_val; 940 reg = sc->sc_cur_val;
 941 DPRINTF(ACPIEC_DEBUG_QUERY, sc, "SCI query: 0x%"PRIx8"\n", reg);
774 942
775 mutex_exit(&sc->sc_mtx); 943 mutex_exit(&sc->sc_mtx);
776 acpiec_unlock(dv); 944 acpiec_unlock(sc);
777 945
778 if (reg == 0) 946 if (reg == 0)
779 goto loop; /* Spurious query result */ 947 goto loop; /* Spurious query result */
780 948
781 /* 949 /*
782 * Evaluate _Qxx to respond to the controller. 950 * Evaluate _Qxx to respond to the controller.
783 */ 951 */
784 snprintf(qxx, sizeof(qxx), "_Q%02X", (unsigned int)reg); 952 snprintf(qxx, sizeof(qxx), "_Q%02X", (unsigned int)reg);
785 rv = AcpiEvaluateObject(sc->sc_ech, qxx, NULL, NULL); 953 rv = AcpiEvaluateObject(sc->sc_ech, qxx, NULL, NULL);
786 if (rv != AE_OK && rv != AE_NOT_FOUND) { 954 if (rv != AE_OK && rv != AE_NOT_FOUND) {
787 aprint_error_dev(dv, "GPE query method %s failed: %s", 955 aprint_error_dev(sc->sc_dev, "GPE query method %s failed: %s",
788 qxx, AcpiFormatException(rv)); 956 qxx, AcpiFormatException(rv));
789 } 957 }
790 958
791 goto loop; 959 goto loop;
792} 960}
793 961
794static void 962static void
795acpiec_gpe_state_machine(device_t dv) 963acpiec_gpe_state_machine(struct acpiec_softc *sc)
796{ 964{
797 struct acpiec_softc *sc = device_private(dv); 
798 uint8_t reg; 965 uint8_t reg;
799 966
 967 KASSERT(mutex_owned(&sc->sc_mtx));
 968
800 reg = acpiec_read_status(sc); 969 reg = acpiec_read_status(sc);
801 970
802 if (reg & EC_STATUS_SCI) 971#ifdef ACPIEC_DEBUG
803 sc->sc_got_sci = true; 972 if (acpiec_debug & __BIT(ACPIEC_DEBUG_TRANSITION)) {
 973 char buf[128];
 974
 975 snprintb(buf, sizeof(buf), EC_STATUS_FMT, reg);
 976 DPRINTF(ACPIEC_DEBUG_TRANSITION, sc, "%s\n", buf);
 977 }
 978#endif
804 979
805 switch (sc->sc_state) { 980 switch (sc->sc_state) {
806 case EC_STATE_QUERY: 981 case EC_STATE_QUERY:
807 if ((reg & EC_STATUS_IBF) != 0) 982 if ((reg & EC_STATUS_IBF) != 0)
808 break; /* Nothing of interest here. */ 983 break; /* Nothing of interest here. */
809 acpiec_write_command(sc, EC_COMMAND_QUERY); 984 acpiec_write_command(sc, EC_COMMAND_QUERY);
810 sc->sc_state = EC_STATE_QUERY_VAL; 985 sc->sc_state = EC_STATE_QUERY_VAL;
811 break; 986 break;
812 987
813 case EC_STATE_QUERY_VAL: 988 case EC_STATE_QUERY_VAL:
814 if ((reg & EC_STATUS_OBF) == 0) 989 if ((reg & EC_STATUS_OBF) == 0)
815 break; /* Nothing of interest here. */ 990 break; /* Nothing of interest here. */
816 
817 sc->sc_cur_val = acpiec_read_data(sc); 991 sc->sc_cur_val = acpiec_read_data(sc);
818 sc->sc_state = EC_STATE_FREE; 992 sc->sc_state = EC_STATE_FREE;
819 
820 cv_signal(&sc->sc_cv); 
821 break; 993 break;
822 994
823 case EC_STATE_READ: 995 case EC_STATE_READ:
824 if ((reg & EC_STATUS_IBF) != 0) 996 if ((reg & EC_STATUS_IBF) != 0)
825 break; /* Nothing of interest here. */ 997 break; /* Nothing of interest here. */
826 
827 acpiec_write_command(sc, EC_COMMAND_READ); 998 acpiec_write_command(sc, EC_COMMAND_READ);
828 sc->sc_state = EC_STATE_READ_ADDR; 999 sc->sc_state = EC_STATE_READ_ADDR;
829 break; 1000 break;
830 1001
831 case EC_STATE_READ_ADDR: 1002 case EC_STATE_READ_ADDR:
832 if ((reg & EC_STATUS_IBF) != 0) 1003 if ((reg & EC_STATUS_IBF) != 0)
833 break; /* Nothing of interest here. */ 1004 break; /* Nothing of interest here. */
834 
835 acpiec_write_data(sc, sc->sc_cur_addr); 1005 acpiec_write_data(sc, sc->sc_cur_addr);
836 sc->sc_state = EC_STATE_READ_VAL; 1006 sc->sc_state = EC_STATE_READ_VAL;
837 break; 1007 break;
838 1008
839 case EC_STATE_READ_VAL: 1009 case EC_STATE_READ_VAL:
840 if ((reg & EC_STATUS_OBF) == 0) 1010 if ((reg & EC_STATUS_OBF) == 0)
841 break; /* Nothing of interest here. */ 1011 break; /* Nothing of interest here. */
842 sc->sc_cur_val = acpiec_read_data(sc); 1012 sc->sc_cur_val = acpiec_read_data(sc);
843 sc->sc_state = EC_STATE_FREE; 1013 sc->sc_state = EC_STATE_FREE;
844 
845 cv_signal(&sc->sc_cv); 
846 break; 1014 break;
847 1015
848 case EC_STATE_WRITE: 1016 case EC_STATE_WRITE:
849 if ((reg & EC_STATUS_IBF) != 0) 1017 if ((reg & EC_STATUS_IBF) != 0)
850 break; /* Nothing of interest here. */ 1018 break; /* Nothing of interest here. */
851 
852 acpiec_write_command(sc, EC_COMMAND_WRITE); 1019 acpiec_write_command(sc, EC_COMMAND_WRITE);
853 sc->sc_state = EC_STATE_WRITE_ADDR; 1020 sc->sc_state = EC_STATE_WRITE_ADDR;
854 break; 1021 break;
855 1022
856 case EC_STATE_WRITE_ADDR: 1023 case EC_STATE_WRITE_ADDR:
857 if ((reg & EC_STATUS_IBF) != 0) 1024 if ((reg & EC_STATUS_IBF) != 0)
858 break; /* Nothing of interest here. */ 1025 break; /* Nothing of interest here. */
859 acpiec_write_data(sc, sc->sc_cur_addr); 1026 acpiec_write_data(sc, sc->sc_cur_addr);
860 sc->sc_state = EC_STATE_WRITE_VAL; 1027 sc->sc_state = EC_STATE_WRITE_VAL;
861 break; 1028 break;
862 1029
863 case EC_STATE_WRITE_VAL: 1030 case EC_STATE_WRITE_VAL:
864 if ((reg & EC_STATUS_IBF) != 0) 1031 if ((reg & EC_STATUS_IBF) != 0)
865 break; /* Nothing of interest here. */ 1032 break; /* Nothing of interest here. */
866 sc->sc_state = EC_STATE_FREE; 
867 cv_signal(&sc->sc_cv); 
868 
869 acpiec_write_data(sc, sc->sc_cur_val); 1033 acpiec_write_data(sc, sc->sc_cur_val);
 1034 sc->sc_state = EC_STATE_FREE;
870 break; 1035 break;
871 1036
872 case EC_STATE_FREE: 1037 case EC_STATE_FREE:
873 if (sc->sc_got_sci) 
874 cv_signal(&sc->sc_cv_sci); 
875 break; 1038 break;
 1039
876 default: 1040 default:
877 panic("invalid state"); 1041 panic("invalid state");
878 } 1042 }
879 1043
880 if (sc->sc_state != EC_STATE_FREE) 1044 /*
 1045 * If we are not in a transaction, wake anyone waiting to start
 1046 * one. If an SCI was requested, notify the SCI thread that it
 1047 * needs to handle the SCI.
 1048 */
 1049 if (sc->sc_state == EC_STATE_FREE) {
 1050 cv_signal(&sc->sc_cv);
 1051 if (reg & EC_STATUS_SCI) {
 1052 DPRINTF(ACPIEC_DEBUG_TRANSITION, sc,
 1053 "wake SCI thread\n");
 1054 sc->sc_got_sci = true;
 1055 cv_signal(&sc->sc_cv_sci);
 1056 }
 1057 }
 1058
 1059 /*
 1060 * In case GPE interrupts are broken, poll once per tick for EC
 1061 * status updates while a transaction is still pending.
 1062 */
 1063 if (sc->sc_state != EC_STATE_FREE) {
 1064 DPRINTF(ACPIEC_DEBUG_INTR, sc, "schedule callout\n");
881 callout_schedule(&sc->sc_pseudo_intr, 1); 1065 callout_schedule(&sc->sc_pseudo_intr, 1);
 1066 }
 1067
 1068 DPRINTF(ACPIEC_DEBUG_TRANSITION, sc, "return\n");
882} 1069}
883 1070
884static void 1071static void
885acpiec_callout(void *arg) 1072acpiec_callout(void *arg)
886{ 1073{
887 device_t dv = arg; 1074 struct acpiec_softc *sc = arg;
888 struct acpiec_softc *sc = device_private(dv); 
889 1075
890 mutex_enter(&sc->sc_mtx); 1076 mutex_enter(&sc->sc_mtx);
891 acpiec_gpe_state_machine(dv); 1077 DPRINTF(ACPIEC_DEBUG_INTR, sc, "callout\n");
 1078 acpiec_gpe_state_machine(sc);
892 mutex_exit(&sc->sc_mtx); 1079 mutex_exit(&sc->sc_mtx);
893} 1080}
894 1081
895static uint32_t 1082static uint32_t
896acpiec_gpe_handler(ACPI_HANDLE hdl, uint32_t gpebit, void *arg) 1083acpiec_gpe_handler(ACPI_HANDLE hdl, uint32_t gpebit, void *arg)
897{ 1084{
898 device_t dv = arg; 1085 struct acpiec_softc *sc = arg;
899 struct acpiec_softc *sc = device_private(dv); 
900 1086
901 mutex_enter(&sc->sc_mtx); 1087 mutex_enter(&sc->sc_mtx);
902 acpiec_gpe_state_machine(dv); 1088 DPRINTF(ACPIEC_DEBUG_INTR, sc, "GPE\n");
 1089 acpiec_gpe_state_machine(sc);
903 mutex_exit(&sc->sc_mtx); 1090 mutex_exit(&sc->sc_mtx);
904 1091
905 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; 1092 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
906} 1093}
907 1094
908ACPI_STATUS 1095ACPI_STATUS
909acpiec_bus_read(device_t dv, u_int addr, ACPI_INTEGER *val, int width) 1096acpiec_bus_read(device_t dv, u_int addr, ACPI_INTEGER *val, int width)
910{ 1097{
911 return acpiec_space_handler(ACPI_READ, addr, width * 8, val, dv, NULL); 1098 struct acpiec_softc *sc = device_private(dv);
 1099
 1100 return acpiec_space_handler(ACPI_READ, addr, width * 8, val, sc, NULL);
912} 1101}
913 1102
914ACPI_STATUS 1103ACPI_STATUS
915acpiec_bus_write(device_t dv, u_int addr, ACPI_INTEGER val, int width) 1104acpiec_bus_write(device_t dv, u_int addr, ACPI_INTEGER val, int width)
916{ 1105{
917 return acpiec_space_handler(ACPI_WRITE, addr, width * 8, &val, dv, 1106 struct acpiec_softc *sc = device_private(dv);
 1107
 1108 return acpiec_space_handler(ACPI_WRITE, addr, width * 8, &val, sc,
918 NULL); 1109 NULL);
919} 1110}
920 1111
921ACPI_HANDLE 1112ACPI_HANDLE
922acpiec_get_handle(device_t dv) 1113acpiec_get_handle(device_t dv)
923{ 1114{
924 struct acpiec_softc *sc = device_private(dv); 1115 struct acpiec_softc *sc = device_private(dv);
925 1116
926 return sc->sc_ech; 1117 return sc->sc_ech;
927} 1118}

cvs diff -r1.126 -r1.126.4.1 src/sys/dev/acpi/files.acpi (expand / switch to unified diff)

--- src/sys/dev/acpi/files.acpi 2022/05/26 02:16:44 1.126
+++ src/sys/dev/acpi/files.acpi 2023/07/30 12:01:53 1.126.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: files.acpi,v 1.126 2022/05/26 02:16:44 mrg Exp $ 1# $NetBSD: files.acpi,v 1.126.4.1 2023/07/30 12:01:53 martin Exp $
2 2
3defflag opt_acpi.h ACPIVERBOSE ACPI_DEBUG ACPI_ACTIVATE_DEV 3defflag opt_acpi.h ACPIVERBOSE ACPI_DEBUG ACPI_ACTIVATE_DEV
4 ACPI_DSDT_OVERRIDE ACPI_SCANPCI ACPI_BREAKPOINT 4 ACPI_DSDT_OVERRIDE ACPI_SCANPCI ACPI_BREAKPOINT
5 ACPI_REDUCED_HW ACPI__DIS_IS_BROKEN 5 ACPI_REDUCED_HW ACPI__DIS_IS_BROKEN
6defparam opt_acpi.h ACPI_DSDT_FILE := "\"/dev/null\"" 6defparam opt_acpi.h ACPI_DSDT_FILE := "\"/dev/null\""
7defparam opt_acpi.h ACPI_BLACKLIST_YEAR = 2000 7defparam opt_acpi.h ACPI_BLACKLIST_YEAR = 2000
8 8
9define acpiapmbus { } 9define acpiapmbus { }
10define acpinodebus { } 10define acpinodebus { }
11define acpiecdtbus { } 11define acpiecdtbus { }
12define acpihpetbus { } 12define acpihpetbus { }
13define acpiwdrtbus { } 13define acpiwdrtbus { }
14define acpisdtbus { } 14define acpisdtbus { }
@@ -35,26 +35,27 @@ file dev/acpi/acpi_usb.c acpi @@ -35,26 +35,27 @@ file dev/acpi/acpi_usb.c acpi
35file dev/acpi/acpi_util.c acpi 35file dev/acpi/acpi_util.c acpi
36file dev/acpi/acpi_wakedev.c acpi 36file dev/acpi/acpi_wakedev.c acpi
37file dev/acpi/acpi_verbose.c acpi & acpiverbose 37file dev/acpi/acpi_verbose.c acpi & acpiverbose
38 38
39# ACPI/apm emulation. 39# ACPI/apm emulation.
40attach apm at acpiapmbus with acpiapm: sysmon_envsys 40attach apm at acpiapmbus with acpiapm: sysmon_envsys
41file dev/acpi/acpi_apm.c acpiapm 41file dev/acpi/acpi_apm.c acpiapm
42 42
43# ACPI Embedded Controller 43# ACPI Embedded Controller
44device acpiec 44device acpiec
45attach acpiec at acpinodebus 45attach acpiec at acpinodebus
46device acpiecdt 46device acpiecdt
47attach acpiecdt at acpiecdtbus 47attach acpiecdt at acpiecdtbus
 48defparam opt_acpi_ec.h ACPIEC_DEBUG
48file dev/acpi/acpi_ec.c acpiec|acpiecdt 49file dev/acpi/acpi_ec.c acpiec|acpiecdt
49 50
50# ACPI Lid Switch 51# ACPI Lid Switch
51device acpilid: sysmon_power 52device acpilid: sysmon_power
52attach acpilid at acpinodebus 53attach acpilid at acpinodebus
53file dev/acpi/acpi_lid.c acpilid 54file dev/acpi/acpi_lid.c acpilid
54 55
55# ACPI Button 56# ACPI Button
56device acpibut: sysmon_power 57device acpibut: sysmon_power
57attach acpibut at acpinodebus 58attach acpibut at acpinodebus
58file dev/acpi/acpi_button.c acpibut 59file dev/acpi/acpi_button.c acpibut
59 60
60# ACPI AC Adapter 61# ACPI AC Adapter