hwmon: (pwm-fan) Add dedicated power switch function
authorAlexander Stein <alexander.stein@ew.tq-group.com>
Wed, 14 Sep 2022 15:31:35 +0000 (17:31 +0200)
committerGuenter Roeck <linux@roeck-us.net>
Sun, 25 Sep 2022 21:22:10 +0000 (14:22 -0700)
This handles enabling/disabling the regulator in a single function, while
keeping the enables/disabled balanced. This is a preparation when
regulator is switched from different code paths.

Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Link: https://lore.kernel.org/r/20220914153137.613982-4-alexander.stein@ew.tq-group.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
drivers/hwmon/pwm-fan.c

index 01412c7..92c5b7f 100644 (file)
@@ -35,6 +35,7 @@ struct pwm_fan_ctx {
        struct pwm_device *pwm;
        struct pwm_state pwm_state;
        struct regulator *reg_en;
+       bool regulator_enabled;
        bool enabled;
 
        int tach_count;
@@ -85,6 +86,25 @@ static void sample_timer(struct timer_list *t)
        mod_timer(&ctx->rpm_timer, jiffies + HZ);
 }
 
+static int pwm_fan_switch_power(struct pwm_fan_ctx *ctx, bool on)
+{
+       int ret = 0;
+
+       if (!ctx->reg_en)
+               return ret;
+
+       if (!ctx->regulator_enabled && on) {
+               ret = regulator_enable(ctx->reg_en);
+               if (ret == 0)
+                       ctx->regulator_enabled = true;
+       } else if (ctx->regulator_enabled && !on) {
+               ret = regulator_disable(ctx->reg_en);
+               if (ret == 0)
+                       ctx->regulator_enabled = false;
+       }
+       return ret;
+}
+
 static int pwm_fan_power_on(struct pwm_fan_ctx *ctx)
 {
        struct pwm_state *state = &ctx->pwm_state;
@@ -320,7 +340,7 @@ static int pwm_fan_of_get_cooling_data(struct device *dev,
 
 static void pwm_fan_regulator_disable(void *data)
 {
-       regulator_disable(data);
+       pwm_fan_switch_power(data, false);
 }
 
 static void pwm_fan_pwm_disable(void *__ctx)
@@ -364,13 +384,13 @@ static int pwm_fan_probe(struct platform_device *pdev)
 
                ctx->reg_en = NULL;
        } else {
-               ret = regulator_enable(ctx->reg_en);
+               ret = pwm_fan_switch_power(ctx, true);
                if (ret) {
                        dev_err(dev, "Failed to enable fan supply: %d\n", ret);
                        return ret;
                }
                ret = devm_add_action_or_reset(dev, pwm_fan_regulator_disable,
-                                              ctx->reg_en);
+                                              ctx);
                if (ret)
                        return ret;
        }
@@ -516,12 +536,10 @@ static int pwm_fan_disable(struct device *dev)
                        return ret;
        }
 
-       if (ctx->reg_en) {
-               ret = regulator_disable(ctx->reg_en);
-               if (ret) {
-                       dev_err(dev, "Failed to disable fan supply: %d\n", ret);
-                       return ret;
-               }
+       ret = pwm_fan_switch_power(ctx, false);
+       if (ret) {
+               dev_err(dev, "Failed to disable fan supply: %d\n", ret);
+               return ret;
        }
 
        return 0;
@@ -543,12 +561,10 @@ static int pwm_fan_resume(struct device *dev)
        struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
        int ret;
 
-       if (ctx->reg_en) {
-               ret = regulator_enable(ctx->reg_en);
-               if (ret) {
-                       dev_err(dev, "Failed to enable fan supply: %d\n", ret);
-                       return ret;
-               }
+       ret = pwm_fan_switch_power(ctx, true);
+       if (ret) {
+               dev_err(dev, "Failed to enable fan supply: %d\n", ret);
+               return ret;
        }
 
        if (ctx->pwm_value == 0)