summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2024-05-06 04:05:06 +0300
committerMark Brown <broonie@kernel.org>2024-05-06 04:05:06 +0300
commit48b6faae69a432b76e453c73ff5210bf5affa936 (patch)
tree4c1920e1cc5c748238c2763c13f043166fdd5963 /drivers/regulator
parent38bcec0e7cbbd6566c12ae4f2b7a48bd50cd215c (diff)
parentd72fd5228c9f2136a3143daf5c7822140211883a (diff)
downloadlinux-48b6faae69a432b76e453c73ff5210bf5affa936.tar.xz
regulator: new API for voltage reference supplies
Merge series from David Lechner <dlechner@baylibre.com>: In the IIO subsystem, we noticed a pattern in many drivers where we need to get, enable and get the voltage of a supply that provides a reference voltage. In these cases, we only need the voltage and not a handle to the regulator. Another common pattern is for chips to have an internal reference voltage that is used when an external reference is not available. There are also a few drivers outside of IIO that do the same. So we would like to propose a new regulator consumer API to handle these specific cases to avoid repeating the same boilerplate code in multiple drivers. As an example of how these functions are used, I have included a few patches to consumer drivers. But to avoid a giant patch bomb, I have omitted the iio/adc and iio/dac patches I have prepared from this series. I will send those separately but these will add 36 more users of devm_regulator_get_enable_read_voltage() in addition to the 6 here. In total, this will eliminate nearly 1000 lines of similar code and will simplify writing and reviewing new drivers in the future.
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/devres.c59
-rw-r--r--drivers/regulator/tps65132-regulator.c7
2 files changed, 66 insertions, 0 deletions
diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c
index 90bb0d178885..4f290b9b559b 100644
--- a/drivers/regulator/devres.c
+++ b/drivers/regulator/devres.c
@@ -145,6 +145,65 @@ struct regulator *devm_regulator_get_optional(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
+/**
+ * devm_regulator_get_enable_read_voltage - Resource managed regulator get and
+ * enable that returns the voltage
+ * @dev: device to supply
+ * @id: supply name or regulator ID.
+ *
+ * Get and enable regulator for duration of the device life-time.
+ * regulator_disable() and regulator_put() are automatically called on driver
+ * detach. See regulator_get_optional(), regulator_enable(), and
+ * regulator_get_voltage() for more information.
+ *
+ * This is a convenience function for supplies that provide a reference voltage
+ * where the consumer driver just needs to know the voltage and keep the
+ * regulator enabled.
+ *
+ * In cases where the supply is not strictly required, callers can check for
+ * -ENODEV error and handle it accordingly.
+ *
+ * Returns: voltage in microvolts on success, or an error code on failure.
+ */
+int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id)
+{
+ struct regulator *r;
+ int ret;
+
+ /*
+ * Since we need a real voltage, we use devm_regulator_get_optional()
+ * rather than getting a dummy regulator with devm_regulator_get() and
+ * then letting regulator_get_voltage() fail with -EINVAL. This way, the
+ * caller can handle the -ENODEV error code if needed instead of the
+ * ambiguous -EINVAL.
+ */
+ r = devm_regulator_get_optional(dev, id);
+ if (IS_ERR(r))
+ return PTR_ERR(r);
+
+ ret = regulator_enable(r);
+ if (ret)
+ goto err_regulator_put;
+
+ ret = devm_add_action_or_reset(dev, regulator_action_disable, r);
+ if (ret)
+ goto err_regulator_put;
+
+ ret = regulator_get_voltage(r);
+ if (ret < 0)
+ goto err_release_action;
+
+ return 0;
+
+err_release_action:
+ devm_release_action(dev, regulator_action_disable, r);
+err_regulator_put:
+ devm_regulator_put(r);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get_enable_read_voltage);
+
static int devm_regulator_match(struct device *dev, void *res, void *data)
{
struct regulator **r = res;
diff --git a/drivers/regulator/tps65132-regulator.c b/drivers/regulator/tps65132-regulator.c
index a06f5f2d7932..9c2f0dd42613 100644
--- a/drivers/regulator/tps65132-regulator.c
+++ b/drivers/regulator/tps65132-regulator.c
@@ -267,10 +267,17 @@ static const struct i2c_device_id tps65132_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tps65132_id);
+static const struct of_device_id __maybe_unused tps65132_of_match[] = {
+ { .compatible = "ti,tps65132" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, tps65132_of_match);
+
static struct i2c_driver tps65132_i2c_driver = {
.driver = {
.name = "tps65132",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ .of_match_table = of_match_ptr(tps65132_of_match),
},
.probe = tps65132_probe,
.id_table = tps65132_id,