History

Merge tag 'tag-chrome-platform-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform updates from Tzung-Bi Shih: "cros_ec_proto: - Leverage Kunit and add Kunit test cases - Clean-ups - Fix typo cros_ec_commands: - Fix typo - Fix compile errors cros_kbd_led_backlight: - Support OF match - Support EC PWM backend cros_ec: - Always expose the last resume result to fix sleep hang detection on ARM-based chromebooks wilco_ec: - Fix typo cros_ec_typec: - Clean-ups - Use Type-C framework utilities to manage altmode structs" * tag 'tag-chrome-platform-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux: (59 commits) platform/chrome: cros_kunit_util: add default value for `msg->result` platform/chrome: merge Kunit utils and test cases platform/chrome: cros_kbd_led_backlight: fix build warning platform/chrome: cros_ec_proto: add Kunit test for cros_ec_cmd() platform/chrome: cros_ec_proto: add Kunit tests for get_sensor_count platform/chrome: cros_ec_proto: add Kunit tests for check_features platform/chrome: cros_ec_proto: add Kunit tests for get_host_event platform/chrome: cros_ec_proto: add Kunit tests for get_next_event platform/chrome: cros_ec_proto: add Kunit test for cros_ec_map_error() platform/chrome: cros_ec_proto: add Kunit tests for cmd_xfer_status platform/chrome: cros_ec_proto: return -EPROTO if empty payload platform/chrome: cros_ec_proto: add Kunit test for empty payload platform/chrome: cros_ec_proto: return -EAGAIN when retries timed out platform/chrome: cros_ec_proto: change Kunit expectation when timed out platform/chrome: cros_ec_proto: separate cros_ec_wait_until_complete() platform/chrome: cros_ec_proto: separate cros_ec_xfer_command() platform/chrome: cros_ec_proto: add Kunit tests for cros_ec_send_command() platform/chrome: cros_ec_proto: add Kunit tests for cros_ec_cmd_xfer() platform/chrome: cros_ec_proto: add "cros_ec_" prefix to send_command() platform/chrome: cros_ec_typec: Register port altmodes ...

Linus Torvalds committed 4 years ago

Commit 5bb3bf22 parents da8d07a afef1e118 files · +3490 −335Browse files

Unified · Split

18 files
  1. Documentation/devicetree/bindings/chrome/google,cros-kbd-led-backlight.yaml +35 −0
  2. Documentation/devicetree/bindings/mfd/google,cros-ec.yaml +3 −0
  3. drivers/mfd/cros_ec_dev.c +2 −2
  4. drivers/platform/chrome/Kconfig +10 −1
  5. drivers/platform/chrome/Makefile +5 −0
  6. drivers/platform/chrome/cros_ec.c +4 −7
  7. drivers/platform/chrome/cros_ec_proto.c +248 −225
  8. drivers/platform/chrome/cros_ec_proto_test.c +2753 −0
  9. drivers/platform/chrome/cros_ec_trace.h +4 −4
  10. drivers/platform/chrome/cros_ec_typec.c +60 −33
  11. drivers/platform/chrome/cros_kbd_led_backlight.c +174 −22
  12. drivers/platform/chrome/cros_kunit_util.c +130 −0
  13. drivers/platform/chrome/cros_kunit_util.h +48 −0
  14. drivers/platform/chrome/cros_usbpd_notify.c +2 −2
  15. drivers/platform/chrome/wilco_ec/event.c +1 −1
  16. drivers/regulator/cros-ec-regulator.c +3 −33
  17. include/linux/platform_data/cros_ec_commands.h +3 −3
  18. include/linux/platform_data/cros_ec_proto.h +5 −2
Documentation/devicetree/bindings/chrome/google,cros-kbd-led-backlight.yaml+35−0
@@ -0,0 +1,35 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/chrome/google,cros-kbd-led-backlight.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: ChromeOS keyboard backlight LED driver.
8+
9+maintainers:
10+ - Tzung-Bi Shih <tzungbi@kernel.org>
11+
12+properties:
13+ compatible:
14+ const: google,cros-kbd-led-backlight
15+
16+required:
17+ - compatible
18+
19+additionalProperties: false
20+
21+examples:
22+ - |
23+ spi0 {
24+ #address-cells = <1>;
25+ #size-cells = <0>;
26+
27+ cros_ec: ec@0 {
28+ compatible = "google,cros-ec-spi";
29+ reg = <0>;
30+
31+ kbd-led-backlight {
32+ compatible = "google,cros-kbd-led-backlight";
33+ };
34+ };
35+ };
Documentation/devicetree/bindings/mfd/google,cros-ec.yaml+3−0
@@ -90,6 +90,9 @@ properties: · 89 unmodified lines
9090 pwm:
9191 $ref: "/schemas/pwm/google,cros-ec-pwm.yaml#"
9292
93+ kbd-led-backlight:
94+ $ref: "/schemas/chrome/google,cros-kbd-led-backlight.yaml#"
95+
9396 keyboard-controller:
9497 $ref: "/schemas/input/google,cros-ec-keyb.yaml#"
9598
drivers/mfd/cros_ec_dev.c+2−2
@@ -250,8 +250,8 @@ static int ec_device_probe(struct platform_device *pdev) · 249 unmodified lines
250250 * The PCHG device cannot be detected by sending EC_FEATURE_GET_CMD, but
251251 * it can be detected by querying the number of peripheral chargers.
252252 */
253− retval = cros_ec_command(ec->ec_dev, 0, EC_CMD_PCHG_COUNT, NULL, 0,
254− &pchg_count, sizeof(pchg_count));
253+ retval = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_PCHG_COUNT, NULL, 0,
254+ &pchg_count, sizeof(pchg_count));
255255 if (retval >= 0 && pchg_count.port_count) {
256256 retval = mfd_add_hotplug_devices(ec->dev,
257257 cros_ec_pchg_cells,
drivers/platform/chrome/Kconfig+10−1
@@ -139,7 +139,7 @@ config CROS_EC_PROTO · 138 unmodified lines
139139
140140 config CROS_KBD_LED_BACKLIGHT
141141 tristate "Backlight LED support for Chrome OS keyboards"
142− depends on LEDS_CLASS && ACPI
142+ depends on LEDS_CLASS && (ACPI || CROS_EC)
143143 help
144144 This option enables support for the keyboard backlight LEDs on
145145 select Chrome OS systems.
@@ -267,4 +267,13 @@ config CHROMEOS_PRIVACY_SCREEN · 121 unmodified lines
267267
268268 source "drivers/platform/chrome/wilco_ec/Kconfig"
269269
270+# Kunit test cases
271+config CROS_KUNIT
272+ tristate "Kunit tests for ChromeOS" if !KUNIT_ALL_TESTS
273+ depends on KUNIT && CROS_EC
274+ default KUNIT_ALL_TESTS
275+ select CROS_EC_PROTO
276+ help
277+ ChromeOS Kunit tests.
278+
270279 endif # CHROMEOS_PLATFORMS
drivers/platform/chrome/Makefile+5−0
@@ -30,3 +30,8 @@ obj-$(CONFIG_CROS_USBPD_LOGGER) += cros_usbpd_logger.o · 29 unmodified lines
3030 obj-$(CONFIG_CROS_USBPD_NOTIFY) += cros_usbpd_notify.o
3131
3232 obj-$(CONFIG_WILCO_EC) += wilco_ec/
33+
34+# Kunit test cases
35+obj-$(CONFIG_CROS_KUNIT) += cros_kunit.o
36+cros_kunit-objs := cros_kunit_util.o
37+cros_kunit-objs += cros_ec_proto_test.o
drivers/platform/chrome/cros_ec.c+4−7
@@ -19,9 +19,6 @@ · 18 unmodified lines
1919
2020 #include "cros_ec.h"
2121
22−#define CROS_EC_DEV_EC_INDEX 0
23−#define CROS_EC_DEV_PD_INDEX 1
24−
2522 static struct cros_ec_platform ec_p = {
2623 .ec_name = CROS_EC_DEV_NAME,
2724 .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_EC_INDEX),
@@ -135,16 +132,16 @@ static int cros_ec_sleep_event(struct cros_ec_device *ec_dev, u8 sleep_event) · 107 unmodified lines
135132 buf.msg.command = EC_CMD_HOST_SLEEP_EVENT;
136133
137134 ret = cros_ec_cmd_xfer_status(ec_dev, &buf.msg);
138−
139− /* For now, report failure to transition to S0ix with a warning. */
135+ /* Report failure to transition to system wide suspend with a warning. */
140136 if (ret >= 0 && ec_dev->host_sleep_v1 &&
141− (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME)) {
137+ (sleep_event == HOST_SLEEP_EVENT_S0IX_RESUME ||
138+ sleep_event == HOST_SLEEP_EVENT_S3_RESUME)) {
142139 ec_dev->last_resume_result =
143140 buf.u.resp1.resume_response.sleep_transitions;
144141
145142 WARN_ONCE(buf.u.resp1.resume_response.sleep_transitions &
146143 EC_HOST_RESUME_SLEEP_TIMEOUT,
147− "EC detected sleep transition timeout. Total slp_s0 transitions: %d",
144+ "EC detected sleep transition timeout. Total sleep transitions: %d",
148145 buf.u.resp1.resume_response.sleep_transitions &
149146 EC_HOST_RESUME_SLEEP_TRANSITIONS_MASK);
150147 }
drivers/platform/chrome/cros_ec_proto.c+248−225
@@ -52,8 +52,8 @@ static int cros_ec_map_error(uint32_t result) · 51 unmodified lines
5252 return ret;
5353 }
5454
55−static int prepare_packet(struct cros_ec_device *ec_dev,
56− struct cros_ec_command *msg)
55+static int prepare_tx(struct cros_ec_device *ec_dev,
56+ struct cros_ec_command *msg)
5757 {
5858 struct ec_host_request *request;
5959 u8 *out;
@@ -85,8 +85,29 @@ static int prepare_packet(struct cros_ec_device *ec_dev, · 25 unmodified lines
8585 return sizeof(*request) + msg->outsize;
8686 }
8787
88−static int send_command(struct cros_ec_device *ec_dev,
89− struct cros_ec_command *msg)
88+static int prepare_tx_legacy(struct cros_ec_device *ec_dev,
89+ struct cros_ec_command *msg)
90+{
91+ u8 *out;
92+ u8 csum;
93+ int i;
94+
95+ if (msg->outsize > EC_PROTO2_MAX_PARAM_SIZE)
96+ return -EINVAL;
97+
98+ out = ec_dev->dout;
99+ out[0] = EC_CMD_VERSION0 + msg->version;
100+ out[1] = msg->command;
101+ out[2] = msg->outsize;
102+ csum = out[0] + out[1] + out[2];
103+ for (i = 0; i < msg->outsize; i++)
104+ csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
105+ out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
106+
107+ return EC_MSG_TX_PROTO_BYTES + msg->outsize;
108+}
109+
110+static int cros_ec_xfer_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
90111 {
91112 int ret;
92113 int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
@@ -102,57 +123,68 @@ static int send_command(struct cros_ec_device *ec_dev, · 9 unmodified lines
102123 * the EC is trying to use protocol v2, on an underlying
103124 * communication mechanism that does not support v2.
104125 */
105− dev_err_once(ec_dev->dev,
106− "missing EC transfer API, cannot send command\n");
126+ dev_err_once(ec_dev->dev, "missing EC transfer API, cannot send command\n");
107127 return -EIO;
108128 }
109129
110130 trace_cros_ec_request_start(msg);
111131 ret = (*xfer_fxn)(ec_dev, msg);
112132 trace_cros_ec_request_done(msg, ret);
113− if (msg->result == EC_RES_IN_PROGRESS) {
114− int i;
115− struct cros_ec_command *status_msg;
116− struct ec_response_get_comms_status *status;
117133
118− status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
119− GFP_KERNEL);
120− if (!status_msg)
121− return -ENOMEM;
134+ return ret;
135+}
122136
123− status_msg->version = 0;
124− status_msg->command = EC_CMD_GET_COMMS_STATUS;
125− status_msg->insize = sizeof(*status);
126− status_msg->outsize = 0;
137+static int cros_ec_wait_until_complete(struct cros_ec_device *ec_dev, uint32_t *result)
138+{
139+ struct {
140+ struct cros_ec_command msg;
141+ struct ec_response_get_comms_status status;
142+ } __packed buf;
143+ struct cros_ec_command *msg = &buf.msg;
144+ struct ec_response_get_comms_status *status = &buf.status;
145+ int ret = 0, i;
127146
128− /*
129− * Query the EC's status until it's no longer busy or
130− * we encounter an error.
131− */
132− for (i = 0; i < EC_COMMAND_RETRIES; i++) {
133− usleep_range(10000, 11000);
134−
135− trace_cros_ec_request_start(status_msg);
136− ret = (*xfer_fxn)(ec_dev, status_msg);
137− trace_cros_ec_request_done(status_msg, ret);
138− if (ret == -EAGAIN)
139− continue;
140− if (ret < 0)
141− break;
142−
143− msg->result = status_msg->result;
144− if (status_msg->result != EC_RES_SUCCESS)
145− break;
146−
147− status = (struct ec_response_get_comms_status *)
148− status_msg->data;
149− if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
150− break;
147+ msg->version = 0;
148+ msg->command = EC_CMD_GET_COMMS_STATUS;
149+ msg->insize = sizeof(*status);
150+ msg->outsize = 0;
151+
152+ /* Query the EC's status until it's no longer busy or we encounter an error. */
153+ for (i = 0; i < EC_COMMAND_RETRIES; ++i) {
154+ usleep_range(10000, 11000);
155+
156+ ret = cros_ec_xfer_command(ec_dev, msg);
157+ if (ret == -EAGAIN)
158+ continue;
159+ if (ret < 0)
160+ return ret;
161+
162+ *result = msg->result;
163+ if (msg->result != EC_RES_SUCCESS)
164+ return ret;
165+
166+ if (ret == 0) {
167+ ret = -EPROTO;
168+ break;
151169 }
152170
153− kfree(status_msg);
171+ if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
172+ return ret;
154173 }
155174
175+ if (i >= EC_COMMAND_RETRIES)
176+ ret = -EAGAIN;
177+
178+ return ret;
179+}
180+
181+static int cros_ec_send_command(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
182+{
183+ int ret = cros_ec_xfer_command(ec_dev, msg);
184+
185+ if (msg->result == EC_RES_IN_PROGRESS)
186+ ret = cros_ec_wait_until_complete(ec_dev, &msg->result);
187+
156188 return ret;
157189 }
158190
@@ -161,35 +193,18 @@ static int send_command(struct cros_ec_device *ec_dev, · 2 unmodified lines
161193 * @ec_dev: Device to register.
162194 * @msg: Message to write.
163195 *
164− * This is intended to be used by all ChromeOS EC drivers, but at present
165− * only SPI uses it. Once LPC uses the same protocol it can start using it.
166− * I2C could use it now, with a refactor of the existing code.
196+ * This is used by all ChromeOS EC drivers to prepare the outgoing message
197+ * according to different protocol versions.
167198 *
168199 * Return: number of prepared bytes on success or negative error code.
169200 */
170201 int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
171202 struct cros_ec_command *msg)
172203 {
173− u8 *out;
174− u8 csum;
175− int i;
176−
177204 if (ec_dev->proto_version > 2)
178− return prepare_packet(ec_dev, msg);
179−
180− if (msg->outsize > EC_PROTO2_MAX_PARAM_SIZE)
181− return -EINVAL;
205+ return prepare_tx(ec_dev, msg);
182206
183− out = ec_dev->dout;
184− out[0] = EC_CMD_VERSION0 + msg->version;
185− out[1] = msg->command;
186− out[2] = msg->outsize;
187− csum = out[0] + out[1] + out[2];
188− for (i = 0; i < msg->outsize; i++)
189− csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
190− out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
191−
192− return EC_MSG_TX_PROTO_BYTES + msg->outsize;
207+ return prepare_tx_legacy(ec_dev, msg);
193208 }
194209 EXPORT_SYMBOL(cros_ec_prepare_tx);
195210
@@ -199,9 +214,12 @@ EXPORT_SYMBOL(cros_ec_prepare_tx); · 3 unmodified lines
199214 * @msg: Message to check.
200215 *
201216 * This is used by ChromeOS EC drivers to check the ec_msg->result for
202− * errors and to warn about them.
217+ * EC_RES_IN_PROGRESS and to warn about them.
203218 *
204− * Return: 0 on success or negative error code.
219+ * The function should not check for furthermore error codes. Otherwise,
220+ * it would break the ABI.
221+ *
222+ * Return: -EAGAIN if ec_msg->result == EC_RES_IN_PROGRESS. Otherwise, 0.
205223 */
206224 int cros_ec_check_result(struct cros_ec_device *ec_dev,
207225 struct cros_ec_command *msg)
@@ -228,59 +246,66 @@ EXPORT_SYMBOL(cros_ec_check_result); · 20 unmodified lines
228246 *
229247 * @ec_dev: EC device to call
230248 * @msg: message structure to use
231− * @mask: result when function returns >=0.
249+ * @mask: result when function returns 0.
232250 *
233251 * LOCKING:
234252 * the caller has ec_dev->lock mutex, or the caller knows there is
235253 * no other command in progress.
236254 */
237−static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev,
238− struct cros_ec_command *msg,
239− uint32_t *mask)
255+static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev, uint32_t *mask)
240256 {
257+ struct cros_ec_command *msg;
241258 struct ec_response_host_event_mask *r;
242− int ret;
259+ int ret, mapped;
260+
261+ msg = kzalloc(sizeof(*msg) + sizeof(*r), GFP_KERNEL);
262+ if (!msg)
263+ return -ENOMEM;
243264
244265 msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;
245− msg->version = 0;
246− msg->outsize = 0;
247266 msg->insize = sizeof(*r);
248267
249− ret = send_command(ec_dev, msg);
250− if (ret >= 0) {
251− if (msg->result == EC_RES_INVALID_COMMAND)
252− return -EOPNOTSUPP;
253− if (msg->result != EC_RES_SUCCESS)
254− return -EPROTO;
268+ ret = cros_ec_send_command(ec_dev, msg);
269+ if (ret < 0)
270+ goto exit;
271+
272+ mapped = cros_ec_map_error(msg->result);
273+ if (mapped) {
274+ ret = mapped;
275+ goto exit;
255276 }
256− if (ret > 0) {
257− r = (struct ec_response_host_event_mask *)msg->data;
258− *mask = r->mask;
277+
278+ if (ret == 0) {
279+ ret = -EPROTO;
280+ goto exit;
259281 }
260282
283+ r = (struct ec_response_host_event_mask *)msg->data;
284+ *mask = r->mask;
285+ ret = 0;
286+exit:
287+ kfree(msg);
261288 return ret;
262289 }
263290
264−static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,
265− int devidx,
266− struct cros_ec_command *msg)
291+static int cros_ec_get_proto_info(struct cros_ec_device *ec_dev, int devidx)
267292 {
268− /*
269− * Try using v3+ to query for supported protocols. If this
270− * command fails, fall back to v2. Returns the highest protocol
271− * supported by the EC.
272− * Also sets the max request/response/passthru size.
273− */
274− int ret;
293+ struct cros_ec_command *msg;
294+ struct ec_response_get_protocol_info *info;
295+ int ret, mapped;
275296
276− if (!ec_dev->pkt_xfer)
277− return -EPROTONOSUPPORT;
297+ ec_dev->proto_version = 3;
298+ if (devidx > 0)
299+ ec_dev->max_passthru = 0;
300+
301+ msg = kzalloc(sizeof(*msg) + sizeof(*info), GFP_KERNEL);
302+ if (!msg)
303+ return -ENOMEM;
278304
279− memset(msg, 0, sizeof(*msg));
280305 msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;
281− msg->insize = sizeof(struct ec_response_get_protocol_info);
306+ msg->insize = sizeof(*info);
282307
283− ret = send_command(ec_dev, msg);
308+ ret = cros_ec_send_command(ec_dev, msg);
284309 /*
285310 * Send command once again when timeout occurred.
286311 * Fingerprint MCU (FPMCU) is restarted during system boot which
@@ -289,68 +314,115 @@ static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev, · 2 unmodified lines
289314 * attempt because we waited at least EC_MSG_DEADLINE_MS.
290315 */
291316 if (ret == -ETIMEDOUT)
292− ret = send_command(ec_dev, msg);
317+ ret = cros_ec_send_command(ec_dev, msg);
293318
294319 if (ret < 0) {
295320 dev_dbg(ec_dev->dev,
296321 "failed to check for EC[%d] protocol version: %d\n",
297322 devidx, ret);
298− return ret;
323+ goto exit;
299324 }
300325
301− if (devidx > 0 && msg->result == EC_RES_INVALID_COMMAND)
302− return -ENODEV;
303− else if (msg->result != EC_RES_SUCCESS)
304− return msg->result;
326+ mapped = cros_ec_map_error(msg->result);
327+ if (mapped) {
328+ ret = mapped;
329+ goto exit;
330+ }
305331
306− return 0;
332+ if (ret == 0) {
333+ ret = -EPROTO;
334+ goto exit;
335+ }
336+
337+ info = (struct ec_response_get_protocol_info *)msg->data;
338+
339+ switch (devidx) {
340+ case CROS_EC_DEV_EC_INDEX:
341+ ec_dev->max_request = info->max_request_packet_size -
342+ sizeof(struct ec_host_request);
343+ ec_dev->max_response = info->max_response_packet_size -
344+ sizeof(struct ec_host_response);
345+ ec_dev->proto_version = min(EC_HOST_REQUEST_VERSION,
346+ fls(info->protocol_versions) - 1);
347+ ec_dev->din_size = info->max_response_packet_size + EC_MAX_RESPONSE_OVERHEAD;
348+ ec_dev->dout_size = info->max_request_packet_size + EC_MAX_REQUEST_OVERHEAD;
349+
350+ dev_dbg(ec_dev->dev, "using proto v%u\n", ec_dev->proto_version);
351+ break;
352+ case CROS_EC_DEV_PD_INDEX:
353+ ec_dev->max_passthru = info->max_request_packet_size -
354+ sizeof(struct ec_host_request);
355+
356+ dev_dbg(ec_dev->dev, "found PD chip\n");
357+ break;
358+ default:
359+ dev_dbg(ec_dev->dev, "unknown passthru index: %d\n", devidx);
360+ break;
361+ }
362+
363+ ret = 0;
364+exit:
365+ kfree(msg);
366+ return ret;
307367 }
308368
309−static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev)
369+static int cros_ec_get_proto_info_legacy(struct cros_ec_device *ec_dev)
310370 {
311371 struct cros_ec_command *msg;
312− struct ec_params_hello *hello_params;
313− struct ec_response_hello *hello_response;
314− int ret;
315− int len = max(sizeof(*hello_params), sizeof(*hello_response));
372+ struct ec_params_hello *params;
373+ struct ec_response_hello *response;
374+ int ret, mapped;
375+
376+ ec_dev->proto_version = 2;
316377
317− msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);
378+ msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*response)), GFP_KERNEL);
318379 if (!msg)
319380 return -ENOMEM;
320381
321− msg->version = 0;
322382 msg->command = EC_CMD_HELLO;
323− hello_params = (struct ec_params_hello *)msg->data;
324− msg->outsize = sizeof(*hello_params);
325− hello_response = (struct ec_response_hello *)msg->data;
326− msg->insize = sizeof(*hello_response);
327−
328− hello_params->in_data = 0xa0b0c0d0;
383+ msg->insize = sizeof(*response);
384+ msg->outsize = sizeof(*params);
329385
330− ret = send_command(ec_dev, msg);
386+ params = (struct ec_params_hello *)msg->data;
387+ params->in_data = 0xa0b0c0d0;
331388
389+ ret = cros_ec_send_command(ec_dev, msg);
332390 if (ret < 0) {
333− dev_dbg(ec_dev->dev,
334− "EC failed to respond to v2 hello: %d\n",
335− ret);
391+ dev_dbg(ec_dev->dev, "EC failed to respond to v2 hello: %d\n", ret);
336392 goto exit;
337− } else if (msg->result != EC_RES_SUCCESS) {
338− dev_err(ec_dev->dev,
339− "EC responded to v2 hello with error: %d\n",
340− msg->result);
341− ret = msg->result;
393+ }
394+
395+ mapped = cros_ec_map_error(msg->result);
396+ if (mapped) {
397+ ret = mapped;
398+ dev_err(ec_dev->dev, "EC responded to v2 hello with error: %d\n", msg->result);
399+ goto exit;
400+ }
401+
402+ if (ret == 0) {
403+ ret = -EPROTO;
342404 goto exit;
343− } else if (hello_response->out_data != 0xa1b2c3d4) {
405+ }
406+
407+ response = (struct ec_response_hello *)msg->data;
408+ if (response->out_data != 0xa1b2c3d4) {
344409 dev_err(ec_dev->dev,
345410 "EC responded to v2 hello with bad result: %u\n",
346− hello_response->out_data);
411+ response->out_data);
347412 ret = -EBADMSG;
348413 goto exit;
349414 }
350415
351− ret = 0;
416+ ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
417+ ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
418+ ec_dev->max_passthru = 0;
419+ ec_dev->pkt_xfer = NULL;
420+ ec_dev->din_size = EC_PROTO2_MSG_BYTES;
421+ ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
352422
353− exit:
423+ dev_dbg(ec_dev->dev, "falling back to proto v2\n");
424+ ret = 0;
425+exit:
354426 kfree(msg);
355427 return ret;
356428 }
@@ -371,13 +443,12 @@ static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev) · 14 unmodified lines
371443 * the caller has ec_dev->lock mutex or the caller knows there is
372444 * no other command in progress.
373445 */
374−static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev,
375− u16 cmd, u32 *mask)
446+static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, u16 cmd, u32 *mask)
376447 {
377448 struct ec_params_get_cmd_versions *pver;
378449 struct ec_response_get_cmd_versions *rver;
379450 struct cros_ec_command *msg;
380− int ret;
451+ int ret, mapped;
381452
382453 msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),
383454 GFP_KERNEL);
@@ -392,14 +463,26 @@ static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, · 8 unmodified lines
392463 pver = (struct ec_params_get_cmd_versions *)msg->data;
393464 pver->cmd = cmd;
394465
395− ret = send_command(ec_dev, msg);
396− if (ret > 0) {
397− rver = (struct ec_response_get_cmd_versions *)msg->data;
398− *mask = rver->version_mask;
466+ ret = cros_ec_send_command(ec_dev, msg);
467+ if (ret < 0)
468+ goto exit;
469+
470+ mapped = cros_ec_map_error(msg->result);
471+ if (mapped) {
472+ ret = mapped;
473+ goto exit;
399474 }
400475
401− kfree(msg);
476+ if (ret == 0) {
477+ ret = -EPROTO;
478+ goto exit;
479+ }
402480
481+ rver = (struct ec_response_get_cmd_versions *)msg->data;
482+ *mask = rver->version_mask;
483+ ret = 0;
484+exit:
485+ kfree(msg);
403486 return ret;
404487 }
405488
@@ -413,71 +496,17 @@ static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, · 7 unmodified lines
413496 int cros_ec_query_all(struct cros_ec_device *ec_dev)
414497 {
415498 struct device *dev = ec_dev->dev;
416− struct cros_ec_command *proto_msg;
417− struct ec_response_get_protocol_info *proto_info;
418− u32 ver_mask = 0;
499+ u32 ver_mask;
419500 int ret;
420501
421− proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
422− GFP_KERNEL);
423− if (!proto_msg)
424− return -ENOMEM;
425−
426502 /* First try sending with proto v3. */
427− ec_dev->proto_version = 3;
428− ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg);
429−
430− if (ret == 0) {
431− proto_info = (struct ec_response_get_protocol_info *)
432− proto_msg->data;
433− ec_dev->max_request = proto_info->max_request_packet_size -
434− sizeof(struct ec_host_request);
435− ec_dev->max_response = proto_info->max_response_packet_size -
436− sizeof(struct ec_host_response);
437− ec_dev->proto_version =
438− min(EC_HOST_REQUEST_VERSION,
439− fls(proto_info->protocol_versions) - 1);
440− dev_dbg(ec_dev->dev,
441− "using proto v%u\n",
442− ec_dev->proto_version);
443−
444− ec_dev->din_size = ec_dev->max_response +
445− sizeof(struct ec_host_response) +
446− EC_MAX_RESPONSE_OVERHEAD;
447− ec_dev->dout_size = ec_dev->max_request +
448− sizeof(struct ec_host_request) +
449− EC_MAX_REQUEST_OVERHEAD;
450−
451− /*
452− * Check for PD
453− */
454− ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg);
455−
456− if (ret) {
457− dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret);
458− ec_dev->max_passthru = 0;
459− } else {
460− dev_dbg(ec_dev->dev, "found PD chip\n");
461− ec_dev->max_passthru =
462− proto_info->max_request_packet_size -
463− sizeof(struct ec_host_request);
464− }
503+ if (!cros_ec_get_proto_info(ec_dev, CROS_EC_DEV_EC_INDEX)) {
504+ /* Check for PD. */
505+ cros_ec_get_proto_info(ec_dev, CROS_EC_DEV_PD_INDEX);
465506 } else {
466507 /* Try querying with a v2 hello message. */
467− ec_dev->proto_version = 2;
468− ret = cros_ec_host_command_proto_query_v2(ec_dev);
469−
470− if (ret == 0) {
471− /* V2 hello succeeded. */
472− dev_dbg(ec_dev->dev, "falling back to proto v2\n");
473−
474− ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
475− ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
476− ec_dev->max_passthru = 0;
477− ec_dev->pkt_xfer = NULL;
478− ec_dev->din_size = EC_PROTO2_MSG_BYTES;
479− ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
480− } else {
508+ ret = cros_ec_get_proto_info_legacy(ec_dev);
509+ if (ret) {
481510 /*
482511 * It's possible for a test to occur too early when
483512 * the EC isn't listening. If this happens, we'll
@@ -485,7 +514,7 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) · 1 unmodified line
485514 */
486515 ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
487516 dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
488− goto exit;
517+ return ret;
489518 }
490519 }
491520
@@ -506,26 +535,21 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) · 14 unmodified lines
506535 }
507536
508537 /* Probe if MKBP event is supported */
509− ret = cros_ec_get_host_command_version_mask(ec_dev,
510− EC_CMD_GET_NEXT_EVENT,
511− &ver_mask);
512− if (ret < 0 || ver_mask == 0)
538+ ret = cros_ec_get_host_command_version_mask(ec_dev, EC_CMD_GET_NEXT_EVENT, &ver_mask);
539+ if (ret < 0 || ver_mask == 0) {
513540 ec_dev->mkbp_event_supported = 0;
514− else
541+ } else {
515542 ec_dev->mkbp_event_supported = fls(ver_mask);
516543
517− dev_dbg(ec_dev->dev, "MKBP support version %u\n",
518− ec_dev->mkbp_event_supported - 1);
544+ dev_dbg(ec_dev->dev, "MKBP support version %u\n", ec_dev->mkbp_event_supported - 1);
545+ }
519546
520547 /* Probe if host sleep v1 is supported for S0ix failure detection. */
521− ret = cros_ec_get_host_command_version_mask(ec_dev,
522− EC_CMD_HOST_SLEEP_EVENT,
523− &ver_mask);
524− ec_dev->host_sleep_v1 = (ret >= 0 && (ver_mask & EC_VER_MASK(1)));
548+ ret = cros_ec_get_host_command_version_mask(ec_dev, EC_CMD_HOST_SLEEP_EVENT, &ver_mask);
549+ ec_dev->host_sleep_v1 = (ret == 0 && (ver_mask & EC_VER_MASK(1)));
525550
526551 /* Get host event wake mask. */
527− ret = cros_ec_get_host_event_wake_mask(ec_dev, proto_msg,
528− &ec_dev->host_event_wake_mask);
552+ ret = cros_ec_get_host_event_wake_mask(ec_dev, &ec_dev->host_event_wake_mask);
529553 if (ret < 0) {
530554 /*
531555 * If the EC doesn't support EC_CMD_HOST_EVENT_GET_WAKE_MASK,
@@ -556,7 +580,6 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) · 24 unmodified lines
556580 ret = 0;
557581
558582 exit:
559− kfree(proto_msg);
560583 return ret;
561584 }
562585 EXPORT_SYMBOL(cros_ec_query_all);
@@ -601,7 +624,7 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) · 38 unmodified lines
601624 msg->insize = ec_dev->max_response;
602625 }
603626
604− if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) {
627+ if (msg->command < EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX)) {
605628 if (msg->outsize > ec_dev->max_request) {
606629 dev_err(ec_dev->dev,
607630 "request of size %u is too big (max: %u)\n",
@@ -621,7 +644,7 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) · 13 unmodified lines
621644 }
622645 }
623646
624− ret = send_command(ec_dev, msg);
647+ ret = cros_ec_send_command(ec_dev, msg);
625648 mutex_unlock(&ec_dev->lock);
626649
627650 return ret;
@@ -852,8 +875,8 @@ bool cros_ec_check_features(struct cros_ec_dev *ec, int feature) · 224 unmodified lines
852875
853876 if (features->flags[0] == -1U && features->flags[1] == -1U) {
854877 /* features bitmap not read yet */
855− ret = cros_ec_command(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,
856− NULL, 0, features, sizeof(*features));
878+ ret = cros_ec_cmd(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,
879+ NULL, 0, features, sizeof(*features));
857880 if (ret < 0) {
858881 dev_warn(ec->dev, "cannot get EC features: %d\n", ret);
859882 memset(features, 0, sizeof(*features));
@@ -934,7 +957,7 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) · 74 unmodified lines
934957 EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count);
935958
936959 /**
937− * cros_ec_command - Send a command to the EC.
960+ * cros_ec_cmd - Send a command to the EC.
938961 *
939962 * @ec_dev: EC device
940963 * @version: EC command version
@@ -946,13 +969,13 @@ EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count); · 5 unmodified lines
946969 *
947970 * Return: >= 0 on success, negative error number on failure.
948971 */
949−int cros_ec_command(struct cros_ec_device *ec_dev,
950− unsigned int version,
951− int command,
952− void *outdata,
953− int outsize,
954− void *indata,
955− int insize)
972+int cros_ec_cmd(struct cros_ec_device *ec_dev,
973+ unsigned int version,
974+ int command,
975+ void *outdata,
976+ size_t outsize,
977+ void *indata,
978+ size_t insize)
956979 {
957980 struct cros_ec_command *msg;
958981 int ret;
@@ -979,4 +1002,4 @@ error: · 20 unmodified lines
9791002 kfree(msg);
9801003 return ret;
9811004 }
982−EXPORT_SYMBOL_GPL(cros_ec_command);
1005+EXPORT_SYMBOL_GPL(cros_ec_cmd);
drivers/platform/chrome/cros_ec_proto_test.c+2753−0
@@ -0,0 +1,2753 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Kunit tests for ChromeOS Embedded Controller protocol.
4+ */
5+
6+#include <kunit/test.h>
7+
8+#include <asm-generic/unaligned.h>
9+#include <linux/platform_data/cros_ec_commands.h>
10+#include <linux/platform_data/cros_ec_proto.h>
11+
12+#include "cros_ec.h"
13+#include "cros_kunit_util.h"
14+
15+#define BUFSIZE 512
16+
17+struct cros_ec_proto_test_priv {
18+ struct cros_ec_device ec_dev;
19+ u8 dout[BUFSIZE];
20+ u8 din[BUFSIZE];
21+ struct cros_ec_command *msg;
22+ u8 _msg[BUFSIZE];
23+};
24+
25+static void cros_ec_proto_test_prepare_tx_legacy_normal(struct kunit *test)
26+{
27+ struct cros_ec_proto_test_priv *priv = test->priv;
28+ struct cros_ec_device *ec_dev = &priv->ec_dev;
29+ struct cros_ec_command *msg = priv->msg;
30+ int ret, i;
31+ u8 csum;
32+
33+ ec_dev->proto_version = 2;
34+
35+ msg->command = EC_CMD_HELLO;
36+ msg->outsize = EC_PROTO2_MAX_PARAM_SIZE;
37+ msg->data[0] = 0xde;
38+ msg->data[1] = 0xad;
39+ msg->data[2] = 0xbe;
40+ msg->data[3] = 0xef;
41+
42+ ret = cros_ec_prepare_tx(ec_dev, msg);
43+
44+ KUNIT_EXPECT_EQ(test, ret, EC_MSG_TX_PROTO_BYTES + EC_PROTO2_MAX_PARAM_SIZE);
45+ KUNIT_EXPECT_EQ(test, ec_dev->dout[0], EC_CMD_VERSION0);
46+ KUNIT_EXPECT_EQ(test, ec_dev->dout[1], EC_CMD_HELLO);
47+ KUNIT_EXPECT_EQ(test, ec_dev->dout[2], EC_PROTO2_MAX_PARAM_SIZE);
48+ KUNIT_EXPECT_EQ(test, EC_MSG_TX_HEADER_BYTES, 3);
49+ KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 0], 0xde);
50+ KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 1], 0xad);
51+ KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 2], 0xbe);
52+ KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + 3], 0xef);
53+ for (i = 4; i < EC_PROTO2_MAX_PARAM_SIZE; ++i)
54+ KUNIT_EXPECT_EQ(test, ec_dev->dout[EC_MSG_TX_HEADER_BYTES + i], 0);
55+
56+ csum = EC_CMD_VERSION0;
57+ csum += EC_CMD_HELLO;
58+ csum += EC_PROTO2_MAX_PARAM_SIZE;
59+ csum += 0xde;
60+ csum += 0xad;
61+ csum += 0xbe;
62+ csum += 0xef;
63+ KUNIT_EXPECT_EQ(test,
64+ ec_dev->dout[EC_MSG_TX_HEADER_BYTES + EC_PROTO2_MAX_PARAM_SIZE],
65+ csum);
66+}
67+
68+static void cros_ec_proto_test_prepare_tx_legacy_bad_msg_outsize(struct kunit *test)
69+{
70+ struct cros_ec_proto_test_priv *priv = test->priv;
71+ struct cros_ec_device *ec_dev = &priv->ec_dev;
72+ struct cros_ec_command *msg = priv->msg;
73+ int ret;
74+
75+ ec_dev->proto_version = 2;
76+
77+ msg->outsize = EC_PROTO2_MAX_PARAM_SIZE + 1;
78+
79+ ret = cros_ec_prepare_tx(ec_dev, msg);
80+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
81+}
82+
83+static void cros_ec_proto_test_prepare_tx_normal(struct kunit *test)
84+{
85+ struct cros_ec_proto_test_priv *priv = test->priv;
86+ struct cros_ec_device *ec_dev = &priv->ec_dev;
87+ struct cros_ec_command *msg = priv->msg;
88+ struct ec_host_request *request = (struct ec_host_request *)ec_dev->dout;
89+ int ret, i;
90+ u8 csum;
91+
92+ msg->command = EC_CMD_HELLO;
93+ msg->outsize = 0x88;
94+ msg->data[0] = 0xde;
95+ msg->data[1] = 0xad;
96+ msg->data[2] = 0xbe;
97+ msg->data[3] = 0xef;
98+
99+ ret = cros_ec_prepare_tx(ec_dev, msg);
100+
101+ KUNIT_EXPECT_EQ(test, ret, sizeof(*request) + 0x88);
102+
103+ KUNIT_EXPECT_EQ(test, request->struct_version, EC_HOST_REQUEST_VERSION);
104+ KUNIT_EXPECT_EQ(test, request->command, EC_CMD_HELLO);
105+ KUNIT_EXPECT_EQ(test, request->command_version, 0);
106+ KUNIT_EXPECT_EQ(test, request->data_len, 0x88);
107+ KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 0], 0xde);
108+ KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 1], 0xad);
109+ KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 2], 0xbe);
110+ KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + 3], 0xef);
111+ for (i = 4; i < 0x88; ++i)
112+ KUNIT_EXPECT_EQ(test, ec_dev->dout[sizeof(*request) + i], 0);
113+
114+ csum = EC_HOST_REQUEST_VERSION;
115+ csum += EC_CMD_HELLO;
116+ csum += 0x88;
117+ csum += 0xde;
118+ csum += 0xad;
119+ csum += 0xbe;
120+ csum += 0xef;
121+ KUNIT_EXPECT_EQ(test, request->checksum, (u8)-csum);
122+}
123+
124+static void cros_ec_proto_test_prepare_tx_bad_msg_outsize(struct kunit *test)
125+{
126+ struct cros_ec_proto_test_priv *priv = test->priv;
127+ struct cros_ec_device *ec_dev = &priv->ec_dev;
128+ struct cros_ec_command *msg = priv->msg;
129+ int ret;
130+
131+ msg->outsize = ec_dev->dout_size - sizeof(struct ec_host_request) + 1;
132+
133+ ret = cros_ec_prepare_tx(ec_dev, msg);
134+ KUNIT_EXPECT_EQ(test, ret, -EINVAL);
135+}
136+
137+static void cros_ec_proto_test_check_result(struct kunit *test)
138+{
139+ struct cros_ec_proto_test_priv *priv = test->priv;
140+ struct cros_ec_device *ec_dev = &priv->ec_dev;
141+ struct cros_ec_command *msg = priv->msg;
142+ int ret, i;
143+ static enum ec_status status[] = {
144+ EC_RES_SUCCESS,
145+ EC_RES_INVALID_COMMAND,
146+ EC_RES_ERROR,
147+ EC_RES_INVALID_PARAM,
148+ EC_RES_ACCESS_DENIED,
149+ EC_RES_INVALID_RESPONSE,
150+ EC_RES_INVALID_VERSION,
151+ EC_RES_INVALID_CHECKSUM,
152+ EC_RES_UNAVAILABLE,
153+ EC_RES_TIMEOUT,
154+ EC_RES_OVERFLOW,
155+ EC_RES_INVALID_HEADER,
156+ EC_RES_REQUEST_TRUNCATED,
157+ EC_RES_RESPONSE_TOO_BIG,
158+ EC_RES_BUS_ERROR,
159+ EC_RES_BUSY,
160+ EC_RES_INVALID_HEADER_VERSION,
161+ EC_RES_INVALID_HEADER_CRC,
162+ EC_RES_INVALID_DATA_CRC,
163+ EC_RES_DUP_UNAVAILABLE,
164+ };
165+
166+ for (i = 0; i < ARRAY_SIZE(status); ++i) {
167+ msg->result = status[i];
168+ ret = cros_ec_check_result(ec_dev, msg);
169+ KUNIT_EXPECT_EQ(test, ret, 0);
170+ }
171+
172+ msg->result = EC_RES_IN_PROGRESS;
173+ ret = cros_ec_check_result(ec_dev, msg);
174+ KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
175+}
176+
177+static void cros_ec_proto_test_query_all_pretest(struct kunit *test)
178+{
179+ struct cros_ec_proto_test_priv *priv = test->priv;
180+ struct cros_ec_device *ec_dev = &priv->ec_dev;
181+
182+ /*
183+ * cros_ec_query_all() will free din and dout and allocate them again to fit the usage by
184+ * calling devm_kfree() and devm_kzalloc(). Set them to NULL as they aren't managed by
185+ * ec_dev->dev but allocated statically in struct cros_ec_proto_test_priv
186+ * (see cros_ec_proto_test_init()).
187+ */
188+ ec_dev->din = NULL;
189+ ec_dev->dout = NULL;
190+}
191+
192+static void cros_ec_proto_test_query_all_normal(struct kunit *test)
193+{
194+ struct cros_ec_proto_test_priv *priv = test->priv;
195+ struct cros_ec_device *ec_dev = &priv->ec_dev;
196+ struct ec_xfer_mock *mock;
197+ int ret;
198+
199+ /* For cros_ec_get_proto_info() without passthru. */
200+ {
201+ struct ec_response_get_protocol_info *data;
202+
203+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
204+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
205+
206+ data = (struct ec_response_get_protocol_info *)mock->o_data;
207+ data->protocol_versions = BIT(3) | BIT(2);
208+ data->max_request_packet_size = 0xbe;
209+ data->max_response_packet_size = 0xef;
210+ }
211+
212+ /* For cros_ec_get_proto_info() with passthru. */
213+ {
214+ struct ec_response_get_protocol_info *data;
215+
216+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
217+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
218+
219+ data = (struct ec_response_get_protocol_info *)mock->o_data;
220+ data->max_request_packet_size = 0xbf;
221+ }
222+
223+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
224+ {
225+ struct ec_response_get_cmd_versions *data;
226+
227+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
228+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
229+
230+ data = (struct ec_response_get_cmd_versions *)mock->o_data;
231+ data->version_mask = BIT(6) | BIT(5);
232+ }
233+
234+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
235+ {
236+ struct ec_response_get_cmd_versions *data;
237+
238+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
239+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
240+
241+ data = (struct ec_response_get_cmd_versions *)mock->o_data;
242+ data->version_mask = BIT(1);
243+ }
244+
245+ /* For cros_ec_get_host_event_wake_mask(). */
246+ {
247+ struct ec_response_host_event_mask *data;
248+
249+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
250+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
251+
252+ data = (struct ec_response_host_event_mask *)mock->o_data;
253+ data->mask = 0xbeef;
254+ }
255+
256+ cros_ec_proto_test_query_all_pretest(test);
257+ ret = cros_ec_query_all(ec_dev);
258+ KUNIT_EXPECT_EQ(test, ret, 0);
259+
260+ /* For cros_ec_get_proto_info() without passthru. */
261+ {
262+ mock = cros_kunit_ec_xfer_mock_next();
263+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
264+
265+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
266+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
267+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
268+ sizeof(struct ec_response_get_protocol_info));
269+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
270+
271+ KUNIT_EXPECT_EQ(test, ec_dev->max_request, 0xbe - sizeof(struct ec_host_request));
272+ KUNIT_EXPECT_EQ(test, ec_dev->max_response, 0xef - sizeof(struct ec_host_response));
273+ KUNIT_EXPECT_EQ(test, ec_dev->proto_version, 3);
274+ KUNIT_EXPECT_EQ(test, ec_dev->din_size, 0xef + EC_MAX_RESPONSE_OVERHEAD);
275+ KUNIT_EXPECT_EQ(test, ec_dev->dout_size, 0xbe + EC_MAX_REQUEST_OVERHEAD);
276+ }
277+
278+ /* For cros_ec_get_proto_info() with passthru. */
279+ {
280+ mock = cros_kunit_ec_xfer_mock_next();
281+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
282+
283+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
284+ KUNIT_EXPECT_EQ(test, mock->msg.command,
285+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
286+ EC_CMD_GET_PROTOCOL_INFO);
287+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
288+ sizeof(struct ec_response_get_protocol_info));
289+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
290+
291+ KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0xbf - sizeof(struct ec_host_request));
292+ }
293+
294+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
295+ {
296+ struct ec_params_get_cmd_versions *data;
297+
298+ mock = cros_kunit_ec_xfer_mock_next();
299+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
300+
301+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
302+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
303+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
304+ sizeof(struct ec_response_get_cmd_versions));
305+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
306+
307+ data = (struct ec_params_get_cmd_versions *)mock->i_data;
308+ KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
309+
310+ KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 7);
311+ }
312+
313+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
314+ {
315+ struct ec_params_get_cmd_versions *data;
316+
317+ mock = cros_kunit_ec_xfer_mock_next();
318+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
319+
320+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
321+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
322+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
323+ sizeof(struct ec_response_get_cmd_versions));
324+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
325+
326+ data = (struct ec_params_get_cmd_versions *)mock->i_data;
327+ KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_HOST_SLEEP_EVENT);
328+
329+ KUNIT_EXPECT_TRUE(test, ec_dev->host_sleep_v1);
330+ }
331+
332+ /* For cros_ec_get_host_event_wake_mask(). */
333+ {
334+ mock = cros_kunit_ec_xfer_mock_next();
335+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
336+
337+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
338+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HOST_EVENT_GET_WAKE_MASK);
339+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_host_event_mask));
340+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
341+
342+ KUNIT_EXPECT_EQ(test, ec_dev->host_event_wake_mask, 0xbeef);
343+ }
344+}
345+
346+static void cros_ec_proto_test_query_all_no_pd_return_error(struct kunit *test)
347+{
348+ struct cros_ec_proto_test_priv *priv = test->priv;
349+ struct cros_ec_device *ec_dev = &priv->ec_dev;
350+ struct ec_xfer_mock *mock;
351+ int ret;
352+
353+ /* Set some garbage bytes. */
354+ ec_dev->max_passthru = 0xbf;
355+
356+ /* For cros_ec_get_proto_info() without passthru. */
357+ {
358+ struct ec_response_get_protocol_info *data;
359+
360+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
361+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
362+
363+ /*
364+ * Although it doesn't check the value, provides valid sizes so that
365+ * cros_ec_query_all() allocates din and dout correctly.
366+ */
367+ data = (struct ec_response_get_protocol_info *)mock->o_data;
368+ data->max_request_packet_size = 0xbe;
369+ data->max_response_packet_size = 0xef;
370+ }
371+
372+ /* For cros_ec_get_proto_info() with passthru. */
373+ {
374+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
375+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
376+ }
377+
378+ cros_ec_proto_test_query_all_pretest(test);
379+ ret = cros_ec_query_all(ec_dev);
380+ KUNIT_EXPECT_EQ(test, ret, 0);
381+
382+ /* For cros_ec_get_proto_info() without passthru. */
383+ {
384+ mock = cros_kunit_ec_xfer_mock_next();
385+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
386+
387+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
388+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
389+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
390+ sizeof(struct ec_response_get_protocol_info));
391+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
392+ }
393+
394+ /* For cros_ec_get_proto_info() with passthru. */
395+ {
396+ mock = cros_kunit_ec_xfer_mock_next();
397+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
398+
399+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
400+ KUNIT_EXPECT_EQ(test, mock->msg.command,
401+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
402+ EC_CMD_GET_PROTOCOL_INFO);
403+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
404+ sizeof(struct ec_response_get_protocol_info));
405+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
406+
407+ KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
408+ }
409+}
410+
411+static void cros_ec_proto_test_query_all_no_pd_return0(struct kunit *test)
412+{
413+ struct cros_ec_proto_test_priv *priv = test->priv;
414+ struct cros_ec_device *ec_dev = &priv->ec_dev;
415+ struct ec_xfer_mock *mock;
416+ int ret;
417+
418+ /* Set some garbage bytes. */
419+ ec_dev->max_passthru = 0xbf;
420+
421+ /* For cros_ec_get_proto_info() without passthru. */
422+ {
423+ struct ec_response_get_protocol_info *data;
424+
425+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
426+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
427+
428+ /*
429+ * Although it doesn't check the value, provides valid sizes so that
430+ * cros_ec_query_all() allocates din and dout correctly.
431+ */
432+ data = (struct ec_response_get_protocol_info *)mock->o_data;
433+ data->max_request_packet_size = 0xbe;
434+ data->max_response_packet_size = 0xef;
435+ }
436+
437+ /* For cros_ec_get_proto_info() with passthru. */
438+ {
439+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
440+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
441+ }
442+
443+ cros_ec_proto_test_query_all_pretest(test);
444+ ret = cros_ec_query_all(ec_dev);
445+ KUNIT_EXPECT_EQ(test, ret, 0);
446+
447+ /* For cros_ec_get_proto_info() without passthru. */
448+ {
449+ mock = cros_kunit_ec_xfer_mock_next();
450+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
451+
452+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
453+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
454+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
455+ sizeof(struct ec_response_get_protocol_info));
456+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
457+ }
458+
459+ /* For cros_ec_get_proto_info() with passthru. */
460+ {
461+ mock = cros_kunit_ec_xfer_mock_next();
462+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
463+
464+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
465+ KUNIT_EXPECT_EQ(test, mock->msg.command,
466+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
467+ EC_CMD_GET_PROTOCOL_INFO);
468+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
469+ sizeof(struct ec_response_get_protocol_info));
470+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
471+
472+ KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
473+ }
474+}
475+
476+static void cros_ec_proto_test_query_all_legacy_normal_v3_return_error(struct kunit *test)
477+{
478+ struct cros_ec_proto_test_priv *priv = test->priv;
479+ struct cros_ec_device *ec_dev = &priv->ec_dev;
480+ struct ec_xfer_mock *mock;
481+ int ret;
482+
483+ /* For cros_ec_get_proto_info() without passthru. */
484+ {
485+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
486+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
487+ }
488+
489+ /* For cros_ec_get_proto_info_legacy(). */
490+ {
491+ struct ec_response_hello *data;
492+
493+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
494+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
495+
496+ data = (struct ec_response_hello *)mock->o_data;
497+ data->out_data = 0xa1b2c3d4;
498+ }
499+
500+ cros_ec_proto_test_query_all_pretest(test);
501+ ret = cros_ec_query_all(ec_dev);
502+ KUNIT_EXPECT_EQ(test, ret, 0);
503+
504+ /* For cros_ec_get_proto_info() without passthru. */
505+ {
506+ mock = cros_kunit_ec_xfer_mock_next();
507+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
508+
509+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
510+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
511+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
512+ sizeof(struct ec_response_get_protocol_info));
513+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
514+ }
515+
516+ /* For cros_ec_get_proto_info_legacy(). */
517+ {
518+ struct ec_params_hello *data;
519+
520+ mock = cros_kunit_ec_xfer_mock_next();
521+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
522+
523+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
524+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
525+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
526+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
527+
528+ data = (struct ec_params_hello *)mock->i_data;
529+ KUNIT_EXPECT_EQ(test, data->in_data, 0xa0b0c0d0);
530+
531+ KUNIT_EXPECT_EQ(test, ec_dev->proto_version, 2);
532+ KUNIT_EXPECT_EQ(test, ec_dev->max_request, EC_PROTO2_MAX_PARAM_SIZE);
533+ KUNIT_EXPECT_EQ(test, ec_dev->max_response, EC_PROTO2_MAX_PARAM_SIZE);
534+ KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
535+ KUNIT_EXPECT_PTR_EQ(test, ec_dev->pkt_xfer, NULL);
536+ KUNIT_EXPECT_EQ(test, ec_dev->din_size, EC_PROTO2_MSG_BYTES);
537+ KUNIT_EXPECT_EQ(test, ec_dev->dout_size, EC_PROTO2_MSG_BYTES);
538+ }
539+}
540+
541+static void cros_ec_proto_test_query_all_legacy_normal_v3_return0(struct kunit *test)
542+{
543+ struct cros_ec_proto_test_priv *priv = test->priv;
544+ struct cros_ec_device *ec_dev = &priv->ec_dev;
545+ struct ec_xfer_mock *mock;
546+ int ret;
547+
548+ /* For cros_ec_get_proto_info() without passthru. */
549+ {
550+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
551+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
552+ }
553+
554+ /* For cros_ec_get_proto_info_legacy(). */
555+ {
556+ struct ec_response_hello *data;
557+
558+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
559+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
560+
561+ data = (struct ec_response_hello *)mock->o_data;
562+ data->out_data = 0xa1b2c3d4;
563+ }
564+
565+ cros_ec_proto_test_query_all_pretest(test);
566+ ret = cros_ec_query_all(ec_dev);
567+ KUNIT_EXPECT_EQ(test, ret, 0);
568+
569+ /* For cros_ec_get_proto_info() without passthru. */
570+ {
571+ mock = cros_kunit_ec_xfer_mock_next();
572+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
573+
574+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
575+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
576+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
577+ sizeof(struct ec_response_get_protocol_info));
578+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
579+ }
580+
581+ /* For cros_ec_get_proto_info_legacy(). */
582+ {
583+ struct ec_params_hello *data;
584+
585+ mock = cros_kunit_ec_xfer_mock_next();
586+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
587+
588+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
589+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
590+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
591+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
592+
593+ data = (struct ec_params_hello *)mock->i_data;
594+ KUNIT_EXPECT_EQ(test, data->in_data, 0xa0b0c0d0);
595+
596+ KUNIT_EXPECT_EQ(test, ec_dev->proto_version, 2);
597+ KUNIT_EXPECT_EQ(test, ec_dev->max_request, EC_PROTO2_MAX_PARAM_SIZE);
598+ KUNIT_EXPECT_EQ(test, ec_dev->max_response, EC_PROTO2_MAX_PARAM_SIZE);
599+ KUNIT_EXPECT_EQ(test, ec_dev->max_passthru, 0);
600+ KUNIT_EXPECT_PTR_EQ(test, ec_dev->pkt_xfer, NULL);
601+ KUNIT_EXPECT_EQ(test, ec_dev->din_size, EC_PROTO2_MSG_BYTES);
602+ KUNIT_EXPECT_EQ(test, ec_dev->dout_size, EC_PROTO2_MSG_BYTES);
603+ }
604+}
605+
606+static void cros_ec_proto_test_query_all_legacy_xfer_error(struct kunit *test)
607+{
608+ struct cros_ec_proto_test_priv *priv = test->priv;
609+ struct cros_ec_device *ec_dev = &priv->ec_dev;
610+ struct ec_xfer_mock *mock;
611+ int ret;
612+
613+ /* For cros_ec_get_proto_info() without passthru. */
614+ {
615+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
616+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
617+ }
618+
619+ /* For cros_ec_get_proto_info_legacy(). */
620+ {
621+ mock = cros_kunit_ec_xfer_mock_addx(test, -EIO, EC_RES_SUCCESS, 0);
622+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
623+ }
624+
625+ cros_ec_proto_test_query_all_pretest(test);
626+ ret = cros_ec_query_all(ec_dev);
627+ KUNIT_EXPECT_EQ(test, ret, -EIO);
628+ KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
629+
630+ /* For cros_ec_get_proto_info() without passthru. */
631+ {
632+ mock = cros_kunit_ec_xfer_mock_next();
633+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
634+
635+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
636+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
637+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
638+ sizeof(struct ec_response_get_protocol_info));
639+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
640+ }
641+
642+ /* For cros_ec_get_proto_info_legacy(). */
643+ {
644+ mock = cros_kunit_ec_xfer_mock_next();
645+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
646+
647+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
648+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
649+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
650+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
651+ }
652+}
653+
654+static void cros_ec_proto_test_query_all_legacy_return_error(struct kunit *test)
655+{
656+ struct cros_ec_proto_test_priv *priv = test->priv;
657+ struct cros_ec_device *ec_dev = &priv->ec_dev;
658+ struct ec_xfer_mock *mock;
659+ int ret;
660+
661+ /* For cros_ec_get_proto_info() without passthru. */
662+ {
663+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
664+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
665+ }
666+
667+ /* For cros_ec_get_proto_info_legacy(). */
668+ {
669+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
670+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
671+ }
672+
673+ cros_ec_proto_test_query_all_pretest(test);
674+ ret = cros_ec_query_all(ec_dev);
675+ KUNIT_EXPECT_EQ(test, ret, -EOPNOTSUPP);
676+ KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
677+
678+ /* For cros_ec_get_proto_info() without passthru. */
679+ {
680+ mock = cros_kunit_ec_xfer_mock_next();
681+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
682+
683+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
684+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
685+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
686+ sizeof(struct ec_response_get_protocol_info));
687+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
688+ }
689+
690+ /* For cros_ec_get_proto_info_legacy(). */
691+ {
692+ mock = cros_kunit_ec_xfer_mock_next();
693+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
694+
695+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
696+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
697+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
698+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
699+ }
700+}
701+
702+static void cros_ec_proto_test_query_all_legacy_data_error(struct kunit *test)
703+{
704+ struct cros_ec_proto_test_priv *priv = test->priv;
705+ struct cros_ec_device *ec_dev = &priv->ec_dev;
706+ struct ec_xfer_mock *mock;
707+ int ret;
708+
709+ /* For cros_ec_get_proto_info() without passthru. */
710+ {
711+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
712+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
713+ }
714+
715+ /* For cros_ec_get_proto_info_legacy(). */
716+ {
717+ struct ec_response_hello *data;
718+
719+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
720+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
721+
722+ data = (struct ec_response_hello *)mock->o_data;
723+ data->out_data = 0xbeefbfbf;
724+ }
725+
726+ cros_ec_proto_test_query_all_pretest(test);
727+ ret = cros_ec_query_all(ec_dev);
728+ KUNIT_EXPECT_EQ(test, ret, -EBADMSG);
729+ KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
730+
731+ /* For cros_ec_get_proto_info() without passthru. */
732+ {
733+ mock = cros_kunit_ec_xfer_mock_next();
734+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
735+
736+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
737+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
738+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
739+ sizeof(struct ec_response_get_protocol_info));
740+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
741+ }
742+
743+ /* For cros_ec_get_proto_info_legacy(). */
744+ {
745+ mock = cros_kunit_ec_xfer_mock_next();
746+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
747+
748+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
749+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
750+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
751+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
752+ }
753+}
754+
755+static void cros_ec_proto_test_query_all_legacy_return0(struct kunit *test)
756+{
757+ struct cros_ec_proto_test_priv *priv = test->priv;
758+ struct cros_ec_device *ec_dev = &priv->ec_dev;
759+ struct ec_xfer_mock *mock;
760+ int ret;
761+
762+ /* For cros_ec_get_proto_info() without passthru. */
763+ {
764+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
765+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
766+ }
767+
768+ /* For cros_ec_get_proto_info_legacy(). */
769+ {
770+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
771+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
772+ }
773+
774+ cros_ec_proto_test_query_all_pretest(test);
775+ ret = cros_ec_query_all(ec_dev);
776+ KUNIT_EXPECT_EQ(test, ret, -EPROTO);
777+ KUNIT_EXPECT_EQ(test, ec_dev->proto_version, EC_PROTO_VERSION_UNKNOWN);
778+
779+ /* For cros_ec_get_proto_info() without passthru. */
780+ {
781+ mock = cros_kunit_ec_xfer_mock_next();
782+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
783+
784+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
785+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
786+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
787+ sizeof(struct ec_response_get_protocol_info));
788+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
789+ }
790+
791+ /* For cros_ec_get_proto_info_legacy(). */
792+ {
793+ mock = cros_kunit_ec_xfer_mock_next();
794+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
795+
796+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
797+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
798+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_hello));
799+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_hello));
800+ }
801+}
802+
803+static void cros_ec_proto_test_query_all_no_mkbp(struct kunit *test)
804+{
805+ struct cros_ec_proto_test_priv *priv = test->priv;
806+ struct cros_ec_device *ec_dev = &priv->ec_dev;
807+ struct ec_xfer_mock *mock;
808+ int ret;
809+
810+ /* Set some garbage bytes. */
811+ ec_dev->mkbp_event_supported = 0xbf;
812+
813+ /* For cros_ec_get_proto_info() without passthru. */
814+ {
815+ struct ec_response_get_protocol_info *data;
816+
817+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
818+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
819+
820+ /*
821+ * Although it doesn't check the value, provides valid sizes so that
822+ * cros_ec_query_all() allocates din and dout correctly.
823+ */
824+ data = (struct ec_response_get_protocol_info *)mock->o_data;
825+ data->max_request_packet_size = 0xbe;
826+ data->max_response_packet_size = 0xef;
827+ }
828+
829+ /* For cros_ec_get_proto_info() with passthru. */
830+ {
831+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
832+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
833+ }
834+
835+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
836+ {
837+ struct ec_response_get_cmd_versions *data;
838+
839+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
840+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
841+
842+ data = (struct ec_response_get_cmd_versions *)mock->o_data;
843+ data->version_mask = 0;
844+ }
845+
846+ cros_ec_proto_test_query_all_pretest(test);
847+ ret = cros_ec_query_all(ec_dev);
848+ KUNIT_EXPECT_EQ(test, ret, 0);
849+
850+ /* For cros_ec_get_proto_info() without passthru. */
851+ {
852+ mock = cros_kunit_ec_xfer_mock_next();
853+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
854+
855+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
856+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
857+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
858+ sizeof(struct ec_response_get_protocol_info));
859+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
860+ }
861+
862+ /* For cros_ec_get_proto_info() with passthru. */
863+ {
864+ mock = cros_kunit_ec_xfer_mock_next();
865+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
866+
867+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
868+ KUNIT_EXPECT_EQ(test, mock->msg.command,
869+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
870+ EC_CMD_GET_PROTOCOL_INFO);
871+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
872+ sizeof(struct ec_response_get_protocol_info));
873+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
874+ }
875+
876+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
877+ {
878+ struct ec_params_get_cmd_versions *data;
879+
880+ mock = cros_kunit_ec_xfer_mock_next();
881+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
882+
883+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
884+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
885+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
886+ sizeof(struct ec_response_get_cmd_versions));
887+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
888+
889+ data = (struct ec_params_get_cmd_versions *)mock->i_data;
890+ KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
891+
892+ KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 0);
893+ }
894+}
895+
896+static void cros_ec_proto_test_query_all_no_mkbp_return_error(struct kunit *test)
897+{
898+ struct cros_ec_proto_test_priv *priv = test->priv;
899+ struct cros_ec_device *ec_dev = &priv->ec_dev;
900+ struct ec_xfer_mock *mock;
901+ int ret;
902+
903+ /* Set some garbage bytes. */
904+ ec_dev->mkbp_event_supported = 0xbf;
905+
906+ /* For cros_ec_get_proto_info() without passthru. */
907+ {
908+ struct ec_response_get_protocol_info *data;
909+
910+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
911+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
912+
913+ /*
914+ * Although it doesn't check the value, provides valid sizes so that
915+ * cros_ec_query_all() allocates din and dout correctly.
916+ */
917+ data = (struct ec_response_get_protocol_info *)mock->o_data;
918+ data->max_request_packet_size = 0xbe;
919+ data->max_response_packet_size = 0xef;
920+ }
921+
922+ /* For cros_ec_get_proto_info() with passthru. */
923+ {
924+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
925+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
926+ }
927+
928+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
929+ {
930+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
931+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
932+ }
933+
934+ cros_ec_proto_test_query_all_pretest(test);
935+ ret = cros_ec_query_all(ec_dev);
936+ KUNIT_EXPECT_EQ(test, ret, 0);
937+
938+ /* For cros_ec_get_proto_info() without passthru. */
939+ {
940+ mock = cros_kunit_ec_xfer_mock_next();
941+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
942+
943+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
944+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
945+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
946+ sizeof(struct ec_response_get_protocol_info));
947+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
948+ }
949+
950+ /* For cros_ec_get_proto_info() with passthru. */
951+ {
952+ mock = cros_kunit_ec_xfer_mock_next();
953+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
954+
955+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
956+ KUNIT_EXPECT_EQ(test, mock->msg.command,
957+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
958+ EC_CMD_GET_PROTOCOL_INFO);
959+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
960+ sizeof(struct ec_response_get_protocol_info));
961+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
962+ }
963+
964+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
965+ {
966+ struct ec_params_get_cmd_versions *data;
967+
968+ mock = cros_kunit_ec_xfer_mock_next();
969+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
970+
971+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
972+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
973+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
974+ sizeof(struct ec_response_get_cmd_versions));
975+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
976+
977+ data = (struct ec_params_get_cmd_versions *)mock->i_data;
978+ KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
979+
980+ KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 0);
981+ }
982+}
983+
984+static void cros_ec_proto_test_query_all_no_mkbp_return0(struct kunit *test)
985+{
986+ struct cros_ec_proto_test_priv *priv = test->priv;
987+ struct cros_ec_device *ec_dev = &priv->ec_dev;
988+ struct ec_xfer_mock *mock;
989+ int ret;
990+
991+ /* Set some garbage bytes. */
992+ ec_dev->mkbp_event_supported = 0xbf;
993+
994+ /* For cros_ec_get_proto_info() without passthru. */
995+ {
996+ struct ec_response_get_protocol_info *data;
997+
998+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
999+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1000+
1001+ /*
1002+ * Although it doesn't check the value, provides valid sizes so that
1003+ * cros_ec_query_all() allocates din and dout correctly.
1004+ */
1005+ data = (struct ec_response_get_protocol_info *)mock->o_data;
1006+ data->max_request_packet_size = 0xbe;
1007+ data->max_response_packet_size = 0xef;
1008+ }
1009+
1010+ /* For cros_ec_get_proto_info() with passthru. */
1011+ {
1012+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1013+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1014+ }
1015+
1016+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1017+ {
1018+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1019+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1020+ }
1021+
1022+ cros_ec_proto_test_query_all_pretest(test);
1023+ ret = cros_ec_query_all(ec_dev);
1024+ KUNIT_EXPECT_EQ(test, ret, 0);
1025+
1026+ /* For cros_ec_get_proto_info() without passthru. */
1027+ {
1028+ mock = cros_kunit_ec_xfer_mock_next();
1029+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1030+
1031+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1032+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1033+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1034+ sizeof(struct ec_response_get_protocol_info));
1035+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1036+ }
1037+
1038+ /* For cros_ec_get_proto_info() with passthru. */
1039+ {
1040+ mock = cros_kunit_ec_xfer_mock_next();
1041+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1042+
1043+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1044+ KUNIT_EXPECT_EQ(test, mock->msg.command,
1045+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1046+ EC_CMD_GET_PROTOCOL_INFO);
1047+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1048+ sizeof(struct ec_response_get_protocol_info));
1049+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1050+ }
1051+
1052+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1053+ {
1054+ struct ec_params_get_cmd_versions *data;
1055+
1056+ mock = cros_kunit_ec_xfer_mock_next();
1057+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1058+
1059+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1060+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1061+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1062+ sizeof(struct ec_response_get_cmd_versions));
1063+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
1064+
1065+ data = (struct ec_params_get_cmd_versions *)mock->i_data;
1066+ KUNIT_EXPECT_EQ(test, data->cmd, EC_CMD_GET_NEXT_EVENT);
1067+
1068+ KUNIT_EXPECT_EQ(test, ec_dev->mkbp_event_supported, 0);
1069+ }
1070+}
1071+
1072+static void cros_ec_proto_test_query_all_no_host_sleep(struct kunit *test)
1073+{
1074+ struct cros_ec_proto_test_priv *priv = test->priv;
1075+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1076+ struct ec_xfer_mock *mock;
1077+ int ret;
1078+
1079+ /* Set some garbage bytes. */
1080+ ec_dev->host_sleep_v1 = true;
1081+
1082+ /* For cros_ec_get_proto_info() without passthru. */
1083+ {
1084+ struct ec_response_get_protocol_info *data;
1085+
1086+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1087+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1088+
1089+ /*
1090+ * Although it doesn't check the value, provides valid sizes so that
1091+ * cros_ec_query_all() allocates din and dout correctly.
1092+ */
1093+ data = (struct ec_response_get_protocol_info *)mock->o_data;
1094+ data->max_request_packet_size = 0xbe;
1095+ data->max_response_packet_size = 0xef;
1096+ }
1097+
1098+ /* For cros_ec_get_proto_info() with passthru. */
1099+ {
1100+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1101+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1102+ }
1103+
1104+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1105+ {
1106+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1107+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1108+ }
1109+
1110+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1111+ {
1112+ struct ec_response_get_cmd_versions *data;
1113+
1114+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1115+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1116+
1117+ data = (struct ec_response_get_cmd_versions *)mock->o_data;
1118+ data->version_mask = 0;
1119+ }
1120+
1121+ cros_ec_proto_test_query_all_pretest(test);
1122+ ret = cros_ec_query_all(ec_dev);
1123+ KUNIT_EXPECT_EQ(test, ret, 0);
1124+
1125+ /* For cros_ec_get_proto_info() without passthru. */
1126+ {
1127+ mock = cros_kunit_ec_xfer_mock_next();
1128+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1129+
1130+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1131+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1132+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1133+ sizeof(struct ec_response_get_protocol_info));
1134+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1135+ }
1136+
1137+ /* For cros_ec_get_proto_info() with passthru. */
1138+ {
1139+ mock = cros_kunit_ec_xfer_mock_next();
1140+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1141+
1142+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1143+ KUNIT_EXPECT_EQ(test, mock->msg.command,
1144+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1145+ EC_CMD_GET_PROTOCOL_INFO);
1146+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1147+ sizeof(struct ec_response_get_protocol_info));
1148+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1149+ }
1150+
1151+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1152+ {
1153+ mock = cros_kunit_ec_xfer_mock_next();
1154+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1155+
1156+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1157+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1158+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1159+ sizeof(struct ec_response_get_cmd_versions));
1160+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1161+ }
1162+
1163+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1164+ {
1165+ mock = cros_kunit_ec_xfer_mock_next();
1166+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1167+
1168+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1169+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1170+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1171+ sizeof(struct ec_response_get_cmd_versions));
1172+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1173+
1174+ KUNIT_EXPECT_FALSE(test, ec_dev->host_sleep_v1);
1175+ }
1176+}
1177+
1178+static void cros_ec_proto_test_query_all_no_host_sleep_return0(struct kunit *test)
1179+{
1180+ struct cros_ec_proto_test_priv *priv = test->priv;
1181+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1182+ struct ec_xfer_mock *mock;
1183+ int ret;
1184+
1185+ /* Set some garbage bytes. */
1186+ ec_dev->host_sleep_v1 = true;
1187+
1188+ /* For cros_ec_get_proto_info() without passthru. */
1189+ {
1190+ struct ec_response_get_protocol_info *data;
1191+
1192+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1193+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1194+
1195+ /*
1196+ * Although it doesn't check the value, provides valid sizes so that
1197+ * cros_ec_query_all() allocates din and dout correctly.
1198+ */
1199+ data = (struct ec_response_get_protocol_info *)mock->o_data;
1200+ data->max_request_packet_size = 0xbe;
1201+ data->max_response_packet_size = 0xef;
1202+ }
1203+
1204+ /* For cros_ec_get_proto_info() with passthru. */
1205+ {
1206+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1207+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1208+ }
1209+
1210+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1211+ {
1212+ struct ec_response_get_cmd_versions *data;
1213+
1214+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1215+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1216+
1217+ /* In order to pollute next cros_ec_get_host_command_version_mask(). */
1218+ data = (struct ec_response_get_cmd_versions *)mock->o_data;
1219+ data->version_mask = 0xbeef;
1220+ }
1221+
1222+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1223+ {
1224+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1225+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1226+ }
1227+
1228+ cros_ec_proto_test_query_all_pretest(test);
1229+ ret = cros_ec_query_all(ec_dev);
1230+ KUNIT_EXPECT_EQ(test, ret, 0);
1231+
1232+ /* For cros_ec_get_proto_info() without passthru. */
1233+ {
1234+ mock = cros_kunit_ec_xfer_mock_next();
1235+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1236+
1237+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1238+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1239+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1240+ sizeof(struct ec_response_get_protocol_info));
1241+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1242+ }
1243+
1244+ /* For cros_ec_get_proto_info() with passthru. */
1245+ {
1246+ mock = cros_kunit_ec_xfer_mock_next();
1247+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1248+
1249+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1250+ KUNIT_EXPECT_EQ(test, mock->msg.command,
1251+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1252+ EC_CMD_GET_PROTOCOL_INFO);
1253+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1254+ sizeof(struct ec_response_get_protocol_info));
1255+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1256+ }
1257+
1258+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1259+ {
1260+ mock = cros_kunit_ec_xfer_mock_next();
1261+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1262+
1263+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1264+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1265+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1266+ sizeof(struct ec_response_get_cmd_versions));
1267+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1268+ }
1269+
1270+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1271+ {
1272+ mock = cros_kunit_ec_xfer_mock_next();
1273+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1274+
1275+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1276+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1277+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1278+ sizeof(struct ec_response_get_cmd_versions));
1279+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1280+
1281+ KUNIT_EXPECT_FALSE(test, ec_dev->host_sleep_v1);
1282+ }
1283+}
1284+
1285+static void cros_ec_proto_test_query_all_default_wake_mask_return_error(struct kunit *test)
1286+{
1287+ struct cros_ec_proto_test_priv *priv = test->priv;
1288+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1289+ struct ec_xfer_mock *mock;
1290+ int ret;
1291+
1292+ /* Set some garbage bytes. */
1293+ ec_dev->host_event_wake_mask = U32_MAX;
1294+
1295+ /* For cros_ec_get_proto_info() without passthru. */
1296+ {
1297+ struct ec_response_get_protocol_info *data;
1298+
1299+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1300+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1301+
1302+ /*
1303+ * Although it doesn't check the value, provides valid sizes so that
1304+ * cros_ec_query_all() allocates din and dout correctly.
1305+ */
1306+ data = (struct ec_response_get_protocol_info *)mock->o_data;
1307+ data->max_request_packet_size = 0xbe;
1308+ data->max_response_packet_size = 0xef;
1309+ }
1310+
1311+ /* For cros_ec_get_proto_info() with passthru. */
1312+ {
1313+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1314+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1315+ }
1316+
1317+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1318+ {
1319+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1320+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1321+ }
1322+
1323+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1324+ {
1325+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1326+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1327+ }
1328+
1329+ /* For cros_ec_get_host_event_wake_mask(). */
1330+ {
1331+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1332+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1333+ }
1334+
1335+ cros_ec_proto_test_query_all_pretest(test);
1336+ ret = cros_ec_query_all(ec_dev);
1337+ KUNIT_EXPECT_EQ(test, ret, 0);
1338+
1339+ /* For cros_ec_get_proto_info() without passthru. */
1340+ {
1341+ mock = cros_kunit_ec_xfer_mock_next();
1342+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1343+
1344+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1345+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1346+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1347+ sizeof(struct ec_response_get_protocol_info));
1348+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1349+ }
1350+
1351+ /* For cros_ec_get_proto_info() with passthru. */
1352+ {
1353+ mock = cros_kunit_ec_xfer_mock_next();
1354+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1355+
1356+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1357+ KUNIT_EXPECT_EQ(test, mock->msg.command,
1358+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1359+ EC_CMD_GET_PROTOCOL_INFO);
1360+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1361+ sizeof(struct ec_response_get_protocol_info));
1362+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1363+ }
1364+
1365+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1366+ {
1367+ mock = cros_kunit_ec_xfer_mock_next();
1368+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1369+
1370+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1371+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1372+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1373+ sizeof(struct ec_response_get_cmd_versions));
1374+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1375+ }
1376+
1377+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1378+ {
1379+ mock = cros_kunit_ec_xfer_mock_next();
1380+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1381+
1382+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1383+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1384+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1385+ sizeof(struct ec_response_get_cmd_versions));
1386+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1387+ }
1388+
1389+ /* For cros_ec_get_host_event_wake_mask(). */
1390+ {
1391+ u32 mask;
1392+
1393+ mock = cros_kunit_ec_xfer_mock_next();
1394+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1395+
1396+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1397+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HOST_EVENT_GET_WAKE_MASK);
1398+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_host_event_mask));
1399+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1400+
1401+ mask = ec_dev->host_event_wake_mask;
1402+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED), 0);
1403+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED), 0);
1404+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW), 0);
1405+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL), 0);
1406+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY), 0);
1407+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU), 0);
1408+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS), 0);
1409+ }
1410+}
1411+
1412+static void cros_ec_proto_test_query_all_default_wake_mask_return0(struct kunit *test)
1413+{
1414+ struct cros_ec_proto_test_priv *priv = test->priv;
1415+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1416+ struct ec_xfer_mock *mock;
1417+ int ret;
1418+
1419+ /* Set some garbage bytes. */
1420+ ec_dev->host_event_wake_mask = U32_MAX;
1421+
1422+ /* For cros_ec_get_proto_info() without passthru. */
1423+ {
1424+ struct ec_response_get_protocol_info *data;
1425+
1426+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1427+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1428+
1429+ /*
1430+ * Although it doesn't check the value, provides valid sizes so that
1431+ * cros_ec_query_all() allocates din and dout correctly.
1432+ */
1433+ data = (struct ec_response_get_protocol_info *)mock->o_data;
1434+ data->max_request_packet_size = 0xbe;
1435+ data->max_response_packet_size = 0xef;
1436+ }
1437+
1438+ /* For cros_ec_get_proto_info() with passthru. */
1439+ {
1440+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1441+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1442+ }
1443+
1444+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1445+ {
1446+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1447+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1448+ }
1449+
1450+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1451+ {
1452+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1453+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1454+ }
1455+
1456+ /* For get_host_event_wake_mask(). */
1457+ {
1458+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1459+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1460+ }
1461+
1462+ cros_ec_proto_test_query_all_pretest(test);
1463+ ret = cros_ec_query_all(ec_dev);
1464+ KUNIT_EXPECT_EQ(test, ret, 0);
1465+
1466+ /* For cros_ec_get_proto_info() without passthru. */
1467+ {
1468+ mock = cros_kunit_ec_xfer_mock_next();
1469+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1470+
1471+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1472+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_PROTOCOL_INFO);
1473+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1474+ sizeof(struct ec_response_get_protocol_info));
1475+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1476+ }
1477+
1478+ /* For cros_ec_get_proto_info() with passthru. */
1479+ {
1480+ mock = cros_kunit_ec_xfer_mock_next();
1481+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1482+
1483+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1484+ KUNIT_EXPECT_EQ(test, mock->msg.command,
1485+ EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) |
1486+ EC_CMD_GET_PROTOCOL_INFO);
1487+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1488+ sizeof(struct ec_response_get_protocol_info));
1489+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1490+ }
1491+
1492+ /* For cros_ec_get_host_command_version_mask() for MKBP. */
1493+ {
1494+ mock = cros_kunit_ec_xfer_mock_next();
1495+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1496+
1497+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1498+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1499+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1500+ sizeof(struct ec_response_get_cmd_versions));
1501+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1502+ }
1503+
1504+ /* For cros_ec_get_host_command_version_mask() for host sleep v1. */
1505+ {
1506+ mock = cros_kunit_ec_xfer_mock_next();
1507+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1508+
1509+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1510+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_CMD_VERSIONS);
1511+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1512+ sizeof(struct ec_response_get_cmd_versions));
1513+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(struct ec_params_get_cmd_versions));
1514+ }
1515+
1516+ /* For get_host_event_wake_mask(). */
1517+ {
1518+ u32 mask;
1519+
1520+ mock = cros_kunit_ec_xfer_mock_next();
1521+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1522+
1523+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1524+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HOST_EVENT_GET_WAKE_MASK);
1525+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_host_event_mask));
1526+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1527+
1528+ mask = ec_dev->host_event_wake_mask;
1529+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED), 0);
1530+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED), 0);
1531+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW), 0);
1532+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL), 0);
1533+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY), 0);
1534+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU), 0);
1535+ KUNIT_EXPECT_EQ(test, mask & EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS), 0);
1536+ }
1537+}
1538+
1539+static void cros_ec_proto_test_cmd_xfer_normal(struct kunit *test)
1540+{
1541+ struct cros_ec_proto_test_priv *priv = test->priv;
1542+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1543+ struct ec_xfer_mock *mock;
1544+ int ret;
1545+ struct {
1546+ struct cros_ec_command msg;
1547+ u8 data[0x100];
1548+ } __packed buf;
1549+
1550+ ec_dev->max_request = 0xff;
1551+ ec_dev->max_response = 0xee;
1552+ ec_dev->max_passthru = 0xdd;
1553+
1554+ buf.msg.version = 0;
1555+ buf.msg.command = EC_CMD_HELLO;
1556+ buf.msg.insize = 4;
1557+ buf.msg.outsize = 2;
1558+ buf.data[0] = 0x55;
1559+ buf.data[1] = 0xaa;
1560+
1561+ {
1562+ u8 *data;
1563+
1564+ mock = cros_kunit_ec_xfer_mock_add(test, 4);
1565+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1566+
1567+ data = (u8 *)mock->o_data;
1568+ data[0] = 0xaa;
1569+ data[1] = 0x55;
1570+ data[2] = 0xcc;
1571+ data[3] = 0x33;
1572+ }
1573+
1574+ ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1575+ KUNIT_EXPECT_EQ(test, ret, 4);
1576+
1577+ {
1578+ u8 *data;
1579+
1580+ mock = cros_kunit_ec_xfer_mock_next();
1581+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1582+
1583+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1584+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
1585+ KUNIT_EXPECT_EQ(test, mock->msg.insize, 4);
1586+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 2);
1587+
1588+ data = (u8 *)mock->i_data;
1589+ KUNIT_EXPECT_EQ(test, data[0], 0x55);
1590+ KUNIT_EXPECT_EQ(test, data[1], 0xaa);
1591+
1592+ KUNIT_EXPECT_EQ(test, buf.data[0], 0xaa);
1593+ KUNIT_EXPECT_EQ(test, buf.data[1], 0x55);
1594+ KUNIT_EXPECT_EQ(test, buf.data[2], 0xcc);
1595+ KUNIT_EXPECT_EQ(test, buf.data[3], 0x33);
1596+ }
1597+}
1598+
1599+static void cros_ec_proto_test_cmd_xfer_excess_msg_insize(struct kunit *test)
1600+{
1601+ struct cros_ec_proto_test_priv *priv = test->priv;
1602+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1603+ struct ec_xfer_mock *mock;
1604+ int ret;
1605+ struct {
1606+ struct cros_ec_command msg;
1607+ u8 data[0x100];
1608+ } __packed buf;
1609+
1610+ ec_dev->max_request = 0xff;
1611+ ec_dev->max_response = 0xee;
1612+ ec_dev->max_passthru = 0xdd;
1613+
1614+ buf.msg.version = 0;
1615+ buf.msg.command = EC_CMD_HELLO;
1616+ buf.msg.insize = 0xee + 1;
1617+ buf.msg.outsize = 2;
1618+
1619+ {
1620+ mock = cros_kunit_ec_xfer_mock_add(test, 0xcc);
1621+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1622+ }
1623+
1624+ ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1625+ KUNIT_EXPECT_EQ(test, ret, 0xcc);
1626+
1627+ {
1628+ mock = cros_kunit_ec_xfer_mock_next();
1629+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1630+
1631+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1632+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_HELLO);
1633+ KUNIT_EXPECT_EQ(test, mock->msg.insize, 0xee);
1634+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 2);
1635+ }
1636+}
1637+
1638+static void cros_ec_proto_test_cmd_xfer_excess_msg_outsize_without_passthru(struct kunit *test)
1639+{
1640+ struct cros_ec_proto_test_priv *priv = test->priv;
1641+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1642+ int ret;
1643+ struct {
1644+ struct cros_ec_command msg;
1645+ u8 data[0x100];
1646+ } __packed buf;
1647+
1648+ ec_dev->max_request = 0xff;
1649+ ec_dev->max_response = 0xee;
1650+ ec_dev->max_passthru = 0xdd;
1651+
1652+ buf.msg.version = 0;
1653+ buf.msg.command = EC_CMD_HELLO;
1654+ buf.msg.insize = 4;
1655+ buf.msg.outsize = 0xff + 1;
1656+
1657+ ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1658+ KUNIT_EXPECT_EQ(test, ret, -EMSGSIZE);
1659+}
1660+
1661+static void cros_ec_proto_test_cmd_xfer_excess_msg_outsize_with_passthru(struct kunit *test)
1662+{
1663+ struct cros_ec_proto_test_priv *priv = test->priv;
1664+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1665+ int ret;
1666+ struct {
1667+ struct cros_ec_command msg;
1668+ u8 data[0x100];
1669+ } __packed buf;
1670+
1671+ ec_dev->max_request = 0xff;
1672+ ec_dev->max_response = 0xee;
1673+ ec_dev->max_passthru = 0xdd;
1674+
1675+ buf.msg.version = 0;
1676+ buf.msg.command = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX) + EC_CMD_HELLO;
1677+ buf.msg.insize = 4;
1678+ buf.msg.outsize = 0xdd + 1;
1679+
1680+ ret = cros_ec_cmd_xfer(ec_dev, &buf.msg);
1681+ KUNIT_EXPECT_EQ(test, ret, -EMSGSIZE);
1682+}
1683+
1684+static void cros_ec_proto_test_cmd_xfer_protocol_v3_normal(struct kunit *test)
1685+{
1686+ struct cros_ec_proto_test_priv *priv = test->priv;
1687+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1688+ int ret;
1689+ struct cros_ec_command msg;
1690+
1691+ memset(&msg, 0, sizeof(msg));
1692+
1693+ ec_dev->proto_version = 3;
1694+ ec_dev->cmd_xfer = cros_kunit_ec_cmd_xfer_mock;
1695+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1696+
1697+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1698+ KUNIT_EXPECT_EQ(test, ret, 0);
1699+
1700+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_cmd_xfer_mock_called, 0);
1701+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 1);
1702+}
1703+
1704+static void cros_ec_proto_test_cmd_xfer_protocol_v3_no_op(struct kunit *test)
1705+{
1706+ struct cros_ec_proto_test_priv *priv = test->priv;
1707+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1708+ int ret;
1709+ struct cros_ec_command msg;
1710+
1711+ memset(&msg, 0, sizeof(msg));
1712+
1713+ ec_dev->proto_version = 3;
1714+ ec_dev->cmd_xfer = cros_kunit_ec_cmd_xfer_mock;
1715+ ec_dev->pkt_xfer = NULL;
1716+
1717+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1718+ KUNIT_EXPECT_EQ(test, ret, -EIO);
1719+}
1720+
1721+static void cros_ec_proto_test_cmd_xfer_protocol_v2_normal(struct kunit *test)
1722+{
1723+ struct cros_ec_proto_test_priv *priv = test->priv;
1724+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1725+ int ret;
1726+ struct cros_ec_command msg;
1727+
1728+ memset(&msg, 0, sizeof(msg));
1729+
1730+ ec_dev->proto_version = 2;
1731+ ec_dev->cmd_xfer = cros_kunit_ec_cmd_xfer_mock;
1732+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1733+
1734+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1735+ KUNIT_EXPECT_EQ(test, ret, 0);
1736+
1737+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_cmd_xfer_mock_called, 1);
1738+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 0);
1739+}
1740+
1741+static void cros_ec_proto_test_cmd_xfer_protocol_v2_no_op(struct kunit *test)
1742+{
1743+ struct cros_ec_proto_test_priv *priv = test->priv;
1744+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1745+ int ret;
1746+ struct cros_ec_command msg;
1747+
1748+ memset(&msg, 0, sizeof(msg));
1749+
1750+ ec_dev->proto_version = 2;
1751+ ec_dev->cmd_xfer = NULL;
1752+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1753+
1754+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1755+ KUNIT_EXPECT_EQ(test, ret, -EIO);
1756+}
1757+
1758+static void cros_ec_proto_test_cmd_xfer_in_progress_normal(struct kunit *test)
1759+{
1760+ struct cros_ec_proto_test_priv *priv = test->priv;
1761+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1762+ struct ec_xfer_mock *mock;
1763+ int ret;
1764+ struct cros_ec_command msg;
1765+
1766+ memset(&msg, 0, sizeof(msg));
1767+
1768+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1769+
1770+ /* For the first host command to return EC_RES_IN_PROGRESS. */
1771+ {
1772+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1773+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1774+ }
1775+
1776+ /* For EC_CMD_GET_COMMS_STATUS. */
1777+ {
1778+ struct ec_response_get_comms_status *data;
1779+
1780+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1781+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1782+
1783+ data = (struct ec_response_get_comms_status *)mock->o_data;
1784+ data->flags = 0;
1785+ }
1786+
1787+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1788+ KUNIT_EXPECT_EQ(test, ret, sizeof(struct ec_response_get_comms_status));
1789+
1790+ KUNIT_EXPECT_EQ(test, msg.result, EC_RES_SUCCESS);
1791+
1792+ /* For the first host command to return EC_RES_IN_PROGRESS. */
1793+ {
1794+ mock = cros_kunit_ec_xfer_mock_next();
1795+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1796+ }
1797+
1798+ /* For EC_CMD_GET_COMMS_STATUS. */
1799+ {
1800+ mock = cros_kunit_ec_xfer_mock_next();
1801+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
1802+
1803+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
1804+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_COMMS_STATUS);
1805+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
1806+ sizeof(struct ec_response_get_comms_status));
1807+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
1808+ }
1809+
1810+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 2);
1811+}
1812+
1813+static void cros_ec_proto_test_cmd_xfer_in_progress_retries_eagain(struct kunit *test)
1814+{
1815+ struct cros_ec_proto_test_priv *priv = test->priv;
1816+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1817+ struct ec_xfer_mock *mock;
1818+ int ret;
1819+ struct cros_ec_command msg;
1820+
1821+ memset(&msg, 0, sizeof(msg));
1822+
1823+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1824+
1825+ /* For the first host command to return EC_RES_IN_PROGRESS. */
1826+ {
1827+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1828+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1829+ }
1830+
1831+ /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1832+ cros_kunit_ec_xfer_mock_default_ret = -EAGAIN;
1833+
1834+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1835+ KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
1836+
1837+ /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1838+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 51);
1839+}
1840+
1841+static void cros_ec_proto_test_cmd_xfer_in_progress_retries_status_processing(struct kunit *test)
1842+{
1843+ struct cros_ec_proto_test_priv *priv = test->priv;
1844+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1845+ struct ec_xfer_mock *mock;
1846+ int ret;
1847+ struct cros_ec_command msg;
1848+
1849+ memset(&msg, 0, sizeof(msg));
1850+
1851+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1852+
1853+ /* For the first host command to return EC_RES_IN_PROGRESS. */
1854+ {
1855+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1856+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1857+ }
1858+
1859+ /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1860+ {
1861+ struct ec_response_get_comms_status *data;
1862+ int i;
1863+
1864+ for (i = 0; i < 50; ++i) {
1865+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
1866+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1867+
1868+ data = (struct ec_response_get_comms_status *)mock->o_data;
1869+ data->flags |= EC_COMMS_STATUS_PROCESSING;
1870+ }
1871+ }
1872+
1873+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1874+ KUNIT_EXPECT_EQ(test, ret, -EAGAIN);
1875+
1876+ /* For EC_CMD_GET_COMMS_STATUS EC_COMMAND_RETRIES times. */
1877+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 51);
1878+}
1879+
1880+static void cros_ec_proto_test_cmd_xfer_in_progress_xfer_error(struct kunit *test)
1881+{
1882+ struct cros_ec_proto_test_priv *priv = test->priv;
1883+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1884+ struct ec_xfer_mock *mock;
1885+ int ret;
1886+ struct cros_ec_command msg;
1887+
1888+ memset(&msg, 0, sizeof(msg));
1889+
1890+ /* For the first host command to return EC_RES_IN_PROGRESS. */
1891+ {
1892+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1893+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1894+ }
1895+
1896+ /* For EC_CMD_GET_COMMS_STATUS. */
1897+ {
1898+ mock = cros_kunit_ec_xfer_mock_addx(test, -EIO, EC_RES_SUCCESS, 0);
1899+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1900+ }
1901+
1902+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1903+ KUNIT_EXPECT_EQ(test, ret, -EIO);
1904+}
1905+
1906+static void cros_ec_proto_test_cmd_xfer_in_progress_return_error(struct kunit *test)
1907+{
1908+ struct cros_ec_proto_test_priv *priv = test->priv;
1909+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1910+ struct ec_xfer_mock *mock;
1911+ int ret;
1912+ struct cros_ec_command msg;
1913+
1914+ memset(&msg, 0, sizeof(msg));
1915+
1916+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1917+
1918+ /* For the first host command to return EC_RES_IN_PROGRESS. */
1919+ {
1920+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1921+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1922+ }
1923+
1924+ /* For EC_CMD_GET_COMMS_STATUS. */
1925+ {
1926+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_INVALID_COMMAND, 0);
1927+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1928+ }
1929+
1930+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1931+ KUNIT_EXPECT_EQ(test, ret, 0);
1932+
1933+ KUNIT_EXPECT_EQ(test, msg.result, EC_RES_INVALID_COMMAND);
1934+
1935+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 2);
1936+}
1937+
1938+static void cros_ec_proto_test_cmd_xfer_in_progress_return0(struct kunit *test)
1939+{
1940+ struct cros_ec_proto_test_priv *priv = test->priv;
1941+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1942+ struct ec_xfer_mock *mock;
1943+ int ret;
1944+ struct cros_ec_command msg;
1945+
1946+ memset(&msg, 0, sizeof(msg));
1947+
1948+ ec_dev->pkt_xfer = cros_kunit_ec_pkt_xfer_mock;
1949+
1950+ /* For the first host command to return EC_RES_IN_PROGRESS. */
1951+ {
1952+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, EC_RES_IN_PROGRESS, 0);
1953+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1954+ }
1955+
1956+ /* For EC_CMD_GET_COMMS_STATUS. */
1957+ {
1958+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1959+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1960+ }
1961+
1962+ ret = cros_ec_cmd_xfer(ec_dev, &msg);
1963+ KUNIT_EXPECT_EQ(test, ret, -EPROTO);
1964+
1965+ KUNIT_EXPECT_EQ(test, cros_kunit_ec_pkt_xfer_mock_called, 2);
1966+}
1967+
1968+static void cros_ec_proto_test_cmd_xfer_status_normal(struct kunit *test)
1969+{
1970+ struct cros_ec_proto_test_priv *priv = test->priv;
1971+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1972+ struct ec_xfer_mock *mock;
1973+ int ret;
1974+ struct cros_ec_command msg;
1975+
1976+ memset(&msg, 0, sizeof(msg));
1977+
1978+ /* For cros_ec_cmd_xfer(). */
1979+ {
1980+ mock = cros_kunit_ec_xfer_mock_add(test, 0);
1981+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
1982+ }
1983+
1984+ ret = cros_ec_cmd_xfer_status(ec_dev, &msg);
1985+ KUNIT_EXPECT_EQ(test, ret, 0);
1986+}
1987+
1988+static void cros_ec_proto_test_cmd_xfer_status_xfer_error(struct kunit *test)
1989+{
1990+ struct cros_ec_proto_test_priv *priv = test->priv;
1991+ struct cros_ec_device *ec_dev = &priv->ec_dev;
1992+ struct ec_xfer_mock *mock;
1993+ int ret;
1994+ struct cros_ec_command msg;
1995+
1996+ memset(&msg, 0, sizeof(msg));
1997+
1998+ /* For cros_ec_cmd_xfer(). */
1999+ {
2000+ mock = cros_kunit_ec_xfer_mock_addx(test, -EPROTO, EC_RES_SUCCESS, 0);
2001+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2002+ }
2003+
2004+ ret = cros_ec_cmd_xfer_status(ec_dev, &msg);
2005+ KUNIT_EXPECT_EQ(test, ret, -EPROTO);
2006+}
2007+
2008+static void cros_ec_proto_test_cmd_xfer_status_return_error(struct kunit *test)
2009+{
2010+ struct cros_ec_proto_test_priv *priv = test->priv;
2011+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2012+ struct ec_xfer_mock *mock;
2013+ int ret, i;
2014+ struct cros_ec_command msg;
2015+ static const int map[] = {
2016+ [EC_RES_SUCCESS] = 0,
2017+ [EC_RES_INVALID_COMMAND] = -EOPNOTSUPP,
2018+ [EC_RES_ERROR] = -EIO,
2019+ [EC_RES_INVALID_PARAM] = -EINVAL,
2020+ [EC_RES_ACCESS_DENIED] = -EACCES,
2021+ [EC_RES_INVALID_RESPONSE] = -EPROTO,
2022+ [EC_RES_INVALID_VERSION] = -ENOPROTOOPT,
2023+ [EC_RES_INVALID_CHECKSUM] = -EBADMSG,
2024+ /*
2025+ * EC_RES_IN_PROGRESS is special because cros_ec_send_command() has extra logic to
2026+ * handle it. Note that default cros_kunit_ec_xfer_mock_default_ret == 0 thus
2027+ * cros_ec_xfer_command() in cros_ec_wait_until_complete() returns 0. As a result,
2028+ * it returns -EPROTO without calling cros_ec_map_error().
2029+ */
2030+ [EC_RES_IN_PROGRESS] = -EPROTO,
2031+ [EC_RES_UNAVAILABLE] = -ENODATA,
2032+ [EC_RES_TIMEOUT] = -ETIMEDOUT,
2033+ [EC_RES_OVERFLOW] = -EOVERFLOW,
2034+ [EC_RES_INVALID_HEADER] = -EBADR,
2035+ [EC_RES_REQUEST_TRUNCATED] = -EBADR,
2036+ [EC_RES_RESPONSE_TOO_BIG] = -EFBIG,
2037+ [EC_RES_BUS_ERROR] = -EFAULT,
2038+ [EC_RES_BUSY] = -EBUSY,
2039+ [EC_RES_INVALID_HEADER_VERSION] = -EBADMSG,
2040+ [EC_RES_INVALID_HEADER_CRC] = -EBADMSG,
2041+ [EC_RES_INVALID_DATA_CRC] = -EBADMSG,
2042+ [EC_RES_DUP_UNAVAILABLE] = -ENODATA,
2043+ };
2044+
2045+ memset(&msg, 0, sizeof(msg));
2046+
2047+ for (i = 0; i < ARRAY_SIZE(map); ++i) {
2048+ mock = cros_kunit_ec_xfer_mock_addx(test, 0, i, 0);
2049+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2050+
2051+ ret = cros_ec_cmd_xfer_status(ec_dev, &msg);
2052+ KUNIT_EXPECT_EQ(test, ret, map[i]);
2053+ }
2054+}
2055+
2056+static void cros_ec_proto_test_get_next_event_no_mkbp_event(struct kunit *test)
2057+{
2058+ struct cros_ec_proto_test_priv *priv = test->priv;
2059+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2060+ struct ec_xfer_mock *mock;
2061+ int ret;
2062+ bool wake_event, more_events;
2063+
2064+ ec_dev->max_request = 0xff;
2065+ ec_dev->max_response = 0xee;
2066+ ec_dev->mkbp_event_supported = 0;
2067+
2068+ /* Set some garbage bytes. */
2069+ wake_event = false;
2070+ more_events = true;
2071+
2072+ /* For get_keyboard_state_event(). */
2073+ {
2074+ union ec_response_get_next_data_v1 *data;
2075+
2076+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2077+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2078+
2079+ data = (union ec_response_get_next_data_v1 *)mock->o_data;
2080+ data->host_event = 0xbeef;
2081+ }
2082+
2083+ ret = cros_ec_get_next_event(ec_dev, &wake_event, &more_events);
2084+ KUNIT_EXPECT_EQ(test, ret, sizeof(union ec_response_get_next_data_v1));
2085+
2086+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_KEY_MATRIX);
2087+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.data.host_event, 0xbeef);
2088+
2089+ KUNIT_EXPECT_TRUE(test, wake_event);
2090+ KUNIT_EXPECT_FALSE(test, more_events);
2091+
2092+ /* For get_keyboard_state_event(). */
2093+ {
2094+ mock = cros_kunit_ec_xfer_mock_next();
2095+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2096+
2097+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
2098+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MKBP_STATE);
2099+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(union ec_response_get_next_data_v1));
2100+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2101+ }
2102+}
2103+
2104+static void cros_ec_proto_test_get_next_event_mkbp_event_ec_suspended(struct kunit *test)
2105+{
2106+ struct cros_ec_proto_test_priv *priv = test->priv;
2107+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2108+ int ret;
2109+
2110+ ec_dev->mkbp_event_supported = 1;
2111+ ec_dev->suspended = true;
2112+
2113+ ret = cros_ec_get_next_event(ec_dev, NULL, NULL);
2114+ KUNIT_EXPECT_EQ(test, ret, -EHOSTDOWN);
2115+}
2116+
2117+static void cros_ec_proto_test_get_next_event_mkbp_event_version0(struct kunit *test)
2118+{
2119+ struct cros_ec_proto_test_priv *priv = test->priv;
2120+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2121+ struct ec_xfer_mock *mock;
2122+ int ret;
2123+ bool wake_event, more_events;
2124+
2125+ ec_dev->max_request = 0xff;
2126+ ec_dev->max_response = 0xee;
2127+ ec_dev->mkbp_event_supported = 1;
2128+
2129+ /* Set some garbage bytes. */
2130+ wake_event = true;
2131+ more_events = false;
2132+
2133+ /* For get_next_event_xfer(). */
2134+ {
2135+ struct ec_response_get_next_event *data;
2136+
2137+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2138+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2139+
2140+ data = (struct ec_response_get_next_event *)mock->o_data;
2141+ data->event_type = EC_MKBP_EVENT_SENSOR_FIFO | EC_MKBP_HAS_MORE_EVENTS;
2142+ data->data.sysrq = 0xbeef;
2143+ }
2144+
2145+ ret = cros_ec_get_next_event(ec_dev, &wake_event, &more_events);
2146+ KUNIT_EXPECT_EQ(test, ret, sizeof(struct ec_response_get_next_event));
2147+
2148+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_SENSOR_FIFO);
2149+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.data.sysrq, 0xbeef);
2150+
2151+ KUNIT_EXPECT_FALSE(test, wake_event);
2152+ KUNIT_EXPECT_TRUE(test, more_events);
2153+
2154+ /* For get_next_event_xfer(). */
2155+ {
2156+ mock = cros_kunit_ec_xfer_mock_next();
2157+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2158+
2159+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
2160+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2161+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_get_next_event));
2162+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2163+ }
2164+}
2165+
2166+static void cros_ec_proto_test_get_next_event_mkbp_event_version2(struct kunit *test)
2167+{
2168+ struct cros_ec_proto_test_priv *priv = test->priv;
2169+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2170+ struct ec_xfer_mock *mock;
2171+ int ret;
2172+ bool wake_event, more_events;
2173+
2174+ ec_dev->max_request = 0xff;
2175+ ec_dev->max_response = 0xee;
2176+ ec_dev->mkbp_event_supported = 3;
2177+
2178+ /* Set some garbage bytes. */
2179+ wake_event = false;
2180+ more_events = true;
2181+
2182+ /* For get_next_event_xfer(). */
2183+ {
2184+ struct ec_response_get_next_event_v1 *data;
2185+
2186+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2187+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2188+
2189+ data = (struct ec_response_get_next_event_v1 *)mock->o_data;
2190+ data->event_type = EC_MKBP_EVENT_FINGERPRINT;
2191+ data->data.sysrq = 0xbeef;
2192+ }
2193+
2194+ ret = cros_ec_get_next_event(ec_dev, &wake_event, &more_events);
2195+ KUNIT_EXPECT_EQ(test, ret, sizeof(struct ec_response_get_next_event_v1));
2196+
2197+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_FINGERPRINT);
2198+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.data.sysrq, 0xbeef);
2199+
2200+ KUNIT_EXPECT_TRUE(test, wake_event);
2201+ KUNIT_EXPECT_FALSE(test, more_events);
2202+
2203+ /* For get_next_event_xfer(). */
2204+ {
2205+ mock = cros_kunit_ec_xfer_mock_next();
2206+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2207+
2208+ KUNIT_EXPECT_EQ(test, mock->msg.version, 2);
2209+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2210+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
2211+ sizeof(struct ec_response_get_next_event_v1));
2212+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2213+ }
2214+}
2215+
2216+static void cros_ec_proto_test_get_next_event_mkbp_event_host_event_rtc(struct kunit *test)
2217+{
2218+ struct cros_ec_proto_test_priv *priv = test->priv;
2219+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2220+ struct ec_xfer_mock *mock;
2221+ int ret;
2222+ bool wake_event;
2223+ struct ec_response_get_next_event_v1 *data;
2224+
2225+ ec_dev->max_request = 0xff;
2226+ ec_dev->max_response = 0xee;
2227+ ec_dev->mkbp_event_supported = 3;
2228+ ec_dev->host_event_wake_mask = U32_MAX;
2229+
2230+ /* Set some garbage bytes. */
2231+ wake_event = true;
2232+
2233+ /* For get_next_event_xfer(). */
2234+ {
2235+ mock = cros_kunit_ec_xfer_mock_add(test,
2236+ sizeof(data->event_type) +
2237+ sizeof(data->data.host_event));
2238+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2239+
2240+ data = (struct ec_response_get_next_event_v1 *)mock->o_data;
2241+ data->event_type = EC_MKBP_EVENT_HOST_EVENT;
2242+ put_unaligned_le32(EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC), &data->data.host_event);
2243+ }
2244+
2245+ ret = cros_ec_get_next_event(ec_dev, &wake_event, NULL);
2246+ KUNIT_EXPECT_EQ(test, ret, sizeof(data->event_type) + sizeof(data->data.host_event));
2247+
2248+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_HOST_EVENT);
2249+
2250+ KUNIT_EXPECT_FALSE(test, wake_event);
2251+
2252+ /* For get_next_event_xfer(). */
2253+ {
2254+ mock = cros_kunit_ec_xfer_mock_next();
2255+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2256+
2257+ KUNIT_EXPECT_EQ(test, mock->msg.version, 2);
2258+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2259+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
2260+ sizeof(struct ec_response_get_next_event_v1));
2261+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2262+ }
2263+}
2264+
2265+static void cros_ec_proto_test_get_next_event_mkbp_event_host_event_masked(struct kunit *test)
2266+{
2267+ struct cros_ec_proto_test_priv *priv = test->priv;
2268+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2269+ struct ec_xfer_mock *mock;
2270+ int ret;
2271+ bool wake_event;
2272+ struct ec_response_get_next_event_v1 *data;
2273+
2274+ ec_dev->max_request = 0xff;
2275+ ec_dev->max_response = 0xee;
2276+ ec_dev->mkbp_event_supported = 3;
2277+ ec_dev->host_event_wake_mask = U32_MAX & ~EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED);
2278+
2279+ /* Set some garbage bytes. */
2280+ wake_event = true;
2281+
2282+ /* For get_next_event_xfer(). */
2283+ {
2284+ mock = cros_kunit_ec_xfer_mock_add(test,
2285+ sizeof(data->event_type) +
2286+ sizeof(data->data.host_event));
2287+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2288+
2289+ data = (struct ec_response_get_next_event_v1 *)mock->o_data;
2290+ data->event_type = EC_MKBP_EVENT_HOST_EVENT;
2291+ put_unaligned_le32(EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED),
2292+ &data->data.host_event);
2293+ }
2294+
2295+ ret = cros_ec_get_next_event(ec_dev, &wake_event, NULL);
2296+ KUNIT_EXPECT_EQ(test, ret, sizeof(data->event_type) + sizeof(data->data.host_event));
2297+
2298+ KUNIT_EXPECT_EQ(test, ec_dev->event_data.event_type, EC_MKBP_EVENT_HOST_EVENT);
2299+
2300+ KUNIT_EXPECT_FALSE(test, wake_event);
2301+
2302+ /* For get_next_event_xfer(). */
2303+ {
2304+ mock = cros_kunit_ec_xfer_mock_next();
2305+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2306+
2307+ KUNIT_EXPECT_EQ(test, mock->msg.version, 2);
2308+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_NEXT_EVENT);
2309+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
2310+ sizeof(struct ec_response_get_next_event_v1));
2311+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2312+ }
2313+}
2314+
2315+static void cros_ec_proto_test_get_host_event_no_mkbp_event(struct kunit *test)
2316+{
2317+ struct cros_ec_proto_test_priv *priv = test->priv;
2318+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2319+ int ret;
2320+
2321+ ec_dev->mkbp_event_supported = 0;
2322+
2323+ ret = cros_ec_get_host_event(ec_dev);
2324+ KUNIT_EXPECT_EQ(test, ret, 0);
2325+}
2326+
2327+static void cros_ec_proto_test_get_host_event_not_host_event(struct kunit *test)
2328+{
2329+ struct cros_ec_proto_test_priv *priv = test->priv;
2330+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2331+ int ret;
2332+
2333+ ec_dev->mkbp_event_supported = 1;
2334+ ec_dev->event_data.event_type = EC_MKBP_EVENT_FINGERPRINT;
2335+
2336+ ret = cros_ec_get_host_event(ec_dev);
2337+ KUNIT_EXPECT_EQ(test, ret, 0);
2338+}
2339+
2340+static void cros_ec_proto_test_get_host_event_wrong_event_size(struct kunit *test)
2341+{
2342+ struct cros_ec_proto_test_priv *priv = test->priv;
2343+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2344+ int ret;
2345+
2346+ ec_dev->mkbp_event_supported = 1;
2347+ ec_dev->event_data.event_type = EC_MKBP_EVENT_HOST_EVENT;
2348+ ec_dev->event_size = 0xff;
2349+
2350+ ret = cros_ec_get_host_event(ec_dev);
2351+ KUNIT_EXPECT_EQ(test, ret, 0);
2352+}
2353+
2354+static void cros_ec_proto_test_get_host_event_normal(struct kunit *test)
2355+{
2356+ struct cros_ec_proto_test_priv *priv = test->priv;
2357+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2358+ int ret;
2359+
2360+ ec_dev->mkbp_event_supported = 1;
2361+ ec_dev->event_data.event_type = EC_MKBP_EVENT_HOST_EVENT;
2362+ ec_dev->event_size = sizeof(ec_dev->event_data.data.host_event);
2363+ put_unaligned_le32(EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC),
2364+ &ec_dev->event_data.data.host_event);
2365+
2366+ ret = cros_ec_get_host_event(ec_dev);
2367+ KUNIT_EXPECT_EQ(test, ret, EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC));
2368+}
2369+
2370+static void cros_ec_proto_test_check_features_cached(struct kunit *test)
2371+{
2372+ int ret, i;
2373+ struct cros_ec_dev ec;
2374+
2375+ ec.features.flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FINGERPRINT);
2376+ ec.features.flags[1] = EC_FEATURE_MASK_0(EC_FEATURE_SCP);
2377+
2378+ for (i = 0; i < EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK; ++i) {
2379+ ret = cros_ec_check_features(&ec, i);
2380+ switch (i) {
2381+ case EC_FEATURE_FINGERPRINT:
2382+ case EC_FEATURE_SCP:
2383+ KUNIT_EXPECT_TRUE(test, ret);
2384+ break;
2385+ default:
2386+ KUNIT_EXPECT_FALSE(test, ret);
2387+ break;
2388+ }
2389+ }
2390+}
2391+
2392+static void cros_ec_proto_test_check_features_not_cached(struct kunit *test)
2393+{
2394+ struct cros_ec_proto_test_priv *priv = test->priv;
2395+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2396+ struct ec_xfer_mock *mock;
2397+ int ret, i;
2398+ struct cros_ec_dev ec;
2399+
2400+ ec_dev->max_request = 0xff;
2401+ ec_dev->max_response = 0xee;
2402+ ec.ec_dev = ec_dev;
2403+ ec.dev = ec_dev->dev;
2404+ ec.cmd_offset = 0;
2405+ ec.features.flags[0] = -1;
2406+ ec.features.flags[1] = -1;
2407+
2408+ /* For EC_CMD_GET_FEATURES. */
2409+ {
2410+ struct ec_response_get_features *data;
2411+
2412+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2413+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2414+
2415+ data = (struct ec_response_get_features *)mock->o_data;
2416+ data->flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FINGERPRINT);
2417+ data->flags[1] = EC_FEATURE_MASK_0(EC_FEATURE_SCP);
2418+ }
2419+
2420+ for (i = 0; i < EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK; ++i) {
2421+ ret = cros_ec_check_features(&ec, i);
2422+ switch (i) {
2423+ case EC_FEATURE_FINGERPRINT:
2424+ case EC_FEATURE_SCP:
2425+ KUNIT_EXPECT_TRUE(test, ret);
2426+ break;
2427+ default:
2428+ KUNIT_EXPECT_FALSE(test, ret);
2429+ break;
2430+ }
2431+ }
2432+
2433+ /* For EC_CMD_GET_FEATURES. */
2434+ {
2435+ mock = cros_kunit_ec_xfer_mock_next();
2436+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2437+
2438+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0);
2439+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_GET_FEATURES);
2440+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_get_features));
2441+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, 0);
2442+ }
2443+}
2444+
2445+static void cros_ec_proto_test_get_sensor_count_normal(struct kunit *test)
2446+{
2447+ struct cros_ec_proto_test_priv *priv = test->priv;
2448+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2449+ struct ec_xfer_mock *mock;
2450+ int ret;
2451+ struct cros_ec_dev ec;
2452+
2453+ ec_dev->max_request = 0xff;
2454+ ec_dev->max_response = 0xee;
2455+ ec.ec_dev = ec_dev;
2456+ ec.dev = ec_dev->dev;
2457+ ec.cmd_offset = 0;
2458+
2459+ /* For EC_CMD_MOTION_SENSE_CMD. */
2460+ {
2461+ struct ec_response_motion_sense *data;
2462+
2463+ mock = cros_kunit_ec_xfer_mock_add(test, sizeof(*data));
2464+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2465+
2466+ data = (struct ec_response_motion_sense *)mock->o_data;
2467+ data->dump.sensor_count = 0xbf;
2468+ }
2469+
2470+ ret = cros_ec_get_sensor_count(&ec);
2471+ KUNIT_EXPECT_EQ(test, ret, 0xbf);
2472+
2473+ /* For EC_CMD_MOTION_SENSE_CMD. */
2474+ {
2475+ struct ec_params_motion_sense *data;
2476+
2477+ mock = cros_kunit_ec_xfer_mock_next();
2478+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2479+
2480+ KUNIT_EXPECT_EQ(test, mock->msg.version, 1);
2481+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MOTION_SENSE_CMD);
2482+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_motion_sense));
2483+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
2484+
2485+ data = (struct ec_params_motion_sense *)mock->i_data;
2486+ KUNIT_EXPECT_EQ(test, data->cmd, MOTIONSENSE_CMD_DUMP);
2487+ }
2488+}
2489+
2490+static void cros_ec_proto_test_get_sensor_count_xfer_error(struct kunit *test)
2491+{
2492+ struct cros_ec_proto_test_priv *priv = test->priv;
2493+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2494+ struct ec_xfer_mock *mock;
2495+ int ret;
2496+ struct cros_ec_dev ec;
2497+
2498+ ec_dev->max_request = 0xff;
2499+ ec_dev->max_response = 0xee;
2500+ ec.ec_dev = ec_dev;
2501+ ec.dev = ec_dev->dev;
2502+ ec.cmd_offset = 0;
2503+
2504+ /* For EC_CMD_MOTION_SENSE_CMD. */
2505+ {
2506+ mock = cros_kunit_ec_xfer_mock_addx(test, -EPROTO, EC_RES_SUCCESS, 0);
2507+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2508+ }
2509+
2510+ ret = cros_ec_get_sensor_count(&ec);
2511+ KUNIT_EXPECT_EQ(test, ret, -EPROTO);
2512+
2513+ /* For EC_CMD_MOTION_SENSE_CMD. */
2514+ {
2515+ struct ec_params_motion_sense *data;
2516+
2517+ mock = cros_kunit_ec_xfer_mock_next();
2518+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2519+
2520+ KUNIT_EXPECT_EQ(test, mock->msg.version, 1);
2521+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MOTION_SENSE_CMD);
2522+ KUNIT_EXPECT_EQ(test, mock->msg.insize, sizeof(struct ec_response_motion_sense));
2523+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
2524+
2525+ data = (struct ec_params_motion_sense *)mock->i_data;
2526+ KUNIT_EXPECT_EQ(test, data->cmd, MOTIONSENSE_CMD_DUMP);
2527+ }
2528+}
2529+
2530+static void cros_ec_proto_test_get_sensor_count_legacy(struct kunit *test)
2531+{
2532+ struct cros_ec_proto_test_priv *priv = test->priv;
2533+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2534+ struct ec_xfer_mock *mock;
2535+ int ret, i;
2536+ struct cros_ec_dev ec;
2537+ struct {
2538+ u8 readmem_data;
2539+ int expected_result;
2540+ } test_data[] = {
2541+ { 0, 0 },
2542+ { EC_MEMMAP_ACC_STATUS_PRESENCE_BIT, 2 },
2543+ };
2544+
2545+ ec_dev->max_request = 0xff;
2546+ ec_dev->max_response = 0xee;
2547+ ec_dev->cmd_readmem = cros_kunit_readmem_mock;
2548+ ec.ec_dev = ec_dev;
2549+ ec.dev = ec_dev->dev;
2550+ ec.cmd_offset = 0;
2551+
2552+ for (i = 0; i < ARRAY_SIZE(test_data); ++i) {
2553+ /* For EC_CMD_MOTION_SENSE_CMD. */
2554+ {
2555+ mock = cros_kunit_ec_xfer_mock_addx(test, -EPROTO, EC_RES_SUCCESS, 0);
2556+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2557+ }
2558+
2559+ /* For readmem. */
2560+ {
2561+ cros_kunit_readmem_mock_data = kunit_kzalloc(test, 1, GFP_KERNEL);
2562+ KUNIT_ASSERT_PTR_NE(test, cros_kunit_readmem_mock_data, NULL);
2563+ cros_kunit_readmem_mock_data[0] = test_data[i].readmem_data;
2564+
2565+ cros_kunit_ec_xfer_mock_default_ret = 1;
2566+ }
2567+
2568+ ret = cros_ec_get_sensor_count(&ec);
2569+ KUNIT_EXPECT_EQ(test, ret, test_data[i].expected_result);
2570+
2571+ /* For EC_CMD_MOTION_SENSE_CMD. */
2572+ {
2573+ struct ec_params_motion_sense *data;
2574+
2575+ mock = cros_kunit_ec_xfer_mock_next();
2576+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2577+
2578+ KUNIT_EXPECT_EQ(test, mock->msg.version, 1);
2579+ KUNIT_EXPECT_EQ(test, mock->msg.command, EC_CMD_MOTION_SENSE_CMD);
2580+ KUNIT_EXPECT_EQ(test, mock->msg.insize,
2581+ sizeof(struct ec_response_motion_sense));
2582+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, sizeof(*data));
2583+
2584+ data = (struct ec_params_motion_sense *)mock->i_data;
2585+ KUNIT_EXPECT_EQ(test, data->cmd, MOTIONSENSE_CMD_DUMP);
2586+ }
2587+
2588+ /* For readmem. */
2589+ {
2590+ KUNIT_EXPECT_EQ(test, cros_kunit_readmem_mock_offset, EC_MEMMAP_ACC_STATUS);
2591+ }
2592+ }
2593+}
2594+
2595+static void cros_ec_proto_test_ec_cmd(struct kunit *test)
2596+{
2597+ struct cros_ec_proto_test_priv *priv = test->priv;
2598+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2599+ struct ec_xfer_mock *mock;
2600+ int ret;
2601+ u8 out[3], in[2];
2602+
2603+ ec_dev->max_request = 0xff;
2604+ ec_dev->max_response = 0xee;
2605+
2606+ out[0] = 0xdd;
2607+ out[1] = 0xcc;
2608+ out[2] = 0xbb;
2609+
2610+ {
2611+ u8 *data;
2612+
2613+ mock = cros_kunit_ec_xfer_mock_add(test, 2);
2614+ KUNIT_ASSERT_PTR_NE(test, mock, NULL);
2615+
2616+ data = (u8 *)mock->o_data;
2617+ data[0] = 0xaa;
2618+ data[1] = 0x99;
2619+ }
2620+
2621+ ret = cros_ec_cmd(ec_dev, 0x88, 0x77, out, ARRAY_SIZE(out), in, ARRAY_SIZE(in));
2622+ KUNIT_EXPECT_EQ(test, ret, 2);
2623+
2624+ {
2625+ u8 *data;
2626+
2627+ mock = cros_kunit_ec_xfer_mock_next();
2628+ KUNIT_EXPECT_PTR_NE(test, mock, NULL);
2629+
2630+ KUNIT_EXPECT_EQ(test, mock->msg.version, 0x88);
2631+ KUNIT_EXPECT_EQ(test, mock->msg.command, 0x77);
2632+ KUNIT_EXPECT_EQ(test, mock->msg.insize, ARRAY_SIZE(in));
2633+ KUNIT_EXPECT_EQ(test, mock->msg.outsize, ARRAY_SIZE(out));
2634+
2635+ data = (u8 *)mock->i_data;
2636+ KUNIT_EXPECT_EQ(test, data[0], 0xdd);
2637+ KUNIT_EXPECT_EQ(test, data[1], 0xcc);
2638+ KUNIT_EXPECT_EQ(test, data[2], 0xbb);
2639+ }
2640+}
2641+
2642+static void cros_ec_proto_test_release(struct device *dev)
2643+{
2644+}
2645+
2646+static int cros_ec_proto_test_init(struct kunit *test)
2647+{
2648+ struct cros_ec_proto_test_priv *priv;
2649+ struct cros_ec_device *ec_dev;
2650+
2651+ priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
2652+ if (!priv)
2653+ return -ENOMEM;
2654+ test->priv = priv;
2655+
2656+ ec_dev = &priv->ec_dev;
2657+ ec_dev->dout = (u8 *)priv->dout;
2658+ ec_dev->dout_size = ARRAY_SIZE(priv->dout);
2659+ ec_dev->din = (u8 *)priv->din;
2660+ ec_dev->din_size = ARRAY_SIZE(priv->din);
2661+ ec_dev->proto_version = EC_HOST_REQUEST_VERSION;
2662+ ec_dev->dev = kunit_kzalloc(test, sizeof(*ec_dev->dev), GFP_KERNEL);
2663+ if (!ec_dev->dev)
2664+ return -ENOMEM;
2665+ device_initialize(ec_dev->dev);
2666+ dev_set_name(ec_dev->dev, "cros_ec_proto_test");
2667+ ec_dev->dev->release = cros_ec_proto_test_release;
2668+ ec_dev->cmd_xfer = cros_kunit_ec_xfer_mock;
2669+ ec_dev->pkt_xfer = cros_kunit_ec_xfer_mock;
2670+
2671+ priv->msg = (struct cros_ec_command *)priv->_msg;
2672+
2673+ cros_kunit_mock_reset();
2674+
2675+ return 0;
2676+}
2677+
2678+static void cros_ec_proto_test_exit(struct kunit *test)
2679+{
2680+ struct cros_ec_proto_test_priv *priv = test->priv;
2681+ struct cros_ec_device *ec_dev = &priv->ec_dev;
2682+
2683+ put_device(ec_dev->dev);
2684+}
2685+
2686+static struct kunit_case cros_ec_proto_test_cases[] = {
2687+ KUNIT_CASE(cros_ec_proto_test_prepare_tx_legacy_normal),
2688+ KUNIT_CASE(cros_ec_proto_test_prepare_tx_legacy_bad_msg_outsize),
2689+ KUNIT_CASE(cros_ec_proto_test_prepare_tx_normal),
2690+ KUNIT_CASE(cros_ec_proto_test_prepare_tx_bad_msg_outsize),
2691+ KUNIT_CASE(cros_ec_proto_test_check_result),
2692+ KUNIT_CASE(cros_ec_proto_test_query_all_normal),
2693+ KUNIT_CASE(cros_ec_proto_test_query_all_no_pd_return_error),
2694+ KUNIT_CASE(cros_ec_proto_test_query_all_no_pd_return0),
2695+ KUNIT_CASE(cros_ec_proto_test_query_all_legacy_normal_v3_return_error),
2696+ KUNIT_CASE(cros_ec_proto_test_query_all_legacy_normal_v3_return0),
2697+ KUNIT_CASE(cros_ec_proto_test_query_all_legacy_xfer_error),
2698+ KUNIT_CASE(cros_ec_proto_test_query_all_legacy_return_error),
2699+ KUNIT_CASE(cros_ec_proto_test_query_all_legacy_data_error),
2700+ KUNIT_CASE(cros_ec_proto_test_query_all_legacy_return0),
2701+ KUNIT_CASE(cros_ec_proto_test_query_all_no_mkbp),
2702+ KUNIT_CASE(cros_ec_proto_test_query_all_no_mkbp_return_error),
2703+ KUNIT_CASE(cros_ec_proto_test_query_all_no_mkbp_return0),
2704+ KUNIT_CASE(cros_ec_proto_test_query_all_no_host_sleep),
2705+ KUNIT_CASE(cros_ec_proto_test_query_all_no_host_sleep_return0),
2706+ KUNIT_CASE(cros_ec_proto_test_query_all_default_wake_mask_return_error),
2707+ KUNIT_CASE(cros_ec_proto_test_query_all_default_wake_mask_return0),
2708+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_normal),
2709+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_excess_msg_insize),
2710+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_excess_msg_outsize_without_passthru),
2711+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_excess_msg_outsize_with_passthru),
2712+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v3_normal),
2713+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v3_no_op),
2714+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v2_normal),
2715+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_protocol_v2_no_op),
2716+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_normal),
2717+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_retries_eagain),
2718+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_retries_status_processing),
2719+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_xfer_error),
2720+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_return_error),
2721+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_in_progress_return0),
2722+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_status_normal),
2723+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_status_xfer_error),
2724+ KUNIT_CASE(cros_ec_proto_test_cmd_xfer_status_return_error),
2725+ KUNIT_CASE(cros_ec_proto_test_get_next_event_no_mkbp_event),
2726+ KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_ec_suspended),
2727+ KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_version0),
2728+ KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_version2),
2729+ KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_host_event_rtc),
2730+ KUNIT_CASE(cros_ec_proto_test_get_next_event_mkbp_event_host_event_masked),
2731+ KUNIT_CASE(cros_ec_proto_test_get_host_event_no_mkbp_event),
2732+ KUNIT_CASE(cros_ec_proto_test_get_host_event_not_host_event),
2733+ KUNIT_CASE(cros_ec_proto_test_get_host_event_wrong_event_size),
2734+ KUNIT_CASE(cros_ec_proto_test_get_host_event_normal),
2735+ KUNIT_CASE(cros_ec_proto_test_check_features_cached),
2736+ KUNIT_CASE(cros_ec_proto_test_check_features_not_cached),
2737+ KUNIT_CASE(cros_ec_proto_test_get_sensor_count_normal),
2738+ KUNIT_CASE(cros_ec_proto_test_get_sensor_count_xfer_error),
2739+ KUNIT_CASE(cros_ec_proto_test_get_sensor_count_legacy),
2740+ KUNIT_CASE(cros_ec_proto_test_ec_cmd),
2741+ {}
2742+};
2743+
2744+static struct kunit_suite cros_ec_proto_test_suite = {
2745+ .name = "cros_ec_proto_test",
2746+ .init = cros_ec_proto_test_init,
2747+ .exit = cros_ec_proto_test_exit,
2748+ .test_cases = cros_ec_proto_test_cases,
2749+};
2750+
2751+kunit_test_suite(cros_ec_proto_test_suite);
2752+
2753+MODULE_LICENSE("GPL");
drivers/platform/chrome/cros_ec_trace.h+4−4
@@ -30,8 +30,8 @@ TRACE_EVENT(cros_ec_request_start, · 29 unmodified lines
3030 ),
3131 TP_fast_assign(
3232 __entry->version = cmd->version;
33− __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(1);
34− __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(1);
33+ __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
34+ __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
3535 __entry->outsize = cmd->outsize;
3636 __entry->insize = cmd->insize;
3737 ),
@@ -55,8 +55,8 @@ TRACE_EVENT(cros_ec_request_done, · 17 unmodified lines
5555 ),
5656 TP_fast_assign(
5757 __entry->version = cmd->version;
58− __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(1);
59− __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(1);
58+ __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
59+ __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX);
6060 __entry->outsize = cmd->outsize;
6161 __entry->insize = cmd->insize;
6262 __entry->result = cmd->result;
drivers/platform/chrome/cros_ec_typec.c+60−33
@@ -25,6 +25,8 @@ · 24 unmodified lines
2525
2626 #define DRV_NAME "cros-ec-typec"
2727
28+#define DP_PORT_VDO (BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D) | DP_CAP_DFP_D)
29+
2830 /* Supported alt modes. */
2931 enum {
3032 CROS_EC_ALTMODE_DP = 0,
@@ -60,8 +62,7 @@ struct cros_typec_port { · 29 unmodified lines
6062 uint8_t mux_flags;
6163 uint8_t role;
6264
63− /* Port alt modes. */
64− struct typec_altmode p_altmode[CROS_EC_ALTMODE_MAX];
65+ struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
6566
6667 /* Flag indicating that PD partner discovery data parsing is completed. */
6768 bool sop_disc_done;
@@ -254,6 +255,14 @@ static void cros_typec_remove_cable(struct cros_typec_data *typec, · 186 unmodified lines
254255 port->sop_prime_disc_done = false;
255256 }
256257
258+static void cros_typec_unregister_port_altmodes(struct cros_typec_port *port)
259+{
260+ int i;
261+
262+ for (i = 0; i < CROS_EC_ALTMODE_MAX; i++)
263+ typec_unregister_altmode(port->port_altmode[i]);
264+}
265+
257266 static void cros_unregister_ports(struct cros_typec_data *typec)
258267 {
259268 int i;
@@ -268,34 +277,49 @@ static void cros_unregister_ports(struct cros_typec_data *typec) · 8 unmodified lines
268277 usb_role_switch_put(typec->ports[i]->role_sw);
269278 typec_switch_put(typec->ports[i]->ori_sw);
270279 typec_mux_put(typec->ports[i]->mux);
280+ cros_typec_unregister_port_altmodes(typec->ports[i]);
271281 typec_unregister_port(typec->ports[i]->port);
272282 }
273283 }
274284
275285 /*
276− * Fake the alt mode structs until we actually start registering Type C port
277− * and partner alt modes.
286+ * Register port alt modes with known values till we start retrieving
287+ * port capabilities from the EC.
278288 */
279−static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
289+static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,
280290 int port_num)
281291 {
282292 struct cros_typec_port *port = typec->ports[port_num];
293+ struct typec_altmode_desc desc;
294+ struct typec_altmode *amode;
283295
284296 /* All PD capable CrOS devices are assumed to support DP altmode. */
285− port->p_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
286− port->p_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
297+ desc.svid = USB_TYPEC_DP_SID,
298+ desc.mode = USB_TYPEC_DP_MODE,
299+ desc.vdo = DP_PORT_VDO,
300+ amode = typec_port_register_altmode(port->port, &desc);
301+ if (IS_ERR(amode))
302+ return PTR_ERR(amode);
303+ port->port_altmode[CROS_EC_ALTMODE_DP] = amode;
287304
288305 /*
289306 * Register TBT compatibility alt mode. The EC will not enter the mode
290307 * if it doesn't support it, so it's safe to register it unconditionally
291308 * here for now.
292309 */
293− port->p_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
294− port->p_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
310+ memset(&desc, 0, sizeof(desc));
311+ desc.svid = USB_TYPEC_TBT_SID,
312+ desc.mode = TYPEC_ANY_MODE,
313+ amode = typec_port_register_altmode(port->port, &desc);
314+ if (IS_ERR(amode))
315+ return PTR_ERR(amode);
316+ port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;
295317
296318 port->state.alt = NULL;
297319 port->state.mode = TYPEC_STATE_USB;
298320 port->state.data = NULL;
321+
322+ return 0;
299323 }
300324
301325 static int cros_typec_init_ports(struct cros_typec_data *typec)
@@ -352,8 +376,8 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) · 50 unmodified lines
352376
353377 cros_port->port = typec_register_port(dev, cap);
354378 if (IS_ERR(cros_port->port)) {
355− dev_err(dev, "Failed to register port %d\n", port_num);
356379 ret = PTR_ERR(cros_port->port);
380+ dev_err_probe(dev, ret, "Failed to register port %d\n", port_num);
357381 goto unregister_ports;
358382 }
359383
@@ -362,7 +386,11 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) · 2 unmodified lines
362386 dev_dbg(dev, "No switch control for port %d\n",
363387 port_num);
364388
365− cros_typec_register_port_altmodes(typec, port_num);
389+ ret = cros_typec_register_port_altmodes(typec, port_num);
390+ if (ret) {
391+ dev_err(dev, "Failed to register port altmodes\n");
392+ goto unregister_ports;
393+ }
366394
367395 cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
368396 if (!cros_port->disc_data) {
@@ -431,7 +459,7 @@ static int cros_typec_enable_tbt(struct cros_typec_data *typec, · 62 unmodified lines
431459 data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
432460
433461 if (!port->state.alt) {
434− port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_TBT];
462+ port->state.alt = port->port_altmode[CROS_EC_ALTMODE_TBT];
435463 ret = cros_typec_usb_safe_state(port);
436464 if (ret)
437465 return ret;
@@ -473,7 +501,7 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec, · 35 unmodified lines
473501 /* Configuration VDO. */
474502 dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
475503 if (!port->state.alt) {
476− port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_DP];
504+ port->state.alt = port->port_altmode[CROS_EC_ALTMODE_DP];
477505 ret = cros_typec_usb_safe_state(port);
478506 if (ret)
479507 return ret;
@@ -525,8 +553,8 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, · 45 unmodified lines
525553 enum typec_orientation orientation;
526554 int ret;
527555
528− ret = cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO,
529− &req, sizeof(req), &resp, sizeof(resp));
556+ ret = cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO,
557+ &req, sizeof(req), &resp, sizeof(resp));
530558 if (ret < 0) {
531559 dev_warn(typec->dev, "Failed to get mux info for port: %d, err = %d\n",
532560 port_num, ret);
@@ -585,8 +613,8 @@ mux_ack: · 52 unmodified lines
585613 /* Sending Acknowledgment to EC */
586614 mux_ack.port = port_num;
587615
588− if (cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack,
589− sizeof(mux_ack), NULL, 0) < 0)
616+ if (cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack,
617+ sizeof(mux_ack), NULL, 0) < 0)
590618 dev_warn(typec->dev,
591619 "Failed to send Mux ACK to EC for port: %d\n",
592620 port_num);
@@ -754,8 +782,8 @@ static int cros_typec_handle_sop_prime_disc(struct cros_typec_data *typec, int p · 161 unmodified lines
754782 int ret = 0;
755783
756784 memset(disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
757− ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
758− disc, EC_PROTO2_MAX_RESPONSE_SIZE);
785+ ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
786+ disc, EC_PROTO2_MAX_RESPONSE_SIZE);
759787 if (ret < 0) {
760788 dev_err(typec->dev, "Failed to get SOP' discovery data for port: %d\n", port_num);
761789 goto sop_prime_disc_exit;
@@ -837,8 +865,8 @@ static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_nu · 75 unmodified lines
837865 typec_partner_set_pd_revision(port->partner, pd_revision);
838866
839867 memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
840− ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
841− sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
868+ ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
869+ sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
842870 if (ret < 0) {
843871 dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);
844872 goto disc_exit;
@@ -870,8 +898,8 @@ static int cros_typec_send_clear_event(struct cros_typec_data *typec, int port_n · 25 unmodified lines
870898 .clear_events_mask = events_mask,
871899 };
872900
873− return cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
874− sizeof(req), NULL, 0);
901+ return cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
902+ sizeof(req), NULL, 0);
875903 }
876904
877905 static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)
@@ -882,8 +910,8 @@ static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num · 4 unmodified lines
882910 };
883911 int ret;
884912
885− ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
886− &resp, sizeof(resp));
913+ ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
914+ &resp, sizeof(resp));
887915 if (ret < 0) {
888916 dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);
889917 return;
@@ -960,9 +988,9 @@ static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) · 70 unmodified lines
960988 req.mux = USB_PD_CTRL_MUX_NO_CHANGE;
961989 req.swap = USB_PD_CTRL_SWAP_NONE;
962990
963− ret = cros_ec_command(typec->ec, typec->pd_ctrl_ver,
964− EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
965− &resp, sizeof(resp));
991+ ret = cros_ec_cmd(typec->ec, typec->pd_ctrl_ver,
992+ EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
993+ &resp, sizeof(resp));
966994 if (ret < 0)
967995 return ret;
968996
@@ -997,9 +1025,8 @@ static int cros_typec_get_cmd_version(struct cros_typec_data *typec) · 28 unmodified lines
9971025
9981026 /* We're interested in the PD control command version. */
9991027 req_v1.cmd = EC_CMD_USB_PD_CONTROL;
1000− ret = cros_ec_command(typec->ec, 1, EC_CMD_GET_CMD_VERSIONS,
1001− &req_v1, sizeof(req_v1), &resp,
1002− sizeof(resp));
1028+ ret = cros_ec_cmd(typec->ec, 1, EC_CMD_GET_CMD_VERSIONS,
1029+ &req_v1, sizeof(req_v1), &resp, sizeof(resp));
10031030 if (ret < 0)
10041031 return ret;
10051032
@@ -1090,8 +1117,8 @@ static int cros_typec_probe(struct platform_device *pdev) · 84 unmodified lines
10901117 typec->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_CMD);
10911118 typec->needs_mux_ack = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK);
10921119
1093− ret = cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
1094− &resp, sizeof(resp));
1120+ ret = cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
1121+ &resp, sizeof(resp));
10951122 if (ret < 0)
10961123 return ret;
10971124
drivers/platform/chrome/cros_kbd_led_backlight.c+174−22
@@ -4,24 +4,60 @@ · 3 unmodified lines
44 // Copyright (C) 2012 Google, Inc.
55
66 #include <linux/acpi.h>
7−#include <linux/leds.h>
87 #include <linux/delay.h>
98 #include <linux/err.h>
10−#include <linux/module.h>
119 #include <linux/init.h>
1210 #include <linux/kernel.h>
11+#include <linux/leds.h>
12+#include <linux/module.h>
13+#include <linux/of.h>
14+#include <linux/platform_data/cros_ec_commands.h>
15+#include <linux/platform_data/cros_ec_proto.h>
1316 #include <linux/platform_device.h>
17+#include <linux/property.h>
1418 #include <linux/slab.h>
1519
20+struct keyboard_led {
21+ struct led_classdev cdev;
22+ struct cros_ec_device *ec;
23+};
24+
25+/**
26+ * struct keyboard_led_drvdata - keyboard LED driver data.
27+ * @init: Init function.
28+ * @brightness_get: Get LED brightness level.
29+ * @brightness_set: Set LED brightness level. Must not sleep.
30+ * @brightness_set_blocking: Set LED brightness level. It can block the
31+ * caller for the time required for accessing a
32+ * LED device register
33+ * @max_brightness: Maximum brightness.
34+ *
35+ * See struct led_classdev in include/linux/leds.h for more details.
36+ */
37+struct keyboard_led_drvdata {
38+ int (*init)(struct platform_device *pdev);
39+
40+ enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
41+
42+ void (*brightness_set)(struct led_classdev *led_cdev,
43+ enum led_brightness brightness);
44+ int (*brightness_set_blocking)(struct led_classdev *led_cdev,
45+ enum led_brightness brightness);
46+
47+ enum led_brightness max_brightness;
48+};
49+
50+#define KEYBOARD_BACKLIGHT_MAX 100
51+
52+#ifdef CONFIG_ACPI
53+
1654 /* Keyboard LED ACPI Device must be defined in firmware */
1755 #define ACPI_KEYBOARD_BACKLIGHT_DEVICE "\\_SB.KBLT"
1856 #define ACPI_KEYBOARD_BACKLIGHT_READ ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBQC"
1957 #define ACPI_KEYBOARD_BACKLIGHT_WRITE ACPI_KEYBOARD_BACKLIGHT_DEVICE ".KBCM"
2058
21−#define ACPI_KEYBOARD_BACKLIGHT_MAX 100
22−
23−static void keyboard_led_set_brightness(struct led_classdev *cdev,
24− enum led_brightness brightness)
59+static void keyboard_led_set_brightness_acpi(struct led_classdev *cdev,
60+ enum led_brightness brightness)
2561 {
2662 union acpi_object param;
2763 struct acpi_object_list input;
@@ -40,7 +76,7 @@ static void keyboard_led_set_brightness(struct led_classdev *cdev, · 12 unmodified lines
4076 }
4177
4278 static enum led_brightness
43−keyboard_led_get_brightness(struct led_classdev *cdev)
79+keyboard_led_get_brightness_acpi(struct led_classdev *cdev)
4480 {
4581 unsigned long long brightness;
4682 acpi_status status;
@@ -56,12 +92,10 @@ keyboard_led_get_brightness(struct led_classdev *cdev) · 9 unmodified lines
5692 return brightness;
5793 }
5894
59−static int keyboard_led_probe(struct platform_device *pdev)
95+static int keyboard_led_init_acpi(struct platform_device *pdev)
6096 {
61− struct led_classdev *cdev;
6297 acpi_handle handle;
6398 acpi_status status;
64− int error;
6599
66100 /* Look for the keyboard LED ACPI Device */
67101 status = acpi_get_handle(ACPI_ROOT_OBJECT,
@@ -73,33 +107,151 @@ static int keyboard_led_probe(struct platform_device *pdev) · 5 unmodified lines
73107 return -ENXIO;
74108 }
75109
76− cdev = devm_kzalloc(&pdev->dev, sizeof(*cdev), GFP_KERNEL);
77− if (!cdev)
110+ return 0;
111+}
112+
113+static const struct keyboard_led_drvdata keyboard_led_drvdata_acpi = {
114+ .init = keyboard_led_init_acpi,
115+ .brightness_set = keyboard_led_set_brightness_acpi,
116+ .brightness_get = keyboard_led_get_brightness_acpi,
117+ .max_brightness = KEYBOARD_BACKLIGHT_MAX,
118+};
119+
120+#endif /* CONFIG_ACPI */
121+
122+#if IS_ENABLED(CONFIG_CROS_EC)
123+
124+static int
125+keyboard_led_set_brightness_ec_pwm(struct led_classdev *cdev,
126+ enum led_brightness brightness)
127+{
128+ struct {
129+ struct cros_ec_command msg;
130+ struct ec_params_pwm_set_keyboard_backlight params;
131+ } __packed buf;
132+ struct ec_params_pwm_set_keyboard_backlight *params = &buf.params;
133+ struct cros_ec_command *msg = &buf.msg;
134+ struct keyboard_led *keyboard_led = container_of(cdev, struct keyboard_led, cdev);
135+
136+ memset(&buf, 0, sizeof(buf));
137+
138+ msg->command = EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT;
139+ msg->outsize = sizeof(*params);
140+
141+ params->percent = brightness;
142+
143+ return cros_ec_cmd_xfer_status(keyboard_led->ec, msg);
144+}
145+
146+static enum led_brightness
147+keyboard_led_get_brightness_ec_pwm(struct led_classdev *cdev)
148+{
149+ struct {
150+ struct cros_ec_command msg;
151+ struct ec_response_pwm_get_keyboard_backlight resp;
152+ } __packed buf;
153+ struct ec_response_pwm_get_keyboard_backlight *resp = &buf.resp;
154+ struct cros_ec_command *msg = &buf.msg;
155+ struct keyboard_led *keyboard_led = container_of(cdev, struct keyboard_led, cdev);
156+ int ret;
157+
158+ memset(&buf, 0, sizeof(buf));
159+
160+ msg->command = EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT;
161+ msg->insize = sizeof(*resp);
162+
163+ ret = cros_ec_cmd_xfer_status(keyboard_led->ec, msg);
164+ if (ret < 0)
165+ return ret;
166+
167+ return resp->percent;
168+}
169+
170+static int keyboard_led_init_ec_pwm(struct platform_device *pdev)
171+{
172+ struct keyboard_led *keyboard_led = platform_get_drvdata(pdev);
173+
174+ keyboard_led->ec = dev_get_drvdata(pdev->dev.parent);
175+ if (!keyboard_led->ec) {
176+ dev_err(&pdev->dev, "no parent EC device\n");
177+ return -EINVAL;
178+ }
179+
180+ return 0;
181+}
182+
183+static const __maybe_unused struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm = {
184+ .init = keyboard_led_init_ec_pwm,
185+ .brightness_set_blocking = keyboard_led_set_brightness_ec_pwm,
186+ .brightness_get = keyboard_led_get_brightness_ec_pwm,
187+ .max_brightness = KEYBOARD_BACKLIGHT_MAX,
188+};
189+
190+#else /* IS_ENABLED(CONFIG_CROS_EC) */
191+
192+static const __maybe_unused struct keyboard_led_drvdata keyboard_led_drvdata_ec_pwm = {};
193+
194+#endif /* IS_ENABLED(CONFIG_CROS_EC) */
195+
196+static int keyboard_led_probe(struct platform_device *pdev)
197+{
198+ const struct keyboard_led_drvdata *drvdata;
199+ struct keyboard_led *keyboard_led;
200+ int error;
201+
202+ drvdata = device_get_match_data(&pdev->dev);
203+ if (!drvdata)
204+ return -EINVAL;
205+
206+ keyboard_led = devm_kzalloc(&pdev->dev, sizeof(*keyboard_led), GFP_KERNEL);
207+ if (!keyboard_led)
78208 return -ENOMEM;
209+ platform_set_drvdata(pdev, keyboard_led);
210+
211+ if (drvdata->init) {
212+ error = drvdata->init(pdev);
213+ if (error)
214+ return error;
215+ }
79216
80− cdev->name = "chromeos::kbd_backlight";
81− cdev->max_brightness = ACPI_KEYBOARD_BACKLIGHT_MAX;
82− cdev->flags |= LED_CORE_SUSPENDRESUME;
83− cdev->brightness_set = keyboard_led_set_brightness;
84− cdev->brightness_get = keyboard_led_get_brightness;
217+ keyboard_led->cdev.name = "chromeos::kbd_backlight";
218+ keyboard_led->cdev.flags |= LED_CORE_SUSPENDRESUME;
219+ keyboard_led->cdev.max_brightness = drvdata->max_brightness;
220+ keyboard_led->cdev.brightness_set = drvdata->brightness_set;
221+ keyboard_led->cdev.brightness_set_blocking = drvdata->brightness_set_blocking;
222+ keyboard_led->cdev.brightness_get = drvdata->brightness_get;
85223
86− error = devm_led_classdev_register(&pdev->dev, cdev);
224+ error = devm_led_classdev_register(&pdev->dev, &keyboard_led->cdev);
87225 if (error)
88226 return error;
89227
90228 return 0;
91229 }
92230
93−static const struct acpi_device_id keyboard_led_id[] = {
94− { "GOOG0002", 0 },
231+#ifdef CONFIG_ACPI
232+static const struct acpi_device_id keyboard_led_acpi_match[] = {
233+ { "GOOG0002", (kernel_ulong_t)&keyboard_led_drvdata_acpi },
95234 { }
96235 };
97−MODULE_DEVICE_TABLE(acpi, keyboard_led_id);
236+MODULE_DEVICE_TABLE(acpi, keyboard_led_acpi_match);
237+#endif
238+
239+#ifdef CONFIG_OF
240+static const struct of_device_id keyboard_led_of_match[] = {
241+ {
242+ .compatible = "google,cros-kbd-led-backlight",
243+ .data = &keyboard_led_drvdata_ec_pwm,
244+ },
245+ {}
246+};
247+MODULE_DEVICE_TABLE(of, keyboard_led_of_match);
248+#endif
98249
99250 static struct platform_driver keyboard_led_driver = {
100251 .driver = {
101252 .name = "chromeos-keyboard-leds",
102− .acpi_match_table = ACPI_PTR(keyboard_led_id),
253+ .acpi_match_table = ACPI_PTR(keyboard_led_acpi_match),
254+ .of_match_table = of_match_ptr(keyboard_led_of_match),
103255 },
104256 .probe = keyboard_led_probe,
105257 };
drivers/platform/chrome/cros_kunit_util.c+130−0
@@ -0,0 +1,130 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * CrOS Kunit tests utilities.
4+ */
5+
6+#include <kunit/test.h>
7+
8+#include <linux/list.h>
9+#include <linux/minmax.h>
10+#include <linux/platform_data/cros_ec_commands.h>
11+#include <linux/platform_data/cros_ec_proto.h>
12+
13+#include "cros_ec.h"
14+#include "cros_kunit_util.h"
15+
16+int cros_kunit_ec_xfer_mock_default_result;
17+int cros_kunit_ec_xfer_mock_default_ret;
18+int cros_kunit_ec_cmd_xfer_mock_called;
19+int cros_kunit_ec_pkt_xfer_mock_called;
20+
21+static struct list_head cros_kunit_ec_xfer_mock_in;
22+static struct list_head cros_kunit_ec_xfer_mock_out;
23+
24+int cros_kunit_ec_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
25+{
26+ struct ec_xfer_mock *mock;
27+
28+ mock = list_first_entry_or_null(&cros_kunit_ec_xfer_mock_in, struct ec_xfer_mock, list);
29+ if (!mock) {
30+ msg->result = cros_kunit_ec_xfer_mock_default_result;
31+ return cros_kunit_ec_xfer_mock_default_ret;
32+ }
33+
34+ list_del(&mock->list);
35+
36+ memcpy(&mock->msg, msg, sizeof(*msg));
37+ if (msg->outsize) {
38+ mock->i_data = kunit_kzalloc(mock->test, msg->outsize, GFP_KERNEL);
39+ if (mock->i_data)
40+ memcpy(mock->i_data, msg->data, msg->outsize);
41+ }
42+
43+ msg->result = mock->result;
44+ if (msg->insize)
45+ memcpy(msg->data, mock->o_data, min(msg->insize, mock->o_data_len));
46+
47+ list_add_tail(&mock->list, &cros_kunit_ec_xfer_mock_out);
48+
49+ return mock->ret;
50+}
51+
52+int cros_kunit_ec_cmd_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
53+{
54+ ++cros_kunit_ec_cmd_xfer_mock_called;
55+ return cros_kunit_ec_xfer_mock(ec_dev, msg);
56+}
57+
58+int cros_kunit_ec_pkt_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
59+{
60+ ++cros_kunit_ec_pkt_xfer_mock_called;
61+ return cros_kunit_ec_xfer_mock(ec_dev, msg);
62+}
63+
64+struct ec_xfer_mock *cros_kunit_ec_xfer_mock_add(struct kunit *test, size_t size)
65+{
66+ return cros_kunit_ec_xfer_mock_addx(test, size, EC_RES_SUCCESS, size);
67+}
68+
69+struct ec_xfer_mock *cros_kunit_ec_xfer_mock_addx(struct kunit *test,
70+ int ret, int result, size_t size)
71+{
72+ struct ec_xfer_mock *mock;
73+
74+ mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL);
75+ if (!mock)
76+ return NULL;
77+
78+ list_add_tail(&mock->list, &cros_kunit_ec_xfer_mock_in);
79+ mock->test = test;
80+
81+ mock->ret = ret;
82+ mock->result = result;
83+ mock->o_data = kunit_kzalloc(test, size, GFP_KERNEL);
84+ if (!mock->o_data)
85+ return NULL;
86+ mock->o_data_len = size;
87+
88+ return mock;
89+}
90+
91+struct ec_xfer_mock *cros_kunit_ec_xfer_mock_next(void)
92+{
93+ struct ec_xfer_mock *mock;
94+
95+ mock = list_first_entry_or_null(&cros_kunit_ec_xfer_mock_out, struct ec_xfer_mock, list);
96+ if (mock)
97+ list_del(&mock->list);
98+
99+ return mock;
100+}
101+
102+int cros_kunit_readmem_mock_offset;
103+u8 *cros_kunit_readmem_mock_data;
104+int cros_kunit_readmem_mock_ret;
105+
106+int cros_kunit_readmem_mock(struct cros_ec_device *ec_dev, unsigned int offset,
107+ unsigned int bytes, void *dest)
108+{
109+ cros_kunit_readmem_mock_offset = offset;
110+
111+ memcpy(dest, cros_kunit_readmem_mock_data, bytes);
112+
113+ return cros_kunit_readmem_mock_ret;
114+}
115+
116+void cros_kunit_mock_reset(void)
117+{
118+ cros_kunit_ec_xfer_mock_default_result = 0;
119+ cros_kunit_ec_xfer_mock_default_ret = 0;
120+ cros_kunit_ec_cmd_xfer_mock_called = 0;
121+ cros_kunit_ec_pkt_xfer_mock_called = 0;
122+ INIT_LIST_HEAD(&cros_kunit_ec_xfer_mock_in);
123+ INIT_LIST_HEAD(&cros_kunit_ec_xfer_mock_out);
124+
125+ cros_kunit_readmem_mock_offset = 0;
126+ cros_kunit_readmem_mock_data = NULL;
127+ cros_kunit_readmem_mock_ret = 0;
128+}
129+
130+MODULE_LICENSE("GPL");
drivers/platform/chrome/cros_kunit_util.h+48−0
@@ -0,0 +1,48 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * CrOS Kunit tests utilities.
4+ */
5+
6+#ifndef _CROS_KUNIT_UTIL_H_
7+#define _CROS_KUNIT_UTIL_H_
8+
9+#include <linux/platform_data/cros_ec_proto.h>
10+
11+struct ec_xfer_mock {
12+ struct list_head list;
13+ struct kunit *test;
14+
15+ /* input */
16+ struct cros_ec_command msg;
17+ void *i_data;
18+
19+ /* output */
20+ int ret;
21+ int result;
22+ void *o_data;
23+ u32 o_data_len;
24+};
25+
26+extern int cros_kunit_ec_xfer_mock_default_result;
27+extern int cros_kunit_ec_xfer_mock_default_ret;
28+extern int cros_kunit_ec_cmd_xfer_mock_called;
29+extern int cros_kunit_ec_pkt_xfer_mock_called;
30+
31+int cros_kunit_ec_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
32+int cros_kunit_ec_cmd_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
33+int cros_kunit_ec_pkt_xfer_mock(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
34+struct ec_xfer_mock *cros_kunit_ec_xfer_mock_add(struct kunit *test, size_t size);
35+struct ec_xfer_mock *cros_kunit_ec_xfer_mock_addx(struct kunit *test,
36+ int ret, int result, size_t size);
37+struct ec_xfer_mock *cros_kunit_ec_xfer_mock_next(void);
38+
39+extern int cros_kunit_readmem_mock_offset;
40+extern u8 *cros_kunit_readmem_mock_data;
41+extern int cros_kunit_readmem_mock_ret;
42+
43+int cros_kunit_readmem_mock(struct cros_ec_device *ec_dev, unsigned int offset,
44+ unsigned int bytes, void *dest);
45+
46+void cros_kunit_mock_reset(void);
47+
48+#endif
drivers/platform/chrome/cros_usbpd_notify.c+2−2
@@ -71,8 +71,8 @@ static void cros_usbpd_get_event_and_notify(struct device *dev, · 70 unmodified lines
7171 }
7272
7373 /* Check for PD host events on EC. */
74− ret = cros_ec_command(ec_dev, 0, EC_CMD_PD_HOST_EVENT_STATUS,
75− NULL, 0, &host_event_status, sizeof(host_event_status));
74+ ret = cros_ec_cmd(ec_dev, 0, EC_CMD_PD_HOST_EVENT_STATUS,
75+ NULL, 0, &host_event_status, sizeof(host_event_status));
7676 if (ret < 0) {
7777 dev_warn(dev, "Can't get host event status (err: %d)\n", ret);
7878 goto send_notify;
drivers/platform/chrome/wilco_ec/event.c+1−1
@@ -343,7 +343,7 @@ static __poll_t event_poll(struct file *filp, poll_table *wait) · 342 unmodified lines
343343 *
344344 * Removes the first event from the queue, places it in the passed buffer.
345345 *
346− * If there are no events in the the queue, then one of two things happens,
346+ * If there are no events in the queue, then one of two things happens,
347347 * depending on if the file was opened in nonblocking mode: If in nonblocking
348348 * mode, then return -EAGAIN to say there's no data. If in blocking mode, then
349349 * block until an event is available.
drivers/regulator/cros-ec-regulator.c+3−33
@@ -22,36 +22,6 @@ struct cros_ec_regulator_data { · 21 unmodified lines
2222 u16 num_voltages;
2323 };
2424
25−static int cros_ec_cmd(struct cros_ec_device *ec, u32 version, u32 command,
26− void *outdata, u32 outsize, void *indata, u32 insize)
27−{
28− struct cros_ec_command *msg;
29− int ret;
30−
31− msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
32− if (!msg)
33− return -ENOMEM;
34−
35− msg->version = version;
36− msg->command = command;
37− msg->outsize = outsize;
38− msg->insize = insize;
39−
40− if (outdata && outsize > 0)
41− memcpy(msg->data, outdata, outsize);
42−
43− ret = cros_ec_cmd_xfer_status(ec, msg);
44− if (ret < 0)
45− goto cleanup;
46−
47− if (insize)
48− memcpy(indata, msg->data, insize);
49−
50−cleanup:
51− kfree(msg);
52− return ret;
53−}
54−
5525 static int cros_ec_regulator_enable(struct regulator_dev *dev)
5626 {
5727 struct cros_ec_regulator_data *data = rdev_get_drvdata(dev);
@@ -61,7 +31,7 @@ static int cros_ec_regulator_enable(struct regulator_dev *dev) · 3 unmodified lines
6131 };
6232
6333 return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
64− sizeof(cmd), NULL, 0);
34+ sizeof(cmd), NULL, 0);
6535 }
6636
6737 static int cros_ec_regulator_disable(struct regulator_dev *dev)
@@ -73,7 +43,7 @@ static int cros_ec_regulator_disable(struct regulator_dev *dev) · 5 unmodified lines
7343 };
7444
7545 return cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_ENABLE, &cmd,
76− sizeof(cmd), NULL, 0);
46+ sizeof(cmd), NULL, 0);
7747 }
7848
7949 static int cros_ec_regulator_is_enabled(struct regulator_dev *dev)
@@ -161,7 +131,7 @@ static int cros_ec_regulator_init_info(struct device *dev, · 81 unmodified lines
161131 int ret;
162132
163133 ret = cros_ec_cmd(data->ec_dev, 0, EC_CMD_REGULATOR_GET_INFO, &cmd,
164− sizeof(cmd), &resp, sizeof(resp));
134+ sizeof(cmd), &resp, sizeof(resp));
165135 if (ret < 0)
166136 return ret;
167137
include/linux/platform_data/cros_ec_commands.h+3−3
@@ -13,8 +13,8 @@ · 12 unmodified lines
1313 #ifndef __CROS_EC_COMMANDS_H
1414 #define __CROS_EC_COMMANDS_H
1515
16−
17−
16+#include <linux/bits.h>
17+#include <linux/types.h>
1818
1919 #define BUILD_ASSERT(_cond)
2020
@@ -787,7 +787,7 @@ struct ec_host_response { · 766 unmodified lines
787787 *
788788 * Packets always start with a request or response header. They are followed
789789 * by data_len bytes of data. If the data_crc_present flag is set, the data
790− * bytes are followed by a CRC-8 of that data, using using x^8 + x^2 + x + 1
790+ * bytes are followed by a CRC-8 of that data, using x^8 + x^2 + x + 1
791791 * polynomial.
792792 *
793793 * Host algorithm when sending a request q:
include/linux/platform_data/cros_ec_proto.h+5−2
@@ -21,6 +21,9 @@ · 20 unmodified lines
2121 #define CROS_EC_DEV_SCP_NAME "cros_scp"
2222 #define CROS_EC_DEV_TP_NAME "cros_tp"
2323
24+#define CROS_EC_DEV_EC_INDEX 0
25+#define CROS_EC_DEV_PD_INDEX 1
26+
2427 /*
2528 * The EC is unresponsive for a time after a reboot command. Add a
2629 * simple delay to make sure that the bus stays locked.
@@ -231,8 +234,8 @@ bool cros_ec_check_features(struct cros_ec_dev *ec, int feature); · 204 unmodified lines
231234
232235 int cros_ec_get_sensor_count(struct cros_ec_dev *ec);
233236
234−int cros_ec_command(struct cros_ec_device *ec_dev, unsigned int version, int command, void *outdata,
235− int outsize, void *indata, int insize);
237+int cros_ec_cmd(struct cros_ec_device *ec_dev, unsigned int version, int command, void *outdata,
238+ size_t outsize, void *indata, size_t insize);
236239
237240 /**
238241 * cros_ec_get_time_ns() - Return time in ns.