]> Git Repo - linux.git/commitdiff
pwm: mtk-disp: Adjust the clocks to avoid them mismatch
authorJitao Shi <[email protected]>
Sun, 8 Aug 2021 13:24:29 +0000 (21:24 +0800)
committerThierry Reding <[email protected]>
Thu, 2 Sep 2021 20:03:43 +0000 (22:03 +0200)
The clks "main" and "mm" are prepared in .probe() (and unprepared in
.remove()). This results in the clocks being on during suspend which
results in unnecessarily increased power consumption.

Remove the clock operations from .probe() and .remove(). Add the
clk_prepare_enable() in .enable() and the clk_disable_unprepare() in
.disable().

Signed-off-by: Jitao Shi <[email protected]>
[[email protected]: squashed in fixup patch]
Signed-off-by: Thierry Reding <[email protected]>
drivers/pwm/pwm-mtk-disp.c

index 7b4a2b8c2aeba2f5d176463193216950a624e31c..5817ac184fa355d6735944ad7fff6b59eacee0ac 100644 (file)
@@ -74,6 +74,19 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        u64 div, rate;
        int err;
 
+       err = clk_prepare_enable(mdp->clk_main);
+       if (err < 0) {
+               dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
+               return err;
+       }
+
+       err = clk_prepare_enable(mdp->clk_mm);
+       if (err < 0) {
+               dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+               clk_disable_unprepare(mdp->clk_main);
+               return err;
+       }
+
        /*
         * Find period, high_width and clk_div to suit duty_ns and period_ns.
         * Calculate proper div value to keep period value in the bound.
@@ -87,8 +100,11 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        rate = clk_get_rate(mdp->clk_main);
        clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
                          PWM_PERIOD_BIT_WIDTH;
-       if (clk_div > PWM_CLKDIV_MAX)
+       if (clk_div > PWM_CLKDIV_MAX) {
+               clk_disable_unprepare(mdp->clk_mm);
+               clk_disable_unprepare(mdp->clk_main);
                return -EINVAL;
+       }
 
        div = NSEC_PER_SEC * (clk_div + 1);
        period = div64_u64(rate * period_ns, div);
@@ -98,16 +114,6 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        high_width = div64_u64(rate * duty_ns, div);
        value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
-       err = clk_enable(mdp->clk_main);
-       if (err < 0)
-               return err;
-
-       err = clk_enable(mdp->clk_mm);
-       if (err < 0) {
-               clk_disable(mdp->clk_main);
-               return err;
-       }
-
        mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
                                 PWM_CLKDIV_MASK,
                                 clk_div << PWM_CLKDIV_SHIFT);
@@ -122,10 +128,21 @@ static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
                mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
                                         mdp->data->commit_mask,
                                         0x0);
+       } else {
+               /*
+                * For MT2701, disable double buffer before writing register
+                * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
+                */
+               mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
+                                        mdp->data->bls_debug_mask,
+                                        mdp->data->bls_debug_mask);
+               mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
+                                        mdp->data->con0_sel,
+                                        mdp->data->con0_sel);
        }
 
-       clk_disable(mdp->clk_mm);
-       clk_disable(mdp->clk_main);
+       clk_disable_unprepare(mdp->clk_mm);
+       clk_disable_unprepare(mdp->clk_main);
 
        return 0;
 }
@@ -135,13 +152,16 @@ static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
        struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
        int err;
 
-       err = clk_enable(mdp->clk_main);
-       if (err < 0)
+       err = clk_prepare_enable(mdp->clk_main);
+       if (err < 0) {
+               dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err));
                return err;
+       }
 
-       err = clk_enable(mdp->clk_mm);
+       err = clk_prepare_enable(mdp->clk_mm);
        if (err < 0) {
-               clk_disable(mdp->clk_main);
+               dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err));
+               clk_disable_unprepare(mdp->clk_main);
                return err;
        }
 
@@ -158,8 +178,8 @@ static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
        mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
                                 0x0);
 
-       clk_disable(mdp->clk_mm);
-       clk_disable(mdp->clk_main);
+       clk_disable_unprepare(mdp->clk_mm);
+       clk_disable_unprepare(mdp->clk_main);
 }
 
 static const struct pwm_ops mtk_disp_pwm_ops = {
@@ -192,46 +212,19 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(mdp->clk_mm))
                return PTR_ERR(mdp->clk_mm);
 
-       ret = clk_prepare(mdp->clk_main);
-       if (ret < 0)
-               return ret;
-
-       ret = clk_prepare(mdp->clk_mm);
-       if (ret < 0)
-               goto disable_clk_main;
-
        mdp->chip.dev = &pdev->dev;
        mdp->chip.ops = &mtk_disp_pwm_ops;
        mdp->chip.npwm = 1;
 
        ret = pwmchip_add(&mdp->chip);
        if (ret < 0) {
-               dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-               goto disable_clk_mm;
+               dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
+               return ret;
        }
 
        platform_set_drvdata(pdev, mdp);
 
-       /*
-        * For MT2701, disable double buffer before writing register
-        * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
-        */
-       if (!mdp->data->has_commit) {
-               mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
-                                        mdp->data->bls_debug_mask,
-                                        mdp->data->bls_debug_mask);
-               mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-                                        mdp->data->con0_sel,
-                                        mdp->data->con0_sel);
-       }
-
        return 0;
-
-disable_clk_mm:
-       clk_unprepare(mdp->clk_mm);
-disable_clk_main:
-       clk_unprepare(mdp->clk_main);
-       return ret;
 }
 
 static int mtk_disp_pwm_remove(struct platform_device *pdev)
@@ -239,8 +232,6 @@ static int mtk_disp_pwm_remove(struct platform_device *pdev)
        struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
 
        pwmchip_remove(&mdp->chip);
-       clk_unprepare(mdp->clk_mm);
-       clk_unprepare(mdp->clk_main);
 
        return 0;
 }
This page took 0.066146 seconds and 4 git commands to generate.