|
@@ -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);
|
|
|
|