mfd: cros-ec: Increase maximum mkbp event size
authorNeil Armstrong <narmstrong@baylibre.com>
Wed, 4 Jul 2018 15:08:18 +0000 (17:08 +0200)
committerLee Jones <lee.jones@linaro.org>
Fri, 13 Jul 2018 07:44:31 +0000 (08:44 +0100)
Having a 16 byte mkbp event size makes it possible to send CEC
messages from the EC to the AP directly inside the mkbp event
instead of first doing a notification and then a read.

Signed-off-by: Stefan Adolfsson <sadolfsson@chromium.org>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
drivers/platform/chrome/cros_ec_proto.c
include/linux/mfd/cros_ec.h
include/linux/mfd/cros_ec_commands.h

index 8350ca2311c73c3af5dd52eb60c967737e44950d..398393ab5df854d71d2158cad47b52923246bcb4 100644 (file)
@@ -506,10 +506,31 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
 }
 EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
 
+static int get_next_event_xfer(struct cros_ec_device *ec_dev,
+                              struct cros_ec_command *msg,
+                              int version, uint32_t size)
+{
+       int ret;
+
+       msg->version = version;
+       msg->command = EC_CMD_GET_NEXT_EVENT;
+       msg->insize = size;
+       msg->outsize = 0;
+
+       ret = cros_ec_cmd_xfer(ec_dev, msg);
+       if (ret > 0) {
+               ec_dev->event_size = ret - 1;
+               memcpy(&ec_dev->event_data, msg->data, ec_dev->event_size);
+       }
+
+       return ret;
+}
+
 static int get_next_event(struct cros_ec_device *ec_dev)
 {
        u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
        struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
+       static int cmd_version = 1;
        int ret;
 
        if (ec_dev->suspended) {
@@ -517,18 +538,19 @@ static int get_next_event(struct cros_ec_device *ec_dev)
                return -EHOSTDOWN;
        }
 
-       msg->version = 0;
-       msg->command = EC_CMD_GET_NEXT_EVENT;
-       msg->insize = sizeof(ec_dev->event_data);
-       msg->outsize = 0;
+       if (cmd_version == 1) {
+               ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+                               sizeof(struct ec_response_get_next_event_v1));
+               if (ret < 0 || msg->result != EC_RES_INVALID_VERSION)
+                       return ret;
 
-       ret = cros_ec_cmd_xfer(ec_dev, msg);
-       if (ret > 0) {
-               ec_dev->event_size = ret - 1;
-               memcpy(&ec_dev->event_data, msg->data,
-                      sizeof(ec_dev->event_data));
+               /* Fallback to version 0 for future send attempts */
+               cmd_version = 0;
        }
 
+       ret = get_next_event_xfer(ec_dev, msg, cmd_version,
+                                 sizeof(struct ec_response_get_next_event));
+
        return ret;
 }
 
index 32421dfeb996cb2e8a36fa210bfae968db6bc849..20949dde35cdff149f259a526e2fadb8fa9f3a34 100644 (file)
@@ -147,7 +147,7 @@ struct cros_ec_device {
        bool mkbp_event_supported;
        struct blocking_notifier_head event_notifier;
 
-       struct ec_response_get_next_event event_data;
+       struct ec_response_get_next_event_v1 event_data;
        int event_size;
        u32 host_event_wake_mask;
 };
index f2edd9969b400703bb3853e17e0e1051bcddfc32..c4f0caa642beb43968f87439bd4ee3df0156e57e 100644 (file)
@@ -2093,12 +2093,28 @@ union ec_response_get_next_data {
        uint32_t   sysrq;
 } __packed;
 
+union ec_response_get_next_data_v1 {
+       uint8_t key_matrix[16];
+       uint32_t host_event;
+       uint32_t buttons;
+       uint32_t switches;
+       uint32_t sysrq;
+       uint32_t cec_events;
+       uint8_t cec_message[16];
+} __packed;
+
 struct ec_response_get_next_event {
        uint8_t event_type;
        /* Followed by event data if any */
        union ec_response_get_next_data data;
 } __packed;
 
+struct ec_response_get_next_event_v1 {
+       uint8_t event_type;
+       /* Followed by event data if any */
+       union ec_response_get_next_data_v1 data;
+} __packed;
+
 /* Bit indices for buttons and switches.*/
 /* Buttons */
 #define EC_MKBP_POWER_BUTTON   0