mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-23 16:02:05 +08:00
arm/stm32f4: Fix I2C mutex initialization and potential mutex leak
Fix two issues in the STM32F4 I2C driver related to mutex handling. The mutex protecting the I2C bus was created with an initial count of 0. For a binary semaphore used as a mutex this causes the first rtems_semaphore_obtain() call to block indefinitely since the semaphore starts in the locked state. Initialize the semaphore with a count of 1 so it starts unlocked. Additionally, stm32f4_i2c_process_message() could return early if the STOP bit was set in CR1 without releasing the mutex. This would leave the mutex locked and cause subsequent calls to deadlock. Release the mutex before returning in this case. Also cast dummy SR2 reads to (void) to make the intent explicit and avoid potential compiler warnings about statements with no effect. arm/stm32f4: Fix I2C mutex initialization and potential mutex leak fix the indentation on these lines.
This commit is contained in:
committed by
Gedare Bloom
parent
14605b6d2b
commit
dc11184541
@@ -122,7 +122,7 @@ static void stm32f4_i2c_handler(void *arg)
|
||||
regs->cr1 = cr1;
|
||||
|
||||
/* Read sr2 to clear flag */
|
||||
regs->sr2;
|
||||
(void) regs->sr2;
|
||||
|
||||
cr1 = regs->cr1;
|
||||
cr1 |= STM32F4_I2C_CR1_STOP;
|
||||
@@ -135,7 +135,7 @@ static void stm32f4_i2c_handler(void *arg)
|
||||
/* special case for two bytes */
|
||||
if(sr1 & STM32F4_I2C_SR1_ADDR) {
|
||||
/* Read sr2 to clear flag */
|
||||
regs->sr2;
|
||||
(void) regs->sr2;
|
||||
|
||||
cr1 = regs->cr1;
|
||||
cr1 &= ~STM32F4_I2C_CR1_ACK;
|
||||
@@ -154,7 +154,7 @@ static void stm32f4_i2c_handler(void *arg)
|
||||
/* more than two bytes */
|
||||
if(sr1 & STM32F4_I2C_SR1_ADDR) {
|
||||
/* Read sr2 to clear flag */
|
||||
regs->sr2;
|
||||
(void) regs->sr2;
|
||||
} else if(sr1 & STM32F4_I2C_SR1_BTF && data == last - 2) {
|
||||
cr1 = regs->cr1;
|
||||
cr1 &= ~STM32F4_I2C_CR1_ACK;
|
||||
@@ -182,7 +182,7 @@ static void stm32f4_i2c_handler(void *arg)
|
||||
} else /* write */ {
|
||||
if(sr1 & STM32F4_I2C_SR1_ADDR) {
|
||||
/* Address sent */
|
||||
regs->sr2;
|
||||
(void) regs->sr2;
|
||||
}
|
||||
|
||||
if((sr1 & (STM32F4_I2C_SR1_ADDR | STM32F4_I2C_SR1_TxE)) && (data <= last)) {
|
||||
@@ -225,7 +225,7 @@ rtems_status_code stm32f4_i2c_init(stm32f4_i2c_bus_entry *e)
|
||||
/* Create mutex */
|
||||
sc = rtems_semaphore_create (
|
||||
rtems_build_name ('I', '2', 'C', '1' + e->index),
|
||||
0,
|
||||
1,
|
||||
RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
|
||||
0,
|
||||
&e->mutex
|
||||
@@ -298,6 +298,7 @@ rtems_status_code stm32f4_i2c_process_message(
|
||||
|
||||
/* Check if no stop is active. */
|
||||
if(cr1 & STM32F4_I2C_CR1_STOP) {
|
||||
rtems_semaphore_release(e->mutex);
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user