Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c fixes from Wolfram Sang:
"Here is a revert and two bugfixes for the I2C designware driver.

Please note that we are still hunting down a regression for the
i2c-octeon driver. While there is a fix pending, we have unclear
feedback from the testers currently. An rc8 would be quite helpful
for this case"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
Revert "i2c: designware: do not disable adapter after transfer"
i2c: designware: fix rx fifo depth tracking
i2c: designware: report short transfers

+25 -39
+25 -39
drivers/i2c/busses/i2c-designware-core.c
··· 91 91 DW_IC_INTR_TX_ABRT | \ 92 92 DW_IC_INTR_STOP_DET) 93 93 94 - #define DW_IC_STATUS_ACTIVITY 0x1 95 - #define DW_IC_STATUS_TFE BIT(2) 96 - #define DW_IC_STATUS_MST_ACTIVITY BIT(5) 94 + #define DW_IC_STATUS_ACTIVITY 0x1 97 95 98 96 #define DW_IC_SDA_HOLD_RX_SHIFT 16 99 97 #define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, DW_IC_SDA_HOLD_RX_SHIFT) ··· 476 478 { 477 479 struct i2c_msg *msgs = dev->msgs; 478 480 u32 ic_tar = 0; 479 - bool enabled; 480 481 481 - enabled = dw_readl(dev, DW_IC_ENABLE_STATUS) & 1; 482 - 483 - if (enabled) { 484 - u32 ic_status; 485 - 486 - /* 487 - * Only disable adapter if ic_tar and ic_con can't be 488 - * dynamically updated 489 - */ 490 - ic_status = dw_readl(dev, DW_IC_STATUS); 491 - if (!dev->dynamic_tar_update_enabled || 492 - (ic_status & DW_IC_STATUS_MST_ACTIVITY) || 493 - !(ic_status & DW_IC_STATUS_TFE)) { 494 - __i2c_dw_enable_and_wait(dev, false); 495 - enabled = false; 496 - } 497 - } 482 + /* Disable the adapter */ 483 + __i2c_dw_enable_and_wait(dev, false); 498 484 499 485 /* if the slave address is ten bit address, enable 10BITADDR */ 500 486 if (dev->dynamic_tar_update_enabled) { ··· 508 526 /* enforce disabled interrupts (due to HW issues) */ 509 527 i2c_dw_disable_int(dev); 510 528 511 - if (!enabled) 512 - __i2c_dw_enable(dev, true); 529 + /* Enable the adapter */ 530 + __i2c_dw_enable(dev, true); 513 531 514 532 /* Clear and enable interrupts */ 515 533 dw_readl(dev, DW_IC_CLR_INTR); ··· 593 611 if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { 594 612 595 613 /* avoid rx buffer overrun */ 596 - if (rx_limit - dev->rx_outstanding <= 0) 614 + if (dev->rx_outstanding >= dev->rx_fifo_depth) 597 615 break; 598 616 599 617 dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD); ··· 690 708 } 691 709 692 710 /* 693 - * Prepare controller for a transaction and start transfer by calling 694 - * i2c_dw_xfer_init() 711 + * Prepare controller for a transaction and call i2c_dw_xfer_msg 695 712 */ 696 713 static int 697 714 i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ··· 733 752 goto done; 734 753 } 735 754 755 + /* 756 + * We must disable the adapter before returning and signaling the end 757 + * of the current transfer. Otherwise the hardware might continue 758 + * generating interrupts which in turn causes a race condition with 759 + * the following transfer. Needs some more investigation if the 760 + * additional interrupts are a hardware bug or this driver doesn't 761 + * handle them correctly yet. 762 + */ 763 + __i2c_dw_enable(dev, false); 764 + 736 765 if (dev->msg_err) { 737 766 ret = dev->msg_err; 738 767 goto done; 739 768 } 740 769 741 770 /* no error */ 742 - if (likely(!dev->cmd_err)) { 771 + if (likely(!dev->cmd_err && !dev->status)) { 743 772 ret = num; 744 773 goto done; 745 774 } ··· 759 768 ret = i2c_dw_handle_tx_abort(dev); 760 769 goto done; 761 770 } 771 + 772 + if (dev->status) 773 + dev_err(dev->dev, 774 + "transfer terminated early - interrupt latency too high?\n"); 775 + 762 776 ret = -EIO; 763 777 764 778 done: ··· 884 888 */ 885 889 886 890 tx_aborted: 887 - if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) 888 - || dev->msg_err) { 889 - /* 890 - * We must disable interruts before returning and signaling 891 - * the end of the current transfer. Otherwise the hardware 892 - * might continue generating interrupts for non-existent 893 - * transfers. 894 - */ 895 - i2c_dw_disable_int(dev); 896 - dw_readl(dev, DW_IC_CLR_INTR); 897 - 891 + if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) 898 892 complete(&dev->cmd_complete); 899 - } else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) { 893 + else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) { 900 894 /* workaround to trigger pending interrupt */ 901 895 stat = dw_readl(dev, DW_IC_INTR_MASK); 902 896 i2c_dw_disable_int(dev);