diff --git a/drivers/i2c/i2c_mcux.c b/drivers/i2c/i2c_mcux.c index cce1e66a6c1..9b445e3d3f4 100644 --- a/drivers/i2c/i2c_mcux.c +++ b/drivers/i2c/i2c_mcux.c @@ -34,6 +34,7 @@ struct i2c_mcux_config { struct i2c_mcux_data { i2c_master_handle_t handle; + struct k_sem lock; struct k_sem device_sync_sem; status_t callback_status; }; @@ -42,6 +43,7 @@ static int i2c_mcux_configure(const struct device *dev, uint32_t dev_config_raw) { I2C_Type *base = DEV_BASE(dev); + struct i2c_mcux_data *data = DEV_DATA(dev); const struct i2c_mcux_config *config = DEV_CFG(dev); uint32_t clock_freq; uint32_t baudrate; @@ -69,7 +71,9 @@ static int i2c_mcux_configure(const struct device *dev, } clock_freq = CLOCK_GetFreq(config->clock_source); + k_sem_take(&data->lock, K_FOREVER); I2C_MasterSetBaudRate(base, baudrate, clock_freq); + k_sem_give(&data->lock); return 0; } @@ -109,11 +113,15 @@ static int i2c_mcux_transfer(const struct device *dev, struct i2c_msg *msgs, struct i2c_mcux_data *data = DEV_DATA(dev); i2c_master_transfer_t transfer; status_t status; + int ret = 0; + + k_sem_take(&data->lock, K_FOREVER); /* Iterate over all the messages */ for (int i = 0; i < num_msgs; i++) { if (I2C_MSG_ADDR_10_BITS & msgs->flags) { - return -ENOTSUP; + ret = -ENOTSUP; + break; } /* Initialize the transfer descriptor */ @@ -142,7 +150,8 @@ static int i2c_mcux_transfer(const struct device *dev, struct i2c_msg *msgs, */ if (status != kStatus_Success) { I2C_MasterTransferAbort(base, &data->handle); - return -EIO; + ret = -EIO; + break; } /* Wait for the transfer to complete */ @@ -153,14 +162,17 @@ static int i2c_mcux_transfer(const struct device *dev, struct i2c_msg *msgs, */ if (data->callback_status != kStatus_Success) { I2C_MasterTransferAbort(base, &data->handle); - return -EIO; + ret = -EIO; + break; } /* Move to the next message */ msgs++; } - return 0; + k_sem_give(&data->lock); + + return ret; } static void i2c_mcux_isr(const struct device *dev) @@ -180,6 +192,7 @@ static int i2c_mcux_init(const struct device *dev) i2c_master_config_t master_config; int error; + k_sem_init(&data->lock, 1, 1); k_sem_init(&data->device_sync_sem, 0, UINT_MAX); clock_freq = CLOCK_GetFreq(config->clock_source);