Messages in this thread Patch in this message | | | From | mike.isely@cobaltdi ... | Subject | [PATCH 1/2] [i2c-bcm2835] Fully clean up hardware state machine after a timeout | Date | Mon, 30 Oct 2023 11:21:13 -0500 |
| |
From: Mike Isely <mike.isely@cobaltdigital.com>
When the driver detects a timeout, there's no guarantee that the ISR would have fired. Thus after a timeout, it's the foreground that becomes responsible to reset the hardware state machine. The change here just duplicates what is already implemented in the ISR.
Signed-off-by: Mike Isely <isely@pobox.com> --- drivers/i2c/busses/i2c-bcm2835.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index 8ce6d3f49551..96de875394e1 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c @@ -345,42 +345,46 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); unsigned long time_left; int i; for (i = 0; i < (num - 1); i++) if (msgs[i].flags & I2C_M_RD) { dev_warn_once(i2c_dev->dev, "only one read message supported, has to be last\n"); return -EOPNOTSUPP; } i2c_dev->curr_msg = msgs; i2c_dev->num_msgs = num; reinit_completion(&i2c_dev->completion); bcm2835_i2c_start_transfer(i2c_dev); time_left = wait_for_completion_timeout(&i2c_dev->completion, adap->timeout); bcm2835_i2c_finish_transfer(i2c_dev); if (!time_left) { + /* Since we can't trust the ISR to have cleaned up, do the + * full cleanup here... */ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); + bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, BCM2835_I2C_S_CLKT | + BCM2835_I2C_S_ERR | BCM2835_I2C_S_DONE); dev_err(i2c_dev->dev, "i2c transfer timed out\n"); return -ETIMEDOUT; } if (!i2c_dev->msg_err) return num; dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) return -EREMOTEIO; return -EIO; } -- 2.39.2
| |