summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@chromium.org>2019-05-09 17:43:02 -0600
committerCommit Bot <commit-bot@chromium.org>2019-05-31 15:44:03 +0000
commit9f32a5cb851523db7fece971561383c30da49f68 (patch)
tree2c04dd6b6b1c257aa26fbbfb8258c12dd31e79df
parent6ef8adde4bf921a701d59766d3366be2df608697 (diff)
downloadchrome-ec-9f32a5cb851523db7fece971561383c30da49f68.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> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1638481 Commit-Queue: Karthikeyan Ramasubramanian <kramasub@chromium.org> Reviewed-by: Karthikeyan Ramasubramanian <kramasub@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 73771f412e..591afff579 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"
@@ -789,7 +790,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;
@@ -797,6 +798,29 @@ void i2c_passthru_protect_port(uint32_t port)
PTHRUPRINTF("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;
@@ -827,6 +851,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 c1c5d7c995..5f48466420 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;
@@ -957,7 +928,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
@@ -1212,7 +1182,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 c485c49ddd..83de527fb0 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -4388,8 +4388,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 bb7f28000d..1dcfe46332 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -392,9 +392,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 */