Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/acpica/acpi_ec.c
39536 views
1
/*-
2
* Copyright (c) 2003-2007 Nate Lawson
3
* Copyright (c) 2000 Michael Smith
4
* Copyright (c) 2000 BSDi
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
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/cdefs.h>
30
#include "opt_acpi.h"
31
#include <sys/param.h>
32
#include <sys/kernel.h>
33
#include <sys/ktr.h>
34
#include <sys/bus.h>
35
#include <sys/lock.h>
36
#include <sys/malloc.h>
37
#include <sys/module.h>
38
#include <sys/sx.h>
39
40
#include <machine/bus.h>
41
#include <machine/resource.h>
42
#include <sys/rman.h>
43
44
#include <contrib/dev/acpica/include/acpi.h>
45
#include <contrib/dev/acpica/include/accommon.h>
46
47
#include <dev/acpica/acpivar.h>
48
49
/* Hooks for the ACPI CA debugging infrastructure */
50
#define _COMPONENT ACPI_EC
51
ACPI_MODULE_NAME("EC")
52
53
/*
54
* EC_COMMAND:
55
* -----------
56
*/
57
typedef UINT8 EC_COMMAND;
58
59
#define EC_COMMAND_UNKNOWN ((EC_COMMAND) 0x00)
60
#define EC_COMMAND_READ ((EC_COMMAND) 0x80)
61
#define EC_COMMAND_WRITE ((EC_COMMAND) 0x81)
62
#define EC_COMMAND_BURST_ENABLE ((EC_COMMAND) 0x82)
63
#define EC_COMMAND_BURST_DISABLE ((EC_COMMAND) 0x83)
64
#define EC_COMMAND_QUERY ((EC_COMMAND) 0x84)
65
66
/*
67
* EC_STATUS:
68
* ----------
69
* The encoding of the EC status register is illustrated below.
70
* Note that a set bit (1) indicates the property is TRUE
71
* (e.g. if bit 0 is set then the output buffer is full).
72
* +-+-+-+-+-+-+-+-+
73
* |7|6|5|4|3|2|1|0|
74
* +-+-+-+-+-+-+-+-+
75
* | | | | | | | |
76
* | | | | | | | +- Output Buffer Full?
77
* | | | | | | +--- Input Buffer Full?
78
* | | | | | +----- <reserved>
79
* | | | | +------- Data Register is Command Byte?
80
* | | | +--------- Burst Mode Enabled?
81
* | | +----------- SCI Event?
82
* | +------------- SMI Event?
83
* +--------------- <reserved>
84
*
85
*/
86
typedef UINT8 EC_STATUS;
87
88
#define EC_FLAG_OUTPUT_BUFFER ((EC_STATUS) 0x01)
89
#define EC_FLAG_INPUT_BUFFER ((EC_STATUS) 0x02)
90
#define EC_FLAG_DATA_IS_CMD ((EC_STATUS) 0x08)
91
#define EC_FLAG_BURST_MODE ((EC_STATUS) 0x10)
92
93
/*
94
* EC_EVENT:
95
* ---------
96
*/
97
typedef UINT8 EC_EVENT;
98
99
#define EC_EVENT_UNKNOWN ((EC_EVENT) 0x00)
100
#define EC_EVENT_OUTPUT_BUFFER_FULL ((EC_EVENT) 0x01)
101
#define EC_EVENT_INPUT_BUFFER_EMPTY ((EC_EVENT) 0x02)
102
#define EC_EVENT_SCI ((EC_EVENT) 0x20)
103
#define EC_EVENT_SMI ((EC_EVENT) 0x40)
104
105
/* Data byte returned after burst enable indicating it was successful. */
106
#define EC_BURST_ACK 0x90
107
108
/*
109
* Register access primitives
110
*/
111
#define EC_GET_DATA(sc) \
112
bus_space_read_1((sc)->ec_data_tag, (sc)->ec_data_handle, 0)
113
114
#define EC_SET_DATA(sc, v) \
115
bus_space_write_1((sc)->ec_data_tag, (sc)->ec_data_handle, 0, (v))
116
117
#define EC_GET_CSR(sc) \
118
bus_space_read_1((sc)->ec_csr_tag, (sc)->ec_csr_handle, 0)
119
120
#define EC_SET_CSR(sc, v) \
121
bus_space_write_1((sc)->ec_csr_tag, (sc)->ec_csr_handle, 0, (v))
122
123
/* Additional params to pass from the probe routine */
124
struct acpi_ec_params {
125
int glk;
126
int gpe_bit;
127
ACPI_HANDLE gpe_handle;
128
int uid;
129
};
130
131
/*
132
* Driver softc.
133
*/
134
struct acpi_ec_softc {
135
device_t ec_dev;
136
ACPI_HANDLE ec_handle;
137
int ec_uid;
138
ACPI_HANDLE ec_gpehandle;
139
UINT8 ec_gpebit;
140
141
int ec_data_rid;
142
struct resource *ec_data_res;
143
bus_space_tag_t ec_data_tag;
144
bus_space_handle_t ec_data_handle;
145
146
int ec_csr_rid;
147
struct resource *ec_csr_res;
148
bus_space_tag_t ec_csr_tag;
149
bus_space_handle_t ec_csr_handle;
150
151
int ec_glk;
152
int ec_glkhandle;
153
int ec_burstactive;
154
int ec_sci_pend;
155
volatile u_int ec_gencount;
156
int ec_suspending;
157
};
158
159
/*
160
* XXX njl
161
* I couldn't find it in the spec but other implementations also use a
162
* value of 1 ms for the time to acquire global lock.
163
*/
164
#define EC_LOCK_TIMEOUT 1000
165
166
/* Default delay in microseconds between each run of the status polling loop. */
167
#define EC_POLL_DELAY 50
168
169
/* Total time in ms spent waiting for a response from EC. */
170
#define EC_TIMEOUT 750
171
172
#define EVENT_READY(event, status) \
173
(((event) == EC_EVENT_OUTPUT_BUFFER_FULL && \
174
((status) & EC_FLAG_OUTPUT_BUFFER) != 0) || \
175
((event) == EC_EVENT_INPUT_BUFFER_EMPTY && \
176
((status) & EC_FLAG_INPUT_BUFFER) == 0))
177
178
ACPI_SERIAL_DECL(ec, "ACPI embedded controller");
179
180
static SYSCTL_NODE(_debug_acpi, OID_AUTO, ec,
181
CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
182
"EC debugging");
183
184
static int ec_burst_mode;
185
SYSCTL_INT(_debug_acpi_ec, OID_AUTO, burst, CTLFLAG_RWTUN, &ec_burst_mode, 0,
186
"Enable use of burst mode (faster for nearly all systems)");
187
static int ec_polled_mode;
188
SYSCTL_INT(_debug_acpi_ec, OID_AUTO, polled, CTLFLAG_RWTUN, &ec_polled_mode, 0,
189
"Force use of polled mode (only if interrupt mode doesn't work)");
190
static int ec_timeout = EC_TIMEOUT;
191
SYSCTL_INT(_debug_acpi_ec, OID_AUTO, timeout, CTLFLAG_RWTUN, &ec_timeout,
192
EC_TIMEOUT, "Total time spent waiting for a response (poll+sleep)");
193
194
static ACPI_STATUS
195
EcLock(struct acpi_ec_softc *sc)
196
{
197
ACPI_STATUS status;
198
199
/* If _GLK is non-zero, acquire the global lock. */
200
status = AE_OK;
201
if (sc->ec_glk) {
202
status = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT, &sc->ec_glkhandle);
203
if (ACPI_FAILURE(status))
204
return (status);
205
}
206
ACPI_SERIAL_BEGIN(ec);
207
return (status);
208
}
209
210
static void
211
EcUnlock(struct acpi_ec_softc *sc)
212
{
213
ACPI_SERIAL_END(ec);
214
if (sc->ec_glk)
215
AcpiReleaseGlobalLock(sc->ec_glkhandle);
216
}
217
218
static UINT32 EcGpeHandler(ACPI_HANDLE, UINT32, void *);
219
static ACPI_STATUS EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function,
220
void *Context, void **return_Context);
221
static ACPI_STATUS EcSpaceHandler(UINT32 Function,
222
ACPI_PHYSICAL_ADDRESS Address,
223
UINT32 Width, UINT64 *Value,
224
void *Context, void *RegionContext);
225
static ACPI_STATUS EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event,
226
u_int gen_count);
227
static ACPI_STATUS EcCommand(struct acpi_ec_softc *sc, EC_COMMAND cmd);
228
static ACPI_STATUS EcRead(struct acpi_ec_softc *sc, UINT8 Address,
229
UINT8 *Data);
230
static ACPI_STATUS EcWrite(struct acpi_ec_softc *sc, UINT8 Address,
231
UINT8 Data);
232
static int acpi_ec_probe(device_t dev);
233
static int acpi_ec_attach(device_t dev);
234
static int acpi_ec_suspend(device_t dev);
235
static int acpi_ec_resume(device_t dev);
236
static int acpi_ec_shutdown(device_t dev);
237
static int acpi_ec_read_method(device_t dev, u_int addr,
238
UINT64 *val, int width);
239
static int acpi_ec_write_method(device_t dev, u_int addr,
240
UINT64 val, int width);
241
242
static device_method_t acpi_ec_methods[] = {
243
/* Device interface */
244
DEVMETHOD(device_probe, acpi_ec_probe),
245
DEVMETHOD(device_attach, acpi_ec_attach),
246
DEVMETHOD(device_suspend, acpi_ec_suspend),
247
DEVMETHOD(device_resume, acpi_ec_resume),
248
DEVMETHOD(device_shutdown, acpi_ec_shutdown),
249
250
/* Embedded controller interface */
251
DEVMETHOD(acpi_ec_read, acpi_ec_read_method),
252
DEVMETHOD(acpi_ec_write, acpi_ec_write_method),
253
254
DEVMETHOD_END
255
};
256
257
static driver_t acpi_ec_driver = {
258
"acpi_ec",
259
acpi_ec_methods,
260
sizeof(struct acpi_ec_softc),
261
};
262
263
DRIVER_MODULE(acpi_ec, acpi, acpi_ec_driver, 0, 0);
264
MODULE_DEPEND(acpi_ec, acpi, 1, 1, 1);
265
266
/*
267
* Look for an ECDT and if we find one, set up default GPE and
268
* space handlers to catch attempts to access EC space before
269
* we have a real driver instance in place.
270
*
271
* TODO: Some old Gateway laptops need us to fake up an ECDT or
272
* otherwise attach early so that _REG methods can run.
273
*/
274
void
275
acpi_ec_ecdt_probe(device_t parent)
276
{
277
ACPI_TABLE_ECDT *ecdt;
278
ACPI_STATUS status;
279
device_t child;
280
ACPI_HANDLE h;
281
struct acpi_ec_params *params;
282
283
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
284
285
/* Find and validate the ECDT. */
286
status = AcpiGetTable(ACPI_SIG_ECDT, 1, (ACPI_TABLE_HEADER **)&ecdt);
287
if (ACPI_FAILURE(status) ||
288
ecdt->Control.BitWidth != 8 ||
289
ecdt->Data.BitWidth != 8) {
290
return;
291
}
292
293
/* Create the child device with the given unit number. */
294
child = BUS_ADD_CHILD(parent, 3, "acpi_ec", ecdt->Uid);
295
if (child == NULL) {
296
printf("%s: can't add child\n", __func__);
297
return;
298
}
299
300
/* Find and save the ACPI handle for this device. */
301
status = AcpiGetHandle(NULL, ecdt->Id, &h);
302
if (ACPI_FAILURE(status)) {
303
device_delete_child(parent, child);
304
printf("%s: can't get handle\n", __func__);
305
return;
306
}
307
acpi_set_handle(child, h);
308
309
/* Set the data and CSR register addresses. */
310
bus_set_resource(child, SYS_RES_IOPORT, 0, ecdt->Data.Address,
311
/*count*/1);
312
bus_set_resource(child, SYS_RES_IOPORT, 1, ecdt->Control.Address,
313
/*count*/1);
314
315
/*
316
* Store values for the probe/attach routines to use. Store the
317
* ECDT GPE bit and set the global lock flag according to _GLK.
318
* Note that it is not perfectly correct to be evaluating a method
319
* before initializing devices, but in practice this function
320
* should be safe to call at this point.
321
*/
322
params = malloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO);
323
params->gpe_handle = NULL;
324
params->gpe_bit = ecdt->Gpe;
325
params->uid = ecdt->Uid;
326
acpi_GetInteger(h, "_GLK", &params->glk);
327
acpi_set_private(child, params);
328
329
/* Finish the attach process. */
330
if (device_probe_and_attach(child) != 0)
331
device_delete_child(parent, child);
332
}
333
334
static int
335
acpi_ec_probe(device_t dev)
336
{
337
ACPI_BUFFER buf;
338
ACPI_HANDLE h;
339
ACPI_OBJECT *obj;
340
ACPI_STATUS status;
341
device_t peer;
342
int ecdt;
343
int ret, rc;
344
struct acpi_ec_params *params;
345
static char *ec_ids[] = { "PNP0C09", NULL };
346
347
ret = ENXIO;
348
349
/* Check that this is a device and that EC is not disabled. */
350
if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("ec"))
351
return (ret);
352
353
if (device_is_devclass_fixed(dev)) {
354
/*
355
* If probed via ECDT, set description and continue. Otherwise, we can
356
* access the namespace and make sure this is not a duplicate probe.
357
*/
358
ecdt = 1;
359
params = acpi_get_private(dev);
360
if (params != NULL)
361
ret = 0;
362
363
goto out;
364
} else
365
ecdt = 0;
366
367
rc = ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids, NULL);
368
if (rc > 0)
369
return (rc);
370
371
params = malloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO);
372
373
buf.Pointer = NULL;
374
buf.Length = ACPI_ALLOCATE_BUFFER;
375
h = acpi_get_handle(dev);
376
377
/*
378
* Read the unit ID to check for duplicate attach and the global lock value
379
* to see if we should acquire it when accessing the EC.
380
*/
381
status = acpi_GetInteger(h, "_UID", &params->uid);
382
if (ACPI_FAILURE(status))
383
params->uid = 0;
384
385
/*
386
* Check for a duplicate probe. This can happen when a probe via ECDT
387
* succeeded already. If this is a duplicate, disable this device.
388
*
389
* NB: It would seem device_disable would be sufficient to not get
390
* duplicated devices, and ENXIO isn't needed, however, device_probe() only
391
* checks DF_ENABLED at the start and so disabling it here is too late to
392
* prevent device_attach() from being called.
393
*/
394
peer = devclass_get_device(device_get_devclass(dev), params->uid);
395
if (peer != NULL && device_is_alive(peer)) {
396
device_disable(dev);
397
goto out;
398
}
399
400
status = acpi_GetInteger(h, "_GLK", &params->glk);
401
if (ACPI_FAILURE(status))
402
params->glk = 0;
403
404
/*
405
* Evaluate the _GPE method to find the GPE bit used by the EC to signal
406
* status (SCI). If it's a package, it contains a reference and GPE bit,
407
* similar to _PRW.
408
*/
409
status = AcpiEvaluateObject(h, "_GPE", NULL, &buf);
410
if (ACPI_FAILURE(status)) {
411
device_printf(dev, "can't evaluate _GPE - %s\n", AcpiFormatException(status));
412
goto out;
413
}
414
415
obj = (ACPI_OBJECT *)buf.Pointer;
416
if (obj == NULL)
417
goto out;
418
419
switch (obj->Type) {
420
case ACPI_TYPE_INTEGER:
421
params->gpe_handle = NULL;
422
params->gpe_bit = obj->Integer.Value;
423
break;
424
case ACPI_TYPE_PACKAGE:
425
if (!ACPI_PKG_VALID(obj, 2))
426
goto out;
427
params->gpe_handle = acpi_GetReference(NULL, &obj->Package.Elements[0]);
428
if (params->gpe_handle == NULL ||
429
acpi_PkgInt32(obj, 1, &params->gpe_bit) != 0)
430
goto out;
431
break;
432
default:
433
device_printf(dev, "_GPE has invalid type %d\n", obj->Type);
434
goto out;
435
}
436
437
/* Store the values we got from the namespace for attach. */
438
acpi_set_private(dev, params);
439
440
if (buf.Pointer)
441
AcpiOsFree(buf.Pointer);
442
443
ret = rc;
444
out:
445
if (ret <= 0) {
446
device_set_descf(dev, "Embedded Controller: GPE %#x%s%s",
447
params->gpe_bit, (params->glk) ? ", GLK" : "",
448
ecdt ? ", ECDT" : "");
449
} else
450
free(params, M_TEMP);
451
452
return (ret);
453
}
454
455
static int
456
acpi_ec_attach(device_t dev)
457
{
458
struct acpi_ec_softc *sc;
459
struct acpi_ec_params *params;
460
ACPI_STATUS Status;
461
462
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
463
464
/* Fetch/initialize softc (assumes softc is pre-zeroed). */
465
sc = device_get_softc(dev);
466
params = acpi_get_private(dev);
467
sc->ec_dev = dev;
468
sc->ec_handle = acpi_get_handle(dev);
469
470
/* Retrieve previously probed values via device ivars. */
471
sc->ec_glk = params->glk;
472
sc->ec_gpebit = params->gpe_bit;
473
sc->ec_gpehandle = params->gpe_handle;
474
sc->ec_uid = params->uid;
475
sc->ec_suspending = FALSE;
476
acpi_set_private(dev, NULL);
477
free(params, M_TEMP);
478
479
/* Attach bus resources for data and command/status ports. */
480
sc->ec_data_rid = 0;
481
sc->ec_data_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT,
482
&sc->ec_data_rid, RF_ACTIVE);
483
if (sc->ec_data_res == NULL) {
484
device_printf(dev, "can't allocate data port\n");
485
goto error;
486
}
487
sc->ec_data_tag = rman_get_bustag(sc->ec_data_res);
488
sc->ec_data_handle = rman_get_bushandle(sc->ec_data_res);
489
490
sc->ec_csr_rid = 1;
491
sc->ec_csr_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT,
492
&sc->ec_csr_rid, RF_ACTIVE);
493
if (sc->ec_csr_res == NULL) {
494
device_printf(dev, "can't allocate command/status port\n");
495
goto error;
496
}
497
sc->ec_csr_tag = rman_get_bustag(sc->ec_csr_res);
498
sc->ec_csr_handle = rman_get_bushandle(sc->ec_csr_res);
499
500
/*
501
* Install a handler for this EC's GPE bit. We want edge-triggered
502
* behavior.
503
*/
504
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching GPE handler\n"));
505
Status = AcpiInstallGpeHandler(sc->ec_gpehandle, sc->ec_gpebit,
506
ACPI_GPE_EDGE_TRIGGERED, EcGpeHandler, sc);
507
if (ACPI_FAILURE(Status)) {
508
device_printf(dev, "can't install GPE handler for %s - %s\n",
509
acpi_name(sc->ec_handle), AcpiFormatException(Status));
510
goto error;
511
}
512
513
/*
514
* Install address space handler
515
*/
516
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching address space handler\n"));
517
Status = AcpiInstallAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC,
518
&EcSpaceHandler, &EcSpaceSetup, sc);
519
if (ACPI_FAILURE(Status)) {
520
device_printf(dev, "can't install address space handler for %s - %s\n",
521
acpi_name(sc->ec_handle), AcpiFormatException(Status));
522
goto error;
523
}
524
525
/* Enable runtime GPEs for the handler. */
526
Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit);
527
if (ACPI_FAILURE(Status)) {
528
device_printf(dev, "AcpiEnableGpe failed: %s\n",
529
AcpiFormatException(Status));
530
goto error;
531
}
532
533
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "acpi_ec_attach complete\n"));
534
return (0);
535
536
error:
537
AcpiRemoveGpeHandler(sc->ec_gpehandle, sc->ec_gpebit, EcGpeHandler);
538
AcpiRemoveAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC,
539
EcSpaceHandler);
540
if (sc->ec_csr_res)
541
bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_csr_rid,
542
sc->ec_csr_res);
543
if (sc->ec_data_res)
544
bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid,
545
sc->ec_data_res);
546
return (ENXIO);
547
}
548
549
static int
550
acpi_ec_suspend(device_t dev)
551
{
552
struct acpi_ec_softc *sc;
553
554
sc = device_get_softc(dev);
555
sc->ec_suspending = TRUE;
556
return (0);
557
}
558
559
static int
560
acpi_ec_resume(device_t dev)
561
{
562
struct acpi_ec_softc *sc;
563
564
sc = device_get_softc(dev);
565
sc->ec_suspending = FALSE;
566
return (0);
567
}
568
569
static int
570
acpi_ec_shutdown(device_t dev)
571
{
572
struct acpi_ec_softc *sc;
573
574
/* Disable the GPE so we don't get EC events during shutdown. */
575
sc = device_get_softc(dev);
576
AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit);
577
return (0);
578
}
579
580
/* Methods to allow other devices (e.g., smbat) to read/write EC space. */
581
static int
582
acpi_ec_read_method(device_t dev, u_int addr, UINT64 *val, int width)
583
{
584
struct acpi_ec_softc *sc;
585
ACPI_STATUS status;
586
587
sc = device_get_softc(dev);
588
status = EcSpaceHandler(ACPI_READ, addr, width * 8, val, sc, NULL);
589
if (ACPI_FAILURE(status))
590
return (ENXIO);
591
return (0);
592
}
593
594
static int
595
acpi_ec_write_method(device_t dev, u_int addr, UINT64 val, int width)
596
{
597
struct acpi_ec_softc *sc;
598
ACPI_STATUS status;
599
600
sc = device_get_softc(dev);
601
status = EcSpaceHandler(ACPI_WRITE, addr, width * 8, &val, sc, NULL);
602
if (ACPI_FAILURE(status))
603
return (ENXIO);
604
return (0);
605
}
606
607
static ACPI_STATUS
608
EcCheckStatus(struct acpi_ec_softc *sc, const char *msg, EC_EVENT event)
609
{
610
ACPI_STATUS status;
611
EC_STATUS ec_status;
612
613
status = AE_NO_HARDWARE_RESPONSE;
614
ec_status = EC_GET_CSR(sc);
615
if (sc->ec_burstactive && !(ec_status & EC_FLAG_BURST_MODE)) {
616
CTR1(KTR_ACPI, "ec burst disabled in waitevent (%s)", msg);
617
sc->ec_burstactive = FALSE;
618
}
619
if (EVENT_READY(event, ec_status)) {
620
CTR2(KTR_ACPI, "ec %s wait ready, status %#x", msg, ec_status);
621
status = AE_OK;
622
}
623
return (status);
624
}
625
626
static void
627
EcGpeQueryHandlerSub(struct acpi_ec_softc *sc)
628
{
629
UINT8 Data;
630
ACPI_STATUS Status;
631
int retry;
632
char qxx[5];
633
634
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
635
636
/* Serialize user access with EcSpaceHandler(). */
637
Status = EcLock(sc);
638
if (ACPI_FAILURE(Status)) {
639
device_printf(sc->ec_dev, "GpeQuery lock error: %s\n",
640
AcpiFormatException(Status));
641
return;
642
}
643
644
/*
645
* Send a query command to the EC to find out which _Qxx call it
646
* wants to make. This command clears the SCI bit and also the
647
* interrupt source since we are edge-triggered. To prevent the GPE
648
* that may arise from running the query from causing another query
649
* to be queued, we clear the pending flag only after running it.
650
*/
651
for (retry = 0; retry < 2; retry++) {
652
Status = EcCommand(sc, EC_COMMAND_QUERY);
653
if (ACPI_SUCCESS(Status))
654
break;
655
if (ACPI_FAILURE(EcCheckStatus(sc, "retr_check",
656
EC_EVENT_INPUT_BUFFER_EMPTY)))
657
break;
658
}
659
if (ACPI_FAILURE(Status)) {
660
EcUnlock(sc);
661
device_printf(sc->ec_dev, "GPE query failed: %s\n",
662
AcpiFormatException(Status));
663
return;
664
}
665
Data = EC_GET_DATA(sc);
666
667
/*
668
* We have to unlock before running the _Qxx method below since that
669
* method may attempt to read/write from EC address space, causing
670
* recursive acquisition of the lock.
671
*/
672
EcUnlock(sc);
673
674
/* Ignore the value for "no outstanding event". (13.3.5) */
675
CTR2(KTR_ACPI, "ec query ok,%s running _Q%02X", Data ? "" : " not", Data);
676
if (Data == 0)
677
return;
678
679
/* Evaluate _Qxx to respond to the controller. */
680
snprintf(qxx, sizeof(qxx), "_Q%02X", Data);
681
AcpiUtStrupr(qxx);
682
Status = AcpiEvaluateObject(sc->ec_handle, qxx, NULL, NULL);
683
if (ACPI_FAILURE(Status) && Status != AE_NOT_FOUND) {
684
device_printf(sc->ec_dev, "evaluation of query method %s failed: %s\n",
685
qxx, AcpiFormatException(Status));
686
}
687
}
688
689
static void
690
EcGpeQueryHandler(void *Context)
691
{
692
struct acpi_ec_softc *sc = (struct acpi_ec_softc *)Context;
693
int pending;
694
695
KASSERT(Context != NULL, ("EcGpeQueryHandler called with NULL"));
696
697
do {
698
/* Read the current pending count */
699
pending = atomic_load_acq_int(&sc->ec_sci_pend);
700
701
/* Call GPE handler function */
702
EcGpeQueryHandlerSub(sc);
703
704
/*
705
* Try to reset the pending count to zero. If this fails we
706
* know another GPE event has occurred while handling the
707
* current GPE event and need to loop.
708
*/
709
} while (!atomic_cmpset_int(&sc->ec_sci_pend, pending, 0));
710
}
711
712
/*
713
* The GPE handler is called when IBE/OBF or SCI events occur. We are
714
* called from an unknown lock context.
715
*/
716
static UINT32
717
EcGpeHandler(ACPI_HANDLE GpeDevice, UINT32 GpeNumber, void *Context)
718
{
719
struct acpi_ec_softc *sc = Context;
720
ACPI_STATUS Status;
721
EC_STATUS EcStatus;
722
723
KASSERT(Context != NULL, ("EcGpeHandler called with NULL"));
724
CTR0(KTR_ACPI, "ec gpe handler start");
725
726
/*
727
* Notify EcWaitEvent() that the status register is now fresh. If we
728
* didn't do this, it wouldn't be possible to distinguish an old IBE
729
* from a new one, for example when doing a write transaction (writing
730
* address and then data values.)
731
*/
732
atomic_add_int(&sc->ec_gencount, 1);
733
wakeup(sc);
734
735
/*
736
* If the EC_SCI bit of the status register is set, queue a query handler.
737
* It will run the query and _Qxx method later, under the lock.
738
*/
739
EcStatus = EC_GET_CSR(sc);
740
if ((EcStatus & EC_EVENT_SCI) &&
741
atomic_fetchadd_int(&sc->ec_sci_pend, 1) == 0) {
742
CTR0(KTR_ACPI, "ec gpe queueing query handler");
743
Status = AcpiOsExecute(OSL_GPE_HANDLER, EcGpeQueryHandler, Context);
744
if (ACPI_FAILURE(Status)) {
745
printf("EcGpeHandler: queuing GPE query handler failed\n");
746
atomic_store_rel_int(&sc->ec_sci_pend, 0);
747
}
748
}
749
return (ACPI_REENABLE_GPE);
750
}
751
752
static ACPI_STATUS
753
EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function, void *Context,
754
void **RegionContext)
755
{
756
757
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
758
759
/*
760
* If deactivating a region, always set the output to NULL. Otherwise,
761
* just pass the context through.
762
*/
763
if (Function == ACPI_REGION_DEACTIVATE)
764
*RegionContext = NULL;
765
else
766
*RegionContext = Context;
767
768
return_ACPI_STATUS (AE_OK);
769
}
770
771
static ACPI_STATUS
772
EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 Width,
773
UINT64 *Value, void *Context, void *RegionContext)
774
{
775
struct acpi_ec_softc *sc = (struct acpi_ec_softc *)Context;
776
ACPI_PHYSICAL_ADDRESS EcAddr;
777
UINT8 *EcData;
778
ACPI_STATUS Status;
779
780
ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address);
781
782
if (Function != ACPI_READ && Function != ACPI_WRITE)
783
return_ACPI_STATUS (AE_BAD_PARAMETER);
784
if (Width % 8 != 0 || Value == NULL || Context == NULL)
785
return_ACPI_STATUS (AE_BAD_PARAMETER);
786
if (Address + Width / 8 > 256)
787
return_ACPI_STATUS (AE_BAD_ADDRESS);
788
789
/*
790
* If booting, check if we need to run the query handler. If so, we
791
* we call it directly here since our thread taskq is not active yet.
792
*/
793
if (cold || rebooting || sc->ec_suspending) {
794
if ((EC_GET_CSR(sc) & EC_EVENT_SCI) &&
795
atomic_fetchadd_int(&sc->ec_sci_pend, 1) == 0) {
796
CTR0(KTR_ACPI, "ec running gpe handler directly");
797
EcGpeQueryHandler(sc);
798
}
799
}
800
801
/* Serialize with EcGpeQueryHandler() at transaction granularity. */
802
Status = EcLock(sc);
803
if (ACPI_FAILURE(Status))
804
return_ACPI_STATUS (Status);
805
806
/* If we can't start burst mode, continue anyway. */
807
Status = EcCommand(sc, EC_COMMAND_BURST_ENABLE);
808
if (ACPI_SUCCESS(Status)) {
809
if (EC_GET_DATA(sc) == EC_BURST_ACK) {
810
CTR0(KTR_ACPI, "ec burst enabled");
811
sc->ec_burstactive = TRUE;
812
}
813
}
814
815
/* Perform the transaction(s), based on Width. */
816
EcAddr = Address;
817
EcData = (UINT8 *)Value;
818
if (Function == ACPI_READ)
819
*Value = 0;
820
do {
821
switch (Function) {
822
case ACPI_READ:
823
Status = EcRead(sc, EcAddr, EcData);
824
break;
825
case ACPI_WRITE:
826
Status = EcWrite(sc, EcAddr, *EcData);
827
break;
828
}
829
if (ACPI_FAILURE(Status))
830
break;
831
EcAddr++;
832
EcData++;
833
} while (EcAddr < Address + Width / 8);
834
835
if (sc->ec_burstactive) {
836
sc->ec_burstactive = FALSE;
837
if (ACPI_SUCCESS(EcCommand(sc, EC_COMMAND_BURST_DISABLE)))
838
CTR0(KTR_ACPI, "ec disabled burst ok");
839
}
840
841
EcUnlock(sc);
842
return_ACPI_STATUS (Status);
843
}
844
845
static ACPI_STATUS
846
EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event, u_int gen_count)
847
{
848
static int no_intr = 0;
849
ACPI_STATUS Status;
850
int count, i, need_poll, slp_ival;
851
852
ACPI_SERIAL_ASSERT(ec);
853
Status = AE_NO_HARDWARE_RESPONSE;
854
need_poll = cold || rebooting || ec_polled_mode || sc->ec_suspending;
855
856
/* Wait for event by polling or GPE (interrupt). */
857
if (need_poll) {
858
count = (ec_timeout * 1000) / EC_POLL_DELAY;
859
if (count == 0)
860
count = 1;
861
DELAY(10);
862
for (i = 0; i < count; i++) {
863
Status = EcCheckStatus(sc, "poll", Event);
864
if (ACPI_SUCCESS(Status))
865
break;
866
DELAY(EC_POLL_DELAY);
867
}
868
} else {
869
slp_ival = hz / 1000;
870
if (slp_ival != 0) {
871
count = ec_timeout;
872
} else {
873
/* hz has less than 1 ms resolution so scale timeout. */
874
slp_ival = 1;
875
count = ec_timeout / (1000 / hz);
876
}
877
878
/*
879
* Wait for the GPE to signal the status changed, checking the
880
* status register each time we get one. It's possible to get a
881
* GPE for an event we're not interested in here (i.e., SCI for
882
* EC query).
883
*/
884
for (i = 0; i < count; i++) {
885
if (gen_count == sc->ec_gencount)
886
tsleep(sc, 0, "ecgpe", slp_ival);
887
/*
888
* Record new generation count. It's possible the GPE was
889
* just to notify us that a query is needed and we need to
890
* wait for a second GPE to signal the completion of the
891
* event we are actually waiting for.
892
*/
893
Status = EcCheckStatus(sc, "sleep", Event);
894
if (ACPI_SUCCESS(Status)) {
895
if (gen_count == sc->ec_gencount)
896
no_intr++;
897
else
898
no_intr = 0;
899
break;
900
}
901
gen_count = sc->ec_gencount;
902
}
903
904
/*
905
* We finished waiting for the GPE and it never arrived. Try to
906
* read the register once and trust whatever value we got. This is
907
* the best we can do at this point.
908
*/
909
if (ACPI_FAILURE(Status))
910
Status = EcCheckStatus(sc, "sleep_end", Event);
911
}
912
if (!need_poll && no_intr > 10) {
913
device_printf(sc->ec_dev,
914
"not getting interrupts, switched to polled mode\n");
915
ec_polled_mode = 1;
916
}
917
if (ACPI_FAILURE(Status))
918
CTR0(KTR_ACPI, "error: ec wait timed out");
919
return (Status);
920
}
921
922
static ACPI_STATUS
923
EcCommand(struct acpi_ec_softc *sc, EC_COMMAND cmd)
924
{
925
ACPI_STATUS status;
926
EC_EVENT event;
927
EC_STATUS ec_status;
928
u_int gen_count;
929
930
ACPI_SERIAL_ASSERT(ec);
931
932
/* Don't use burst mode if user disabled it. */
933
if (!ec_burst_mode && cmd == EC_COMMAND_BURST_ENABLE)
934
return (AE_ERROR);
935
936
/* Decide what to wait for based on command type. */
937
switch (cmd) {
938
case EC_COMMAND_READ:
939
case EC_COMMAND_WRITE:
940
case EC_COMMAND_BURST_DISABLE:
941
event = EC_EVENT_INPUT_BUFFER_EMPTY;
942
break;
943
case EC_COMMAND_QUERY:
944
case EC_COMMAND_BURST_ENABLE:
945
event = EC_EVENT_OUTPUT_BUFFER_FULL;
946
break;
947
default:
948
device_printf(sc->ec_dev, "EcCommand: invalid command %#x\n", cmd);
949
return (AE_BAD_PARAMETER);
950
}
951
952
/*
953
* Ensure empty input buffer before issuing command.
954
* Use generation count of zero to force a quick check.
955
*/
956
status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, 0);
957
if (ACPI_FAILURE(status))
958
return (status);
959
960
/* Run the command and wait for the chosen event. */
961
CTR1(KTR_ACPI, "ec running command %#x", cmd);
962
gen_count = sc->ec_gencount;
963
EC_SET_CSR(sc, cmd);
964
status = EcWaitEvent(sc, event, gen_count);
965
if (ACPI_SUCCESS(status)) {
966
/* If we succeeded, burst flag should now be present. */
967
if (cmd == EC_COMMAND_BURST_ENABLE) {
968
ec_status = EC_GET_CSR(sc);
969
if ((ec_status & EC_FLAG_BURST_MODE) == 0)
970
status = AE_ERROR;
971
}
972
} else
973
device_printf(sc->ec_dev, "EcCommand: no response to %#x\n", cmd);
974
return (status);
975
}
976
977
static ACPI_STATUS
978
EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
979
{
980
ACPI_STATUS status;
981
u_int gen_count;
982
int retry;
983
984
ACPI_SERIAL_ASSERT(ec);
985
CTR1(KTR_ACPI, "ec read from %#x", Address);
986
987
for (retry = 0; retry < 2; retry++) {
988
status = EcCommand(sc, EC_COMMAND_READ);
989
if (ACPI_FAILURE(status))
990
return (status);
991
992
gen_count = sc->ec_gencount;
993
EC_SET_DATA(sc, Address);
994
status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL, gen_count);
995
if (ACPI_SUCCESS(status)) {
996
*Data = EC_GET_DATA(sc);
997
return (AE_OK);
998
}
999
if (ACPI_FAILURE(EcCheckStatus(sc, "retr_check",
1000
EC_EVENT_INPUT_BUFFER_EMPTY)))
1001
break;
1002
}
1003
device_printf(sc->ec_dev, "EcRead: failed waiting to get data\n");
1004
return (status);
1005
}
1006
1007
static ACPI_STATUS
1008
EcWrite(struct acpi_ec_softc *sc, UINT8 Address, UINT8 Data)
1009
{
1010
ACPI_STATUS status;
1011
u_int gen_count;
1012
1013
ACPI_SERIAL_ASSERT(ec);
1014
CTR2(KTR_ACPI, "ec write to %#x, data %#x", Address, Data);
1015
1016
status = EcCommand(sc, EC_COMMAND_WRITE);
1017
if (ACPI_FAILURE(status))
1018
return (status);
1019
1020
gen_count = sc->ec_gencount;
1021
EC_SET_DATA(sc, Address);
1022
status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count);
1023
if (ACPI_FAILURE(status)) {
1024
device_printf(sc->ec_dev, "EcWrite: failed waiting for sent address\n");
1025
return (status);
1026
}
1027
1028
gen_count = sc->ec_gencount;
1029
EC_SET_DATA(sc, Data);
1030
status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY, gen_count);
1031
if (ACPI_FAILURE(status)) {
1032
device_printf(sc->ec_dev, "EcWrite: failed waiting for sent data\n");
1033
return (status);
1034
}
1035
1036
return (AE_OK);
1037
}
1038
1039