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