Skip to content

Commit

Permalink
pwm: sun4i: Add an optional probe for reset line
Browse files Browse the repository at this point in the history
H6 PWM core needs deasserted reset line in order to work.

Add an optional probe for it.

Signed-off-by: Jernej Skrabec <[email protected]>
Reviewed-by: Uwe Kleine-König <[email protected]>
Signed-off-by: Clément Péron <[email protected]>
Signed-off-by: Thierry Reding <[email protected]>
  • Loading branch information
jernejsk authored and thierryreding committed Jan 8, 2020
1 parent bd88d31 commit a7fe985
Showing 1 changed file with 32 additions and 2 deletions.
34 changes: 32 additions & 2 deletions drivers/pwm/pwm-sun4i.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/time.h>
Expand Down Expand Up @@ -78,6 +79,7 @@ struct sun4i_pwm_data {
struct sun4i_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
struct reset_control *rst;
void __iomem *base;
spinlock_t ctrl_lock;
const struct sun4i_pwm_data *data;
Expand Down Expand Up @@ -364,6 +366,22 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pwm->clk))
return PTR_ERR(pwm->clk);

pwm->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
if (IS_ERR(pwm->rst)) {
if (PTR_ERR(pwm->rst) != -EPROBE_DEFER)
dev_err(&pdev->dev, "get reset failed %pe\n",
pwm->rst);
return PTR_ERR(pwm->rst);
}

/* Deassert reset */
ret = reset_control_deassert(pwm->rst);
if (ret) {
dev_err(&pdev->dev, "cannot deassert reset control: %pe\n",
ERR_PTR(ret));
return ret;
}

pwm->chip.dev = &pdev->dev;
pwm->chip.ops = &sun4i_pwm_ops;
pwm->chip.base = -1;
Expand All @@ -376,19 +394,31 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
ret = pwmchip_add(&pwm->chip);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
return ret;
goto err_pwm_add;
}

platform_set_drvdata(pdev, pwm);

return 0;

err_pwm_add:
reset_control_assert(pwm->rst);

return ret;
}

static int sun4i_pwm_remove(struct platform_device *pdev)
{
struct sun4i_pwm_chip *pwm = platform_get_drvdata(pdev);
int ret;

ret = pwmchip_remove(&pwm->chip);
if (ret)
return ret;

reset_control_assert(pwm->rst);

return pwmchip_remove(&pwm->chip);
return 0;
}

static struct platform_driver sun4i_pwm_driver = {
Expand Down

0 comments on commit a7fe985

Please sign in to comment.