@@ -718,6 +718,20 @@ static void stm32f7_i2c_smbus_reload(struct stm32f7_i2c_dev *i2c_dev)
718
718
writel_relaxed (cr2 , i2c_dev -> base + STM32F7_I2C_CR2 );
719
719
}
720
720
721
+ static int stm32f7_i2c_release_bus (struct i2c_adapter * i2c_adap )
722
+ {
723
+ struct stm32f7_i2c_dev * i2c_dev = i2c_get_adapdata (i2c_adap );
724
+
725
+ dev_info (i2c_dev -> dev , "Trying to recover bus\n" );
726
+
727
+ stm32f7_i2c_clr_bits (i2c_dev -> base + STM32F7_I2C_CR1 ,
728
+ STM32F7_I2C_CR1_PE );
729
+
730
+ stm32f7_i2c_hw_config (i2c_dev );
731
+
732
+ return 0 ;
733
+ }
734
+
721
735
static int stm32f7_i2c_wait_free_bus (struct stm32f7_i2c_dev * i2c_dev )
722
736
{
723
737
u32 status ;
@@ -727,12 +741,18 @@ static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev)
727
741
status ,
728
742
!(status & STM32F7_I2C_ISR_BUSY ),
729
743
10 , 1000 );
744
+ if (!ret )
745
+ return 0 ;
746
+
747
+ dev_info (i2c_dev -> dev , "bus busy\n" );
748
+
749
+ ret = stm32f7_i2c_release_bus (& i2c_dev -> adap );
730
750
if (ret ) {
731
- dev_dbg (i2c_dev -> dev , "bus busy \n" );
732
- ret = - EBUSY ;
751
+ dev_err (i2c_dev -> dev , "Failed to recover the bus (%d) \n" , ret );
752
+ return ret ;
733
753
}
734
754
735
- return ret ;
755
+ return - EBUSY ;
736
756
}
737
757
738
758
static void stm32f7_i2c_xfer_msg (struct stm32f7_i2c_dev * i2c_dev ,
@@ -1474,6 +1494,7 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
1474
1494
if (status & STM32F7_I2C_ISR_BERR ) {
1475
1495
dev_err (dev , "<%s>: Bus error\n" , __func__ );
1476
1496
writel_relaxed (STM32F7_I2C_ICR_BERRCF , base + STM32F7_I2C_ICR );
1497
+ stm32f7_i2c_release_bus (& i2c_dev -> adap );
1477
1498
f7_msg -> result = - EIO ;
1478
1499
}
1479
1500
0 commit comments