Skip to content

Commit b31cd46

Browse files
committed
Merge branch 'at91-5.10-trunk/i2c' into linux-5.10-at91
2 parents 201b4ff + 38f0f95 commit b31cd46

2 files changed

Lines changed: 44 additions & 10 deletions

File tree

drivers/i2c/busses/i2c-at91-core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ static struct at91_twi_pdata sama5d4_config = {
120120
.clk_offset = 4,
121121
.has_hold_field = true,
122122
.has_dig_filtr = true,
123+
.has_adv_dig_filtr = true,
123124
};
124125

125126
static struct at91_twi_pdata sama5d2_config = {

drivers/i2c/busses/i2c-at91-master.c

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev)
3838
/* FIFO should be enabled immediately after the software reset */
3939
if (dev->fifo_size)
4040
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_FIFOEN);
41-
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);
41+
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSDIS);
4242
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS);
4343
at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
4444

@@ -593,7 +593,6 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
593593
if (time_left == 0) {
594594
dev->transfer_status |= at91_twi_read(dev, AT91_TWI_SR);
595595
dev_err(dev->dev, "controller timed out\n");
596-
at91_init_twi_bus(dev);
597596
ret = -ETIMEDOUT;
598597
goto error;
599598
}
@@ -639,16 +638,29 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
639638
AT91_TWI_THRCLR | AT91_TWI_LOCKCLR);
640639
}
641640

642-
/*
643-
* some faulty I2C slave devices might hold SDA down;
644-
* we can send a bus clear command, hoping that the pins will be
645-
* released
646-
*/
647-
i2c_recover_bus(&dev->adapter);
648-
649641
return ret;
650642
}
651643

644+
static void at91_twi_disable(struct at91_twi_dev *dev)
645+
{
646+
/* return if previous operation is completed */
647+
if (!(at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_TXCOMP)) {
648+
/* wait for previous command to complete before disabling the controller */
649+
dev_dbg(dev->dev, "wait for command to complete...\n");
650+
reinit_completion(&dev->cmd_complete);
651+
dev->transfer_status = 0;
652+
at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
653+
wait_for_completion_timeout(&dev->cmd_complete, dev->adapter.timeout);
654+
if (!(dev->transfer_status & AT91_TWI_TXCOMP)) {
655+
dev_dbg(dev->dev, "IP still busy, resetting the controller...\n");
656+
at91_init_twi_bus(dev);
657+
return;
658+
}
659+
}
660+
661+
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSDIS);
662+
}
663+
652664
static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
653665
{
654666
struct at91_twi_dev *dev = i2c_get_adapdata(adap);
@@ -663,6 +675,8 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
663675
if (ret < 0)
664676
goto out;
665677

678+
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);
679+
666680
if (num == 2) {
667681
int internal_address = 0;
668682
int i;
@@ -705,7 +719,26 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
705719

706720
ret = at91_do_twi_transfer(dev);
707721

708-
ret = (ret < 0) ? ret : num;
722+
if (ret < 0) {
723+
/* disable controller before using GPIO recovery */
724+
if (!dev->pdata->has_clear_cmd)
725+
at91_twi_disable(dev);
726+
727+
/*
728+
* some faulty I2C slave devices might hold SDA down;
729+
* we can send a bus clear command, hoping that the pins will be
730+
* released
731+
*/
732+
i2c_recover_bus(&dev->adapter);
733+
734+
/* disable controller if not disabled before */
735+
if (dev->pdata->has_clear_cmd)
736+
at91_twi_disable(dev);
737+
} else {
738+
at91_twi_disable(dev);
739+
ret = num;
740+
}
741+
709742
out:
710743
pm_runtime_mark_last_busy(dev->dev);
711744
pm_runtime_put_autosuspend(dev->dev);

0 commit comments

Comments
 (0)