summaryrefslogtreecommitdiff
path: root/drivers/platform/chrome/cros_ec_proto.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/chrome/cros_ec_proto.c')
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c76
1 files changed, 71 insertions, 5 deletions
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index d6942a67a182..8dfa7fcb1248 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -150,6 +150,40 @@ int cros_ec_check_result(struct cros_ec_device *ec_dev,
}
EXPORT_SYMBOL(cros_ec_check_result);
+/*
+ * cros_ec_get_host_event_wake_mask
+ *
+ * Get the mask of host events that cause wake from suspend.
+ *
+ * @ec_dev: EC device to call
+ * @msg: message structure to use
+ * @mask: result when function returns >=0.
+ *
+ * LOCKING:
+ * the caller has ec_dev->lock mutex, or the caller knows there is
+ * no other command in progress.
+ */
+static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev,
+ struct cros_ec_command *msg,
+ uint32_t *mask)
+{
+ struct ec_response_host_event_mask *r;
+ int ret;
+
+ msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;
+ msg->version = 0;
+ msg->outsize = 0;
+ msg->insize = sizeof(*r);
+
+ ret = send_command(ec_dev, msg);
+ if (ret > 0) {
+ r = (struct ec_response_host_event_mask *)msg->data;
+ *mask = r->mask;
+ }
+
+ return ret;
+}
+
static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,
int devidx,
struct cros_ec_command *msg)
@@ -387,6 +421,15 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev)
else
ec_dev->mkbp_event_supported = 1;
+ /*
+ * Get host event wake mask, assume all events are wake events
+ * if unavailable.
+ */
+ ret = cros_ec_get_host_event_wake_mask(ec_dev, proto_msg,
+ &ec_dev->host_event_wake_mask);
+ if (ret < 0)
+ ec_dev->host_event_wake_mask = U32_MAX;
+
ret = 0;
exit:
@@ -504,12 +547,35 @@ static int get_keyboard_state_event(struct cros_ec_device *ec_dev)
return ec_dev->event_size;
}
-int cros_ec_get_next_event(struct cros_ec_device *ec_dev)
+int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event)
{
- if (ec_dev->mkbp_event_supported)
- return get_next_event(ec_dev);
- else
- return get_keyboard_state_event(ec_dev);
+ u32 host_event;
+ int ret;
+
+ if (!ec_dev->mkbp_event_supported) {
+ ret = get_keyboard_state_event(ec_dev);
+ if (ret < 0)
+ return ret;
+
+ if (wake_event)
+ *wake_event = true;
+
+ return ret;
+ }
+
+ ret = get_next_event(ec_dev);
+ if (ret < 0)
+ return ret;
+
+ if (wake_event) {
+ host_event = cros_ec_get_host_event(ec_dev);
+
+ /* Consider non-host_event as wake event */
+ *wake_event = !host_event ||
+ !!(host_event & ec_dev->host_event_wake_mask);
+ }
+
+ return ret;
}
EXPORT_SYMBOL(cros_ec_get_next_event);