diff options
author | Jarkko Nikula <jarkko.nikula@linux.intel.com> | 2017-02-13 04:18:19 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2017-02-14 16:10:26 -0500 |
commit | 12688dc21f71f4dcc9e2b8b5556b0c6cc8df1491 (patch) | |
tree | 386cd553531c6273bbcc0bdb672c671877c3ad4d | |
parent | 7089db84e356562f8ba737c29e472cc42d530dbc (diff) |
Revert "i2c: designware: detect when dynamic tar update is possible"
This reverts commit 63d0f0a6952a1a02bc4f116b7da7c7887e46efa3.
It caused a regression on platforms where I2C controller is synthesized
with dynamic TAR update disabled. Detection code is testing is bit
DW_IC_CON_10BITADDR_MASTER in register DW_IC_CON read-only but fails to
restore original value in case bit is read-write.
Instead of fixing this we revert the commit since it was preparation for
the commit 0317e6c0f1dc ("i2c: designware: do not disable adapter after
transfer") which was also reverted.
Reported-by: Shah Nehal-Bakulchandra <Nehal-bakulchandra.Shah@amd.com>
Reported-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Acked-By: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: <stable@vger.kernel.org> # v4.9+
Fixes: 63d0f0a6952a ("i2c: designware: detect when dynamic tar update is possible")
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 45 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.h | 1 |
2 files changed, 11 insertions, 35 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 6d81c56184d3..e9db857c6226 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -475,30 +475,28 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) | |||
475 | static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) | 475 | static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) |
476 | { | 476 | { |
477 | struct i2c_msg *msgs = dev->msgs; | 477 | struct i2c_msg *msgs = dev->msgs; |
478 | u32 ic_tar = 0; | 478 | u32 ic_con, ic_tar = 0; |
479 | 479 | ||
480 | /* Disable the adapter */ | 480 | /* Disable the adapter */ |
481 | __i2c_dw_enable_and_wait(dev, false); | 481 | __i2c_dw_enable_and_wait(dev, false); |
482 | 482 | ||
483 | /* if the slave address is ten bit address, enable 10BITADDR */ | 483 | /* if the slave address is ten bit address, enable 10BITADDR */ |
484 | if (dev->dynamic_tar_update_enabled) { | 484 | ic_con = dw_readl(dev, DW_IC_CON); |
485 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { | ||
486 | ic_con |= DW_IC_CON_10BITADDR_MASTER; | ||
485 | /* | 487 | /* |
486 | * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing | 488 | * If I2C_DYNAMIC_TAR_UPDATE is set, the 10-bit addressing |
487 | * mode has to be enabled via bit 12 of IC_TAR register, | 489 | * mode has to be enabled via bit 12 of IC_TAR register. |
488 | * otherwise bit 4 of IC_CON is used. | 490 | * We set it always as I2C_DYNAMIC_TAR_UPDATE can't be |
491 | * detected from registers. | ||
489 | */ | 492 | */ |
490 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) | 493 | ic_tar = DW_IC_TAR_10BITADDR_MASTER; |
491 | ic_tar = DW_IC_TAR_10BITADDR_MASTER; | ||
492 | } else { | 494 | } else { |
493 | u32 ic_con = dw_readl(dev, DW_IC_CON); | 495 | ic_con &= ~DW_IC_CON_10BITADDR_MASTER; |
494 | |||
495 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) | ||
496 | ic_con |= DW_IC_CON_10BITADDR_MASTER; | ||
497 | else | ||
498 | ic_con &= ~DW_IC_CON_10BITADDR_MASTER; | ||
499 | dw_writel(dev, ic_con, DW_IC_CON); | ||
500 | } | 496 | } |
501 | 497 | ||
498 | dw_writel(dev, ic_con, DW_IC_CON); | ||
499 | |||
502 | /* | 500 | /* |
503 | * Set the slave (target) address and enable 10-bit addressing mode | 501 | * Set the slave (target) address and enable 10-bit addressing mode |
504 | * if applicable. | 502 | * if applicable. |
@@ -963,7 +961,6 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) | |||
963 | { | 961 | { |
964 | struct i2c_adapter *adap = &dev->adapter; | 962 | struct i2c_adapter *adap = &dev->adapter; |
965 | int r; | 963 | int r; |
966 | u32 reg; | ||
967 | 964 | ||
968 | init_completion(&dev->cmd_complete); | 965 | init_completion(&dev->cmd_complete); |
969 | 966 | ||
@@ -971,26 +968,6 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) | |||
971 | if (r) | 968 | if (r) |
972 | return r; | 969 | return r; |
973 | 970 | ||
974 | r = i2c_dw_acquire_lock(dev); | ||
975 | if (r) | ||
976 | return r; | ||
977 | |||
978 | /* | ||
979 | * Test if dynamic TAR update is enabled in this controller by writing | ||
980 | * to IC_10BITADDR_MASTER field in IC_CON: when it is enabled this | ||
981 | * field is read-only so it should not succeed | ||
982 | */ | ||
983 | reg = dw_readl(dev, DW_IC_CON); | ||
984 | dw_writel(dev, reg ^ DW_IC_CON_10BITADDR_MASTER, DW_IC_CON); | ||
985 | |||
986 | if ((dw_readl(dev, DW_IC_CON) & DW_IC_CON_10BITADDR_MASTER) == | ||
987 | (reg & DW_IC_CON_10BITADDR_MASTER)) { | ||
988 | dev->dynamic_tar_update_enabled = true; | ||
989 | dev_dbg(dev->dev, "Dynamic TAR update enabled"); | ||
990 | } | ||
991 | |||
992 | i2c_dw_release_lock(dev); | ||
993 | |||
994 | snprintf(adap->name, sizeof(adap->name), | 971 | snprintf(adap->name, sizeof(adap->name), |
995 | "Synopsys DesignWare I2C adapter"); | 972 | "Synopsys DesignWare I2C adapter"); |
996 | adap->retries = 3; | 973 | adap->retries = 3; |
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 26250b425e2f..c1db3a5a340f 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h | |||
@@ -125,7 +125,6 @@ struct dw_i2c_dev { | |||
125 | int (*acquire_lock)(struct dw_i2c_dev *dev); | 125 | int (*acquire_lock)(struct dw_i2c_dev *dev); |
126 | void (*release_lock)(struct dw_i2c_dev *dev); | 126 | void (*release_lock)(struct dw_i2c_dev *dev); |
127 | bool pm_runtime_disabled; | 127 | bool pm_runtime_disabled; |
128 | bool dynamic_tar_update_enabled; | ||
129 | }; | 128 | }; |
130 | 129 | ||
131 | #define ACCESS_SWAP 0x00000001 | 130 | #define ACCESS_SWAP 0x00000001 |