Skip to content

Commit b011810

Browse files
warp5twAndi Shyti
authored andcommitted
i2c: npcm: use a software flag to indicate a BER condition
If not clearing the BB (bus busy) condition in the BER (bus error) interrupt, the driver causes a timeout and hence the i2c core doesn't do the i2c transfer retry but returns the driver's return value to the upper layer instead. Clear the BB condition in the BER interrupt and a software flag is used. The driver does an i2c recovery without causing the timeout if the flag is set. Signed-off-by: Tyrone Ting <[email protected]> Reviewed-by: Tali Perry <[email protected]> Signed-off-by: Andi Shyti <[email protected]>
1 parent e365422 commit b011810

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

drivers/i2c/busses/i2c-npcm7xx.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ struct npcm_i2c {
334334
u64 nack_cnt;
335335
u64 timeout_cnt;
336336
u64 tx_complete_cnt;
337+
bool ber_state; /* Indicate the bus error state */
337338
};
338339

339340
static inline void npcm_i2c_select_bank(struct npcm_i2c *bus,
@@ -1521,6 +1522,7 @@ static void npcm_i2c_irq_handle_ber(struct npcm_i2c *bus)
15211522
if (npcm_i2c_is_master(bus)) {
15221523
npcm_i2c_master_abort(bus);
15231524
} else {
1525+
bus->ber_state = true;
15241526
npcm_i2c_clear_master_status(bus);
15251527

15261528
/* Clear BB (BUS BUSY) bit */
@@ -1699,6 +1701,7 @@ static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap)
16991701
dev_dbg(bus->dev, "bus%d-0x%x recovery skipped, bus not stuck",
17001702
bus->num, bus->dest_addr);
17011703
npcm_i2c_reset(bus);
1704+
bus->ber_state = false;
17021705
return 0;
17031706
}
17041707

@@ -1763,6 +1766,7 @@ static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap)
17631766
if (bus->rec_succ_cnt < ULLONG_MAX)
17641767
bus->rec_succ_cnt++;
17651768
}
1769+
bus->ber_state = false;
17661770
return status;
17671771
}
17681772

@@ -2158,7 +2162,16 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
21582162

21592163
} while (time_is_after_jiffies(time_left) && bus_busy);
21602164

2161-
if (bus_busy) {
2165+
/*
2166+
* Check the BER (bus error) state, when ber_state is true, it means that the module
2167+
* detects the bus error which is caused by some factor like that the electricity
2168+
* noise occurs on the bus. Under this condition, the module is reset and the bus
2169+
* gets recovered.
2170+
*
2171+
* While ber_state is false, the module reset and bus recovery also get done as the
2172+
* bus is busy.
2173+
*/
2174+
if (bus_busy || bus->ber_state) {
21622175
iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
21632176
npcm_i2c_reset(bus);
21642177
i2c_recover_bus(adap);

0 commit comments

Comments
 (0)