Skip to content

Commit ab386c4

Browse files
committed
Merge branch 'i2c/for-current-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Three driver bugfixes, and two reverts because the original patches revealed underlying problems which the Tegra guys are now working on" * 'i2c/for-current-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: aspeed: Avoid i2c interrupt status clear race condition. i2c: amd-mp2-pci: Fix Oops in amd_mp2_pci_init() error handling Revert "i2c: tegra: Better handle case where CPU0 is busy for a long time" Revert "i2c: tegra: Synchronize DMA before termination" i2c: iproc: generate stop event for slave writes
2 parents c536419 + c926c87 commit ab386c4

File tree

4 files changed

+20
-26
lines changed

4 files changed

+20
-26
lines changed

drivers/i2c/busses/i2c-amd-mp2-pci.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,12 @@ static int amd_mp2_pci_probe(struct pci_dev *pci_dev,
349349
if (!privdata)
350350
return -ENOMEM;
351351

352+
privdata->pci_dev = pci_dev;
352353
rc = amd_mp2_pci_init(privdata, pci_dev);
353354
if (rc)
354355
return rc;
355356

356357
mutex_init(&privdata->c2p_lock);
357-
privdata->pci_dev = pci_dev;
358358

359359
pm_runtime_set_autosuspend_delay(&pci_dev->dev, 1000);
360360
pm_runtime_use_autosuspend(&pci_dev->dev);

drivers/i2c/busses/i2c-aspeed.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
603603
/* Ack all interrupts except for Rx done */
604604
writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE,
605605
bus->base + ASPEED_I2C_INTR_STS_REG);
606+
readl(bus->base + ASPEED_I2C_INTR_STS_REG);
606607
irq_remaining = irq_received;
607608

608609
#if IS_ENABLED(CONFIG_I2C_SLAVE)
@@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
645646
irq_received, irq_handled);
646647

647648
/* Ack Rx done */
648-
if (irq_received & ASPEED_I2CD_INTR_RX_DONE)
649+
if (irq_received & ASPEED_I2CD_INTR_RX_DONE) {
649650
writel(ASPEED_I2CD_INTR_RX_DONE,
650651
bus->base + ASPEED_I2C_INTR_STS_REG);
652+
readl(bus->base + ASPEED_I2C_INTR_STS_REG);
653+
}
651654
spin_unlock(&bus->lock);
652655
return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
653656
}

drivers/i2c/busses/i2c-bcm-iproc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,9 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c,
360360
value = (u8)((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK);
361361
i2c_slave_event(iproc_i2c->slave,
362362
I2C_SLAVE_WRITE_RECEIVED, &value);
363+
if (rx_status == I2C_SLAVE_RX_END)
364+
i2c_slave_event(iproc_i2c->slave,
365+
I2C_SLAVE_STOP, &value);
363366
}
364367
} else if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) {
365368
/* Master read other than start */

drivers/i2c/busses/i2c-tegra.c

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -996,13 +996,14 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
996996
do {
997997
u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
998998

999-
if (status)
999+
if (status) {
10001000
tegra_i2c_isr(i2c_dev->irq, i2c_dev);
10011001

1002-
if (completion_done(complete)) {
1003-
s64 delta = ktime_ms_delta(ktimeout, ktime);
1002+
if (completion_done(complete)) {
1003+
s64 delta = ktime_ms_delta(ktimeout, ktime);
10041004

1005-
return msecs_to_jiffies(delta) ?: 1;
1005+
return msecs_to_jiffies(delta) ?: 1;
1006+
}
10061007
}
10071008

10081009
ktime = ktime_get();
@@ -1029,18 +1030,14 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
10291030
disable_irq(i2c_dev->irq);
10301031

10311032
/*
1032-
* Under some rare circumstances (like running KASAN +
1033-
* NFS root) CPU, which handles interrupt, may stuck in
1034-
* uninterruptible state for a significant time. In this
1035-
* case we will get timeout if I2C transfer is running on
1036-
* a sibling CPU, despite of IRQ being raised.
1037-
*
1038-
* In order to handle this rare condition, the IRQ status
1039-
* needs to be checked after timeout.
1033+
* There is a chance that completion may happen after IRQ
1034+
* synchronization, which is done by disable_irq().
10401035
*/
1041-
if (ret == 0)
1042-
ret = tegra_i2c_poll_completion_timeout(i2c_dev,
1043-
complete, 0);
1036+
if (ret == 0 && completion_done(complete)) {
1037+
dev_warn(i2c_dev->dev,
1038+
"completion done after timeout\n");
1039+
ret = 1;
1040+
}
10441041
}
10451042

10461043
return ret;
@@ -1219,15 +1216,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
12191216
time_left = tegra_i2c_wait_completion_timeout(
12201217
i2c_dev, &i2c_dev->dma_complete, xfer_time);
12211218

1222-
/*
1223-
* Synchronize DMA first, since dmaengine_terminate_sync()
1224-
* performs synchronization after the transfer's termination
1225-
* and we want to get a completion if transfer succeeded.
1226-
*/
1227-
dmaengine_synchronize(i2c_dev->msg_read ?
1228-
i2c_dev->rx_dma_chan :
1229-
i2c_dev->tx_dma_chan);
1230-
12311219
dmaengine_terminate_sync(i2c_dev->msg_read ?
12321220
i2c_dev->rx_dma_chan :
12331221
i2c_dev->tx_dma_chan);

0 commit comments

Comments
 (0)