diff options
author | Shardar Shariff Md <smohammed@nvidia.com> | 2016-08-31 09:28:40 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2016-09-08 16:32:46 -0400 |
commit | 685143a1598b36227250f6c0a90ec234218f58ff (patch) | |
tree | 2e1a6dd0ff908afe3b773e0fa542947a6d67a230 | |
parent | 17f80487f653dfcc6cc3a8b64891442dc4182f62 (diff) |
i2c: tegra: use readl_poll_timeout after config_load reg programmed
After CONFIG_LOAD register is programmed instead of explicitly waiting
for timeout, use readl_poll_timeout() to check for register value to get
updated or wait till timeout.
Signed-off-by: Shardar Shariff Md <smohammed@nvidia.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index d86a993b75d6..e93c72aec555 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/reset.h> | 30 | #include <linux/reset.h> |
31 | #include <linux/pinctrl/consumer.h> | 31 | #include <linux/pinctrl/consumer.h> |
32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
33 | #include <linux/iopoll.h> | ||
33 | 34 | ||
34 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
35 | 36 | ||
@@ -112,6 +113,8 @@ | |||
112 | #define I2C_CLKEN_OVERRIDE 0x090 | 113 | #define I2C_CLKEN_OVERRIDE 0x090 |
113 | #define I2C_MST_CORE_CLKEN_OVR BIT(0) | 114 | #define I2C_MST_CORE_CLKEN_OVR BIT(0) |
114 | 115 | ||
116 | #define I2C_CONFIG_LOAD_TIMEOUT 1000000 | ||
117 | |||
115 | /* | 118 | /* |
116 | * msg_end_type: The bus control which need to be send at end of transfer. | 119 | * msg_end_type: The bus control which need to be send at end of transfer. |
117 | * @MSG_END_STOP: Send stop pulse at end of transfer. | 120 | * @MSG_END_STOP: Send stop pulse at end of transfer. |
@@ -448,7 +451,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) | |||
448 | u32 val; | 451 | u32 val; |
449 | int err; | 452 | int err; |
450 | u32 clk_divisor; | 453 | u32 clk_divisor; |
451 | unsigned long timeout = jiffies + HZ; | ||
452 | 454 | ||
453 | err = pm_runtime_get_sync(i2c_dev->dev); | 455 | err = pm_runtime_get_sync(i2c_dev->dev); |
454 | if (err < 0) { | 456 | if (err < 0) { |
@@ -497,15 +499,18 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) | |||
497 | i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE); | 499 | i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE); |
498 | 500 | ||
499 | if (i2c_dev->hw->has_config_load_reg) { | 501 | if (i2c_dev->hw->has_config_load_reg) { |
502 | unsigned long reg_offset; | ||
503 | void __iomem *addr; | ||
504 | |||
505 | reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_CONFIG_LOAD); | ||
506 | addr = i2c_dev->base + reg_offset; | ||
500 | i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD); | 507 | i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD); |
501 | while (i2c_readl(i2c_dev, I2C_CONFIG_LOAD) != 0) { | 508 | err = readl_poll_timeout(addr, val, val == 0, 1000, |
502 | if (time_after(jiffies, timeout)) { | 509 | I2C_CONFIG_LOAD_TIMEOUT); |
503 | dev_warn(i2c_dev->dev, | 510 | if (err) { |
504 | "timeout waiting for config load\n"); | 511 | dev_warn(i2c_dev->dev, |
505 | err = -ETIMEDOUT; | 512 | "timeout waiting for config load\n"); |
506 | goto err; | 513 | goto err; |
507 | } | ||
508 | msleep(1); | ||
509 | } | 514 | } |
510 | } | 515 | } |
511 | 516 | ||