Merge tag 'pwm/for-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[platform/kernel/linux-rpi.git] / drivers / pwm / pwm-atmel-tcb.c
index 4a116dc..c00dd37 100644 (file)
@@ -19,8 +19,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
+#include <linux/of.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
 #include <soc/at91/atmel_tcb.h>
@@ -34,7 +33,6 @@
                                 ATMEL_TC_BEEVT | ATMEL_TC_BSWTRG)
 
 struct atmel_tcb_pwm_device {
-       enum pwm_polarity polarity;     /* PWM polarity */
        unsigned div;                   /* PWM clock divider */
        unsigned duty;                  /* PWM duty expressed in clk cycles */
        unsigned period;                /* PWM period expressed in clk cycles */
@@ -57,7 +55,7 @@ struct atmel_tcb_pwm_chip {
        struct clk *clk;
        struct clk *gclk;
        struct clk *slow_clk;
-       struct atmel_tcb_pwm_device *pwms[NPWM];
+       struct atmel_tcb_pwm_device pwms[NPWM];
        struct atmel_tcb_channel bkup;
 };
 
@@ -68,37 +66,18 @@ static inline struct atmel_tcb_pwm_chip *to_tcb_chip(struct pwm_chip *chip)
        return container_of(chip, struct atmel_tcb_pwm_chip, chip);
 }
 
-static int atmel_tcb_pwm_set_polarity(struct pwm_chip *chip,
-                                     struct pwm_device *pwm,
-                                     enum pwm_polarity polarity)
-{
-       struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
-       struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
-
-       tcbpwm->polarity = polarity;
-
-       return 0;
-}
-
 static int atmel_tcb_pwm_request(struct pwm_chip *chip,
                                 struct pwm_device *pwm)
 {
        struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
-       struct atmel_tcb_pwm_device *tcbpwm;
+       struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
        unsigned cmr;
        int ret;
 
-       tcbpwm = devm_kzalloc(chip->dev, sizeof(*tcbpwm), GFP_KERNEL);
-       if (!tcbpwm)
-               return -ENOMEM;
-
        ret = clk_prepare_enable(tcbpwmc->clk);
-       if (ret) {
-               devm_kfree(chip->dev, tcbpwm);
+       if (ret)
                return ret;
-       }
 
-       tcbpwm->polarity = PWM_POLARITY_NORMAL;
        tcbpwm->duty = 0;
        tcbpwm->period = 0;
        tcbpwm->div = 0;
@@ -131,27 +110,22 @@ static int atmel_tcb_pwm_request(struct pwm_chip *chip,
        regmap_write(tcbpwmc->regmap, ATMEL_TC_REG(tcbpwmc->channel, CMR), cmr);
        spin_unlock(&tcbpwmc->lock);
 
-       tcbpwmc->pwms[pwm->hwpwm] = tcbpwm;
-
        return 0;
 }
 
 static void atmel_tcb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
-       struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
 
        clk_disable_unprepare(tcbpwmc->clk);
-       tcbpwmc->pwms[pwm->hwpwm] = NULL;
-       devm_kfree(chip->dev, tcbpwm);
 }
 
-static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
+                                 enum pwm_polarity polarity)
 {
        struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
-       struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
+       struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
        unsigned cmr;
-       enum pwm_polarity polarity = tcbpwm->polarity;
 
        /*
         * If duty is 0 the timer will be stopped and we have to
@@ -203,12 +177,12 @@ static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        spin_unlock(&tcbpwmc->lock);
 }
 
-static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm,
+                               enum pwm_polarity polarity)
 {
        struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
-       struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
+       struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
        u32 cmr;
-       enum pwm_polarity polarity = tcbpwm->polarity;
 
        /*
         * If duty is 0 the timer will be stopped and we have to
@@ -291,7 +265,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                                int duty_ns, int period_ns)
 {
        struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
-       struct atmel_tcb_pwm_device *tcbpwm = tcbpwmc->pwms[pwm->hwpwm];
+       struct atmel_tcb_pwm_device *tcbpwm = &tcbpwmc->pwms[pwm->hwpwm];
        struct atmel_tcb_pwm_device *atcbpwm = NULL;
        int i = 0;
        int slowclk = 0;
@@ -338,9 +312,9 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        period = div_u64(period_ns, min);
 
        if (pwm->hwpwm == 0)
-               atcbpwm = tcbpwmc->pwms[1];
+               atcbpwm = &tcbpwmc->pwms[1];
        else
-               atcbpwm = tcbpwmc->pwms[0];
+               atcbpwm = &tcbpwmc->pwms[0];
 
        /*
         * PWM devices provided by the TCB driver are grouped by 2.
@@ -371,11 +345,8 @@ static int atmel_tcb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        int duty_cycle, period;
        int ret;
 
-       /* This function only sets a flag in driver data */
-       atmel_tcb_pwm_set_polarity(chip, pwm, state->polarity);
-
        if (!state->enabled) {
-               atmel_tcb_pwm_disable(chip, pwm);
+               atmel_tcb_pwm_disable(chip, pwm, state->polarity);
                return 0;
        }
 
@@ -386,7 +357,7 @@ static int atmel_tcb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        if (ret)
                return ret;
 
-       return atmel_tcb_pwm_enable(chip, pwm);
+       return atmel_tcb_pwm_enable(chip, pwm, state->polarity);
 }
 
 static const struct pwm_ops atmel_tcb_pwm_ops = {
@@ -422,13 +393,14 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
        struct atmel_tcb_pwm_chip *tcbpwm;
        const struct atmel_tcb_config *config;
        struct device_node *np = pdev->dev.of_node;
-       struct regmap *regmap;
-       struct clk *clk, *gclk = NULL;
-       struct clk *slow_clk;
        char clk_name[] = "t0_clk";
        int err;
        int channel;
 
+       tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
+       if (tcbpwm == NULL)
+               return -ENOMEM;
+
        err = of_property_read_u32(np, "reg", &channel);
        if (err < 0) {
                dev_err(&pdev->dev,
@@ -437,49 +409,43 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
                return err;
        }
 
-       regmap = syscon_node_to_regmap(np->parent);
-       if (IS_ERR(regmap))
-               return PTR_ERR(regmap);
+       tcbpwm->regmap = syscon_node_to_regmap(np->parent);
+       if (IS_ERR(tcbpwm->regmap))
+               return PTR_ERR(tcbpwm->regmap);
 
-       slow_clk = of_clk_get_by_name(np->parent, "slow_clk");
-       if (IS_ERR(slow_clk))
-               return PTR_ERR(slow_clk);
+       tcbpwm->slow_clk = of_clk_get_by_name(np->parent, "slow_clk");
+       if (IS_ERR(tcbpwm->slow_clk))
+               return PTR_ERR(tcbpwm->slow_clk);
 
        clk_name[1] += channel;
-       clk = of_clk_get_by_name(np->parent, clk_name);
-       if (IS_ERR(clk))
-               clk = of_clk_get_by_name(np->parent, "t0_clk");
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       tcbpwm->clk = of_clk_get_by_name(np->parent, clk_name);
+       if (IS_ERR(tcbpwm->clk))
+               tcbpwm->clk = of_clk_get_by_name(np->parent, "t0_clk");
+       if (IS_ERR(tcbpwm->clk)) {
+               err = PTR_ERR(tcbpwm->clk);
+               goto err_slow_clk;
+       }
 
        match = of_match_node(atmel_tcb_of_match, np->parent);
        config = match->data;
 
        if (config->has_gclk) {
-               gclk = of_clk_get_by_name(np->parent, "gclk");
-               if (IS_ERR(gclk))
-                       return PTR_ERR(gclk);
-       }
-
-       tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
-       if (tcbpwm == NULL) {
-               err = -ENOMEM;
-               goto err_slow_clk;
+               tcbpwm->gclk = of_clk_get_by_name(np->parent, "gclk");
+               if (IS_ERR(tcbpwm->gclk)) {
+                       err = PTR_ERR(tcbpwm->gclk);
+                       goto err_clk;
+               }
        }
 
        tcbpwm->chip.dev = &pdev->dev;
        tcbpwm->chip.ops = &atmel_tcb_pwm_ops;
        tcbpwm->chip.npwm = NPWM;
        tcbpwm->channel = channel;
-       tcbpwm->regmap = regmap;
-       tcbpwm->clk = clk;
-       tcbpwm->gclk = gclk;
-       tcbpwm->slow_clk = slow_clk;
        tcbpwm->width = config->counter_width;
 
-       err = clk_prepare_enable(slow_clk);
+       err = clk_prepare_enable(tcbpwm->slow_clk);
        if (err)
-               goto err_slow_clk;
+               goto err_gclk;
 
        spin_lock_init(&tcbpwm->lock);
 
@@ -494,8 +460,14 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 err_disable_clk:
        clk_disable_unprepare(tcbpwm->slow_clk);
 
+err_gclk:
+       clk_put(tcbpwm->gclk);
+
+err_clk:
+       clk_put(tcbpwm->clk);
+
 err_slow_clk:
-       clk_put(slow_clk);
+       clk_put(tcbpwm->slow_clk);
 
        return err;
 }
@@ -507,8 +479,9 @@ static void atmel_tcb_pwm_remove(struct platform_device *pdev)
        pwmchip_remove(&tcbpwm->chip);
 
        clk_disable_unprepare(tcbpwm->slow_clk);
-       clk_put(tcbpwm->slow_clk);
+       clk_put(tcbpwm->gclk);
        clk_put(tcbpwm->clk);
+       clk_put(tcbpwm->slow_clk);
 }
 
 static const struct of_device_id atmel_tcb_pwm_dt_ids[] = {