drivers: i2c: MEC15xx i2c error handling

Updates to MEC15xx i2c error handling:
1. timeout_seen handling is simplified. For all errors we
continuously poll
2. error flag is not set for timeout_seen handling and hence
recover_from_error() call is not required.
3. In i2c_xec_poll_write(), ETIMEDOUT for (START + ADDRESS) byte
is treated as default error and error_seen flag is set (instead
of timeout_seen flag)

Signed-off-by: Jay Vasanth <jay.vasanth@microchip.com>
This commit is contained in:
Jay Vasanth 2022-04-04 10:51:43 -04:00 committed by Carles Cufí
commit 89d6695f7c

View file

@ -362,27 +362,18 @@ static int i2c_xec_poll_write(const struct device *dev, struct i2c_msg msg,
struct i2c_xec_data *data = struct i2c_xec_data *data =
(struct i2c_xec_data *const) (dev->data); (struct i2c_xec_data *const) (dev->data);
uint32_t ba = config->base_addr; uint32_t ba = config->base_addr;
uint8_t i2c_timer = 0, byte, error = 0; uint8_t i2c_timer = 0, byte;
int ret; int ret;
if (data->timeout_seen == 1) { if (data->timeout_seen == 1) {
/* Wait to see if the slave has released the CLK */ /* Wait to see if the slave has released the CLK */
ret = wait_completion(dev); ret = wait_completion(dev);
switch (ret) { if (ret) {
case 0: /* Success */
break;
case -ETIMEDOUT:
data->timeout_seen = 1; data->timeout_seen = 1;
LOG_ERR("%s: %s wait_completion Timeout %d\n", LOG_ERR("%s: %s wait_completion failure %d\n",
__func__, dev->name, ret); __func__, dev->name, ret);
return ret; return ret;
default:
error = 1;
break;
} }
data->timeout_seen = 0; data->timeout_seen = 0;
/* If we are here, it means the slave has finally released /* If we are here, it means the slave has finally released
@ -406,13 +397,6 @@ static int i2c_xec_poll_write(const struct device *dev, struct i2c_msg msg,
data->previously_in_read = 0; data->previously_in_read = 0;
byte = MCHP_I2C_SMB_DATA(ba); byte = MCHP_I2C_SMB_DATA(ba);
} }
if (error) {
LOG_DBG("%s: Recovering %s previously in error",
__func__, dev->name);
recover_from_error(dev);
}
return -EBUSY; return -EBUSY;
} }
@ -463,12 +447,6 @@ static int i2c_xec_poll_write(const struct device *dev, struct i2c_msg msg,
__func__, addr >> 1, dev->name); __func__, addr >> 1, dev->name);
return ret; return ret;
case -ETIMEDOUT:
data->timeout_seen = 1;
LOG_ERR("%s: Addr Clk stretch Timeout - Slave 0x%x on %s",
__func__, addr >> 1, dev->name);
return ret;
default: default:
data->error_seen = 1; data->error_seen = 1;
LOG_ERR("%s: %s wait_comp error for addr send", LOG_ERR("%s: %s wait_comp error for addr send",
@ -529,27 +507,18 @@ static int i2c_xec_poll_read(const struct device *dev, struct i2c_msg msg,
struct i2c_xec_data *data = struct i2c_xec_data *data =
(struct i2c_xec_data *const) (dev->data); (struct i2c_xec_data *const) (dev->data);
uint32_t ba = config->base_addr; uint32_t ba = config->base_addr;
uint8_t byte, ctrl, i2c_timer = 0, error = 0; uint8_t byte, ctrl, i2c_timer = 0;
int ret; int ret;
if (data->timeout_seen == 1) { if (data->timeout_seen == 1) {
/* Wait to see if the slave has released the CLK */ /* Wait to see if the slave has released the CLK */
ret = wait_completion(dev); ret = wait_completion(dev);
switch (ret) { if (ret) {
case 0: /* Success */
break;
case -ETIMEDOUT:
data->timeout_seen = 1; data->timeout_seen = 1;
LOG_ERR("%s: %s wait_completion Timeout %d\n", LOG_ERR("%s: %s wait_completion failure %d\n",
__func__, dev->name, ret); __func__, dev->name, ret);
return ret; return ret;
default:
error = 1;
break;
} }
data->timeout_seen = 0; data->timeout_seen = 0;
/* If we are here, it means the slave has finally released /* If we are here, it means the slave has finally released
@ -563,12 +532,6 @@ static int i2c_xec_poll_read(const struct device *dev, struct i2c_msg msg,
MCHP_I2C_SMB_CTRL_STO | MCHP_I2C_SMB_CTRL_STO |
MCHP_I2C_SMB_CTRL_ACK; MCHP_I2C_SMB_CTRL_ACK;
k_busy_wait(BUS_IDLE_US_DFLT); k_busy_wait(BUS_IDLE_US_DFLT);
if (error) {
LOG_DBG("%s: Recovering %s previously in error",
__func__, dev->name);
recover_from_error(dev);
}
return -EBUSY; return -EBUSY;
} }