summaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-tegra.c
diff options
context:
space:
mode:
authorRohith Seelaboyina <rseelaboyina@nvidia.com>2016-06-22 07:47:19 -0400
committerThierry Reding <thierry.reding@gmail.com>2016-07-11 06:49:31 -0400
commit5dfbd2bd5439f1ada5ddaa3883e9e038de5d2abe (patch)
tree2a7d98e034a4e9d7f1194ad9f379de6597b44d0c /drivers/pwm/pwm-tegra.c
parent4f57f5a01fcb4ec9d98e274837c0cd853d447da3 (diff)
pwm: tegra: Add support for reset control
Add reset control of the PWM controller to reset it before accessing the PWM register. Signed-off-by: Rohith Seelaboyina <rseelaboyina@nvidia.com> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm/pwm-tegra.c')
-rw-r--r--drivers/pwm/pwm-tegra.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 3cbb32d8064f..097658e0751b 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -29,6 +29,7 @@
29#include <linux/pwm.h> 29#include <linux/pwm.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/reset.h>
32 33
33#define PWM_ENABLE (1 << 31) 34#define PWM_ENABLE (1 << 31)
34#define PWM_DUTY_WIDTH 8 35#define PWM_DUTY_WIDTH 8
@@ -41,6 +42,7 @@ struct tegra_pwm_chip {
41 struct device *dev; 42 struct device *dev;
42 43
43 struct clk *clk; 44 struct clk *clk;
45 struct reset_control*rst;
44 46
45 void __iomem *regs; 47 void __iomem *regs;
46}; 48};
@@ -187,6 +189,15 @@ static int tegra_pwm_probe(struct platform_device *pdev)
187 if (IS_ERR(pwm->clk)) 189 if (IS_ERR(pwm->clk))
188 return PTR_ERR(pwm->clk); 190 return PTR_ERR(pwm->clk);
189 191
192 pwm->rst = devm_reset_control_get(&pdev->dev, "pwm");
193 if (IS_ERR(pwm->rst)) {
194 ret = PTR_ERR(pwm->rst);
195 dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
196 return ret;
197 }
198
199 reset_control_deassert(pwm->rst);
200
190 pwm->chip.dev = &pdev->dev; 201 pwm->chip.dev = &pdev->dev;
191 pwm->chip.ops = &tegra_pwm_ops; 202 pwm->chip.ops = &tegra_pwm_ops;
192 pwm->chip.base = -1; 203 pwm->chip.base = -1;
@@ -195,6 +206,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
195 ret = pwmchip_add(&pwm->chip); 206 ret = pwmchip_add(&pwm->chip);
196 if (ret < 0) { 207 if (ret < 0) {
197 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); 208 dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
209 reset_control_assert(pwm->rst);
198 return ret; 210 return ret;
199 } 211 }
200 212
@@ -205,10 +217,15 @@ static int tegra_pwm_remove(struct platform_device *pdev)
205{ 217{
206 struct tegra_pwm_chip *pc = platform_get_drvdata(pdev); 218 struct tegra_pwm_chip *pc = platform_get_drvdata(pdev);
207 unsigned int i; 219 unsigned int i;
220 int err;
208 221
209 if (WARN_ON(!pc)) 222 if (WARN_ON(!pc))
210 return -ENODEV; 223 return -ENODEV;
211 224
225 err = clk_prepare_enable(pc->clk);
226 if (err < 0)
227 return err;
228
212 for (i = 0; i < pc->chip.npwm; i++) { 229 for (i = 0; i < pc->chip.npwm; i++) {
213 struct pwm_device *pwm = &pc->chip.pwms[i]; 230 struct pwm_device *pwm = &pc->chip.pwms[i];
214 231
@@ -221,6 +238,9 @@ static int tegra_pwm_remove(struct platform_device *pdev)
221 clk_disable_unprepare(pc->clk); 238 clk_disable_unprepare(pc->clk);
222 } 239 }
223 240
241 reset_control_assert(pc->rst);
242 clk_disable_unprepare(pc->clk);
243
224 return pwmchip_remove(&pc->chip); 244 return pwmchip_remove(&pc->chip);
225} 245}
226 246