diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-26 18:28:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-11-26 18:28:34 -0500 |
commit | e348031214d5dce67be93271433b27a93cba5b3f (patch) | |
tree | d8c9a8d61ef041a8a6629b34a6f2ebc19264d410 | |
parent | a56f3eb2cd72d4d678a63cf8cacf9d39aa8020f3 (diff) | |
parent | 89119f08354b628548118cacd686a7700372ad19 (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.c | 64 |
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 | */ |
714 | static int | 695 | static int |
715 | i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | 696 | i2c_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 | ||
773 | done: | 769 | done: |
@@ -888,19 +884,9 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) | |||
888 | */ | 884 | */ |
889 | 885 | ||
890 | tx_aborted: | 886 | tx_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); |