@@ -182,6 +182,7 @@ static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
{
u8 stat;
+ u64 mode;
/*
* This is ugly... in HLC mode the status is not in the status register
@@ -244,6 +245,13 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
case STAT_RXADDR_NAK:
case STAT_AD2W_NAK:
return -ENXIO;
+
+ case STAT_WDOG_TOUT:
+ mode = __raw_readq(i2c->twsi_base + MODE(i2c));
+ /* Set BUS_MON_RST to reset bus monitor */
+ mode |= BUS_MON_RST_MASK;
+ octeon_i2c_writeq_flush(mode, i2c->twsi_base + MODE(i2c));
+ return -EIO;
default:
dev_err(i2c->dev, "unhandled state: %d\n", stat);
return -EIO;
@@ -72,6 +72,7 @@
#define STAT_SLAVE_ACK 0xC8
#define STAT_AD2W_ACK 0xD0
#define STAT_AD2W_NAK 0xD8
+#define STAT_WDOG_TOUT 0xF0
#define STAT_IDLE 0xF8
/* TWSI_INT values */
@@ -104,6 +105,9 @@ struct octeon_i2c_reg_offset {
/* Set REFCLK_SRC and HS_MODE in TWSX_MODE register */
#define TWSX_MODE_HS_MASK (BIT(4) | BIT(0))
+/* Set BUS_MON_RST to reset bus monitor */
+#define BUS_MON_RST_MASK BIT(3)
+
struct octeon_i2c {
wait_queue_head_t queue;
struct i2c_adapter adap;