diff options
author | Duncan Laurie <dlaurie@google.com> | 2017-06-29 07:14:58 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-30 03:08:42 -0700 |
commit | bbb759ceaa843f548f90c35d1668e17c8879bad3 (patch) | |
tree | 7e1b84d8cd73740c01d3cad2398666581f16cee4 /common/device_event.c | |
parent | 5e5788f3cac7fecd45072807bb6a79ce2b767961 (diff) | |
download | chrome-ec-bbb759ceaa843f548f90c35d1668e17c8879bad3.tar.gz |
Add support for reporting device events
In order to report specific wake events from differernt devices
add a host command that allows setting device event mask, and
triggering a host event when that device event is set.
This is done as a separate command and mask because we are running
out of host events, and it takes over the unused thermal overload
event that was never used in EC or BIOS.
The first use case for this is platforms that have AP wake events
that go to the EC, for instance devices that use Deep S3 and have
a limited set of wake pins. (such as Eve)
This allows the AP to determine the exact wake source for an event
so it can be logged and acted on by the AP if necessary.
BUG=b:36024430
BRANCH=eve
TEST=manual testing on eve with trackpad and dsp wake events
Change-Id: I48d94014c00dc1dad098ab96af0ddc7860229762
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Reviewed-on: https://chromium-review.googlesource.com/555632
Reviewed-by: Scott Collyer <scollyer@chromium.org>
Diffstat (limited to 'common/device_event.c')
-rw-r--r-- | common/device_event.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/common/device_event.c b/common/device_event.c new file mode 100644 index 0000000000..4b4e37724c --- /dev/null +++ b/common/device_event.c @@ -0,0 +1,129 @@ +/* Copyright (c) 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* Device event commands for Chrome EC */ + +#include "atomic.h" +#include "common.h" +#include "console.h" +#include "host_command.h" +#include "lpc.h" +#include "mkbp_event.h" +#include "util.h" + +/* Console output macros */ +#define CPUTS(outstr) cputs(CC_EVENTS, outstr) +#define CPRINTS(format, args...) cprints(CC_EVENTS, format, ## args) + +static uint32_t device_current_events; +static uint32_t device_enabled_events; + +uint32_t device_get_current_events(void) +{ + return device_current_events; +} + +static uint32_t device_get_and_clear_events(void) +{ + return atomic_read_clear(&device_current_events); +} + +static uint32_t device_get_enabled_events(void) +{ + return device_enabled_events; +} + +void device_set_events(uint32_t mask) +{ + /* Ignore events that are not enabled */ + mask &= device_enabled_events; + + if ((device_current_events & mask) != mask) + CPRINTS("device event set 0x%08x", mask); + + atomic_or(&device_current_events, mask); + + /* Signal host that a device event is pending */ + host_set_single_event(EC_HOST_EVENT_DEVICE); +} + +void device_clear_events(uint32_t mask) +{ + /* Only print if something's about to change */ + if (device_current_events & mask) + CPRINTS("device event clear 0x%08x", mask); + + atomic_clear(&device_current_events, mask); +} + +static void device_set_enabled_events(uint32_t mask) +{ + if ((device_enabled_events & mask) != mask) + CPRINTS("device enabled events set 0x%08x", mask); + + device_enabled_events = mask; +} + +/*****************************************************************************/ +/* Console commands */ + +#ifdef CONFIG_CMD_DEVICE_EVENT +static int command_device_event(int argc, char **argv) +{ + /* Handle sub-commands */ + if (argc == 3) { + char *e; + int i = strtoi(argv[2], &e, 0); + + if (*e) + return EC_ERROR_PARAM2; + else if (!strcasecmp(argv[1], "set")) + device_set_events(i); + else if (!strcasecmp(argv[1], "clear")) + device_clear_events(i); + else if (!strcasecmp(argv[1], "enable")) + device_set_enabled_events(i); + else + return EC_ERROR_PARAM1; + } + + ccprintf("Enabled Events: 0x%08x\n", device_get_enabled_events()); + ccprintf("Current Events: 0x%08x\n", device_get_current_events()); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(deviceevent, command_device_event, + "[set | clear | enable] [mask]", + "Print / set device event state"); +#endif + +/*****************************************************************************/ +/* Host commands */ + +static int device_event_cmd(struct host_cmd_handler_args *args) +{ + const struct ec_params_device_event *p = args->params; + struct ec_response_device_event *r = args->response; + + switch (p->param) { + case EC_DEVICE_EVENT_PARAM_GET_CURRENT_EVENTS: + r->event_mask = device_get_and_clear_events(); + break; + case EC_DEVICE_EVENT_PARAM_GET_ENABLED_EVENTS: + r->event_mask = device_get_enabled_events(); + break; + case EC_DEVICE_EVENT_PARAM_SET_ENABLED_EVENTS: + device_set_enabled_events(p->event_mask); + r->event_mask = device_get_enabled_events(); + break; + default: + return EC_RES_INVALID_PARAM; + } + + args->response_size = sizeof(*r); + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_DEVICE_EVENT, device_event_cmd, EC_VER_MASK(0)); |