diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2011-02-17 16:37:09 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:41:51 -0800 |
commit | 3d6207d9466d462ae377d2f1cff0eefb3b74e21d (patch) | |
tree | 8fb372369d4fedacf395906b1db98f9e883fcd6c /drivers/i2c | |
parent | f35f9094fee64871420b6a57cb1e859c30e79319 (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.c | 29 |
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) { |