From 154f661f50d08adc3a546360be020a7e0321fe2e Mon Sep 17 00:00:00 2001 From: Dino Li Date: Wed, 7 Jul 2021 15:55:04 +0800 Subject: zephyr: i2c: protect physical port If i2c devices are connected to the same port, they should use the same mutex_lock() index. So the new transaction won't break the ongoing transaction. BRANCH=none BUG=b:189855648 TEST=Enable CONFIG_SMBUS_PEC and voltage regulator function on asurada. No i2c transaction is broken. Change-Id: Ib848e3c2e60b99ce66ad5fd2fc7095f90820a15d Signed-off-by: Dino Li Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3010920 Reviewed-by: Jack Rosenthal Reviewed-by: Denis Brockus Commit-Queue: Denis Brockus --- zephyr/shim/src/i2c.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'zephyr/shim/src') diff --git a/zephyr/shim/src/i2c.c b/zephyr/shim/src/i2c.c index cc4af85021..ae82db1a0a 100644 --- a/zephyr/shim/src/i2c.c +++ b/zephyr/shim/src/i2c.c @@ -18,6 +18,9 @@ #define INIT_REMOTE_PORTS(id) \ i2c_remote_ports[I2C_PORT(id)] = DT_PROP_OR(id, remote_port, -1); +#define INIT_PHYSICAL_PORTS(id) \ + i2c_physical_ports[I2C_PORT(id)] = DT_PROP_OR(id, physical_port, -1); + #define I2C_CONFIG_GPIO(id, type) \ DT_ENUM_UPPER_TOKEN(DT_CHILD(DT_CHILD(id, config), type), enum_name) @@ -41,6 +44,7 @@ const struct i2c_port_t i2c_ports[] = { }; const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); static int i2c_remote_ports[I2C_PORT_COUNT]; +static int i2c_physical_ports[I2C_PORT_COUNT]; int i2c_get_line_levels(int port) { @@ -54,6 +58,7 @@ static int init_device_bindings(const struct device *device) ARG_UNUSED(device); DT_FOREACH_CHILD(DT_PATH(named_i2c_ports), INIT_DEV_BINDING) DT_FOREACH_CHILD(DT_PATH(named_i2c_ports), INIT_REMOTE_PORTS) + DT_FOREACH_CHILD(DT_PATH(named_i2c_ports), INIT_PHYSICAL_PORTS) return 0; } SYS_INIT(init_device_bindings, POST_KERNEL, 51); @@ -75,3 +80,15 @@ int i2c_get_port_from_remote_port(int remote_port) /* Remote port is not defined, return -1 to signal the problem */ return -1; } + +int i2c_get_physical_port(int enum_port) +{ + int i2c_port = i2c_physical_ports[enum_port]; + + /* + * Return -1 for caller if physical port is not defined or the + * port number is out of port_mutex space. + * Please ensure the caller won't change anything if -1 received. + */ + return (i2c_port < I2C_PORT_COUNT) ? i2c_port : -1; +} -- cgit v1.2.1