Skip to content

Commit d9ad8c9

Browse files
ydamigosnashif
authored andcommitted
i2c_smartbond: Fix spin locking
Fix spin locking Signed-off-by: Ioannis Damigos <[email protected]>
1 parent c7da55e commit d9ad8c9

File tree

1 file changed

+12
-29
lines changed

1 file changed

+12
-29
lines changed

drivers/i2c/i2c_smartbond.c

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ struct i2c_smartbond_data {
3838
#if defined(CONFIG_PM_DEVICE)
3939
ATOMIC_DEFINE(pm_policy_state_flag, 1);
4040
#endif
41+
#ifdef CONFIG_I2C_CALLBACK
42+
k_spinlock_key_t spinlock_key;
43+
#endif
4144
};
4245

4346
#if defined(CONFIG_PM_DEVICE)
@@ -111,7 +114,7 @@ static int i2c_smartbond_apply_configure(const struct device *dev, uint32_t dev_
111114
const struct i2c_smartbond_cfg *config = dev->config;
112115
struct i2c_smartbond_data *data = dev->data;
113116
uint32_t con_reg = 0x0UL;
114-
k_spinlock_key_t key;
117+
k_spinlock_key_t key = k_spin_lock(&data->lock);
115118

116119
/* Configure Speed (SCL frequency) */
117120
switch (I2C_SPEED_GET(dev_config)) {
@@ -144,8 +147,6 @@ static int i2c_smartbond_apply_configure(const struct device *dev, uint32_t dev_
144147
/* Enable sending RESTART as master */
145148
con_reg |= I2C_I2C_CON_REG_I2C_RESTART_EN_Msk;
146149

147-
key = k_spin_lock(&data->lock);
148-
149150
i2c_smartbond_disable_when_inactive(dev);
150151

151152
/* Write control register*/
@@ -221,8 +222,6 @@ static inline void i2c_smartbond_set_target_address(const struct i2c_smartbond_c
221222
struct i2c_smartbond_data *data,
222223
const struct i2c_msg *const msg, uint16_t addr)
223224
{
224-
k_spinlock_key_t key = k_spin_lock(&data->lock);
225-
226225
/* Disable I2C Controller */
227226
config->regs->I2C_ENABLE_REG &= ~I2C_I2C_ENABLE_REG_I2C_EN_Msk;
228227
/* Configure addressing mode*/
@@ -237,8 +236,6 @@ static inline void i2c_smartbond_set_target_address(const struct i2c_smartbond_c
237236
(addr & I2C_I2C_TAR_REG_IC_TAR_Msk));
238237
/* Enable again the I2C to use the new address */
239238
config->regs->I2C_ENABLE_REG |= I2C_I2C_ENABLE_REG_I2C_EN_Msk;
240-
241-
k_spin_unlock(&data->lock, key);
242239
}
243240

244241
static inline int i2c_smartbond_set_msg_flags(struct i2c_msg *msgs, uint8_t num_msgs)
@@ -289,16 +286,13 @@ static inline int i2c_smartbond_prep_transfer(const struct device *dev, struct i
289286
static inline int i2c_smartbond_tx(const struct i2c_smartbond_cfg *const config,
290287
struct i2c_smartbond_data *data)
291288
{
292-
k_spinlock_key_t key;
293289
const bool rw = ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ);
294290
int ret = 0;
295291

296292
if (!data->msgs->buf || data->msgs->len == 0) {
297293
return -EINVAL;
298294
}
299295

300-
key = k_spin_lock(&data->lock);
301-
302296
/* Transmits data or read commands with correct flags */
303297
while ((data->transmit_cnt < data->msgs->len) &&
304298
(config->regs->I2C_STATUS_REG & I2C_I2C_STATUS_REG_TFNF_Msk)) {
@@ -329,23 +323,18 @@ static inline int i2c_smartbond_tx(const struct i2c_smartbond_cfg *const config,
329323
(void)config->regs->I2C_CLR_TX_ABRT_REG;
330324
}
331325

332-
k_spin_unlock(&data->lock, key);
333-
334326
return ret;
335327
}
336328

337329
static inline int i2c_smartbond_rx(const struct i2c_smartbond_cfg *const config,
338330
struct i2c_smartbond_data *data)
339331
{
340-
k_spinlock_key_t key;
341332
int ret = 0;
342333

343334
if (!data->msgs->buf || data->msgs->len == 0) {
344335
return -EINVAL;
345336
}
346337

347-
key = k_spin_lock(&data->lock);
348-
349338
/* Reads the data register until fifo is empty */
350339
while ((data->receive_cnt < data->transmit_cnt) &&
351340
(config->regs->I2C_STATUS_REG & I2C2_I2C2_STATUS_REG_RFNE_Msk)) {
@@ -354,8 +343,6 @@ static inline int i2c_smartbond_rx(const struct i2c_smartbond_cfg *const config,
354343
data->receive_cnt++;
355344
}
356345

357-
k_spin_unlock(&data->lock, key);
358-
359346
return ret;
360347
}
361348

@@ -365,6 +352,7 @@ static int i2c_smartbond_transfer(const struct device *dev, struct i2c_msg *msgs
365352
const struct i2c_smartbond_cfg *config = dev->config;
366353
struct i2c_smartbond_data *data = dev->data;
367354
int ret = 0;
355+
k_spinlock_key_t key = k_spin_lock(&data->lock);
368356

369357
i2c_smartbond_pm_policy_state_lock_get(dev);
370358

@@ -405,6 +393,7 @@ static int i2c_smartbond_transfer(const struct device *dev, struct i2c_msg *msgs
405393
while (!i2c_smartbond_is_idle(dev)) {
406394
};
407395
i2c_smartbond_pm_policy_state_lock_put(dev);
396+
k_spin_unlock(&data->lock, key);
408397

409398
return ret;
410399
}
@@ -414,8 +403,6 @@ static int i2c_smartbond_transfer(const struct device *dev, struct i2c_msg *msgs
414403
static int i2c_smartbond_enable_msg_interrupts(const struct i2c_smartbond_cfg *const config,
415404
struct i2c_smartbond_data *data)
416405
{
417-
k_spinlock_key_t key = k_spin_lock(&data->lock);
418-
419406
if ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
420407
uint32_t remaining = data->msgs->len - data->receive_cnt;
421408
uint32_t tx_space = 32 - config->regs->I2C_TXFLR_REG;
@@ -430,8 +417,6 @@ static int i2c_smartbond_enable_msg_interrupts(const struct i2c_smartbond_cfg *c
430417
config->regs->I2C_TX_TL_REG = 0UL;
431418
config->regs->I2C_INTR_MASK_REG |= I2C_I2C_INTR_MASK_REG_M_TX_EMPTY_Msk;
432419

433-
k_spin_unlock(&data->lock, key);
434-
435420
return 0;
436421
}
437422

@@ -442,6 +427,7 @@ static int i2c_smartbond_transfer_cb(const struct device *dev, struct i2c_msg *m
442427
const struct i2c_smartbond_cfg *config = dev->config;
443428
struct i2c_smartbond_data *data = dev->data;
444429
int ret = 0;
430+
k_spinlock_key_t key = k_spin_lock(&data->lock);
445431

446432
if (cb == NULL) {
447433
return -EINVAL;
@@ -451,6 +437,7 @@ static int i2c_smartbond_transfer_cb(const struct device *dev, struct i2c_msg *m
451437
return -EWOULDBLOCK;
452438
}
453439

440+
data->spinlock_key = key;
454441
data->cb = cb;
455442
data->userdata = userdata;
456443

@@ -459,6 +446,7 @@ static int i2c_smartbond_transfer_cb(const struct device *dev, struct i2c_msg *m
459446
ret = i2c_smartbond_prep_transfer(dev, msgs, num_msgs, addr);
460447
if (ret != 0) {
461448
i2c_smartbond_pm_policy_state_lock_put(dev);
449+
k_spin_unlock(&data->lock, key);
462450
return ret;
463451
}
464452

@@ -471,9 +459,7 @@ static int i2c_smartbond_transfer_cb(const struct device *dev, struct i2c_msg *m
471459

472460
static inline void isr_tx(const struct i2c_smartbond_cfg *config, struct i2c_smartbond_data *data)
473461
{
474-
475462
const bool rw = ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ);
476-
k_spinlock_key_t key = k_spin_lock(&data->lock);
477463

478464
while ((data->transmit_cnt < data->msgs->len) &&
479465
(config->regs->I2C_STATUS_REG & I2C_I2C_STATUS_REG_TFNF_Msk)) {
@@ -490,22 +476,16 @@ static inline void isr_tx(const struct i2c_smartbond_cfg *config, struct i2c_sma
490476
: 0);
491477
data->transmit_cnt++;
492478
}
493-
494-
k_spin_unlock(&data->lock, key);
495479
}
496480

497481
static inline void isr_rx(const struct i2c_smartbond_cfg *config, struct i2c_smartbond_data *data)
498482
{
499-
k_spinlock_key_t key = k_spin_lock(&data->lock);
500-
501483
while ((data->receive_cnt < data->transmit_cnt) &&
502484
(config->regs->I2C_STATUS_REG & I2C2_I2C2_STATUS_REG_RFNE_Msk)) {
503485
data->msgs->buf[data->receive_cnt] =
504486
config->regs->I2C_DATA_CMD_REG & I2C_I2C_DATA_CMD_REG_I2C_DAT_Msk;
505487
data->receive_cnt++;
506488
}
507-
508-
k_spin_unlock(&data->lock, key);
509489
}
510490

511491
static inline void i2c_smartbond_async_msg_done(const struct device *dev)
@@ -526,7 +506,10 @@ static inline void i2c_smartbond_async_msg_done(const struct device *dev)
526506
data->cb = NULL;
527507
LOG_INF("async transfer finished");
528508
cb(dev, 0, data->userdata);
509+
while (!i2c_smartbond_is_idle(dev)) {
510+
};
529511
i2c_smartbond_pm_policy_state_lock_put(dev);
512+
k_spin_unlock(&data->lock, data->spinlock_key);
530513
}
531514
}
532515

0 commit comments

Comments
 (0)