Re: [PATCH 2/6] pwm: sun4i: Add a quirk for reset line

Uwe Kleine-König
2019-07-29T06:36:44Z

Cc += reset framework maintainer

Hello Jernej,

On Fri, Jul 26, 2019 at 08:40:41PM +0200, Jernej Skrabec wrote:
> H6 PWM core needs deasserted reset line in order to work.
>
> Add a quirk for it.
>
> Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
> ---
> drivers/pwm/pwm-sun4i.c | 27 +++++++++++++++++++++++++--
> 1 file changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c
> index de78c824bbfd..1b7be8fbde86 100644
> --- a/drivers/pwm/pwm-sun4i.c
> +++ b/drivers/pwm/pwm-sun4i.c
> @@ -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>
> @@ -72,12 +73,14 @@ static const u32 prescaler_table[] = {
>
> struct sun4i_pwm_data {
> bool has_prescaler_bypass;
> + bool has_reset;
> unsigned int npwm;
> };
>
> 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;
> @@ -371,6 +374,14 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
> if (IS_ERR(pwm->clk))
> return PTR_ERR(pwm->clk);
>
> + if (pwm->data->has_reset) {
> + pwm->rst = devm_reset_control_get(&pdev->dev, NULL);
> + if (IS_ERR(pwm->rst))
> + return PTR_ERR(pwm->rst);
> +
> + reset_control_deassert(pwm->rst);
> + }
> +

I wonder why there is a need to track if a given chip needs a reset
line. I'd just use devm_reset_control_get_optional() and drop the
.has_reset member in struct sun4i_pwm_data.

> pwm->chip.dev = &pdev->dev;
> pwm->chip.ops = &sun4i_pwm_ops;
> pwm->chip.base = -1;
> @@ -383,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;
>
> - return pwmchip_remove(&pwm->chip);
> + reset_control_assert(pwm->rst);
> +
> + return 0;
> }
>
> static struct platform_driver sun4i_pwm_driver = {

--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |