aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShardar Shariff Md <smohammed@nvidia.com>2016-08-31 09:28:40 -0400
committerWolfram Sang <wsa@the-dreams.de>2016-09-08 16:32:46 -0400
commit685143a1598b36227250f6c0a90ec234218f58ff (patch)
tree2e1a6dd0ff908afe3b773e0fa542947a6d67a230
parent17f80487f653dfcc6cc3a8b64891442dc4182f62 (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.c23
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