From 1716420e8de2705cd16905134d1eaeda94272a17 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 22 Aug 2020 08:08:51 -0700 Subject: iio: cros_ec: Accept -EOPNOTSUPP as 'not supported' error code A follow-up patch will extend the number of errors reported by cros_ec_cmd_xfer_status(). Specifically, the function will return -EOPNOTSUPP if a command is not supported by the EC. Prepare for it. Cc: Gwendal Grignou Cc: Yu-Hsuan Hsu Cc: Prashant Malani Cc: Brian Norris Acked-by: Jonathan Cameron Reviewed-by: Brian Norris Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c index 130ab8ce0269..d71e9064c789 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c @@ -73,7 +73,7 @@ static int cros_ec_sensors_read(struct iio_dev *indio_dev, st->core.param.sensor_offset.flags = 0; ret = cros_ec_motion_send_host_cmd(&st->core, 0); - if (ret == -EPROTO) { + if (ret == -EPROTO || ret == -EOPNOTSUPP) { /* Reading calibscale is not supported on older EC. */ *val = 1; *val2 = 0; -- cgit From 064df8851f4ac25f64c0323fc93c3f9705e1702d Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 22 Aug 2020 08:08:52 -0700 Subject: cros_ec_lightbar: Accept more error codes from cros_ec_cmd_xfer_status Since commit c5cd2b47b203 ("platform/chrome: cros_ec_proto: Report command not supported") we can no longer assume that cros_ec_cmd_xfer_status() reports -EPROTO for all errors returned by the EC itself. A follow-up patch will change cros_ec_cmd_xfer_status() to report additional errors reported by the EC as distinguished Linux error codes. Handle this change by no longer assuming that -EPROTO is used to report all errors returned by the EC itself. Since errors reported by the EC are already reported in text form through sysfs attributes, extend this form of error reporting to all errors reported by cros_ec_cmd_xfer_status(). Cc: Gwendal Grignou Cc: Yu-Hsuan Hsu Cc: Prashant Malani Cc: Brian Norris Reviewed-by: Brian Norris Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_lightbar.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c index b59180bff5a3..8445cda57927 100644 --- a/drivers/platform/chrome/cros_ec_lightbar.c +++ b/drivers/platform/chrome/cros_ec_lightbar.c @@ -117,7 +117,7 @@ static int get_lightbar_version(struct cros_ec_dev *ec, param = (struct ec_params_lightbar *)msg->data; param->cmd = LIGHTBAR_CMD_VERSION; ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); - if (ret < 0) { + if (ret < 0 && ret != -EINVAL) { ret = 0; goto exit; } @@ -298,11 +298,9 @@ static ssize_t sequence_show(struct device *dev, goto exit; ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); - if (ret == -EPROTO) { - ret = scnprintf(buf, PAGE_SIZE, - "ERROR: EC returned %d\n", msg->result); - goto exit; - } else if (ret < 0) { + if (ret < 0) { + ret = scnprintf(buf, PAGE_SIZE, "XFER / EC ERROR %d / %d\n", + ret, msg->result); goto exit; } -- cgit From b646e7db1ce85e24bdb3afd16e542a348a53d2ab Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 22 Aug 2020 08:08:53 -0700 Subject: platform/chrome: cros_ec_sysfs: Report range of error codes from EC Since commit c5cd2b47b203 ("platform/chrome: cros_ec_proto: Report command not supported") we can no longer assume that cros_ec_cmd_xfer_status() reports -EPROTO for all errors returned by the EC itself. A follow-up patch will change cros_ec_cmd_xfer_status() to report additional errors reported by the EC as distinguished Linux error codes. Prepare for this change by always reporting both the Linux error code and the EC error code in sysfs attributes. Cc: Gwendal Grignou Cc: Yu-Hsuan Hsu Cc: Prashant Malani Cc: Brian Norris Reviewed-by: Brian Norris Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_sysfs.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c index d45ea5d5bfa4..9c1e0998a721 100644 --- a/drivers/platform/chrome/cros_ec_sysfs.c +++ b/drivers/platform/chrome/cros_ec_sysfs.c @@ -150,12 +150,10 @@ static ssize_t version_show(struct device *dev, msg->command = EC_CMD_GET_BUILD_INFO + ec->cmd_offset; msg->insize = EC_HOST_PARAM_SIZE; ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); - if (ret == -EPROTO) { - count += scnprintf(buf + count, PAGE_SIZE - count, - "Build info: EC error %d\n", msg->result); - } else if (ret < 0) { + if (ret < 0) { count += scnprintf(buf + count, PAGE_SIZE - count, - "Build info: XFER ERROR %d\n", ret); + "Build info: XFER / EC ERROR %d / %d\n", + ret, msg->result); } else { msg->data[EC_HOST_PARAM_SIZE - 1] = '\0'; count += scnprintf(buf + count, PAGE_SIZE - count, @@ -166,12 +164,10 @@ static ssize_t version_show(struct device *dev, msg->command = EC_CMD_GET_CHIP_INFO + ec->cmd_offset; msg->insize = sizeof(*r_chip); ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); - if (ret == -EPROTO) { - count += scnprintf(buf + count, PAGE_SIZE - count, - "Chip info: EC error %d\n", msg->result); - } else if (ret < 0) { + if (ret < 0) { count += scnprintf(buf + count, PAGE_SIZE - count, - "Chip info: XFER ERROR %d\n", ret); + "Chip info: XFER / EC ERROR %d / %d\n", + ret, msg->result); } else { r_chip = (struct ec_response_get_chip_info *)msg->data; @@ -190,12 +186,10 @@ static ssize_t version_show(struct device *dev, msg->command = EC_CMD_GET_BOARD_VERSION + ec->cmd_offset; msg->insize = sizeof(*r_board); ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); - if (ret == -EPROTO) { - count += scnprintf(buf + count, PAGE_SIZE - count, - "Board version: EC error %d\n", msg->result); - } else if (ret < 0) { + if (ret < 0) { count += scnprintf(buf + count, PAGE_SIZE - count, - "Board version: XFER ERROR %d\n", ret); + "Board version: XFER / EC ERROR %d / %d\n", + ret, msg->result); } else { r_board = (struct ec_response_board_version *)msg->data; -- cgit From d509f8a71aa0a5e6d92409d9f0b4eaa94615727d Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 22 Aug 2020 08:08:54 -0700 Subject: pwm: cros-ec: Accept more error codes from cros_ec_cmd_xfer_status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit c5cd2b47b203 ("platform/chrome: cros_ec_proto: Report command not supported") we can no longer assume that cros_ec_cmd_xfer_status() reports -EPROTO for all errors returned by the EC itself. A follow-up patch will change cros_ec_cmd_xfer_status() to report additional errors reported by the EC as distinguished Linux error codes. Handle this change by no longer assuming that only -EPROTO is used to report all errors returned by the EC itself. Instead, support both the old and the new error codes. Add a comment describing cros_ec_num_pwms() to explain its functionality. Cc: Gwendal Grignou Cc: Yu-Hsuan Hsu Cc: Prashant Malani Cc: Brian Norris Acked-by: Thierry Reding Acked-by: Uwe Kleine-König Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/pwm/pwm-cros-ec.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c index 09c08dee099e..94d3dff9b0e5 100644 --- a/drivers/pwm/pwm-cros-ec.c +++ b/drivers/pwm/pwm-cros-ec.c @@ -204,6 +204,11 @@ static const struct pwm_ops cros_ec_pwm_ops = { .owner = THIS_MODULE, }; +/* + * Determine the number of supported PWMs. The EC does not return the number + * of PWMs it supports directly, so we have to read the pwm duty cycle for + * subsequent channels until we get an error. + */ static int cros_ec_num_pwms(struct cros_ec_device *ec) { int i, ret; @@ -213,20 +218,30 @@ static int cros_ec_num_pwms(struct cros_ec_device *ec) u32 result = 0; ret = __cros_ec_pwm_get_duty(ec, i, &result); - /* We want to parse EC protocol errors */ - if (ret < 0 && !(ret == -EPROTO && result)) - return ret; - /* * We look for SUCCESS, INVALID_COMMAND, or INVALID_PARAM * responses; everything else is treated as an error. + * The EC error codes either map to -EOPNOTSUPP / -EINVAL, + * or -EPROTO is returned and the EC error is in the result + * field. Check for both. */ - if (result == EC_RES_INVALID_COMMAND) + switch (ret) { + case -EOPNOTSUPP: /* invalid command */ return -ENODEV; - else if (result == EC_RES_INVALID_PARAM) + case -EINVAL: /* invalid parameter */ return i; - else if (result) + case -EPROTO: + /* Old or new error return code: Handle both */ + if (result == EC_RES_INVALID_COMMAND) + return -ENODEV; + else if (result == EC_RES_INVALID_PARAM) + return i; return -EPROTO; + default: + if (ret < 0) + return ret; + break; + } } return U8_MAX; -- cgit From b4e452b5e97dc70d529475168a37ad7394994b8b Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 22 Aug 2020 08:08:55 -0700 Subject: platform/input: cros_ec: Replace -ENOTSUPP with -ENOPROTOOPT -ENOTSUPP is not a SUSV4 error code and should not be used. Use -ENOPROTOOPT instead to report EC_RES_INVALID_VERSION responses from the EC. This matches match the NFS response for unsupported protocol versions. Cc: Gwendal Grignou Cc: Yu-Hsuan Hsu Cc: Prashant Malani Cc: Brian Norris Acked-by: Dmitry Torokhov Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/input/keyboard/cros_ec_keyb.c | 2 +- drivers/platform/chrome/cros_ec_proto.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index fc1793ca2f17..15d17c717081 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -348,7 +348,7 @@ static int cros_ec_keyb_info(struct cros_ec_device *ec_dev, params->event_type = event_type; ret = cros_ec_cmd_xfer_status(ec_dev, msg); - if (ret == -ENOTSUPP) { + if (ret == -ENOPROTOOPT) { /* With older ECs we just return 0 for everything */ memset(result, 0, result_size); ret = 0; diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 8d52b3b4bd4e..f4727511fb41 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -579,7 +579,7 @@ static int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, * * Return: * >=0 - The number of bytes transferred - * -ENOTSUPP - Operation not supported + * -ENOPROTOOPT - Operation not supported * -EPROTO - Protocol error */ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, @@ -593,7 +593,7 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, } else if (msg->result == EC_RES_INVALID_VERSION) { dev_dbg(ec_dev->dev, "Command invalid version (err:%d)\n", msg->result); - return -ENOTSUPP; + return -ENOPROTOOPT; } else if (msg->result != EC_RES_SUCCESS) { dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result); return -EPROTO; -- cgit From 0d080459e813ce8076f183cc73a4c9b64a39a4d8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 22 Aug 2020 08:08:56 -0700 Subject: platform/chrome: cros_ec_proto: Convert EC error codes to Linux error codes The EC reports a variety of error codes. Most of those, with the exception of EC_RES_INVALID_VERSION, are converted to -EPROTO. As result, the actual EC error code gets lost. Introduce cros_ec_map_error() to map EC error codes to Linux error codes, and use it in cros_ec_cmd_xfer_status() to report more meaningful errors to the caller. With this change, callers of cros_ec_cmd_xfer_status() can implement a more distinguished action without having to rely on the EC error code. At the same time, debugging is improved in situations where the Linux error code is reported to userspace and/or in the kernel log. Cc: Gwendal Grignou Cc: Yu-Hsuan Hsu Cc: Prashant Malani Cc: Brian Norris Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_proto.c | 57 ++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index f4727511fb41..dda182132a6a 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -15,6 +15,43 @@ #define EC_COMMAND_RETRIES 50 +static const int cros_ec_error_map[] = { + [EC_RES_INVALID_COMMAND] = -EOPNOTSUPP, + [EC_RES_ERROR] = -EIO, + [EC_RES_INVALID_PARAM] = -EINVAL, + [EC_RES_ACCESS_DENIED] = -EACCES, + [EC_RES_INVALID_RESPONSE] = -EPROTO, + [EC_RES_INVALID_VERSION] = -ENOPROTOOPT, + [EC_RES_INVALID_CHECKSUM] = -EBADMSG, + [EC_RES_IN_PROGRESS] = -EINPROGRESS, + [EC_RES_UNAVAILABLE] = -ENODATA, + [EC_RES_TIMEOUT] = -ETIMEDOUT, + [EC_RES_OVERFLOW] = -EOVERFLOW, + [EC_RES_INVALID_HEADER] = -EBADR, + [EC_RES_REQUEST_TRUNCATED] = -EBADR, + [EC_RES_RESPONSE_TOO_BIG] = -EFBIG, + [EC_RES_BUS_ERROR] = -EFAULT, + [EC_RES_BUSY] = -EBUSY, + [EC_RES_INVALID_HEADER_VERSION] = -EBADMSG, + [EC_RES_INVALID_HEADER_CRC] = -EBADMSG, + [EC_RES_INVALID_DATA_CRC] = -EBADMSG, + [EC_RES_DUP_UNAVAILABLE] = -ENODATA, +}; + +static int cros_ec_map_error(uint32_t result) +{ + int ret = 0; + + if (result != EC_RES_SUCCESS) { + if (result < ARRAY_SIZE(cros_ec_error_map) && cros_ec_error_map[result]) + ret = cros_ec_error_map[result]; + else + ret = -EPROTO; + } + + return ret; +} + static int prepare_packet(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { @@ -579,26 +616,24 @@ static int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, * * Return: * >=0 - The number of bytes transferred - * -ENOPROTOOPT - Operation not supported - * -EPROTO - Protocol error + * <0 - Linux error code */ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { - int ret; + int ret, mapped; ret = cros_ec_cmd_xfer(ec_dev, msg); if (ret < 0) { dev_err(ec_dev->dev, "Command xfer error (err:%d)\n", ret); - } else if (msg->result == EC_RES_INVALID_VERSION) { - dev_dbg(ec_dev->dev, "Command invalid version (err:%d)\n", - msg->result); - return -ENOPROTOOPT; - } else if (msg->result != EC_RES_SUCCESS) { - dev_dbg(ec_dev->dev, "Command result (err: %d)\n", msg->result); - return -EPROTO; + return ret; + } + mapped = cros_ec_map_error(msg->result); + if (mapped) { + dev_dbg(ec_dev->dev, "Command result (err: %d [%d])\n", + msg->result, mapped); + ret = mapped; } - return ret; } EXPORT_SYMBOL(cros_ec_cmd_xfer_status); -- cgit From be020f0df5a92d90af7506e96cdf86105c396965 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 22 Aug 2020 08:08:57 -0700 Subject: pwm: cros-ec: Simplify EC error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With enhanced error reporting from cros_ec_cmd_xfer_status() in place, we can fully use it and no longer rely on EC error codes. Acked-by: Uwe Kleine-König Reviewed-by: Brian Norris Signed-off-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/pwm/pwm-cros-ec.c | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/pwm/pwm-cros-ec.c b/drivers/pwm/pwm-cros-ec.c index 94d3dff9b0e5..c1c337969e4e 100644 --- a/drivers/pwm/pwm-cros-ec.c +++ b/drivers/pwm/pwm-cros-ec.c @@ -81,8 +81,7 @@ static int cros_ec_pwm_set_duty(struct cros_ec_device *ec, u8 index, u16 duty) return cros_ec_cmd_xfer_status(ec, msg); } -static int __cros_ec_pwm_get_duty(struct cros_ec_device *ec, u8 index, - u32 *result) +static int cros_ec_pwm_get_duty(struct cros_ec_device *ec, u8 index) { struct { struct cros_ec_command msg; @@ -107,19 +106,12 @@ static int __cros_ec_pwm_get_duty(struct cros_ec_device *ec, u8 index, params->index = index; ret = cros_ec_cmd_xfer_status(ec, msg); - if (result) - *result = msg->result; if (ret < 0) return ret; return resp->duty; } -static int cros_ec_pwm_get_duty(struct cros_ec_device *ec, u8 index) -{ - return __cros_ec_pwm_get_duty(ec, index, NULL); -} - static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { @@ -215,28 +207,18 @@ static int cros_ec_num_pwms(struct cros_ec_device *ec) /* The index field is only 8 bits */ for (i = 0; i <= U8_MAX; i++) { - u32 result = 0; - - ret = __cros_ec_pwm_get_duty(ec, i, &result); + ret = cros_ec_pwm_get_duty(ec, i); /* * We look for SUCCESS, INVALID_COMMAND, or INVALID_PARAM * responses; everything else is treated as an error. - * The EC error codes either map to -EOPNOTSUPP / -EINVAL, - * or -EPROTO is returned and the EC error is in the result - * field. Check for both. + * The EC error codes map to -EOPNOTSUPP and -EINVAL, + * so check for those. */ switch (ret) { case -EOPNOTSUPP: /* invalid command */ return -ENODEV; case -EINVAL: /* invalid parameter */ return i; - case -EPROTO: - /* Old or new error return code: Handle both */ - if (result == EC_RES_INVALID_COMMAND) - return -ENODEV; - else if (result == EC_RES_INVALID_PARAM) - return i; - return -EPROTO; default: if (ret < 0) return ret; -- cgit From 46c5bbd2df4a8b7eed427db866a5bce7234744bf Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 10 Jul 2020 12:40:17 -0700 Subject: platform/chrome: cros_ec_typec: USB4 support With USB4 mode the mux driver needs the Enter_USB Data Object (EUDO) that was used when the USB mode was entered. Though the object is not available in the driver, it is possible to construct it from the information we have. Signed-off-by: Heikki Krogerus Signed-off-by: Prashant Malani Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_typec.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 3fcd27ec9ad8..585f27e2b362 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -496,6 +497,34 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec, return typec_mux_set(port->mux, &port->state); } +static int cros_typec_enable_usb4(struct cros_typec_data *typec, + int port_num, + struct ec_response_usb_pd_control_v2 *pd_ctrl) +{ + struct cros_typec_port *port = typec->ports[port_num]; + struct enter_usb_data data; + + data.eudo = EUDO_USB_MODE_USB4 << EUDO_USB_MODE_SHIFT; + + /* Cable Speed */ + data.eudo |= pd_ctrl->cable_speed << EUDO_CABLE_SPEED_SHIFT; + + /* Cable Type */ + if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE) + data.eudo |= EUDO_CABLE_TYPE_OPTICAL << EUDO_CABLE_TYPE_SHIFT; + else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE) + data.eudo |= EUDO_CABLE_TYPE_RE_TIMER << EUDO_CABLE_TYPE_SHIFT; + + data.active_link_training = !!(pd_ctrl->control_flags & + USB_PD_CTRL_ACTIVE_LINK_UNIDIR); + + port->state.alt = NULL; + port->state.data = &data; + port->state.mode = TYPEC_MODE_USB4; + + return typec_mux_set(port->mux, &port->state); +} + static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, uint8_t mux_flags, struct ec_response_usb_pd_control_v2 *pd_ctrl) @@ -516,7 +545,9 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, if (ret) return ret; - if (mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) { + if (mux_flags & USB_PD_MUX_USB4_ENABLED) { + ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl); + } else if (mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) { ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl); } else if (mux_flags & USB_PD_MUX_DP_ENABLED) { ret = cros_typec_enable_dp(typec, port_num, pd_ctrl); -- cgit From 5381b0ed54b6af3c0e8184b43e34154e17904848 Mon Sep 17 00:00:00 2001 From: Azhar Shaikh Date: Fri, 21 Aug 2020 14:47:22 -0700 Subject: platform/chrome: cros_ec_typec: Send enum values to usb_role_switch_set_role() usb_role_switch_set_role() has the second argument as enum for usb_role. Currently depending upon the data role i.e. UFP(0) or DFP(1) is sent. This eventually translates to USB_ROLE_NONE in case of UFP and USB_ROLE_DEVICE in case of DFP. Correct this by sending correct enum values as USB_ROLE_DEVICE in case of UFP and USB_ROLE_HOST in case of DFP. Fixes: 7e7def15fa4b ("platform/chrome: cros_ec_typec: Add USB mux control") Signed-off-by: Azhar Shaikh Cc: Prashant Malani Reviewed-by: Prashant Malani Reviewed-by: Heikki Krogerus Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_typec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 585f27e2b362..739a1c846949 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -622,7 +622,8 @@ static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) dev_warn(typec->dev, "Configure muxes failed, err = %d\n", ret); return usb_role_switch_set_role(typec->ports[port_num]->role_sw, - !!(resp.role & PD_CTRL_RESP_ROLE_DATA)); + resp.role & PD_CTRL_RESP_ROLE_DATA + ? USB_ROLE_HOST : USB_ROLE_DEVICE); } static int cros_typec_get_cmd_version(struct cros_typec_data *typec) -- cgit From b12e4fd5f3e4852cdb1fa11d1a48498bea9e92cf Mon Sep 17 00:00:00 2001 From: Azhar Shaikh Date: Fri, 21 Aug 2020 14:47:23 -0700 Subject: platform/chrome: cros_ec_typec: Avoid setting usb role twice during disconnect On disconnect port partner is removed and usb role is set to NONE. But then in cros_typec_port_update() the role is set again. Avoid this by moving usb_role_switch_set_role() to cros_typec_configure_mux(). Suggested-by: Prashant Malani Signed-off-by: Azhar Shaikh Reviewed-by: Heikki Krogerus Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_typec.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 739a1c846949..39989069decf 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -564,7 +564,12 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, ret = -ENOTSUPP; } - return ret; + if (ret) + return ret; + + return usb_role_switch_set_role(typec->ports[port_num]->role_sw, + pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA + ? USB_ROLE_HOST : USB_ROLE_DEVICE); } static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) @@ -621,9 +626,7 @@ static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) if (ret) dev_warn(typec->dev, "Configure muxes failed, err = %d\n", ret); - return usb_role_switch_set_role(typec->ports[port_num]->role_sw, - resp.role & PD_CTRL_RESP_ROLE_DATA - ? USB_ROLE_HOST : USB_ROLE_DEVICE); + return ret; } static int cros_typec_get_cmd_version(struct cros_typec_data *typec) -- cgit From a772336596dfadbbe22db24d4c4b9516c4b2dd57 Mon Sep 17 00:00:00 2001 From: Azhar Shaikh Date: Fri, 21 Aug 2020 14:47:24 -0700 Subject: platform/chrome: cros_ec_typec: Re-order connector configuration steps As per USB Type-C Spec R2.0 section 4.5.1.2 (Connecting Sources and Sinks) and section 4.5.2.2 (Connection State Machine Requirements), the typical flow for configuring a device connected to a typeC port is as below: 1. Source/sink detection 2. Orientation 3. Data role 4. VCONN 5. VBUS (USB Type-C currents) 6. The connector is now configured. We can start the PD communication that should lead into configuration of the mux if we enter a mode. But in existing code data role was set after the connector and mux are already configured. So fix this by following the spec to set the data role before the connector and mux are configured. Signed-off-by: Azhar Shaikh Reviewed-by: Prashant Malani Reviewed-by: Heikki Krogerus Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_typec.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index 39989069decf..31be31161350 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -545,6 +545,12 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, if (ret) return ret; + ret = usb_role_switch_set_role(typec->ports[port_num]->role_sw, + pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA + ? USB_ROLE_HOST : USB_ROLE_DEVICE); + if (ret) + return ret; + if (mux_flags & USB_PD_MUX_USB4_ENABLED) { ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl); } else if (mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) { @@ -564,12 +570,7 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num, ret = -ENOTSUPP; } - if (ret) - return ret; - - return usb_role_switch_set_role(typec->ports[port_num]->role_sw, - pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA - ? USB_ROLE_HOST : USB_ROLE_DEVICE); + return ret; } static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) -- cgit From 8143182426874a509f65481c7b740115df22f7f3 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Fri, 14 Aug 2020 20:39:08 -0700 Subject: platform/chrome: cros_ec_trace: Add fields to command traces In ftrace, add more fields to the cros_ec command event: - Add size of commands to check if they are properly set. - Add offset (in case an EC is cascaded being another EC), to allow proper command output With: echo 1 > events/cros_ec/cros_ec_cmd/enable We now have (on samus) Invalid command for the sensor stack: ectool-6942 [002] .... 3082.783116: cros_ec_request_done: version: 3, offset: 0, command: EC_CMD_MOTION_SENSE_CMD, outsize: 2, insize: 19, ec result: EC_RES_INVALID_PARAM, retval: 0 Powerd accessing PD EC being the main EC: powerd-1272 [002] .... 40.644026: cros_ec_request_done: version: 0, offset: 1, command: EC_CMD_USB_PD_POWER_INFO, outsize: 1, insize: 16, ec result: EC_RES_SUCCESS, retval: 16 Signed-off-by: Gwendal Grignou Acked-by: Raul E Rangel Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_trace.h | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_trace.h b/drivers/platform/chrome/cros_ec_trace.h index e9fb05f89ef0..f744b21bc655 100644 --- a/drivers/platform/chrome/cros_ec_trace.h +++ b/drivers/platform/chrome/cros_ec_trace.h @@ -23,14 +23,22 @@ TRACE_EVENT(cros_ec_request_start, TP_ARGS(cmd), TP_STRUCT__entry( __field(uint32_t, version) + __field(uint32_t, offset) __field(uint32_t, command) + __field(uint32_t, outsize) + __field(uint32_t, insize) ), TP_fast_assign( __entry->version = cmd->version; - __entry->command = cmd->command; + __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(1); + __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(1); + __entry->outsize = cmd->outsize; + __entry->insize = cmd->insize; ), - TP_printk("version: %u, command: %s", __entry->version, - __print_symbolic(__entry->command, EC_CMDS)) + TP_printk("version: %u, offset: %d, command: %s, outsize: %u, insize: %u", + __entry->version, __entry->offset, + __print_symbolic(__entry->command, EC_CMDS), + __entry->outsize, __entry->insize) ); TRACE_EVENT(cros_ec_request_done, @@ -38,19 +46,26 @@ TRACE_EVENT(cros_ec_request_done, TP_ARGS(cmd, retval), TP_STRUCT__entry( __field(uint32_t, version) + __field(uint32_t, offset) __field(uint32_t, command) + __field(uint32_t, outsize) + __field(uint32_t, insize) __field(uint32_t, result) __field(int, retval) ), TP_fast_assign( __entry->version = cmd->version; - __entry->command = cmd->command; + __entry->offset = cmd->command / EC_CMD_PASSTHRU_OFFSET(1); + __entry->command = cmd->command % EC_CMD_PASSTHRU_OFFSET(1); + __entry->outsize = cmd->outsize; + __entry->insize = cmd->insize; __entry->result = cmd->result; __entry->retval = retval; ), - TP_printk("version: %u, command: %s, ec result: %s, retval: %d", - __entry->version, + TP_printk("version: %u, offset: %d, command: %s, outsize: %u, insize: %u, ec result: %s, retval: %u", + __entry->version, __entry->offset, __print_symbolic(__entry->command, EC_CMDS), + __entry->outsize, __entry->insize, __print_symbolic(__entry->result, EC_RESULT), __entry->retval) ); -- cgit From 1e7913ff5f9f1b73146ad8522958bd266f22a510 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Sat, 29 Aug 2020 23:59:37 -0700 Subject: platform/chrome: cros_ec_lightbar: Reduce ligthbar get version command By default, the lightbar commands are set to the biggest lightbar command and response. That length is greater than 128 bytes and may not work on all machines. But all EC are probed for lightbar by sending a get version request. Set that request size precisely. Before the command would be: cros_ec_cmd: version: 0, command: EC_CMD_LIGHTBAR_CMD, outsize: 194, insize: 128, result: 0 Afer: cros_ec_cmd: version: 0, command: EC_CMD_LIGHTBAR_CMD, outsize: 1, insize: 8, result: 0 Fixes: a841178445bb7 ("mfd: cros_ec: Use a zero-length array for command data") Signed-off-by: Gwendal Grignou Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_lightbar.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c index 8445cda57927..de8dfb12e486 100644 --- a/drivers/platform/chrome/cros_ec_lightbar.c +++ b/drivers/platform/chrome/cros_ec_lightbar.c @@ -116,6 +116,8 @@ static int get_lightbar_version(struct cros_ec_dev *ec, param = (struct ec_params_lightbar *)msg->data; param->cmd = LIGHTBAR_CMD_VERSION; + msg->outsize = sizeof(param->cmd); + msg->result = sizeof(resp->version); ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); if (ret < 0 && ret != -EINVAL) { ret = 0; -- cgit From dd92f7dfe1ba3bad556c8a529edacce7c6fd0195 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 3 Sep 2020 16:17:46 +0200 Subject: platform/chrome: Kconfig: Remove the transitional MFD_CROS_EC config The MFD_CROS_EC config was a transitional Kconfig option to not break current defconfigs in the kernel. Now, this is not required anymore because all the defconfigs have been removed this option and migrated to enable the CrOS EC parts individually. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Guenter Roeck Tested-by: Gwendal Grignou --- drivers/platform/chrome/Kconfig | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index a056031dee81..ccc23d8686e8 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig @@ -3,16 +3,6 @@ # Platform support for Chrome OS hardware (Chromebooks and Chromeboxes) # -config MFD_CROS_EC - tristate "Platform support for Chrome hardware (transitional)" - select CHROME_PLATFORMS - select CROS_EC - select MFD_CROS_EC_DEV - depends on X86 || ARM || ARM64 || COMPILE_TEST - help - This is a transitional Kconfig option and will be removed after - everyone enables the parts individually. - menuconfig CHROME_PLATFORMS bool "Platform support for Chrome hardware" depends on X86 || ARM || ARM64 || COMPILE_TEST -- cgit From 64b02e54e50fea8ebe0a2b2dc37ea096d0030cc5 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Mon, 21 Sep 2020 10:51:58 +0200 Subject: platform/chrome: cros_ec_proto: Update cros_ec_cmd_xfer() call-sites Since all the other call-sites of cros_ec_cmd_xfer() have been converted to use cros_ec_cmd_xfer_status() instead, update the remaining call-sites to prepare for the merge of cros_ec_cmd_xfer() into cros_ec_cmd_xfer_status(). As part of this update, change the error handling inside cros_ec_get_sensor_count() such that the legacy LPC interface is tried on all error values, not just when msg->result != EC_RESULT_SUCCESS. Note that there is a slight change in API in cros_ec_get_sensor_count(): it will return a negative number of sensors when there are no sensors on arm platform when MOTIONSENSE_CMD_DUMP is not supported (typical for sensorless chromebook) instead of 0. However, this is not a problem when probing the EC as we ignore errors only looking for cros_ec_get_sensor_count() returning a positive number of sensors. Signed-off-by: Prashant Malani Reviewed-by: Gwendal Grignou Tested-by: Gwendal Grignou Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_proto.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index dda182132a6a..2cb1defcdd13 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -650,7 +650,7 @@ static int get_next_event_xfer(struct cros_ec_device *ec_dev, msg->insize = size; msg->outsize = 0; - ret = cros_ec_cmd_xfer(ec_dev, msg); + ret = cros_ec_cmd_xfer_status(ec_dev, msg); if (ret > 0) { ec_dev->event_size = ret - 1; ec_dev->event_data = *event; @@ -694,7 +694,7 @@ static int get_keyboard_state_event(struct cros_ec_device *ec_dev) msg->insize = sizeof(ec_dev->event_data.data); msg->outsize = 0; - ec_dev->event_size = cros_ec_cmd_xfer(ec_dev, msg); + ec_dev->event_size = cros_ec_cmd_xfer_status(ec_dev, msg); ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX; memcpy(&ec_dev->event_data.data, msg->data, sizeof(ec_dev->event_data.data)); @@ -883,11 +883,9 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) params = (struct ec_params_motion_sense *)msg->data; params->cmd = MOTIONSENSE_CMD_DUMP; - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); if (ret < 0) { sensor_count = ret; - } else if (msg->result != EC_RES_SUCCESS) { - sensor_count = -EPROTO; } else { resp = (struct ec_response_motion_sense *)msg->data; sensor_count = resp->dump.sensor_count; @@ -898,9 +896,7 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) * Check legacy mode: Let's find out if sensors are accessible * via LPC interface. */ - if (sensor_count == -EPROTO && - ec->cmd_offset == 0 && - ec_dev->cmd_readmem) { + if (sensor_count < 0 && ec->cmd_offset == 0 && ec_dev->cmd_readmem) { ret = ec_dev->cmd_readmem(ec_dev, EC_MEMMAP_ACC_STATUS, 1, &status); if (ret >= 0 && @@ -915,9 +911,6 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) */ sensor_count = 0; } - } else if (sensor_count == -EPROTO) { - /* EC responded, but does not understand DUMP command. */ - sensor_count = 0; } return sensor_count; } -- cgit From 6b194ee986463ec7e6de7ccf3728ae4ede3b8d29 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Mon, 21 Sep 2020 10:51:58 +0200 Subject: platform/chrome: cros_ec_proto: Drop cros_ec_cmd_xfer() Since cros_ec_cmd_xfer_status() now returns Linux error codes and all other files use that command, remove the now-unused function cros_ec_cmd_xfer(). Signed-off-by: Prashant Malani Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_proto.c | 44 +++++++++------------------------ 1 file changed, 11 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 2cb1defcdd13..0ecee8b8773d 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -549,19 +549,22 @@ exit: EXPORT_SYMBOL(cros_ec_query_all); /** - * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC. + * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. * @ec_dev: EC device. * @msg: Message to write. * - * Call this to send a command to the ChromeOS EC. This should be used - * instead of calling the EC's cmd_xfer() callback directly. + * Call this to send a command to the ChromeOS EC. This should be used instead of calling the EC's + * cmd_xfer() callback directly. It returns success status only if both the command was transmitted + * successfully and the EC replied with success status. * - * Return: 0 on success or negative error code. + * Return: + * >=0 - The number of bytes transferred + * <0 - Linux error code */ -static int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, +int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { - int ret; + int ret, mapped; mutex_lock(&ec_dev->lock); if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) { @@ -598,42 +601,17 @@ static int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, return -EMSGSIZE; } } + ret = send_command(ec_dev, msg); mutex_unlock(&ec_dev->lock); - return ret; -} - -/** - * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. - * @ec_dev: EC device. - * @msg: Message to write. - * - * This function is identical to cros_ec_cmd_xfer, except it returns success - * status only if both the command was transmitted successfully and the EC - * replied with success status. It's not necessary to check msg->result when - * using this function. - * - * Return: - * >=0 - The number of bytes transferred - * <0 - Linux error code - */ -int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, - struct cros_ec_command *msg) -{ - int ret, mapped; - - ret = cros_ec_cmd_xfer(ec_dev, msg); - if (ret < 0) { - dev_err(ec_dev->dev, "Command xfer error (err:%d)\n", ret); - return ret; - } mapped = cros_ec_map_error(msg->result); if (mapped) { dev_dbg(ec_dev->dev, "Command result (err: %d [%d])\n", msg->result, mapped); ret = mapped; } + return ret; } EXPORT_SYMBOL(cros_ec_cmd_xfer_status); -- cgit From 9aa7bd452af17a3966e3583d959dcacab030bb8e Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Sat, 26 Sep 2020 15:03:37 +0800 Subject: platform/chrome: Use kobj_to_dev() instead of container_of() Use kobj_to_dev() instead of container_of(). Signed-off-by: Wang Qing Reviewed-by: Guenter Roeck Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_sysfs.c | 2 +- drivers/platform/chrome/cros_ec_vbc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c index 9c1e0998a721..f521a5c65091 100644 --- a/drivers/platform/chrome/cros_ec_sysfs.c +++ b/drivers/platform/chrome/cros_ec_sysfs.c @@ -320,7 +320,7 @@ static struct attribute *__ec_attrs[] = { static umode_t cros_ec_ctrl_visible(struct kobject *kobj, struct attribute *a, int n) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct cros_ec_dev *ec = to_cros_ec_dev(dev); if (a == &dev_attr_kb_wake_angle.attr && !ec->has_kb_wake_angle) diff --git a/drivers/platform/chrome/cros_ec_vbc.c b/drivers/platform/chrome/cros_ec_vbc.c index 46482d12cffe..f3a70a312b43 100644 --- a/drivers/platform/chrome/cros_ec_vbc.c +++ b/drivers/platform/chrome/cros_ec_vbc.c @@ -17,7 +17,7 @@ static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj, struct bin_attribute *att, char *buf, loff_t pos, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct cros_ec_dev *ec = to_cros_ec_dev(dev); struct cros_ec_device *ecdev = ec->ec_dev; struct ec_params_vbnvcontext *params; @@ -57,7 +57,7 @@ static ssize_t vboot_context_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t pos, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct cros_ec_dev *ec = to_cros_ec_dev(dev); struct cros_ec_device *ecdev = ec->ec_dev; struct ec_params_vbnvcontext *params; -- cgit