diff options
Diffstat (limited to 'common/i2c_controller.c')
-rw-r--r-- | common/i2c_controller.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/common/i2c_controller.c b/common/i2c_controller.c index f2d1cf4a5f..92234bc600 100644 --- a/common/i2c_controller.c +++ b/common/i2c_controller.c @@ -100,13 +100,23 @@ const struct i2c_port_t *get_i2c_port(const int port) { int i; - /* Find the matching port in i2c_ports[] table. */ - for (i = 0; i < i2c_ports_used; i++) { - if (i2c_ports[i].port == port) - return &i2c_ports[i]; + /* + * If the EC's I2C driver implementation is task event based and the + * I2C is accessed before the task is initialized, it causes the system + * panic hence these I2C will fall back to bitbang mode if enabled at + * board level and will again switch back to event based I2C upon task + * initialization. + */ + if (task_start_called()) { + /* Find the matching port in i2c_ports[] table. */ + for (i = 0; i < i2c_ports_used; i++) { + if (i2c_ports[i].port == port) + return &i2c_ports[i]; + } } if (IS_ENABLED(CONFIG_I2C_BITBANG)) { + /* Find the matching port in i2c_bitbang_ports[] table. */ for (i = 0; i < i2c_bitbang_ports_used; i++) { if (i2c_bitbang_ports[i].port == port) return &i2c_bitbang_ports[i]; @@ -137,6 +147,7 @@ __maybe_unused static int chip_i2c_xfer_with_notify( * remove the flag so it won't confuse chip driver. */ no_pec_af &= ~I2C_FLAG_PEC; + if (i2c_port->drv) ret = i2c_port->drv->xfer(i2c_port, no_pec_af, out, out_size, in, in_size, flags); |