coreboot-libre-fam15h-rdimm/3rdparty/chromeec/common/device_event.c

130 lines
3.3 KiB
C

/* Copyright 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 enum ec_status 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));