[PATCH v3 3/6] regulator: core: Add helper for allow access to enable register

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a helper function that allow regulator consumers to allow low-level
enable register access, in order to enable/disable regulator in atomic
context.

The use-case for RZ/G2L SoC is to enable VBUS selection register based
on vbus detection that happens in interrupt context.

Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
v3:
 * New patch.
---
 Documentation/power/regulator/consumer.rst |  5 ++++
 drivers/regulator/core.c                   | 32 ++++++++++++++++++++++
 include/linux/regulator/consumer.h         |  8 ++++++
 3 files changed, 45 insertions(+)

diff --git a/Documentation/power/regulator/consumer.rst b/Documentation/power/regulator/consumer.rst
index 85c2bf5ac07e..b5502f4ffe46 100644
--- a/Documentation/power/regulator/consumer.rst
+++ b/Documentation/power/regulator/consumer.rst
@@ -227,3 +227,8 @@ directly written to the voltage selector register, use::
 
 	int regulator_list_hardware_vsel(struct regulator *regulator,
 					 unsigned selector);
+
+To access the hardware register for enabling/disabling the regulator, use::
+
+	int regulator_set_hardware_enable_register(struct regulator *regulator,
+						   bool enable);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5794f4e9dd52..19df42868bbd 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3407,6 +3407,38 @@ int regulator_list_hardware_vsel(struct regulator *regulator,
 }
 EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel);
 
+/**
+ * regulator_set_hardware_enable_register - set the HW enable register
+ * @regulator: regulator source
+ * @enable: true for enable, false for disable
+ *
+ * Request that the regulator be enabled/disabled with the regulator output at
+ * the predefined voltage or current value.
+ *
+ * On success 0 is returned, otherwise a negative errno is returned.
+ */
+int regulator_set_hardware_enable_register(struct regulator *regulator,
+					   bool enable)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+	const struct regulator_ops *ops = rdev->desc->ops;
+	int ret = -EOPNOTSUPP;
+
+	if (!ops)
+		return ret;
+
+	if (enable) {
+		if (ops->enable == regulator_enable_regmap)
+			ret = ops->enable(rdev);
+	} else {
+		if (ops->disable == regulator_disable_regmap)
+			ret = rdev->desc->ops->disable(rdev);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_set_hardware_enable_register);
+
 /**
  * regulator_get_linear_step - return the voltage step size between VSEL values
  * @regulator: regulator source
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index e6f81fc1fb17..4aa5c57de052 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -250,6 +250,8 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator,
 					 unsigned *vsel_mask);
 int regulator_list_hardware_vsel(struct regulator *regulator,
 				 unsigned selector);
+int regulator_set_hardware_enable_register(struct regulator *regulator,
+					   bool enable);
 
 /* regulator notifier block */
 int regulator_register_notifier(struct regulator *regulator,
@@ -571,6 +573,12 @@ static inline int regulator_list_hardware_vsel(struct regulator *regulator,
 	return -EOPNOTSUPP;
 }
 
+static inline int regulator_set_hardware_enable_register(struct regulator *regulator,
+							 bool enable)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int regulator_register_notifier(struct regulator *regulator,
 			      struct notifier_block *nb)
 {
-- 
2.25.1





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux