History

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

Pull chrome platform updates from Tzung-Bi Shih: "New drivers: - cros_ec_uart for ChromeOS EC protocol over UART - cros_typec_vdm for USB PD Vendor Defined Message Improvements: - Preserve logs as much as possible when EC panics - Shutdown to refrain from potential HW damages when EC panics Fixes: - Fix DP_PORT_VDO to include DP_CAP_RECEPTACLE - Fix a lockdep false positive Cleanups: - Use sysfs_emit*() instead of scnprintf() - Use asm instead of asm-generic for unaligned.h Misc: - Rename module name from cros_ec_typec to cros-ec-typec - Minor fixes" * tag 'tag-chrome-platform-for-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux: (34 commits) platform/chrome: cros_ec_typec: Fix spelling mistake platform/chrome: cros_typec_vdm: Add Attention support platform/chrome: cros_ec: Add VDM attention headers platform/chrome: cros_typec_vdm: Fix VDO copy platform/chrome: cros_ec_typec: allow deferred probe of switch handles platform/chrome: cros_ec_proto: remove big stub objects from stack platform/chrome: cros_ec_uart: fix negative type promoted to high platform/chrome: cros_ec: Use per-device lockdep key platform/chrome: fix kernel-doc warnings for cros_ec_command platform/chrome: fix kernel-doc warning for last_resume_result platform/chrome: fix kernel-doc warning for suspend_timeout_ms platform/chrome: fix kernel-doc warnings for panic notifier platform/chrome: cros_ec_lpc: initialize the buf variable platform/chrome: cros_ec: Fix panic notifier registration platform/chrome: cros_typec_switch: Check for retimer flag platform/chrome: cros_typec_switch: Use fwnode* prop check platform/chrome: cros_typec_vdm: Add VDM send support platform/chrome: cros_typec_vdm: Add VDM reply support platform/chrome: cros_ec_typec: Add initial VDM support platform/chrome: cros_ec_typec: Alter module name with hyphens ...

Linus Torvalds committed 3 years ago

Commit 5f5ce6b2 parents 239451e b0d8a6719 files · +846 −147Browse files

Unified · Split

19 files
  1. MAINTAINERS +9 −1
  2. drivers/mfd/cros_ec_dev.c +0 −5
  3. drivers/platform/chrome/Kconfig +11 −1
  4. drivers/platform/chrome/Makefile +3 −1
  5. drivers/platform/chrome/cros_ec.c +12 −3
  6. drivers/platform/chrome/cros_ec_debugfs.c +25 −0
  7. drivers/platform/chrome/cros_ec_lightbar.c +6 −8
  8. drivers/platform/chrome/cros_ec_lpc.c +11 −1
  9. drivers/platform/chrome/cros_ec_proto_test.c +7 −6
  10. drivers/platform/chrome/cros_ec_sysfs.c +16 −24
  11. drivers/platform/chrome/cros_ec_typec.c +41 −82
  12. drivers/platform/chrome/cros_ec_typec.h +85 −0
  13. drivers/platform/chrome/cros_ec_uart.c +362 −0
  14. drivers/platform/chrome/cros_typec_switch.c +9 −7
  15. drivers/platform/chrome/cros_typec_vdm.c +148 −0
  16. drivers/platform/chrome/cros_typec_vdm.h +13 −0
  17. drivers/platform/chrome/wilco_ec/sysfs.c +1 −2
  18. include/linux/platform_data/cros_ec_commands.h +64 −5
  19. include/linux/platform_data/cros_ec_proto.h +23 −1
MAINTAINERS+9−1
@@ -4823,6 +4823,13 @@ S: Maintained · 4822 unmodified lines
4823F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml4823F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml
4824F: sound/soc/codecs/cros_ec_codec.*4824F: sound/soc/codecs/cros_ec_codec.*
4825 4825
4826CHROMEOS EC UART DRIVER
4827M: Bhanu Prakash Maiya <bhanumaiya@chromium.org>
4828R: Benson Leung <bleung@chromium.org>
4829R: Tzung-Bi Shih <tzungbi@kernel.org>
4830S: Maintained
4831F: drivers/platform/chrome/cros_ec_uart.c
4832
4826CHROMEOS EC SUBDRIVERS4833CHROMEOS EC SUBDRIVERS
4827M: Benson Leung <bleung@chromium.org>4834M: Benson Leung <bleung@chromium.org>
4828R: Guenter Roeck <groeck@chromium.org>4835R: Guenter Roeck <groeck@chromium.org>
@@ -4836,8 +4843,9 @@ CHROMEOS EC USB TYPE-C DRIVER · 7 unmodified lines
4836M: Prashant Malani <pmalani@chromium.org>4843M: Prashant Malani <pmalani@chromium.org>
4837L: chrome-platform@lists.linux.dev4844L: chrome-platform@lists.linux.dev
4838S: Maintained4845S: Maintained
4839F: drivers/platform/chrome/cros_ec_typec.c4846F: drivers/platform/chrome/cros_ec_typec.*
4840F: drivers/platform/chrome/cros_typec_switch.c4847F: drivers/platform/chrome/cros_typec_switch.c
4848F: drivers/platform/chrome/cros_typec_vdm.*
4841 4849
4842CHROMEOS EC USB PD NOTIFY DRIVER4850CHROMEOS EC USB PD NOTIFY DRIVER
4843M: Prashant Malani <pmalani@chromium.org>4851M: Prashant Malani <pmalani@chromium.org>
drivers/mfd/cros_ec_dev.c+0−5
@@ -64,11 +64,6 @@ static const struct cros_feature_to_name cros_mcu_devices[] = { · 63 unmodified lines
64 .name = CROS_EC_DEV_SCP_NAME,64 .name = CROS_EC_DEV_SCP_NAME,
65 .desc = "System Control Processor",65 .desc = "System Control Processor",
66 },66 },
67 {
68 .id = EC_FEATURE_SCP_C1,
69 .name = CROS_EC_DEV_SCP_C1_NAME,
70 .desc = "System Control Processor 2nd Core",
71 },
72 {67 {
73 .id = EC_FEATURE_TOUCHPAD,68 .id = EC_FEATURE_TOUCHPAD,
74 .name = CROS_EC_DEV_TP_NAME,69 .name = CROS_EC_DEV_TP_NAME,
drivers/platform/chrome/Kconfig+11−1
@@ -119,6 +119,16 @@ config CROS_EC_SPI · 118 unmodified lines
119 response time cannot be guaranteed, we support ignoring119 response time cannot be guaranteed, we support ignoring
120 'pre-amble' bytes before the response actually starts.120 'pre-amble' bytes before the response actually starts.
121 121
122config CROS_EC_UART
123 tristate "ChromeOS Embedded Controller (UART)"
124 depends on CROS_EC && ACPI && SERIAL_DEV_BUS
125 help
126 If you say Y here, you get support for talking to the ChromeOS EC
127 through a UART, using a byte-level protocol.
128
129 To compile this driver as a module, choose M here: the
130 module will be called cros_ec_uart.
131
122config CROS_EC_LPC132config CROS_EC_LPC
123 tristate "ChromeOS Embedded Controller (LPC)"133 tristate "ChromeOS Embedded Controller (LPC)"
124 depends on CROS_EC && ACPI && (X86 || COMPILE_TEST)134 depends on CROS_EC && ACPI && (X86 || COMPILE_TEST)
@@ -226,7 +236,7 @@ config CROS_EC_TYPEC · 101 unmodified lines
226 information from the Chrome OS EC.236 information from the Chrome OS EC.
227 237
228 To compile this driver as a module, choose M here: the module will be238 To compile this driver as a module, choose M here: the module will be
229 called cros_ec_typec.239 called cros-ec-typec.
230 240
231config CROS_HPS_I2C241config CROS_HPS_I2C
232 tristate "ChromeOS HPS device"242 tristate "ChromeOS HPS device"
drivers/platform/chrome/Makefile+3−1
@@ -15,8 +15,10 @@ obj-$(CONFIG_CROS_EC_ISHTP) += cros_ec_ishtp.o · 14 unmodified lines
15obj-$(CONFIG_CROS_TYPEC_SWITCH) += cros_typec_switch.o15obj-$(CONFIG_CROS_TYPEC_SWITCH) += cros_typec_switch.o
16obj-$(CONFIG_CROS_EC_RPMSG) += cros_ec_rpmsg.o16obj-$(CONFIG_CROS_EC_RPMSG) += cros_ec_rpmsg.o
17obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o17obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
18obj-$(CONFIG_CROS_EC_UART) += cros_ec_uart.o
18cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_mec.o19cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_mec.o
19obj-$(CONFIG_CROS_EC_TYPEC) += cros_ec_typec.o20cros-ec-typec-objs := cros_ec_typec.o cros_typec_vdm.o
21obj-$(CONFIG_CROS_EC_TYPEC) += cros-ec-typec.o
20obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o22obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o
21obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o cros_ec_trace.o23obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o cros_ec_trace.o
22obj-$(CONFIG_CROS_KBD_LED_BACKLIGHT) += cros_kbd_led_backlight.o24obj-$(CONFIG_CROS_KBD_LED_BACKLIGHT) += cros_kbd_led_backlight.o
drivers/platform/chrome/cros_ec.c+12−3
@@ -182,6 +182,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) · 181 unmodified lines
182 int err = 0;182 int err = 0;
183 183
184 BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);184 BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
185 BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->panic_notifier);
185 186
186 ec_dev->max_request = sizeof(struct ec_params_hello);187 ec_dev->max_request = sizeof(struct ec_params_hello);
187 ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);188 ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
@@ -198,12 +199,14 @@ int cros_ec_register(struct cros_ec_device *ec_dev) · 10 unmodified lines
198 if (!ec_dev->dout)199 if (!ec_dev->dout)
199 return -ENOMEM;200 return -ENOMEM;
200 201
202 lockdep_register_key(&ec_dev->lockdep_key);
201 mutex_init(&ec_dev->lock);203 mutex_init(&ec_dev->lock);
204 lockdep_set_class(&ec_dev->lock, &ec_dev->lockdep_key);
202 205
203 err = cros_ec_query_all(ec_dev);206 err = cros_ec_query_all(ec_dev);
204 if (err) {207 if (err) {
205 dev_err(dev, "Cannot identify the EC: error %d\n", err);208 dev_err(dev, "Cannot identify the EC: error %d\n", err);
206 return err;209 goto destroy_mutex;
207 }210 }
208 211
209 if (ec_dev->irq > 0) {212 if (ec_dev->irq > 0) {
@@ -215,7 +218,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) · 5 unmodified lines
215 if (err) {218 if (err) {
216 dev_err(dev, "Failed to request IRQ %d: %d\n",219 dev_err(dev, "Failed to request IRQ %d: %d\n",
217 ec_dev->irq, err);220 ec_dev->irq, err);
218 return err;221 goto destroy_mutex;
219 }222 }
220 }223 }
221 224
@@ -226,7 +229,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev) · 4 unmodified lines
226 if (IS_ERR(ec_dev->ec)) {229 if (IS_ERR(ec_dev->ec)) {
227 dev_err(ec_dev->dev,230 dev_err(ec_dev->dev,
228 "Failed to create CrOS EC platform device\n");231 "Failed to create CrOS EC platform device\n");
229 return PTR_ERR(ec_dev->ec);232 err = PTR_ERR(ec_dev->ec);
233 goto destroy_mutex;
230 }234 }
231 235
232 if (ec_dev->max_passthru) {236 if (ec_dev->max_passthru) {
@@ -292,6 +296,9 @@ int cros_ec_register(struct cros_ec_device *ec_dev) · 59 unmodified lines
292exit:296exit:
293 platform_device_unregister(ec_dev->ec);297 platform_device_unregister(ec_dev->ec);
294 platform_device_unregister(ec_dev->pd);298 platform_device_unregister(ec_dev->pd);
299destroy_mutex:
300 mutex_destroy(&ec_dev->lock);
301 lockdep_unregister_key(&ec_dev->lockdep_key);
295 return err;302 return err;
296}303}
297EXPORT_SYMBOL(cros_ec_register);304EXPORT_SYMBOL(cros_ec_register);
@@ -309,6 +316,8 @@ void cros_ec_unregister(struct cros_ec_device *ec_dev) · 11 unmodified lines
309 if (ec_dev->pd)316 if (ec_dev->pd)
310 platform_device_unregister(ec_dev->pd);317 platform_device_unregister(ec_dev->pd);
311 platform_device_unregister(ec_dev->ec);318 platform_device_unregister(ec_dev->ec);
319 mutex_destroy(&ec_dev->lock);
320 lockdep_unregister_key(&ec_dev->lockdep_key);
312}321}
313EXPORT_SYMBOL(cros_ec_unregister);322EXPORT_SYMBOL(cros_ec_unregister);
314 323
drivers/platform/chrome/cros_ec_debugfs.c+25−0
@@ -38,6 +38,8 @@ static DECLARE_WAIT_QUEUE_HEAD(cros_ec_debugfs_log_wq); · 37 unmodified lines
38 * @log_mutex: mutex to protect circular buffer38 * @log_mutex: mutex to protect circular buffer
39 * @log_poll_work: recurring task to poll EC for new console log data39 * @log_poll_work: recurring task to poll EC for new console log data
40 * @panicinfo_blob: panicinfo debugfs blob40 * @panicinfo_blob: panicinfo debugfs blob
41 * @notifier_panic: notifier_block to let kernel to flush buffered log
42 * when EC panic
41 */43 */
42struct cros_ec_debugfs {44struct cros_ec_debugfs {
43 struct cros_ec_dev *ec;45 struct cros_ec_dev *ec;
@@ -49,6 +51,7 @@ struct cros_ec_debugfs { · 5 unmodified lines
49 struct delayed_work log_poll_work;51 struct delayed_work log_poll_work;
50 /* EC panicinfo */52 /* EC panicinfo */
51 struct debugfs_blob_wrapper panicinfo_blob;53 struct debugfs_blob_wrapper panicinfo_blob;
54 struct notifier_block notifier_panic;
52};55};
53 56
54/*57/*
@@ -437,6 +440,22 @@ free: · 382 unmodified lines
437 return ret;440 return ret;
438}441}
439 442
443static int cros_ec_debugfs_panic_event(struct notifier_block *nb,
444 unsigned long queued_during_suspend, void *_notify)
445{
446 struct cros_ec_debugfs *debug_info =
447 container_of(nb, struct cros_ec_debugfs, notifier_panic);
448
449 if (debug_info->log_buffer.buf) {
450 /* Force log poll work to run immediately */
451 mod_delayed_work(debug_info->log_poll_work.wq, &debug_info->log_poll_work, 0);
452 /* Block until log poll work finishes */
453 flush_delayed_work(&debug_info->log_poll_work);
454 }
455
456 return NOTIFY_DONE;
457}
458
440static int cros_ec_debugfs_probe(struct platform_device *pd)459static int cros_ec_debugfs_probe(struct platform_device *pd)
441{460{
442 struct cros_ec_dev *ec = dev_get_drvdata(pd->dev.parent);461 struct cros_ec_dev *ec = dev_get_drvdata(pd->dev.parent);
@@ -473,6 +492,12 @@ static int cros_ec_debugfs_probe(struct platform_device *pd) · 30 unmodified lines
473 debugfs_create_u16("suspend_timeout_ms", 0664, debug_info->dir,492 debugfs_create_u16("suspend_timeout_ms", 0664, debug_info->dir,
474 &ec->ec_dev->suspend_timeout_ms);493 &ec->ec_dev->suspend_timeout_ms);
475 494
495 debug_info->notifier_panic.notifier_call = cros_ec_debugfs_panic_event;
496 ret = blocking_notifier_chain_register(&ec->ec_dev->panic_notifier,
497 &debug_info->notifier_panic);
498 if (ret)
499 goto remove_debugfs;
500
476 ec->debug_info = debug_info;501 ec->debug_info = debug_info;
477 502
478 dev_set_drvdata(&pd->dev, ec);503 dev_set_drvdata(&pd->dev, ec);
drivers/platform/chrome/cros_ec_lightbar.c+6−8
@@ -34,7 +34,7 @@ static ssize_t interval_msec_show(struct device *dev, · 33 unmodified lines
34{34{
35 unsigned long msec = lb_interval_jiffies * 1000 / HZ;35 unsigned long msec = lb_interval_jiffies * 1000 / HZ;
36 36
37 return scnprintf(buf, PAGE_SIZE, "%lu\n", msec);37 return sysfs_emit(buf, "%lu\n", msec);
38}38}
39 39
40static ssize_t interval_msec_store(struct device *dev,40static ssize_t interval_msec_store(struct device *dev,
@@ -169,7 +169,7 @@ static ssize_t version_show(struct device *dev, · 128 unmodified lines
169 if (!get_lightbar_version(ec, &version, &flags))169 if (!get_lightbar_version(ec, &version, &flags))
170 return -EIO;170 return -EIO;
171 171
172 return scnprintf(buf, PAGE_SIZE, "%d %d\n", version, flags);172 return sysfs_emit(buf, "%d %d\n", version, flags);
173}173}
174 174
175static ssize_t brightness_store(struct device *dev,175static ssize_t brightness_store(struct device *dev,
@@ -302,17 +302,15 @@ static ssize_t sequence_show(struct device *dev, · 126 unmodified lines
302 302
303 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);303 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
304 if (ret < 0) {304 if (ret < 0) {
305 ret = scnprintf(buf, PAGE_SIZE, "XFER / EC ERROR %d / %d\n",305 ret = sysfs_emit(buf, "XFER / EC ERROR %d / %d\n", ret, msg->result);
306 ret, msg->result);
307 goto exit;306 goto exit;
308 }307 }
309 308
310 resp = (struct ec_response_lightbar *)msg->data;309 resp = (struct ec_response_lightbar *)msg->data;
311 if (resp->get_seq.num >= ARRAY_SIZE(seqname))310 if (resp->get_seq.num >= ARRAY_SIZE(seqname))
312 ret = scnprintf(buf, PAGE_SIZE, "%d\n", resp->get_seq.num);311 ret = sysfs_emit(buf, "%d\n", resp->get_seq.num);
313 else312 else
314 ret = scnprintf(buf, PAGE_SIZE, "%s\n",313 ret = sysfs_emit(buf, "%s\n", seqname[resp->get_seq.num]);
315 seqname[resp->get_seq.num]);
316 314
317exit:315exit:
318 kfree(msg);316 kfree(msg);
@@ -483,7 +481,7 @@ static ssize_t userspace_control_show(struct device *dev, · 164 unmodified lines
483 struct device_attribute *attr,481 struct device_attribute *attr,
484 char *buf)482 char *buf)
485{483{
486 return scnprintf(buf, PAGE_SIZE, "%d\n", userspace_control);484 return sysfs_emit(buf, "%d\n", userspace_control);
487}485}
488 486
489static ssize_t userspace_control_store(struct device *dev,487static ssize_t userspace_control_store(struct device *dev,
drivers/platform/chrome/cros_ec_lpc.c+11−1
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include <linux/platform_data/cros_ec_proto.h>21#include <linux/platform_data/cros_ec_proto.h>
22#include <linux/platform_device.h>22#include <linux/platform_device.h>
23#include <linux/printk.h>23#include <linux/printk.h>
24#include <linux/reboot.h>
24#include <linux/suspend.h>25#include <linux/suspend.h>
25 26
26#include "cros_ec.h"27#include "cros_ec.h"
@@ -320,6 +321,15 @@ static void cros_ec_lpc_acpi_notify(acpi_handle device, u32 value, void *data) · 293 unmodified lines
320 321
321 ec_dev->last_event_time = cros_ec_get_time_ns();322 ec_dev->last_event_time = cros_ec_get_time_ns();
322 323
324 if (value == ACPI_NOTIFY_CROS_EC_PANIC) {
325 dev_emerg(ec_dev->dev, "CrOS EC Panic Reported. Shutdown is imminent!");
326 blocking_notifier_call_chain(&ec_dev->panic_notifier, 0, ec_dev);
327 /* Begin orderly shutdown. Force shutdown after 1 second. */
328 hw_protection_shutdown("CrOS EC Panic", 1000);
329 /* Do not query for other events after a panic is reported */
330 return;
331 }
332
323 if (ec_dev->mkbp_event_supported)333 if (ec_dev->mkbp_event_supported)
324 do {334 do {
325 ret = cros_ec_get_next_event(ec_dev, NULL,335 ret = cros_ec_get_next_event(ec_dev, NULL,
@@ -340,7 +350,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) · 14 unmodified lines
340 struct acpi_device *adev;350 struct acpi_device *adev;
341 acpi_status status;351 acpi_status status;
342 struct cros_ec_device *ec_dev;352 struct cros_ec_device *ec_dev;
343 u8 buf[2];353 u8 buf[2] = {};
344 int irq, ret;354 int irq, ret;
345 355
346 /*356 /*
drivers/platform/chrome/cros_ec_proto_test.c+7−6
@@ -5,7 +5,8 @@ · 4 unmodified lines
5 5
6#include <kunit/test.h>6#include <kunit/test.h>
7 7
8#include <asm-generic/unaligned.h>8#include <asm/unaligned.h>
9
9#include <linux/platform_data/cros_ec_commands.h>10#include <linux/platform_data/cros_ec_commands.h>
10#include <linux/platform_data/cros_ec_proto.h>11#include <linux/platform_data/cros_ec_proto.h>
11 12
@@ -2370,7 +2371,7 @@ static void cros_ec_proto_test_get_host_event_normal(struct kunit *test) · 2358 unmodified lines
2370static void cros_ec_proto_test_check_features_cached(struct kunit *test)2371static void cros_ec_proto_test_check_features_cached(struct kunit *test)
2371{2372{
2372 int ret, i;2373 int ret, i;
2373 struct cros_ec_dev ec;2374 static struct cros_ec_dev ec;
2374 2375
2375 ec.features.flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FINGERPRINT);2376 ec.features.flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FINGERPRINT);
2376 ec.features.flags[1] = EC_FEATURE_MASK_0(EC_FEATURE_SCP);2377 ec.features.flags[1] = EC_FEATURE_MASK_0(EC_FEATURE_SCP);
@@ -2395,7 +2396,7 @@ static void cros_ec_proto_test_check_features_not_cached(struct kunit *test) · 18 unmodified lines
2395 struct cros_ec_device *ec_dev = &priv->ec_dev;2396 struct cros_ec_device *ec_dev = &priv->ec_dev;
2396 struct ec_xfer_mock *mock;2397 struct ec_xfer_mock *mock;
2397 int ret, i;2398 int ret, i;
2398 struct cros_ec_dev ec;2399 static struct cros_ec_dev ec;
2399 2400
2400 ec_dev->max_request = 0xff;2401 ec_dev->max_request = 0xff;
2401 ec_dev->max_response = 0xee;2402 ec_dev->max_response = 0xee;
@@ -2448,7 +2449,7 @@ static void cros_ec_proto_test_get_sensor_count_normal(struct kunit *test) · 46 unmodified lines
2448 struct cros_ec_device *ec_dev = &priv->ec_dev;2449 struct cros_ec_device *ec_dev = &priv->ec_dev;
2449 struct ec_xfer_mock *mock;2450 struct ec_xfer_mock *mock;
2450 int ret;2451 int ret;
2451 struct cros_ec_dev ec;2452 static struct cros_ec_dev ec;
2452 2453
2453 ec_dev->max_request = 0xff;2454 ec_dev->max_request = 0xff;
2454 ec_dev->max_response = 0xee;2455 ec_dev->max_response = 0xee;
@@ -2493,7 +2494,7 @@ static void cros_ec_proto_test_get_sensor_count_xfer_error(struct kunit *test) · 38 unmodified lines
2493 struct cros_ec_device *ec_dev = &priv->ec_dev;2494 struct cros_ec_device *ec_dev = &priv->ec_dev;
2494 struct ec_xfer_mock *mock;2495 struct ec_xfer_mock *mock;
2495 int ret;2496 int ret;
2496 struct cros_ec_dev ec;2497 static struct cros_ec_dev ec;
2497 2498
2498 ec_dev->max_request = 0xff;2499 ec_dev->max_request = 0xff;
2499 ec_dev->max_response = 0xee;2500 ec_dev->max_response = 0xee;
@@ -2533,7 +2534,7 @@ static void cros_ec_proto_test_get_sensor_count_legacy(struct kunit *test) · 33 unmodified lines
2533 struct cros_ec_device *ec_dev = &priv->ec_dev;2534 struct cros_ec_device *ec_dev = &priv->ec_dev;
2534 struct ec_xfer_mock *mock;2535 struct ec_xfer_mock *mock;
2535 int ret, i;2536 int ret, i;
2536 struct cros_ec_dev ec;2537 static struct cros_ec_dev ec;
2537 struct {2538 struct {
2538 u8 readmem_data;2539 u8 readmem_data;
2539 int expected_result;2540 int expected_result;
drivers/platform/chrome/cros_ec_sysfs.c+16−24
@@ -27,10 +27,9 @@ static ssize_t reboot_show(struct device *dev, · 26 unmodified lines
27{27{
28 int count = 0;28 int count = 0;
29 29
30 count += scnprintf(buf + count, PAGE_SIZE - count,30 count += sysfs_emit_at(buf, count,
31 "ro|rw|cancel|cold|disable-jump|hibernate|cold-ap-off");31 "ro|rw|cancel|cold|disable-jump|hibernate|cold-ap-off");
32 count += scnprintf(buf + count, PAGE_SIZE - count,32 count += sysfs_emit_at(buf, count, " [at-shutdown]\n");
33 " [at-shutdown]\n");
34 return count;33 return count;
35}34}
36 35
@@ -138,12 +137,9 @@ static ssize_t version_show(struct device *dev, · 101 unmodified lines
138 /* Strings should be null-terminated, but let's be sure. */137 /* Strings should be null-terminated, but let's be sure. */
139 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0';138 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0';
140 r_ver->version_string_rw[sizeof(r_ver->version_string_rw) - 1] = '\0';139 r_ver->version_string_rw[sizeof(r_ver->version_string_rw) - 1] = '\0';
141 count += scnprintf(buf + count, PAGE_SIZE - count,140 count += sysfs_emit_at(buf, count, "RO version: %s\n", r_ver->version_string_ro);
142 "RO version: %s\n", r_ver->version_string_ro);141 count += sysfs_emit_at(buf, count, "RW version: %s\n", r_ver->version_string_rw);
143 count += scnprintf(buf + count, PAGE_SIZE - count,142 count += sysfs_emit_at(buf, count, "Firmware copy: %s\n",
144 "RW version: %s\n", r_ver->version_string_rw);
145 count += scnprintf(buf + count, PAGE_SIZE - count,
146 "Firmware copy: %s\n",
147 (r_ver->current_image < ARRAY_SIZE(image_names) ?143 (r_ver->current_image < ARRAY_SIZE(image_names) ?
148 image_names[r_ver->current_image] : "?"));144 image_names[r_ver->current_image] : "?"));
149 145
@@ -152,13 +148,12 @@ static ssize_t version_show(struct device *dev, · 2 unmodified lines
152 msg->insize = EC_HOST_PARAM_SIZE;148 msg->insize = EC_HOST_PARAM_SIZE;
153 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);149 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
154 if (ret < 0) {150 if (ret < 0) {
155 count += scnprintf(buf + count, PAGE_SIZE - count,151 count += sysfs_emit_at(buf, count,
156 "Build info: XFER / EC ERROR %d / %d\n",152 "Build info: XFER / EC ERROR %d / %d\n",
157 ret, msg->result);153 ret, msg->result);
158 } else {154 } else {
159 msg->data[EC_HOST_PARAM_SIZE - 1] = '\0';155 msg->data[EC_HOST_PARAM_SIZE - 1] = '\0';
160 count += scnprintf(buf + count, PAGE_SIZE - count,156 count += sysfs_emit_at(buf, count, "Build info: %s\n", msg->data);
161 "Build info: %s\n", msg->data);
162 }157 }
163 158
164 /* Get chip info. */159 /* Get chip info. */
@@ -166,7 +161,7 @@ static ssize_t version_show(struct device *dev, · 1 unmodified line
166 msg->insize = sizeof(*r_chip);161 msg->insize = sizeof(*r_chip);
167 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);162 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
168 if (ret < 0) {163 if (ret < 0) {
169 count += scnprintf(buf + count, PAGE_SIZE - count,164 count += sysfs_emit_at(buf, count,
170 "Chip info: XFER / EC ERROR %d / %d\n",165 "Chip info: XFER / EC ERROR %d / %d\n",
171 ret, msg->result);166 ret, msg->result);
172 } else {167 } else {
@@ -175,12 +170,9 @@ static ssize_t version_show(struct device *dev, · 2 unmodified lines
175 r_chip->vendor[sizeof(r_chip->vendor) - 1] = '\0';170 r_chip->vendor[sizeof(r_chip->vendor) - 1] = '\0';
176 r_chip->name[sizeof(r_chip->name) - 1] = '\0';171 r_chip->name[sizeof(r_chip->name) - 1] = '\0';
177 r_chip->revision[sizeof(r_chip->revision) - 1] = '\0';172 r_chip->revision[sizeof(r_chip->revision) - 1] = '\0';
178 count += scnprintf(buf + count, PAGE_SIZE - count,173 count += sysfs_emit_at(buf, count, "Chip vendor: %s\n", r_chip->vendor);
179 "Chip vendor: %s\n", r_chip->vendor);174 count += sysfs_emit_at(buf, count, "Chip name: %s\n", r_chip->name);
180 count += scnprintf(buf + count, PAGE_SIZE - count,175 count += sysfs_emit_at(buf, count, "Chip revision: %s\n", r_chip->revision);
181 "Chip name: %s\n", r_chip->name);
182 count += scnprintf(buf + count, PAGE_SIZE - count,
183 "Chip revision: %s\n", r_chip->revision);
184 }176 }
185 177
186 /* Get board version */178 /* Get board version */
@@ -188,13 +180,13 @@ static ssize_t version_show(struct device *dev, · 1 unmodified line
188 msg->insize = sizeof(*r_board);180 msg->insize = sizeof(*r_board);
189 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);181 ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
190 if (ret < 0) {182 if (ret < 0) {
191 count += scnprintf(buf + count, PAGE_SIZE - count,183 count += sysfs_emit_at(buf, count,
192 "Board version: XFER / EC ERROR %d / %d\n",184 "Board version: XFER / EC ERROR %d / %d\n",
193 ret, msg->result);185 ret, msg->result);
194 } else {186 } else {
195 r_board = (struct ec_response_board_version *)msg->data;187 r_board = (struct ec_response_board_version *)msg->data;
196 188
197 count += scnprintf(buf + count, PAGE_SIZE - count,189 count += sysfs_emit_at(buf, count,
198 "Board version: %d\n",190 "Board version: %d\n",
199 r_board->board_version);191 r_board->board_version);
200 }192 }
@@ -227,7 +219,7 @@ static ssize_t flashinfo_show(struct device *dev, · 26 unmodified lines
227 219
228 resp = (struct ec_response_flash_info *)msg->data;220 resp = (struct ec_response_flash_info *)msg->data;
229 221
230 ret = scnprintf(buf, PAGE_SIZE,222 ret = sysfs_emit(buf,
231 "FlashSize %d\nWriteSize %d\n"223 "FlashSize %d\nWriteSize %d\n"
232 "EraseSize %d\nProtectSize %d\n",224 "EraseSize %d\nProtectSize %d\n",
233 resp->flash_size, resp->write_block_size,225 resp->flash_size, resp->write_block_size,
@@ -264,7 +256,7 @@ static ssize_t kb_wake_angle_show(struct device *dev, · 30 unmodified lines
264 goto exit;256 goto exit;
265 257
266 resp = (struct ec_response_motion_sense *)msg->data;258 resp = (struct ec_response_motion_sense *)msg->data;
267 ret = scnprintf(buf, PAGE_SIZE, "%d\n", resp->kb_wake_angle.ret);259 ret = sysfs_emit(buf, "%d\n", resp->kb_wake_angle.ret);
268exit:260exit:
269 kfree(msg);261 kfree(msg);
270 return ret;262 return ret;
drivers/platform/chrome/cros_ec_typec.c+41−82
@@ -7,92 +7,22 @@ · 6 unmodified lines
7 */7 */
8 8
9#include <linux/acpi.h>9#include <linux/acpi.h>
10#include <linux/list.h>
11#include <linux/module.h>10#include <linux/module.h>
12#include <linux/of.h>11#include <linux/of.h>
13#include <linux/platform_data/cros_ec_commands.h>12#include <linux/platform_data/cros_ec_commands.h>
14#include <linux/platform_data/cros_ec_proto.h>
15#include <linux/platform_data/cros_usbpd_notify.h>13#include <linux/platform_data/cros_usbpd_notify.h>
16#include <linux/platform_device.h>14#include <linux/platform_device.h>
17#include <linux/usb/pd.h>
18#include <linux/usb/pd_vdo.h>15#include <linux/usb/pd_vdo.h>
19#include <linux/usb/typec.h>
20#include <linux/usb/typec_altmode.h>
21#include <linux/usb/typec_dp.h>16#include <linux/usb/typec_dp.h>
22#include <linux/usb/typec_mux.h>
23#include <linux/usb/typec_retimer.h>
24#include <linux/usb/typec_tbt.h>17#include <linux/usb/typec_tbt.h>
25#include <linux/usb/role.h>18
19#include "cros_ec_typec.h"
20#include "cros_typec_vdm.h"
26 21
27#define DRV_NAME "cros-ec-typec"22#define DRV_NAME "cros-ec-typec"
28 23
29#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \24#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
30 DP_CAP_DFP_D)25 DP_CAP_DFP_D | DP_CAP_RECEPTACLE)
31
32/* Supported alt modes. */
33enum {
34 CROS_EC_ALTMODE_DP = 0,
35 CROS_EC_ALTMODE_TBT,
36 CROS_EC_ALTMODE_MAX,
37};
38
39/* Container for altmode pointer nodes. */
40struct cros_typec_altmode_node {
41 struct typec_altmode *amode;
42 struct list_head list;
43};
44
45/* Per port data. */
46struct cros_typec_port {
47 struct typec_port *port;
48 /* Initial capabilities for the port. */
49 struct typec_capability caps;
50 struct typec_partner *partner;
51 struct typec_cable *cable;
52 /* SOP' plug. */
53 struct typec_plug *plug;
54 /* Port partner PD identity info. */
55 struct usb_pd_identity p_identity;
56 /* Port cable PD identity info. */
57 struct usb_pd_identity c_identity;
58 struct typec_switch *ori_sw;
59 struct typec_mux *mux;
60 struct typec_retimer *retimer;
61 struct usb_role_switch *role_sw;
62
63 /* Variables keeping track of switch state. */
64 struct typec_mux_state state;
65 uint8_t mux_flags;
66 uint8_t role;
67
68 struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
69
70 /* Flag indicating that PD partner discovery data parsing is completed. */
71 bool sop_disc_done;
72 bool sop_prime_disc_done;
73 struct ec_response_typec_discovery *disc_data;
74 struct list_head partner_mode_list;
75 struct list_head plug_mode_list;
76
77 /* PDO-related structs */
78 struct usb_power_delivery *partner_pd;
79 struct usb_power_delivery_capabilities *partner_src_caps;
80 struct usb_power_delivery_capabilities *partner_sink_caps;
81};
82
83/* Platform-specific data for the Chrome OS EC Type C controller. */
84struct cros_typec_data {
85 struct device *dev;
86 struct cros_ec_device *ec;
87 int num_ports;
88 unsigned int pd_ctrl_ver;
89 /* Array of ports, indexed by port number. */
90 struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
91 struct notifier_block nb;
92 struct work_struct port_work;
93 bool typec_cmd_supported;
94 bool needs_mux_ack;
95};
96 26
97static int cros_typec_parse_port_props(struct typec_capability *cap,27static int cros_typec_parse_port_props(struct typec_capability *cap,
98 struct fwnode_handle *fwnode,28 struct fwnode_handle *fwnode,
@@ -145,27 +75,33 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port, · 46 unmodified lines
145 struct fwnode_handle *fwnode,75 struct fwnode_handle *fwnode,
146 struct device *dev)76 struct device *dev)
147{77{
78 int ret = 0;
79
148 port->mux = fwnode_typec_mux_get(fwnode, NULL);80 port->mux = fwnode_typec_mux_get(fwnode, NULL);
149 if (IS_ERR(port->mux)) {81 if (IS_ERR(port->mux)) {
150 dev_dbg(dev, "Mux handle not found.\n");82 ret = PTR_ERR(port->mux);
83 dev_dbg(dev, "Mux handle not found: %d.\n", ret);
151 goto mux_err;84 goto mux_err;
152 }85 }
153 86
154 port->retimer = fwnode_typec_retimer_get(fwnode);87 port->retimer = fwnode_typec_retimer_get(fwnode);
155 if (IS_ERR(port->retimer)) {88 if (IS_ERR(port->retimer)) {
156 dev_dbg(dev, "Retimer handle not found.\n");89 ret = PTR_ERR(port->retimer);
90 dev_dbg(dev, "Retimer handle not found: %d.\n", ret);
157 goto retimer_sw_err;91 goto retimer_sw_err;
158 }92 }
159 93
160 port->ori_sw = fwnode_typec_switch_get(fwnode);94 port->ori_sw = fwnode_typec_switch_get(fwnode);
161 if (IS_ERR(port->ori_sw)) {95 if (IS_ERR(port->ori_sw)) {
162 dev_dbg(dev, "Orientation switch handle not found.\n");96 ret = PTR_ERR(port->ori_sw);
97 dev_dbg(dev, "Orientation switch handle not found: %d\n", ret);
163 goto ori_sw_err;98 goto ori_sw_err;
164 }99 }
165 100
166 port->role_sw = fwnode_usb_role_switch_get(fwnode);101 port->role_sw = fwnode_usb_role_switch_get(fwnode);
167 if (IS_ERR(port->role_sw)) {102 if (IS_ERR(port->role_sw)) {
168 dev_dbg(dev, "USB role switch handle not found.\n");103 ret = PTR_ERR(port->role_sw);
104 dev_dbg(dev, "USB role switch handle not found: %d\n", ret);
169 goto role_sw_err;105 goto role_sw_err;
170 }106 }
171 107
@@ -181,7 +117,7 @@ retimer_sw_err: · 9 unmodified lines
181 typec_mux_put(port->mux);117 typec_mux_put(port->mux);
182 port->mux = NULL;118 port->mux = NULL;
183mux_err:119mux_err:
184 return -ENODEV;120 return ret;
185}121}
186 122
187static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,123static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,
@@ -342,6 +278,8 @@ static int cros_typec_register_port_altmodes(struct cros_typec_data *typec, · 154 unmodified lines
342 if (IS_ERR(amode))278 if (IS_ERR(amode))
343 return PTR_ERR(amode);279 return PTR_ERR(amode);
344 port->port_altmode[CROS_EC_ALTMODE_DP] = amode;280 port->port_altmode[CROS_EC_ALTMODE_DP] = amode;
281 typec_altmode_set_drvdata(amode, port);
282 amode->ops = &port_amode_ops;
345 283
346 /*284 /*
347 * Register TBT compatibility alt mode. The EC will not enter the mode285 * Register TBT compatibility alt mode. The EC will not enter the mode
@@ -355,6 +293,8 @@ static int cros_typec_register_port_altmodes(struct cros_typec_data *typec, · 7 unmodified lines
355 if (IS_ERR(amode))293 if (IS_ERR(amode))
356 return PTR_ERR(amode);294 return PTR_ERR(amode);
357 port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;295 port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;
296 typec_altmode_set_drvdata(amode, port);
297 amode->ops = &port_amode_ops;
358 298
359 port->state.alt = NULL;299 port->state.alt = NULL;
360 port->state.mode = TYPEC_STATE_USB;300 port->state.mode = TYPEC_STATE_USB;
@@ -408,6 +348,8 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) · 47 unmodified lines
408 goto unregister_ports;348 goto unregister_ports;
409 }349 }
410 350
351 cros_port->port_num = port_num;
352 cros_port->typec_data = typec;
411 typec->ports[port_num] = cros_port;353 typec->ports[port_num] = cros_port;
412 cap = &cros_port->caps;354 cap = &cros_port->caps;
413 355
@@ -423,9 +365,11 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) · 9 unmodified lines
423 }365 }
424 366
425 ret = cros_typec_get_switch_handles(cros_port, fwnode, dev);367 ret = cros_typec_get_switch_handles(cros_port, fwnode, dev);
426 if (ret)368 if (ret) {
427 dev_dbg(dev, "No switch control for port %d\n",369 dev_dbg(dev, "No switch control for port %d, err: %d\n", port_num, ret);
428 port_num);370 if (ret == -EPROBE_DEFER)
371 goto unregister_ports;
372 }
429 373
430 ret = cros_typec_register_port_altmodes(typec, port_num);374 ret = cros_typec_register_port_altmodes(typec, port_num);
431 if (ret) {375 if (ret) {
@@ -1064,6 +1008,21 @@ static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num · 632 unmodified lines
1064 "Failed SOP Disc event clear, port: %d\n", port_num);1008 "Failed SOP Disc event clear, port: %d\n", port_num);
1065 }1009 }
1066 }1010 }
1011
1012 if (resp.events & PD_STATUS_EVENT_VDM_REQ_REPLY) {
1013 cros_typec_handle_vdm_response(typec, port_num);
1014 ret = cros_typec_send_clear_event(typec, port_num, PD_STATUS_EVENT_VDM_REQ_REPLY);
1015 if (ret < 0)
1016 dev_warn(typec->dev, "Failed VDM Reply event clear, port: %d\n", port_num);
1017 }
1018
1019 if (resp.events & PD_STATUS_EVENT_VDM_ATTENTION) {
1020 cros_typec_handle_vdm_attention(typec, port_num);
1021 ret = cros_typec_send_clear_event(typec, port_num, PD_STATUS_EVENT_VDM_ATTENTION);
1022 if (ret < 0)
1023 dev_warn(typec->dev, "Failed VDM attention event clear, port: %d\n",
1024 port_num);
1025 }
1067}1026}
1068 1027
1069static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)1028static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
drivers/platform/chrome/cros_ec_typec.h+85−0
@@ -0,0 +1,85 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#ifndef __CROS_EC_TYPEC__
4#define __CROS_EC_TYPEC__
5
6#include <linux/list.h>
7#include <linux/notifier.h>
8#include <linux/platform_data/cros_ec_proto.h>
9#include <linux/usb/pd.h>
10#include <linux/usb/role.h>
11#include <linux/usb/typec.h>
12#include <linux/usb/typec_altmode.h>
13#include <linux/usb/typec_mux.h>
14#include <linux/usb/typec_retimer.h>
15#include <linux/workqueue.h>
16
17/* Supported alt modes. */
18enum {
19 CROS_EC_ALTMODE_DP = 0,
20 CROS_EC_ALTMODE_TBT,
21 CROS_EC_ALTMODE_MAX,
22};
23
24/* Container for altmode pointer nodes. */
25struct cros_typec_altmode_node {
26 struct typec_altmode *amode;
27 struct list_head list;
28};
29
30/* Platform-specific data for the Chrome OS EC Type C controller. */
31struct cros_typec_data {
32 struct device *dev;
33 struct cros_ec_device *ec;
34 int num_ports;
35 unsigned int pd_ctrl_ver;
36 /* Array of ports, indexed by port number. */
37 struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
38 struct notifier_block nb;
39 struct work_struct port_work;
40 bool typec_cmd_supported;
41 bool needs_mux_ack;
42};
43
44/* Per port data. */
45struct cros_typec_port {
46 struct typec_port *port;
47 int port_num;
48 /* Initial capabilities for the port. */
49 struct typec_capability caps;
50 struct typec_partner *partner;
51 struct typec_cable *cable;
52 /* SOP' plug. */
53 struct typec_plug *plug;
54 /* Port partner PD identity info. */
55 struct usb_pd_identity p_identity;
56 /* Port cable PD identity info. */
57 struct usb_pd_identity c_identity;
58 struct typec_switch *ori_sw;
59 struct typec_mux *mux;
60 struct typec_retimer *retimer;
61 struct usb_role_switch *role_sw;
62
63 /* Variables keeping track of switch state. */
64 struct typec_mux_state state;
65 uint8_t mux_flags;
66 uint8_t role;
67
68 struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
69
70 /* Flag indicating that PD partner discovery data parsing is completed. */
71 bool sop_disc_done;
72 bool sop_prime_disc_done;
73 struct ec_response_typec_discovery *disc_data;
74 struct list_head partner_mode_list;
75 struct list_head plug_mode_list;
76
77 /* PDO-related structs */
78 struct usb_power_delivery *partner_pd;
79 struct usb_power_delivery_capabilities *partner_src_caps;
80 struct usb_power_delivery_capabilities *partner_sink_caps;
81
82 struct cros_typec_data *typec_data;
83};
84
85#endif /* __CROS_EC_TYPEC__ */
drivers/platform/chrome/cros_ec_uart.c+362−0
@@ -0,0 +1,362 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * UART interface for ChromeOS Embedded Controller
4 *
5 * Copyright 2020-2022 Google LLC.
6 */
7
8#include <linux/acpi.h>
9#include <linux/delay.h>
10#include <linux/errno.h>
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/platform_data/cros_ec_proto.h>
16#include <linux/serdev.h>
17#include <linux/slab.h>
18#include <uapi/linux/sched/types.h>
19
20#include "cros_ec.h"
21
22/*
23 * EC sends contiguous bytes of response packet on UART AP RX.
24 * TTY driver in AP accumulates incoming bytes and calls the registered callback
25 * function. Byte count can range from 1 to MAX bytes supported by EC.
26 * This driver should wait for long time for all callbacks to be processed.
27 * Considering the worst case scenario, wait for 500 msec. This timeout should
28 * account for max latency and some additional guard time.
29 * Best case: Entire packet is received in ~200 ms, wait queue will be released
30 * and packet will be processed.
31 * Worst case: TTY driver sends bytes in multiple callbacks. In this case this
32 * driver will wait for ~1 sec beyond which it will timeout.
33 * This timeout value should not exceed ~500 msec because in case if
34 * EC_CMD_REBOOT_EC sent, high level driver should be able to intercept EC
35 * in RO.
36 */
37#define EC_MSG_DEADLINE_MS 500
38
39/**
40 * struct response_info - Encapsulate EC response related
41 * information for passing between function
42 * cros_ec_uart_pkt_xfer() and cros_ec_uart_rx_bytes()
43 * callback.
44 * @data: Copy the data received from EC here.
45 * @max_size: Max size allocated for the @data buffer. If the
46 * received data exceeds this value, we log an error.
47 * @size: Actual size of data received from EC. This is also
48 * used to accumulate byte count with response is received
49 * in dma chunks.
50 * @exp_len: Expected bytes of response from EC including header.
51 * @status: Re-init to 0 before sending a cmd. Updated to 1 when
52 * a response is successfully received, or an error number
53 * on failure.
54 * @wait_queue: Wait queue EC response where the cros_ec sends request
55 * to EC and waits
56 */
57struct response_info {
58 void *data;
59 size_t max_size;
60 size_t size;
61 size_t exp_len;
62 int status;
63 wait_queue_head_t wait_queue;
64};
65
66/**
67 * struct cros_ec_uart - information about a uart-connected EC
68 *
69 * @serdev: serdev uart device we are connected to.
70 * @baudrate: UART baudrate of attached EC device.
71 * @flowcontrol: UART flowcontrol of attached device.
72 * @irq: Linux IRQ number of associated serial device.
73 * @response: Response info passing between cros_ec_uart_pkt_xfer()
74 * and cros_ec_uart_rx_bytes()
75 */
76struct cros_ec_uart {
77 struct serdev_device *serdev;
78 u32 baudrate;
79 u8 flowcontrol;
80 u32 irq;
81 struct response_info response;
82};
83
84static int cros_ec_uart_rx_bytes(struct serdev_device *serdev,
85 const u8 *data,
86 size_t count)
87{
88 struct ec_host_response *host_response;
89 struct cros_ec_device *ec_dev = serdev_device_get_drvdata(serdev);
90 struct cros_ec_uart *ec_uart = ec_dev->priv;
91 struct response_info *resp = &ec_uart->response;
92
93 /* Check if bytes were sent out of band */
94 if (!resp->data) {
95 /* Discard all bytes */
96 dev_warn(ec_dev->dev, "Bytes received out of band, dropping them.\n");
97 return count;
98 }
99
100 /*
101 * Check if incoming bytes + resp->size is greater than allocated
102 * buffer in din by cros_ec. This will ensure that if EC sends more
103 * bytes than max_size, waiting process will be notified with an error.
104 */
105 if (resp->size + count > resp->max_size) {
106 resp->status = -EMSGSIZE;
107 wake_up(&resp->wait_queue);
108 return count;
109 }
110
111 memcpy(resp->data + resp->size, data, count);
112
113 resp->size += count;
114
115 /* Read data_len if we received response header and if exp_len was not read before. */
116 if (resp->size >= sizeof(*host_response) && resp->exp_len == 0) {
117 host_response = (struct ec_host_response *)resp->data;
118 resp->exp_len = host_response->data_len + sizeof(*host_response);
119 }
120
121 /* If driver received response header and payload from EC, wake up the wait queue. */
122 if (resp->size >= sizeof(*host_response) && resp->size == resp->exp_len) {
123 resp->status = 1;
124 wake_up(&resp->wait_queue);
125 }
126
127 return count;
128}
129
130static int cros_ec_uart_pkt_xfer(struct cros_ec_device *ec_dev,
131 struct cros_ec_command *ec_msg)
132{
133 struct cros_ec_uart *ec_uart = ec_dev->priv;
134 struct serdev_device *serdev = ec_uart->serdev;
135 struct response_info *resp = &ec_uart->response;
136 struct ec_host_response *host_response;
137 unsigned int len;
138 int ret, i;
139 u8 sum;
140
141 len = cros_ec_prepare_tx(ec_dev, ec_msg);
142 dev_dbg(ec_dev->dev, "Prepared len=%d\n", len);
143
144 /* Setup for incoming response */
145 resp->data = ec_dev->din;
146 resp->max_size = ec_dev->din_size;
147 resp->size = 0;
148 resp->exp_len = 0;
149 resp->status = 0;
150
151 ret = serdev_device_write_buf(serdev, ec_dev->dout, len);
152 if (ret < 0 || ret < len) {
153 dev_err(ec_dev->dev, "Unable to write data\n");
154 if (ret >= 0)
155 ret = -EIO;
156 goto exit;
157 }
158
159 ret = wait_event_timeout(resp->wait_queue, resp->status,
160 msecs_to_jiffies(EC_MSG_DEADLINE_MS));
161 if (ret == 0) {
162 dev_warn(ec_dev->dev, "Timed out waiting for response.\n");
163 ret = -ETIMEDOUT;
164 goto exit;
165 }
166
167 if (resp->status < 0) {
168 ret = resp->status;
169 dev_warn(ec_dev->dev, "Error response received: %d\n", ret);
170 goto exit;
171 }
172
173 host_response = (struct ec_host_response *)ec_dev->din;
174 ec_msg->result = host_response->result;
175
176 if (host_response->data_len > ec_msg->insize) {
177 dev_err(ec_dev->dev, "Resp too long (%d bytes, expected %d)\n",
178 host_response->data_len, ec_msg->insize);
179 ret = -ENOSPC;
180 goto exit;
181 }
182
183 /* Validate checksum */
184 sum = 0;
185 for (i = 0; i < sizeof(*host_response) + host_response->data_len; i++)
186 sum += ec_dev->din[i];
187
188 if (sum) {
189 dev_err(ec_dev->dev, "Bad packet checksum calculated %x\n", sum);
190 ret = -EBADMSG;
191 goto exit;
192 }
193
194 memcpy(ec_msg->data, ec_dev->din + sizeof(*host_response), host_response->data_len);
195
196 ret = host_response->data_len;
197
198exit:
199 /* Invalidate response buffer to guard against out of band rx data */
200 resp->data = NULL;
201
202 if (ec_msg->command == EC_CMD_REBOOT_EC)
203 msleep(EC_REBOOT_DELAY_MS);
204
205 return ret;
206}
207
208static int cros_ec_uart_resource(struct acpi_resource *ares, void *data)
209{
210 struct cros_ec_uart *ec_uart = data;
211 struct acpi_resource_uart_serialbus *sb = &ares->data.uart_serial_bus;
212
213 if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS &&
214 sb->type == ACPI_RESOURCE_SERIAL_TYPE_UART) {
215 ec_uart->baudrate = sb->default_baud_rate;
216 dev_dbg(&ec_uart->serdev->dev, "Baudrate %d\n", ec_uart->baudrate);
217
218 ec_uart->flowcontrol = sb->flow_control;
219 dev_dbg(&ec_uart->serdev->dev, "Flow control %d\n", ec_uart->flowcontrol);
220 }
221
222 return 0;
223}
224
225static int cros_ec_uart_acpi_probe(struct cros_ec_uart *ec_uart)
226{
227 int ret;
228 LIST_HEAD(resources);
229 struct acpi_device *adev = ACPI_COMPANION(&ec_uart->serdev->dev);
230
231 ret = acpi_dev_get_resources(adev, &resources, cros_ec_uart_resource, ec_uart);
232 if (ret < 0)
233 return ret;
234
235 acpi_dev_free_resource_list(&resources);
236
237 /* Retrieve GpioInt and translate it to Linux IRQ number */
238 ret = acpi_dev_gpio_irq_get(adev, 0);
239 if (ret < 0)
240 return ret;
241
242 ec_uart->irq = ret;
243 dev_dbg(&ec_uart->serdev->dev, "IRQ number %d\n", ec_uart->irq);
244
245 return 0;
246}
247
248static const struct serdev_device_ops cros_ec_uart_client_ops = {
249 .receive_buf = cros_ec_uart_rx_bytes,
250};
251
252static int cros_ec_uart_probe(struct serdev_device *serdev)
253{
254 struct device *dev = &serdev->dev;
255 struct cros_ec_device *ec_dev;
256 struct cros_ec_uart *ec_uart;
257 int ret;
258
259 ec_uart = devm_kzalloc(dev, sizeof(*ec_uart), GFP_KERNEL);
260 if (!ec_uart)
261 return -ENOMEM;
262
263 ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
264 if (!ec_dev)
265 return -ENOMEM;
266
267 ret = devm_serdev_device_open(dev, serdev);
268 if (ret) {
269 dev_err(dev, "Unable to open UART device");
270 return ret;
271 }
272
273 serdev_device_set_drvdata(serdev, ec_dev);
274 init_waitqueue_head(&ec_uart->response.wait_queue);
275
276 ec_uart->serdev = serdev;
277
278 ret = cros_ec_uart_acpi_probe(ec_uart);
279 if (ret < 0) {
280 dev_err(dev, "Failed to get ACPI info (%d)", ret);
281 return ret;
282 }
283
284 ret = serdev_device_set_baudrate(serdev, ec_uart->baudrate);
285 if (ret < 0) {
286 dev_err(dev, "Failed to set up host baud rate (%d)", ret);
287 return ret;
288 }
289
290 serdev_device_set_flow_control(serdev, ec_uart->flowcontrol);
291
292 /* Initialize ec_dev for cros_ec */
293 ec_dev->phys_name = dev_name(dev);
294 ec_dev->dev = dev;
295 ec_dev->priv = ec_uart;
296 ec_dev->irq = ec_uart->irq;
297 ec_dev->cmd_xfer = NULL;
298 ec_dev->pkt_xfer = cros_ec_uart_pkt_xfer;
299 ec_dev->din_size = sizeof(struct ec_host_response) +
300 sizeof(struct ec_response_get_protocol_info);
301 ec_dev->dout_size = sizeof(struct ec_host_request);
302
303 serdev_device_set_client_ops(serdev, &cros_ec_uart_client_ops);
304
305 return cros_ec_register(ec_dev);
306}
307
308static void cros_ec_uart_remove(struct serdev_device *serdev)
309{
310 struct cros_ec_device *ec_dev = serdev_device_get_drvdata(serdev);
311
312 cros_ec_unregister(ec_dev);
313};
314
315static int __maybe_unused cros_ec_uart_suspend(struct device *dev)
316{
317 struct cros_ec_device *ec_dev = dev_get_drvdata(dev);
318
319 return cros_ec_suspend(ec_dev);
320}
321
322static int __maybe_unused cros_ec_uart_resume(struct device *dev)
323{
324 struct cros_ec_device *ec_dev = dev_get_drvdata(dev);
325
326 return cros_ec_resume(ec_dev);
327}
328
329static SIMPLE_DEV_PM_OPS(cros_ec_uart_pm_ops, cros_ec_uart_suspend,
330 cros_ec_uart_resume);
331
332static const struct of_device_id cros_ec_uart_of_match[] = {
333 { .compatible = "google,cros-ec-uart" },
334 {}
335};
336MODULE_DEVICE_TABLE(of, cros_ec_uart_of_match);
337
338#ifdef CONFIG_ACPI
339static const struct acpi_device_id cros_ec_uart_acpi_id[] = {
340 { "GOOG0019", 0 },
341 {}
342};
343
344MODULE_DEVICE_TABLE(acpi, cros_ec_uart_acpi_id);
345#endif
346
347static struct serdev_device_driver cros_ec_uart_driver = {
348 .driver = {
349 .name = "cros-ec-uart",
350 .acpi_match_table = ACPI_PTR(cros_ec_uart_acpi_id),
351 .of_match_table = cros_ec_uart_of_match,
352 .pm = &cros_ec_uart_pm_ops,
353 },
354 .probe = cros_ec_uart_probe,
355 .remove = cros_ec_uart_remove,
356};
357
358module_serdev_device_driver(cros_ec_uart_driver);
359
360MODULE_LICENSE("GPL");
361MODULE_DESCRIPTION("UART interface for ChromeOS Embedded Controller");
362MODULE_AUTHOR("Bhanu Prakash Maiya <bhanumaiya@chromium.org>");
drivers/platform/chrome/cros_typec_switch.c+9−7
@@ -246,15 +246,17 @@ static int cros_typec_register_switches(struct cros_typec_switch_data *sdata) · 245 unmodified lines
246 port->port_num = index;246 port->port_num = index;
247 sdata->ports[index] = port;247 sdata->ports[index] = port;
248 248
249 ret = cros_typec_register_retimer(port, fwnode);249 if (fwnode_property_present(fwnode, "retimer-switch")) {
250 if (ret) {250 ret = cros_typec_register_retimer(port, fwnode);
251 dev_err(dev, "Retimer switch register failed\n");251 if (ret) {
252 goto err_switch;252 dev_err(dev, "Retimer switch register failed\n");
253 goto err_switch;
254 }
255
256 dev_dbg(dev, "Retimer switch registered for index %llu\n", index);
253 }257 }
254 258
255 dev_dbg(dev, "Retimer switch registered for index %llu\n", index);259 if (!fwnode_property_present(fwnode, "mode-switch"))
256
257 if (!device_property_present(fwnode->dev, "mode-switch"))
258 continue;260 continue;
259 261
260 ret = cros_typec_register_mode_switch(port, fwnode);262 ret = cros_typec_register_mode_switch(port, fwnode);
drivers/platform/chrome/cros_typec_vdm.c+148−0
@@ -0,0 +1,148 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * USB Power Delivery Vendor Defined Message (VDM) support code.
4 *
5 * Copyright 2023 Google LLC
6 * Author: Prashant Malani <pmalani@chromium.org>
7 */
8
9#include <linux/module.h>
10#include <linux/platform_data/cros_ec_commands.h>
11#include <linux/usb/pd_vdo.h>
12
13#include "cros_ec_typec.h"
14#include "cros_typec_vdm.h"
15
16/*
17 * Retrieves pending VDM attention messages from the EC and forwards them to the altmode driver
18 * based on SVID.
19 */
20void cros_typec_handle_vdm_attention(struct cros_typec_data *typec, int port_num)
21{
22 struct ec_response_typec_vdm_response resp;
23 struct ec_params_typec_vdm_response req = {
24 .port = port_num,
25 };
26 struct typec_altmode *amode;
27 u16 svid;
28 u32 hdr;
29 int ret;
30
31 do {
32 ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_VDM_RESPONSE, &req,
33 sizeof(req), &resp, sizeof(resp));
34 if (ret < 0) {
35 dev_warn(typec->dev, "Failed VDM response fetch, port: %d\n", port_num);
36 return;
37 }
38
39 hdr = resp.vdm_response[0];
40 svid = PD_VDO_VID(hdr);
41 dev_dbg(typec->dev, "Received VDM Attention header: %x, port: %d\n", hdr, port_num);
42
43 amode = typec_match_altmode(typec->ports[port_num]->port_altmode,
44 CROS_EC_ALTMODE_MAX, svid, PD_VDO_OPOS(hdr));
45 if (!amode) {
46 dev_err(typec->dev,
47 "Received VDM for unregistered altmode (SVID:%x), port: %d\n",
48 svid, port_num);
49 return;
50 }
51
52 typec_altmode_attention(amode, resp.vdm_attention[1]);
53 } while (resp.vdm_attention_left);
54}
55
56/*
57 * Retrieves a VDM response from the EC and forwards it to the altmode driver based on SVID.
58 */
59void cros_typec_handle_vdm_response(struct cros_typec_data *typec, int port_num)
60{
61 struct ec_response_typec_vdm_response resp;
62 struct ec_params_typec_vdm_response req = {
63 .port = port_num,
64 };
65 struct typec_altmode *amode;
66 u16 svid;
67 u32 hdr;
68 int ret;
69
70 ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_VDM_RESPONSE, &req,
71 sizeof(req), &resp, sizeof(resp));
72 if (ret < 0) {
73 dev_warn(typec->dev, "Failed VDM response fetch, port: %d\n", port_num);
74 return;
75 }
76
77 hdr = resp.vdm_response[0];
78 svid = PD_VDO_VID(hdr);
79 dev_dbg(typec->dev, "Received VDM header: %x, port: %d\n", hdr, port_num);
80
81 amode = typec_match_altmode(typec->ports[port_num]->port_altmode, CROS_EC_ALTMODE_MAX,
82 svid, PD_VDO_OPOS(hdr));
83 if (!amode) {
84 dev_err(typec->dev, "Received VDM for unregistered altmode (SVID:%x), port: %d\n",
85 svid, port_num);
86 return;
87 }
88
89 ret = typec_altmode_vdm(amode, hdr, &resp.vdm_response[1], resp.vdm_data_objects);
90 if (ret)
91 dev_err(typec->dev, "Failed to forward VDM to altmode (SVID:%x), port: %d\n",
92 svid, port_num);
93}
94
95static int cros_typec_port_amode_enter(struct typec_altmode *amode, u32 *vdo)
96{
97 struct cros_typec_port *port = typec_altmode_get_drvdata(amode);
98 struct ec_params_typec_control req = {
99 .port = port->port_num,
100 .command = TYPEC_CONTROL_COMMAND_SEND_VDM_REQ,
101 };
102 struct typec_vdm_req vdm_req = {};
103 u32 hdr;
104
105 hdr = VDO(amode->svid, 1, SVDM_VER_2_0, CMD_ENTER_MODE);
106 hdr |= VDO_OPOS(amode->mode);
107
108 vdm_req.vdm_data[0] = hdr;
109 vdm_req.vdm_data_objects = 1;
110 vdm_req.partner_type = TYPEC_PARTNER_SOP;
111 req.vdm_req_params = vdm_req;
112
113 dev_dbg(port->typec_data->dev, "Sending EnterMode VDM, hdr: %x, port: %d\n",
114 hdr, port->port_num);
115
116 return cros_ec_cmd(port->typec_data->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
117 sizeof(req), NULL, 0);
118}
119
120static int cros_typec_port_amode_vdm(struct typec_altmode *amode, const u32 hdr,
121 const u32 *vdo, int cnt)
122{
123 struct cros_typec_port *port = typec_altmode_get_drvdata(amode);
124 struct ec_params_typec_control req = {
125 .port = port->port_num,
126 .command = TYPEC_CONTROL_COMMAND_SEND_VDM_REQ,
127 };
128 struct typec_vdm_req vdm_req = {};
129 int i;
130
131 vdm_req.vdm_data[0] = hdr;
132 vdm_req.vdm_data_objects = cnt;
133 for (i = 1; i < cnt; i++)
134 vdm_req.vdm_data[i] = vdo[i-1];
135 vdm_req.partner_type = TYPEC_PARTNER_SOP;
136 req.vdm_req_params = vdm_req;
137
138 dev_dbg(port->typec_data->dev, "Sending VDM, hdr: %x, num_objects: %d, port: %d\n",
139 hdr, cnt, port->port_num);
140
141 return cros_ec_cmd(port->typec_data->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
142 sizeof(req), NULL, 0);
143}
144
145struct typec_altmode_ops port_amode_ops = {
146 .enter = cros_typec_port_amode_enter,
147 .vdm = cros_typec_port_amode_vdm,
148};
drivers/platform/chrome/cros_typec_vdm.h+13−0
@@ -0,0 +1,13 @@
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#ifndef __CROS_TYPEC_VDM__
4#define __CROS_TYPEC_VDM__
5
6#include <linux/usb/typec_altmode.h>
7
8extern struct typec_altmode_ops port_amode_ops;
9
10void cros_typec_handle_vdm_attention(struct cros_typec_data *typec, int port_num);
11void cros_typec_handle_vdm_response(struct cros_typec_data *typec, int port_num);
12
13#endif /* __CROS_TYPEC_VDM__ */
drivers/platform/chrome/wilco_ec/sysfs.c+1−2
@@ -119,8 +119,7 @@ static ssize_t get_info(struct device *dev, char *buf, enum get_ec_info_op op) · 118 unmodified lines
119 if (ret < 0)119 if (ret < 0)
120 return ret;120 return ret;
121 121
122 return scnprintf(buf, PAGE_SIZE, "%.*s\n", (int)sizeof(resp.value),122 return sysfs_emit(buf, "%.*s\n", (int)sizeof(resp.value), (char *)&resp.value);
123 (char *)&resp.value);
124}123}
125 124
126static ssize_t version_show(struct device *dev, struct device_attribute *attr,125static ssize_t version_show(struct device *dev, struct device_attribute *attr,
include/linux/platform_data/cros_ec_commands.h+64−5
@@ -1082,7 +1082,7 @@ struct ec_params_get_cmd_versions_v1 { · 1081 unmodified lines
1082} __ec_align2;1082} __ec_align2;
1083 1083
1084/**1084/**
1085 * struct ec_response_get_cmd_version - Response to the get command versions.1085 * struct ec_response_get_cmd_versions - Response to the get command versions.
1086 * @version_mask: Mask of supported versions; use EC_VER_MASK() to compare with1086 * @version_mask: Mask of supported versions; use EC_VER_MASK() to compare with
1087 * a desired version.1087 * a desired version.
1088 */1088 */
@@ -1300,8 +1300,18 @@ enum ec_feature_code { · 211 unmodified lines
1300 * mux.1300 * mux.
1301 */1301 */
1302 EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK = 43,1302 EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK = 43,
1303 /* The MCU is a System Companion Processor (SCP) 2nd Core. */1303 /*
1304 EC_FEATURE_SCP_C1 = 45,1304 * The EC supports entering and residing in S4.
1305 */
1306 EC_FEATURE_S4_RESIDENCY = 44,
1307 /*
1308 * The EC supports the AP directing mux sets for the board.
1309 */
1310 EC_FEATURE_TYPEC_AP_MUX_SET = 45,
1311 /*
1312 * The EC supports the AP composing VDMs for us to send.
1313 */
1314 EC_FEATURE_TYPEC_AP_VDM_SEND = 46,
1305};1315};
1306 1316
1307#define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32)1317#define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32)
@@ -5470,7 +5480,7 @@ struct ec_response_rollback_info { · 4162 unmodified lines
5470/* Issue AP reset */5480/* Issue AP reset */
5471#define EC_CMD_AP_RESET 0x01255481#define EC_CMD_AP_RESET 0x0125
5472 5482
5473/**5483/*
5474 * Get the number of peripheral charge ports5484 * Get the number of peripheral charge ports
5475 */5485 */
5476#define EC_CMD_PCHG_COUNT 0x01345486#define EC_CMD_PCHG_COUNT 0x0134
@@ -5481,7 +5491,7 @@ struct ec_response_pchg_count { · 4 unmodified lines
5481 uint8_t port_count;5491 uint8_t port_count;
5482} __ec_align1;5492} __ec_align1;
5483 5493
5484/**5494/*
5485 * Get the status of a peripheral charge port5495 * Get the status of a peripheral charge port
5486 */5496 */
5487#define EC_CMD_PCHG 0x01355497#define EC_CMD_PCHG 0x0135
@@ -5726,6 +5736,8 @@ enum typec_control_command { · 238 unmodified lines
5726 TYPEC_CONTROL_COMMAND_ENTER_MODE,5736 TYPEC_CONTROL_COMMAND_ENTER_MODE,
5727 TYPEC_CONTROL_COMMAND_TBT_UFP_REPLY,5737 TYPEC_CONTROL_COMMAND_TBT_UFP_REPLY,
5728 TYPEC_CONTROL_COMMAND_USB_MUX_SET,5738 TYPEC_CONTROL_COMMAND_USB_MUX_SET,
5739 TYPEC_CONTROL_COMMAND_BIST_SHARE_MODE,
5740 TYPEC_CONTROL_COMMAND_SEND_VDM_REQ,
5729};5741};
5730 5742
5731/* Replies the AP may specify to the TBT EnterMode command as a UFP */5743/* Replies the AP may specify to the TBT EnterMode command as a UFP */
@@ -5739,6 +5751,17 @@ struct typec_usb_mux_set { · 7 unmodified lines
5739 uint8_t mux_flags; /* USB_PD_MUX_*-encoded USB mux state to set */5751 uint8_t mux_flags; /* USB_PD_MUX_*-encoded USB mux state to set */
5740} __ec_align1;5752} __ec_align1;
5741 5753
5754#define VDO_MAX_SIZE 7
5755
5756struct typec_vdm_req {
5757 /* VDM data, including VDM header */
5758 uint32_t vdm_data[VDO_MAX_SIZE];
5759 /* Number of 32-bit fields filled in */
5760 uint8_t vdm_data_objects;
5761 /* Partner to address - see enum typec_partner_type */
5762 uint8_t partner_type;
5763} __ec_align1;
5764
5742struct ec_params_typec_control {5765struct ec_params_typec_control {
5743 uint8_t port;5766 uint8_t port;
5744 uint8_t command; /* enum typec_control_command */5767 uint8_t command; /* enum typec_control_command */
@@ -5754,6 +5777,8 @@ struct ec_params_typec_control { · 9 unmodified lines
5754 uint8_t mode_to_enter; /* enum typec_mode */5777 uint8_t mode_to_enter; /* enum typec_mode */
5755 uint8_t tbt_ufp_reply; /* enum typec_tbt_ufp_reply */5778 uint8_t tbt_ufp_reply; /* enum typec_tbt_ufp_reply */
5756 struct typec_usb_mux_set mux_params;5779 struct typec_usb_mux_set mux_params;
5780 /* Used for VMD_REQ */
5781 struct typec_vdm_req vdm_req_params;
5757 uint8_t placeholder[128];5782 uint8_t placeholder[128];
5758 };5783 };
5759} __ec_align1;5784} __ec_align1;
@@ -5835,6 +5860,9 @@ enum tcpc_cc_polarity { · 75 unmodified lines
5835#define PD_STATUS_EVENT_DISCONNECTED BIT(3)5860#define PD_STATUS_EVENT_DISCONNECTED BIT(3)
5836#define PD_STATUS_EVENT_MUX_0_SET_DONE BIT(4)5861#define PD_STATUS_EVENT_MUX_0_SET_DONE BIT(4)
5837#define PD_STATUS_EVENT_MUX_1_SET_DONE BIT(5)5862#define PD_STATUS_EVENT_MUX_1_SET_DONE BIT(5)
5863#define PD_STATUS_EVENT_VDM_REQ_REPLY BIT(6)
5864#define PD_STATUS_EVENT_VDM_REQ_FAILED BIT(7)
5865#define PD_STATUS_EVENT_VDM_ATTENTION BIT(8)
5838 5866
5839struct ec_params_typec_status {5867struct ec_params_typec_status {
5840 uint8_t port;5868 uint8_t port;
@@ -5878,6 +5906,37 @@ struct ec_response_typec_status { · 37 unmodified lines
5878 uint32_t sink_cap_pdos[7]; /* Max 7 PDOs can be present */5906 uint32_t sink_cap_pdos[7]; /* Max 7 PDOs can be present */
5879} __ec_align1;5907} __ec_align1;
5880 5908
5909/*
5910 * Gather the response to the most recent VDM REQ from the AP, as well
5911 * as popping the oldest VDM:Attention from the DPM queue
5912 */
5913#define EC_CMD_TYPEC_VDM_RESPONSE 0x013C
5914
5915struct ec_params_typec_vdm_response {
5916 uint8_t port;
5917} __ec_align1;
5918
5919struct ec_response_typec_vdm_response {
5920 /* Number of 32-bit fields filled in */
5921 uint8_t vdm_data_objects;
5922 /* Partner to address - see enum typec_partner_type */
5923 uint8_t partner_type;
5924 /* enum ec_status describing VDM response */
5925 uint16_t vdm_response_err;
5926 /* VDM data, including VDM header */
5927 uint32_t vdm_response[VDO_MAX_SIZE];
5928 /* Number of 32-bit Attention fields filled in */
5929 uint8_t vdm_attention_objects;
5930 /* Number of remaining messages to consume */
5931 uint8_t vdm_attention_left;
5932 /* Reserved */
5933 uint16_t reserved1;
5934 /* VDM:Attention contents */
5935 uint32_t vdm_attention[2];
5936} __ec_align1;
5937
5938#undef VDO_MAX_SIZE
5939
5881/*****************************************************************************/5940/*****************************************************************************/
5882/* The command range 0x200-0x2FF is reserved for Rotor. */5941/* The command range 0x200-0x2FF is reserved for Rotor. */
5883 5942
include/linux/platform_data/cros_ec_proto.h+23−1
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#define __LINUX_CROS_EC_PROTO_H9#define __LINUX_CROS_EC_PROTO_H
10 10
11#include <linux/device.h>11#include <linux/device.h>
12#include <linux/lockdep_types.h>
12#include <linux/mutex.h>13#include <linux/mutex.h>
13#include <linux/notifier.h>14#include <linux/notifier.h>
14 15
@@ -19,7 +20,6 @@ · 4 unmodified lines
19#define CROS_EC_DEV_ISH_NAME "cros_ish"20#define CROS_EC_DEV_ISH_NAME "cros_ish"
20#define CROS_EC_DEV_PD_NAME "cros_pd"21#define CROS_EC_DEV_PD_NAME "cros_pd"
21#define CROS_EC_DEV_SCP_NAME "cros_scp"22#define CROS_EC_DEV_SCP_NAME "cros_scp"
22#define CROS_EC_DEV_SCP_C1_NAME "cros_scp_c1"
23#define CROS_EC_DEV_TP_NAME "cros_tp"23#define CROS_EC_DEV_TP_NAME "cros_tp"
24 24
25#define CROS_EC_DEV_EC_INDEX 025#define CROS_EC_DEV_EC_INDEX 0
@@ -41,6 +41,13 @@ · 15 unmodified lines
41#define EC_MAX_REQUEST_OVERHEAD 141#define EC_MAX_REQUEST_OVERHEAD 1
42#define EC_MAX_RESPONSE_OVERHEAD 3242#define EC_MAX_RESPONSE_OVERHEAD 32
43 43
44/*
45 * EC panic is not covered by the standard (0-F) ACPI notify values.
46 * Arbitrarily choosing B0 to notify ec panic, which is in the 84-BF
47 * device specific ACPI notify range.
48 */
49#define ACPI_NOTIFY_CROS_EC_PANIC 0xB0
50
44/*51/*
45 * Command interface between EC and AP, for LPC, I2C and SPI interfaces.52 * Command interface between EC and AP, for LPC, I2C and SPI interfaces.
46 */53 */
@@ -116,6 +123,8 @@ struct cros_ec_command { · 69 unmodified lines
116 * command. The caller should check msg.result for the EC's result123 * command. The caller should check msg.result for the EC's result
117 * code.124 * code.
118 * @pkt_xfer: Send packet to EC and get response.125 * @pkt_xfer: Send packet to EC and get response.
126 * @lockdep_key: Lockdep class for each instance. Unused if CONFIG_LOCKDEP is
127 * not enabled.
119 * @lock: One transaction at a time.128 * @lock: One transaction at a time.
120 * @mkbp_event_supported: 0 if MKBP not supported. Otherwise its value is129 * @mkbp_event_supported: 0 if MKBP not supported. Otherwise its value is
121 * the maximum supported version of the MKBP host event130 * the maximum supported version of the MKBP host event
@@ -125,6 +134,15 @@ struct cros_ec_command { · 3 unmodified lines
125 * @event_data: Raw payload transferred with the MKBP event.134 * @event_data: Raw payload transferred with the MKBP event.
126 * @event_size: Size in bytes of the event data.135 * @event_size: Size in bytes of the event data.
127 * @host_event_wake_mask: Mask of host events that cause wake from suspend.136 * @host_event_wake_mask: Mask of host events that cause wake from suspend.
137 * @suspend_timeout_ms: The timeout in milliseconds between when sleep event
138 * is received and when the EC will declare sleep
139 * transition failure if the sleep signal is not
140 * asserted. See also struct
141 * ec_params_host_sleep_event_v1 in cros_ec_commands.h.
142 * @last_resume_result: The number of sleep power signal transitions that
143 * occurred since the suspend message. The high bit
144 * indicates a timeout occurred. See also struct
145 * ec_response_host_sleep_event_v1 in cros_ec_commands.h.
128 * @last_event_time: exact time from the hard irq when we got notified of146 * @last_event_time: exact time from the hard irq when we got notified of
129 * a new event.147 * a new event.
130 * @notifier_ready: The notifier_block to let the kernel re-query EC148 * @notifier_ready: The notifier_block to let the kernel re-query EC
@@ -134,6 +152,7 @@ struct cros_ec_command { · 3 unmodified lines
134 * main EC.152 * main EC.
135 * @pd: The platform_device used by the mfd driver to interface with the153 * @pd: The platform_device used by the mfd driver to interface with the
136 * PD behind an EC.154 * PD behind an EC.
155 * @panic_notifier: EC panic notifier.
137 */156 */
138struct cros_ec_device {157struct cros_ec_device {
139 /* These are used by other drivers that want to talk to the EC */158 /* These are used by other drivers that want to talk to the EC */
@@ -160,6 +179,7 @@ struct cros_ec_device { · 20 unmodified lines
160 struct cros_ec_command *msg);179 struct cros_ec_command *msg);
161 int (*pkt_xfer)(struct cros_ec_device *ec,180 int (*pkt_xfer)(struct cros_ec_device *ec,
162 struct cros_ec_command *msg);181 struct cros_ec_command *msg);
182 struct lock_class_key lockdep_key;
163 struct mutex lock;183 struct mutex lock;
164 u8 mkbp_event_supported;184 u8 mkbp_event_supported;
165 bool host_sleep_v1;185 bool host_sleep_v1;
@@ -176,6 +196,8 @@ struct cros_ec_device { · 10 unmodified lines
176 /* The platform devices used by the mfd driver */196 /* The platform devices used by the mfd driver */
177 struct platform_device *ec;197 struct platform_device *ec;
178 struct platform_device *pd;198 struct platform_device *pd;
199
200 struct blocking_notifier_head panic_notifier;
179};201};
180 202
181/**203/**

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t