regulator: pwm: implement ->enable(), ->disable() and ->is_enabled methods
authorBoris Brezillon <boris.brezillon@free-electrons.com>
Mon, 21 Sep 2015 09:33:28 +0000 (11:33 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 21 Sep 2015 21:11:18 +0000 (14:11 -0700)
Implement the ->enable(), ->disable() and ->is_enabled methods and remove
the PWM call in ->set_voltage_sel().
This is particularly important for critical regulators tagged as always-on,
because not claiming the PWM (and its dependencies) might lead to
unpredictable behavior (like a system hang because the PWM clk is only
claimed when the PWM device is enabled).

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/regulator/pwm-regulator.c

index fc3166dfcbfaa455b5105ef8e7715d3e17c56d6b..3aca067b990114f7e0618fdfb963d6f66c21c37a 100644 (file)
@@ -69,12 +69,6 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
 
        drvdata->state = selector;
 
-       ret = pwm_enable(drvdata->pwm);
-       if (ret) {
-               dev_err(&rdev->dev, "Failed to enable PWM\n");
-               return ret;
-       }
-
        return 0;
 }
 
@@ -89,6 +83,29 @@ static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
        return drvdata->duty_cycle_table[selector].uV;
 }
 
+static int pwm_regulator_enable(struct regulator_dev *dev)
+{
+       struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+
+       return pwm_enable(drvdata->pwm);
+}
+
+static int pwm_regulator_disable(struct regulator_dev *dev)
+{
+       struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+
+       pwm_disable(drvdata->pwm);
+
+       return 0;
+}
+
+static int pwm_regulator_is_enabled(struct regulator_dev *dev)
+{
+       struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
+
+       return pwm_is_enabled(drvdata->pwm);
+}
+
 /**
  * Continuous voltage call-backs
  */
@@ -144,11 +161,17 @@ static struct regulator_ops pwm_regulator_voltage_table_ops = {
        .get_voltage_sel = pwm_regulator_get_voltage_sel,
        .list_voltage    = pwm_regulator_list_voltage,
        .map_voltage     = regulator_map_voltage_iterate,
+       .enable          = pwm_regulator_enable,
+       .disable         = pwm_regulator_disable,
+       .is_enabled      = pwm_regulator_is_enabled,
 };
 
 static struct regulator_ops pwm_regulator_voltage_continuous_ops = {
        .get_voltage = pwm_regulator_get_voltage,
        .set_voltage = pwm_regulator_set_voltage,
+       .enable          = pwm_regulator_enable,
+       .disable         = pwm_regulator_disable,
+       .is_enabled      = pwm_regulator_is_enabled,
 };
 
 static struct regulator_desc pwm_regulator_desc = {