diff options
author | Chaitanya Bandi <bandik@nvidia.com> | 2013-02-18 14:36:55 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 13:02:01 -0700 |
commit | bf3a1e02b9e5c87d57095da5e584c3c644c23c14 (patch) | |
tree | 86c48a16c046f42cb44f4f5d78f159b5204d537d /drivers/i2c | |
parent | 4c0f348e32d3be403f6947b6a2aea283629db03a (diff) |
i2c: tegra: Add cl_dvfs clock enabling for PWR_I2C
Added cl_dvfs clocks enabling for PWR_I2C in i2c
driver.
Bug 1234556
Change-Id: Ied62a1cfc3d8c296e9aa46f08c7f34d0ab9766e1
Signed-off-by: Chaitanya Bandi <bandik@nvidia.com>
Reviewed-on: http://git-master/r/201584
(cherry picked from commit 5ee5ac1624de959b8293242def231276c1d5d823)
Reviewed-on: http://git-master/r/206942
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Tested-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 324fbd397211..bf5c359cd1ab 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -181,6 +181,9 @@ struct tegra_i2c_dev { struct i2c_adapter adapter; struct clk *div_clk; struct clk *fast_clk; + bool needs_cl_dvfs_clock; + struct clk *dvfs_ref_clk; + struct clk *dvfs_soc_clk; spinlock_t fifo_lock; void __iomem *base; int cont_id; @@ -459,20 +462,46 @@ static void tegra_i2c_slave_init(struct tegra_i2c_dev *i2c_dev) static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev) { int ret; + + if (i2c_dev->needs_cl_dvfs_clock) { + ret = clk_prepare_enable(i2c_dev->dvfs_soc_clk); + if (ret < 0) { + dev_err(i2c_dev->dev, + "Error in enabling dvfs soc clock %d\n", ret); + return ret; + } + ret = clk_prepare_enable(i2c_dev->dvfs_ref_clk); + if (ret < 0) { + dev_err(i2c_dev->dev, + "Error in enabling dvfs ref clock %d\n", ret); + goto ref_clk_err; + } + } if (i2c_dev->chipdata->has_fast_clock) { ret = clk_prepare_enable(i2c_dev->fast_clk); if (ret < 0) { dev_err(i2c_dev->dev, "Enabling fast clk failed, err %d\n", ret); - return ret; + goto fast_clk_err; } } ret = clk_prepare_enable(i2c_dev->div_clk); if (ret < 0) { dev_err(i2c_dev->dev, "Enabling div clk failed, err %d\n", ret); - clk_disable_unprepare(i2c_dev->fast_clk); + goto div_clk_err; } + return 0; + +div_clk_err: + if (i2c_dev->chipdata->has_fast_clock) + clk_disable_unprepare(i2c_dev->fast_clk); +fast_clk_err: + if (i2c_dev->needs_cl_dvfs_clock) + clk_disable_unprepare(i2c_dev->dvfs_ref_clk); +ref_clk_err: + if (i2c_dev->needs_cl_dvfs_clock) + clk_disable_unprepare(i2c_dev->dvfs_soc_clk); return ret; } @@ -481,6 +510,10 @@ static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev) clk_disable_unprepare(i2c_dev->div_clk); if (i2c_dev->chipdata->has_fast_clock) clk_disable_unprepare(i2c_dev->fast_clk); + if (i2c_dev->needs_cl_dvfs_clock) { + clk_disable_unprepare(i2c_dev->dvfs_soc_clk); + clk_disable_unprepare(i2c_dev->dvfs_ref_clk); + } } static void tegra_i2c_set_clk_rate(struct tegra_i2c_dev *i2c_dev) @@ -1171,6 +1204,8 @@ static int tegra_i2c_probe(struct platform_device *pdev) struct resource *res; struct clk *div_clk; struct clk *fast_clk = NULL; + struct clk *dvfs_ref_clk = NULL; + struct clk *dvfs_soc_clk = NULL; void __iomem *base; int irq; int ret = 0; @@ -1224,6 +1259,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) } i2c_dev->chipdata = chip_data; + i2c_dev->needs_cl_dvfs_clock = pdata->needs_cl_dvfs_clock; div_clk = devm_clk_get(&pdev->dev, "div-clk"); if (IS_ERR(div_clk)) { @@ -1239,6 +1275,21 @@ static int tegra_i2c_probe(struct platform_device *pdev) } } + if (i2c_dev->needs_cl_dvfs_clock) { + dvfs_ref_clk = devm_clk_get(&pdev->dev, "cl_dvfs_ref"); + if (IS_ERR(dvfs_ref_clk)) { + dev_err(&pdev->dev, "missing cl_dvfs_ref clock"); + return PTR_ERR(dvfs_ref_clk); + } + i2c_dev->dvfs_ref_clk = dvfs_ref_clk; + dvfs_soc_clk = devm_clk_get(&pdev->dev, "cl_dvfs_soc"); + if (IS_ERR(dvfs_soc_clk)) { + dev_err(&pdev->dev, "missing cl_dvfs_soc clock"); + return PTR_ERR(dvfs_soc_clk); + } + i2c_dev->dvfs_soc_clk = dvfs_soc_clk; + } + i2c_dev->base = base; i2c_dev->div_clk = div_clk; if (i2c_dev->chipdata->has_fast_clock) |