summaryrefslogtreecommitdiff
path: root/include/linux/regulator
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2019-06-24 00:08:31 +0300
committerMark Brown <broonie@kernel.org>2019-06-25 12:15:32 +0100
commitd8ca7d184b33af7913c244900df77c6cad6a5590 (patch)
tree6b259024fbb00ecf42bc589e95b31f8e6d77c6fc /include/linux/regulator
parenta188339ca5a396acc588e5851ed7e19f66b0ebd9 (diff)
regulator: core: Introduce API for regulators coupling customization
Right now regulator core supports only one type of regulators coupling, the "voltage max-spread" which keeps voltages of coupled regulators in a given range from each other. A more sophisticated coupling may be required in practice, one example is the NVIDIA Tegra SoCs which besides the max-spreading have other restrictions that must be adhered. Introduce API that allow platforms to provide their own customized coupling algorithms. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'include/linux/regulator')
-rw-r--r--include/linux/regulator/coupler.h62
-rw-r--r--include/linux/regulator/driver.h6
-rw-r--r--include/linux/regulator/machine.h2
3 files changed, 66 insertions, 4 deletions
diff --git a/include/linux/regulator/coupler.h b/include/linux/regulator/coupler.h
new file mode 100644
index 000000000000..98dd1f74d605
--- /dev/null
+++ b/include/linux/regulator/coupler.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * coupler.h -- SoC Regulator support, coupler API.
+ *
+ * Regulator Coupler Interface.
+ */
+
+#ifndef __LINUX_REGULATOR_COUPLER_H_
+#define __LINUX_REGULATOR_COUPLER_H_
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+
+struct regulator_coupler;
+struct regulator_dev;
+
+/**
+ * struct regulator_coupler - customized regulator's coupler
+ *
+ * Regulator's coupler allows to customize coupling algorithm.
+ *
+ * @list: couplers list entry
+ * @attach_regulator: Callback invoked on creation of a coupled regulator,
+ * couples are unresolved at this point. The callee should
+ * check that it could handle the regulator and return 0 on
+ * success, -errno on failure and 1 if given regulator is
+ * not suitable for this coupler (case of having multiple
+ * regulators in a system). Callback shall be implemented.
+ * @detach_regulator: Callback invoked on destruction of a coupled regulator.
+ * This callback is optional and could be NULL.
+ * @balance_voltage: Callback invoked when voltage of a coupled regulator is
+ * changing. Called with all of the coupled rdev's being held
+ * under "consumer lock". The callee should perform voltage
+ * balancing, changing voltage of the coupled regulators as
+ * needed. It's up to the coupler to verify the voltage
+ * before changing it in hardware, i.e. coupler should
+ * check consumer's min/max and etc. This callback is
+ * optional and could be NULL, in which case a generic
+ * voltage balancer will be used.
+ */
+struct regulator_coupler {
+ struct list_head list;
+
+ int (*attach_regulator)(struct regulator_coupler *coupler,
+ struct regulator_dev *rdev);
+ int (*detach_regulator)(struct regulator_coupler *coupler,
+ struct regulator_dev *rdev);
+ int (*balance_voltage)(struct regulator_coupler *coupler,
+ struct regulator_dev *rdev,
+ suspend_state_t state);
+};
+
+#ifdef CONFIG_REGULATOR
+int regulator_coupler_register(struct regulator_coupler *coupler);
+#else
+static inline int regulator_coupler_register(struct regulator_coupler *coupler)
+{
+ return 0;
+}
+#endif
+
+#endif
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 377da2357118..31b38a2b6995 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -15,8 +15,6 @@
#ifndef __LINUX_REGULATOR_DRIVER_H_
#define __LINUX_REGULATOR_DRIVER_H_
-#define MAX_COUPLED 2
-
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/regulator/consumer.h>
@@ -426,7 +424,8 @@ struct regulator_config {
* incremented.
*/
struct coupling_desc {
- struct regulator_dev *coupled_rdevs[MAX_COUPLED];
+ struct regulator_dev **coupled_rdevs;
+ struct regulator_coupler *coupler;
int n_resolved;
int n_coupled;
};
@@ -552,4 +551,5 @@ void regulator_unlock(struct regulator_dev *rdev);
*/
int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
unsigned int selector);
+
#endif
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 1d34a70ffda2..21db06e5c1ed 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -156,7 +156,7 @@ struct regulation_constraints {
int system_load;
/* used for coupled regulators */
- int max_spread;
+ u32 *max_spread;
/* used for changing voltage in steps */
int max_uV_step;