summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@chromium.org>2019-05-09 17:43:02 -0600
committerchrome-bot <chrome-bot@chromium.org>2019-05-30 11:47:58 -0700
commitc23cced7340ba977e9aacb9af02b86ac5df7d347 (patch)
tree46a9b72f7027fef8d9e61706cc984a7cfe31ee24
parentea05ecfd8a2c278b1da5e2c111e6f71485c84ad9 (diff)
downloadchrome-ec-c23cced7340ba977e9aacb9af02b86ac5df7d347.tar.gz
common/i2c_master: Add a subcommand to protect all TCPC ports
Currently the I2C tunnels of all TCPC ports are protected implicitly when the system jump is disabled. Depthcharge issues that command after the EC jumps to RW and before the TCPC firmware update is applied. This leads to failure while updating the TCPC firmware and hence a reboot loop. Fix this behavior by adding a sub-command to protect all the I2C tunnels so that depthcharge can issue that command after both EC SW Sync and TCPC Firmware update are done. BUG=b:129545729 BRANCH=None TEST=make -j buildall; Boot to ChromeOS. Force a TCPC FW update and ensure that the reboot loop does not happen. Change-Id: I5dd2314cf82dcfff520dc32ce3ced232326ab3d5 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://chromium-review.googlesource.com/1605260 Commit-Ready: Karthikeyan Ramasubramanian <kramasub@chromium.org> Tested-by: Karthikeyan Ramasubramanian <kramasub@chromium.org> Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r--common/i2c_master.c30
-rw-r--r--common/system.c31
-rw-r--r--include/ec_commands.h5
-rw-r--r--include/i2c.h5
4 files changed, 32 insertions, 39 deletions
diff --git a/common/i2c_master.c b/common/i2c_master.c
index 6d4dc1120a..564af89820 100644
--- a/common/i2c_master.c
+++ b/common/i2c_master.c
@@ -14,6 +14,7 @@
#include "i2c.h"
#include "system.h"
#include "task.h"
+#include "usb_pd_tcpm.h"
#include "util.h"
#include "watchdog.h"
#include "virtual_battery.h"
@@ -884,7 +885,7 @@ DECLARE_HOST_COMMAND(EC_CMD_I2C_LOOKUP, i2c_command_lookup, EC_VER_MASK(0));
/* If the params union expands in the future, need to bump EC_VER_MASK */
BUILD_ASSERT(sizeof(struct ec_params_i2c_lookup) == 4);
-void i2c_passthru_protect_port(uint32_t port)
+static void i2c_passthru_protect_port(uint32_t port)
{
if (port < I2C_PORT_COUNT)
port_protected[port] = 1;
@@ -892,6 +893,29 @@ void i2c_passthru_protect_port(uint32_t port)
PTHRUPRINTS("Invalid I2C port %d to be protected\n", port);
}
+static void i2c_passthru_protect_tcpc_ports(void)
+{
+#ifdef CONFIG_USB_PD_PORT_COUNT
+ int i;
+
+ /*
+ * If WP is not enabled i.e. system is not locked leave the tunnels open
+ * so that factory line can do updates without a new RO BIOS.
+ */
+ if (!system_is_locked()) {
+ CPRINTS("System unlocked, TCPC I2C tunnels may be unprotected");
+ return;
+ }
+
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
+ /* TCPC tunnel not configured. No need to protect anything */
+ if (!tcpc_config[i].i2c_slave_addr)
+ continue;
+ i2c_passthru_protect_port(tcpc_config[i].i2c_host_port);
+ }
+#endif
+}
+
static int i2c_command_passthru_protect(struct host_cmd_handler_args *args)
{
const struct ec_params_i2c_passthru_protect *params = args->params;
@@ -920,6 +944,10 @@ static int i2c_command_passthru_protect(struct host_cmd_handler_args *args)
args->response_size = sizeof(*resp);
} else if (params->subcmd == EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE) {
i2c_passthru_protect_port(params->port);
+ } else if (params->subcmd == EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE_TCPCS) {
+ if (IS_ENABLED(CONFIG_USB_POWER_DELIVERY) &&
+ !IS_ENABLED(CONFIG_USB_PD_TCPM_STUB))
+ i2c_passthru_protect_tcpc_ports();
} else {
return EC_RES_INVALID_COMMAND;
}
diff --git a/common/system.c b/common/system.c
index 632cc19695..39390a9418 100644
--- a/common/system.c
+++ b/common/system.c
@@ -351,35 +351,6 @@ const uint8_t *system_get_jump_tag(uint16_t tag, int *version, int *size)
return NULL;
}
-#if defined(CONFIG_USB_POWER_DELIVERY) && !defined(CONFIG_USB_PD_TCPM_STUB) && \
- defined(CONFIG_I2C_MASTER)
-
-static void system_protect_tcpc_i2c_ports(void)
-{
- uint32_t locked = system_is_locked();
- int i;
-
- /*
- * If WP is not enabled i.e. system is not locked leave the tunnels open
- * so that factory line can do updates without a new RO BIOS.
- */
- if (!locked) {
- CPRINTS("System unlocked, TCPC I2C tunnels may be unprotected");
- return;
- }
-
- for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
- i2c_passthru_protect_port(tcpc_config[i].i2c_host_port);
-}
-
-#else
-
-static void system_protect_tcpc_i2c_ports(void)
-{
-}
-
-#endif
-
void system_disable_jump(void)
{
disable_jump = 1;
@@ -962,7 +933,6 @@ static int handle_pending_reboot(enum ec_reboot_cmd cmd)
/* That shouldn't return... */
return EC_ERROR_UNKNOWN;
case EC_REBOOT_DISABLE_JUMP:
- system_protect_tcpc_i2c_ports();
system_disable_jump();
return EC_SUCCESS;
#ifdef CONFIG_HIBERNATE
@@ -1217,7 +1187,6 @@ static int command_sysjump(int argc, char **argv)
return EC_ERROR_PARAM1;
#endif
} else if (!strcasecmp(argv[1], "disable")) {
- system_protect_tcpc_i2c_ports();
system_disable_jump();
return EC_SUCCESS;
}
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 5cfd86e97a..70527a40ac 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -4471,8 +4471,9 @@ struct ec_params_entering_mode {
#define EC_CMD_I2C_PASSTHRU_PROTECT 0x00B7
enum ec_i2c_passthru_protect_subcmd {
- EC_CMD_I2C_PASSTHRU_PROTECT_STATUS = 0x0,
- EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE = 0x1,
+ EC_CMD_I2C_PASSTHRU_PROTECT_STATUS = 0,
+ EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE = 1,
+ EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE_TCPCS = 2,
};
struct ec_params_i2c_passthru_protect {
diff --git a/include/i2c.h b/include/i2c.h
index a43a2223d3..c28230c721 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -420,9 +420,4 @@ void i2c_start_xfer_notify(int port, int slave_addr);
*/
void i2c_end_xfer_notify(int port, int slave_addr);
-/**
- * Function to protect I2C port/tunnel. This is invoked either when through
- * host command or when sys_jump is disabld.
- */
-void i2c_passthru_protect_port(uint32_t port);
#endif /* __CROS_EC_I2C_H */