Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5dfbd2bd authored by Rohith Seelaboyina's avatar Rohith Seelaboyina Committed by Thierry Reding
Browse files

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: default avatarRohith Seelaboyina <rseelaboyina@nvidia.com>
Signed-off-by: default avatarLaxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 4f57f5a0
Loading
Loading
Loading
Loading
+20 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/pwm.h>
#include <linux/pwm.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/reset.h>


#define PWM_ENABLE	(1 << 31)
#define PWM_ENABLE	(1 << 31)
#define PWM_DUTY_WIDTH	8
#define PWM_DUTY_WIDTH	8
@@ -41,6 +42,7 @@ struct tegra_pwm_chip {
	struct device *dev;
	struct device *dev;


	struct clk *clk;
	struct clk *clk;
	struct reset_control*rst;


	void __iomem *regs;
	void __iomem *regs;
};
};
@@ -187,6 +189,15 @@ static int tegra_pwm_probe(struct platform_device *pdev)
	if (IS_ERR(pwm->clk))
	if (IS_ERR(pwm->clk))
		return PTR_ERR(pwm->clk);
		return PTR_ERR(pwm->clk);


	pwm->rst = devm_reset_control_get(&pdev->dev, "pwm");
	if (IS_ERR(pwm->rst)) {
		ret = PTR_ERR(pwm->rst);
		dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
		return ret;
	}

	reset_control_deassert(pwm->rst);

	pwm->chip.dev = &pdev->dev;
	pwm->chip.dev = &pdev->dev;
	pwm->chip.ops = &tegra_pwm_ops;
	pwm->chip.ops = &tegra_pwm_ops;
	pwm->chip.base = -1;
	pwm->chip.base = -1;
@@ -195,6 +206,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
	ret = pwmchip_add(&pwm->chip);
	ret = pwmchip_add(&pwm->chip);
	if (ret < 0) {
	if (ret < 0) {
		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
		reset_control_assert(pwm->rst);
		return ret;
		return ret;
	}
	}


@@ -205,10 +217,15 @@ static int tegra_pwm_remove(struct platform_device *pdev)
{
{
	struct tegra_pwm_chip *pc = platform_get_drvdata(pdev);
	struct tegra_pwm_chip *pc = platform_get_drvdata(pdev);
	unsigned int i;
	unsigned int i;
	int err;


	if (WARN_ON(!pc))
	if (WARN_ON(!pc))
		return -ENODEV;
		return -ENODEV;


	err = clk_prepare_enable(pc->clk);
	if (err < 0)
		return err;

	for (i = 0; i < pc->chip.npwm; i++) {
	for (i = 0; i < pc->chip.npwm; i++) {
		struct pwm_device *pwm = &pc->chip.pwms[i];
		struct pwm_device *pwm = &pc->chip.pwms[i];


@@ -221,6 +238,9 @@ static int tegra_pwm_remove(struct platform_device *pdev)
		clk_disable_unprepare(pc->clk);
		clk_disable_unprepare(pc->clk);
	}
	}


	reset_control_assert(pc->rst);
	clk_disable_unprepare(pc->clk);

	return pwmchip_remove(&pc->chip);
	return pwmchip_remove(&pc->chip);
}
}