aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Green <evgreen@chromium.org>2019-04-03 17:34:28 -0400
committerLee Jones <lee.jones@linaro.org>2019-05-14 03:13:27 -0400
commit7235560ac77a2516b84b86946debaa4fb951ed9b (patch)
treeb0dd3de2e289e8b8b9ed6bc0ce376177b9cc36d9
parentafe2bb5c4b6227a347be60c70df2890c3f57553d (diff)
platform/chrome: Add support for v1 of host sleep event
Add support in code for the new forms of the host sleep event. Detects the presence of this version of the command at runtime, and use whichever form the EC supports. At this time, always request the default timeout, and only report the failing response via a WARN_ONCE(). Future versions could accept the sleep parameter from outside the driver, and return the response information to usermode or elsewhere. Signed-off-by: Evan Green <evgreen@chromium.org> Reviewed-by: Rajat Jain <rajatja@chromium.org> Reviewed-by: Guenter Roeck <groeck@chromium.org> Acked-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/cros_ec.c39
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c6
-rw-r--r--include/linux/mfd/cros_ec.h2
3 files changed, 42 insertions, 5 deletions
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index 6acfe036d522..bd2bcdd4718b 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -75,20 +75,49 @@ static irqreturn_t ec_irq_thread(int irq, void *data)
75 75
76static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) 76static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event)
77{ 77{
78 int ret;
78 struct { 79 struct {
79 struct cros_ec_command msg; 80 struct cros_ec_command msg;
80 struct ec_params_host_sleep_event req; 81 union {
82 struct ec_params_host_sleep_event req0;
83 struct ec_params_host_sleep_event_v1 req1;
84 struct ec_response_host_sleep_event_v1 resp1;
85 } u;
81 } __packed buf; 86 } __packed buf;
82 87
83 memset(&buf, 0, sizeof(buf)); 88 memset(&buf, 0, sizeof(buf));
84 89
85 buf.req.sleep_event = sleep_event; 90 if (ec_dev->host_sleep_v1) {
91 buf.u.req1.sleep_event = sleep_event;
92 buf.u.req1.suspend_params.sleep_timeout_ms =
93 EC_HOST_SLEEP_TIMEOUT_DEFAULT;
94
95 buf.msg.outsize = sizeof(buf.u.req1);
96 if ((sleep_event == HOST_SLEEP_EVENT_S3_RESUME) ||
97 (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME))
98 buf.msg.insize = sizeof(buf.u.resp1);
99
100 buf.msg.version = 1;
101
102 } else {
103 buf.u.req0.sleep_event = sleep_event;
104 buf.msg.outsize = sizeof(buf.u.req0);
105 }
86 106
87 buf.msg.command = EC_CMD_HOST_SLEEP_EVENT; 107 buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
88 buf.msg.version = 0;
89 buf.msg.outsize = sizeof(buf.req);
90 108
91 return cros_ec_cmd_xfer(ec_dev, &buf.msg); 109 ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
110
111 /* For now, report failure to transition to S0ix with a warning. */
112 if (ret >= 0 && ec_dev->host_sleep_v1 &&
113 (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME))
114 WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &
115 EC_HOST_RESUME_SLEEP_TIMEOUT,
116 "EC detected sleep transition timeout. Total slp_s0 transitions: %d",
117 buf.u.resp1.resume_response.sleep_transitions &
118 EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);
119
120 return ret;
92} 121}
93 122
94int cros_ec_register(struct cros_ec_device *ec_dev) 123int cros_ec_register(struct cros_ec_device *ec_dev)
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index 97a068dff192..52ca564a64e7 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -414,6 +414,12 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev)
414 else 414 else
415 ec_dev->mkbp_event_supported = 1; 415 ec_dev->mkbp_event_supported = 1;
416 416
417 /* Probe if host sleep v1 is supported for S0ix failure detection. */
418 ret = cros_ec_get_host_command_version_mask(ec_dev,
419 EC_CMD_HOST_SLEEP_EVENT,
420 &ver_mask);
421 ec_dev->host_sleep_v1 = (ret >= 0 && (ver_mask & EC_VER_MASK(1)));
422
417 /* 423 /*
418 * Get host event wake mask, assume all events are wake events 424 * Get host event wake mask, assume all events are wake events
419 * if unavailable. 425 * if unavailable.
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index 109292a60499..31c88a0070a3 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -121,6 +121,7 @@ struct cros_ec_command {
121 * @pkt_xfer: Send packet to EC and get response. 121 * @pkt_xfer: Send packet to EC and get response.
122 * @lock: One transaction at a time. 122 * @lock: One transaction at a time.
123 * @mkbp_event_supported: True if this EC supports the MKBP event protocol. 123 * @mkbp_event_supported: True if this EC supports the MKBP event protocol.
124 * @host_sleep_v1: True if this EC supports the sleep v1 command.
124 * @event_notifier: Interrupt event notifier for transport devices. 125 * @event_notifier: Interrupt event notifier for transport devices.
125 * @event_data: Raw payload transferred with the MKBP event. 126 * @event_data: Raw payload transferred with the MKBP event.
126 * @event_size: Size in bytes of the event data. 127 * @event_size: Size in bytes of the event data.
@@ -154,6 +155,7 @@ struct cros_ec_device {
154 struct cros_ec_command *msg); 155 struct cros_ec_command *msg);
155 struct mutex lock; 156 struct mutex lock;
156 bool mkbp_event_supported; 157 bool mkbp_event_supported;
158 bool host_sleep_v1;
157 struct blocking_notifier_head event_notifier; 159 struct blocking_notifier_head event_notifier;
158 160
159 struct ec_response_get_next_event_v1 event_data; 161 struct ec_response_get_next_event_v1 event_data;