Skip to content

Commit 8ee66a1

Browse files
Romain Pelletantdleach02
authored andcommitted
drivers: i2c: i2c_gecko: add exclusive access
- Add exclusive and atomic access to resource Fixes #79110 Signed-off-by: Romain Pelletant <[email protected]>
1 parent f4e07d1 commit 8ee66a1

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

drivers/i2c/i2c_gecko.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct i2c_gecko_config {
3737

3838
struct i2c_gecko_data {
3939
struct k_sem device_sync_sem;
40+
struct k_sem bus_lock;
4041
uint32_t dev_config;
4142
#if defined(CONFIG_I2C_TARGET)
4243
struct i2c_target_config *target_cfg;
@@ -68,6 +69,8 @@ static int i2c_gecko_configure(const struct device *dev, uint32_t dev_config_raw
6869
return -EINVAL;
6970
}
7071

72+
k_sem_take(&data->bus_lock, K_FOREVER);
73+
7174
data->dev_config = dev_config_raw;
7275
i2cInit.freq = baudrate;
7376

@@ -77,6 +80,8 @@ static int i2c_gecko_configure(const struct device *dev, uint32_t dev_config_raw
7780

7881
I2C_Init(base, &i2cInit);
7982

83+
k_sem_give(&data->bus_lock);
84+
8085
return 0;
8186
}
8287

@@ -93,6 +98,8 @@ static int i2c_gecko_transfer(const struct device *dev, struct i2c_msg *msgs, ui
9398
return 0;
9499
}
95100

101+
k_sem_take(&data->bus_lock, K_FOREVER);
102+
96103
seq.addr = addr << 1;
97104

98105
do {
@@ -137,6 +144,8 @@ static int i2c_gecko_transfer(const struct device *dev, struct i2c_msg *msgs, ui
137144
} while (num_msgs);
138145

139146
finish:
147+
k_sem_give(&data->bus_lock);
148+
140149
if (ret != i2cTransferDone) {
141150
ret = -EIO;
142151
}
@@ -145,10 +154,16 @@ static int i2c_gecko_transfer(const struct device *dev, struct i2c_msg *msgs, ui
145154

146155
static int i2c_gecko_init(const struct device *dev)
147156
{
157+
struct i2c_gecko_data *data = dev->data;
148158
const struct i2c_gecko_config *config = dev->config;
149159
uint32_t bitrate_cfg;
150160
int error;
151161

162+
/* Initialize mutex to guarantee that each transaction
163+
* is atomic and has exclusive access to the I2C bus
164+
*/
165+
k_sem_init(&data->bus_lock, 1, 1);
166+
152167
CMU_ClockEnable(config->clock, true);
153168

154169
error = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);

0 commit comments

Comments
 (0)