summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-02-17 16:37:09 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:41:51 -0800
commit3d6207d9466d462ae377d2f1cff0eefb3b74e21d (patch)
tree8fb372369d4fedacf395906b1db98f9e883fcd6c /drivers/i2c
parentf35f9094fee64871420b6a57cb1e859c30e79319 (diff)
i2c: tegra: suppporting clock enable always through platform data.
To make the response fast from i2c, providing the option to enable clock of i2c always through platform data. Original-Change-Id: I89c9156fc97f92a45ce72626ccd77920e02ca356 Reviewed-on: http://git-master/r/19880 Tested-by: Pradeep Goudagunta <pgoudagunta@nvidia.com> Reviewed-by: Ramachandrudu Kandhala <rkandhala@nvidia.com> Original-Change-Id: Ifaab9d7e052fb377abe27afdeb5c9cb4d19a6320 Rebase-Id: R15e2cfa9080024d9e2bbc8d966f5145766ee9e1a
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 27e7b341f512..5341cce41047 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -163,6 +163,7 @@ struct tegra_i2c_dev {
int last_mux_len;
unsigned long last_bus_clk_rate;
u16 slave_addr;
+ bool is_clkon_always;
struct tegra_i2c_bus busses[1];
};
@@ -382,7 +383,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
u32 val;
int err = 0;
- clk_enable(i2c_dev->clk);
+ if (!i2c_dev->is_clkon_always)
+ clk_enable(i2c_dev->clk);
tegra_periph_reset_assert(i2c_dev->clk);
udelay(2);
@@ -416,7 +418,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (tegra_i2c_flush_fifos(i2c_dev))
err = -ETIMEDOUT;
- clk_disable(i2c_dev->clk);
+ if (!i2c_dev->is_clkon_always)
+ clk_disable(i2c_dev->clk);
if (i2c_dev->irq_disabled) {
i2c_dev->irq_disabled = 0;
@@ -652,14 +655,16 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
i2c_dev->msgs = msgs;
i2c_dev->msgs_num = num;
- clk_enable(i2c_dev->clk);
+ if (!i2c_dev->is_clkon_always)
+ clk_enable(i2c_dev->clk);
for (i = 0; i < num; i++) {
int stop = (i == (num - 1)) ? 1 : 0;
ret = tegra_i2c_xfer_msg(i2c_bus, &msgs[i], stop);
if (ret)
break;
}
- clk_disable(i2c_dev->clk);
+ if (!i2c_dev->is_clkon_always)
+ clk_disable(i2c_dev->clk);
rt_mutex_unlock(&i2c_dev->dev_lock);
@@ -760,6 +765,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
i2c_dev->irq = irq;
i2c_dev->cont_id = pdev->id;
i2c_dev->dev = &pdev->dev;
+ i2c_dev->is_clkon_always = plat->is_clkon_always;
i2c_dev->last_bus_clk_rate = 100000; /* default clock rate */
if (pdata) {
@@ -786,6 +792,10 @@ static int tegra_i2c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, i2c_dev);
+ clk_enable(i2c_dev->i2c_clk);
+ if (i2c_dev->is_clkon_always)
+ clk_enable(i2c_dev->clk);
+
ret = tegra_i2c_init(i2c_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize i2c controller");
@@ -798,7 +808,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
goto err_free;
}
- clk_enable(i2c_dev->i2c_clk);
for (i = 0; i < nbus; i++) {
struct tegra_i2c_bus *i2c_bus = &i2c_dev->busses[i];
@@ -861,6 +870,9 @@ static int tegra_i2c_remove(struct platform_device *pdev)
while (i2c_dev->bus_count--)
i2c_del_adapter(&i2c_dev->busses[i2c_dev->bus_count].adapter);
+ if (i2c_dev->is_clkon_always)
+ clk_disable(i2c_dev->clk);
+
free_irq(i2c_dev->irq, i2c_dev);
clk_put(i2c_dev->i2c_clk);
clk_put(i2c_dev->clk);
@@ -878,7 +890,11 @@ static int tegra_i2c_suspend_noirq(struct device *dev)
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
rt_mutex_lock(&i2c_dev->dev_lock);
+
i2c_dev->is_suspended = true;
+ if (i2c_dev->is_clkon_always)
+ clk_disable(i2c_dev->clk);
+
rt_mutex_unlock(&i2c_dev->dev_lock);
return 0;
@@ -892,6 +908,9 @@ static int tegra_i2c_resume_noirq(struct device *dev)
rt_mutex_lock(&i2c_dev->dev_lock);
+ if (i2c_dev->is_clkon_always)
+ clk_enable(i2c_dev->clk);
+
ret = tegra_i2c_init(i2c_dev);
if (ret) {