summaryrefslogtreecommitdiff
path: root/zephyr/shim/src
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2021-07-07 15:55:04 +0800
committerCommit Bot <commit-bot@chromium.org>2021-07-22 19:54:04 +0000
commit154f661f50d08adc3a546360be020a7e0321fe2e (patch)
tree0a85a77f8aa5215595a91cf9c5d3c39972387c27 /zephyr/shim/src
parent506a1ee872aad4ef21d7c90717f1917963dec6b1 (diff)
downloadchrome-ec-154f661f50d08adc3a546360be020a7e0321fe2e.tar.gz
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 <Dino.Li@ite.com.tw> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3010920 Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org> Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'zephyr/shim/src')
-rw-r--r--zephyr/shim/src/i2c.c17
1 files changed, 17 insertions, 0 deletions
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;
+}