devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] Add regulator suspend and resume support
@ 2018-01-12 10:18 Chunyan Zhang
  2018-01-12 10:18 ` [PATCH v3 1/5] bindings: regulator: added support for suspend states Chunyan Zhang
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-12 10:18 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Arnd Bergmann,
	Chunyan Zhang

Some systems need to set regulators to specific states when they enter low
power modes, especially around CPUs.

Currently the regulator driver, for suspend and resume features, provides
two functions which are exported for being called directly by any modules
or subsystems when they thought the regulator should be entering into
suspend states.

This patchset adds hooks to PM suspend core and provides suspend/resume
callback functions to regulator device, for those who can be switched
off or set low voltage in suspend states only need to implement the
callback functions in the driver, and set the right configurations for
suspend states via device tree and the APIs which regulator core
driver provides.

Those drivers who use the old interfaces - i.e. regulator_suspend_prepare()
and regulator_suspend_finish() should stop using that, since we leave these
two functions empty and plan to remove them one day in the future.

Any comments would be greatly appreciated.

Thanks,
Chunyan

Changes from V1: (https://lkml.org/lkml/2017/12/21/9)
* Rephrased the commit message of patch 0001;
* Declared the property 'regulator-suspend-microvolt' deperated and documented
  the way recommended;
* Revised of_regulator.c, use suspend_state::min_uV as default suspend
  voltage if the property 'regulator-suspend-microvolt' is not used.

Changes from V2: (https://lkml.org/lkml/2018/1/4/75)
* Correct the typo;
* Removed redundant comments;
* Export regulator_suspend_enable/disable(), on't call these two functions in
  regulator_set_suspend_voltage() instead;
* Checking if rstate->min_uV == rstate->max_uV instead of checking the flag.

Chunyan Zhang (5):
  bindings: regulator: added support for suspend states
  regulator: make regulator voltage be an array to support more states
  drivers: regulator: leave one item to record whether regulator is
    enabled
  drivers: regulator: empty the old suspend functions
  regulator: add PM suspend and resume hooks

 .../devicetree/bindings/regulator/regulator.txt    |  15 +-
 drivers/regulator/core.c                           | 336 ++++++++++++++-------
 drivers/regulator/internal.h                       |  18 +-
 drivers/regulator/of_regulator.c                   |  20 +-
 include/linux/regulator/driver.h                   |   2 +
 include/linux/regulator/machine.h                  |  37 ++-
 6 files changed, 302 insertions(+), 126 deletions(-)

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 1/5] bindings: regulator: added support for suspend states
  2018-01-12 10:18 [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang
@ 2018-01-12 10:18 ` Chunyan Zhang
  2018-01-19 22:11   ` Rob Herring
       [not found]   ` <1515752305-15907-2-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  2018-01-12 10:18 ` [PATCH v3 2/5] regulator: make regulator voltage be an array to support more states Chunyan Zhang
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-12 10:18 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree, linux-kernel, Ulf Hansson, Arnd Bergmann, Chunyan Zhang

Some systems need to set regulators to specific states when they enter
low power modes, especially around CPUs. There are many of these modes
depending on the particular runtime state.

Currently the regulator consumers are not granted permission to change
suspend state of regulator devices, the constraints are configured at
startup.  In order to allow changes in a vlotage range, we need to add
new properties for voltage range and a flag to give permission to
change the suspend voltage and suspend on/off in suspend mode.

Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
 Documentation/devicetree/bindings/regulator/regulator.txt | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 378f6dc..532e286 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -42,8 +42,19 @@ Optional properties:
 - regulator-state-[mem/disk] node has following common properties:
 	- regulator-on-in-suspend: regulator should be on in suspend state.
 	- regulator-off-in-suspend: regulator should be off in suspend state.
-	- regulator-suspend-microvolt: regulator should be set to this voltage
-	  in suspend.
+	- regulator-suspend-min-microvolt: minimum voltage may be set in
+	  suspend state.
+	- regulator-suspend-max-microvolt: maximum voltage may be set in
+	  suspend state.
+	- regulator-suspend-microvolt: the default voltage which regulator
+	  would be set in suspend. The voltage for suspend also can be
+	  adjusted among {regulator-suspend-min-microvolt,
+	  regulator-suspend-max-microvolt} by calling
+	  regulator_set_suspend_voltage(). This property is now deprecated,
+	  setting voltage for suspend mode via API the regulator driver
+	  provides is recommended.
+	- regulator-changeable-in-suspend: whether the default voltage and
+	  the regulator on/off in suspend can be changed in runtime.
 	- regulator-mode: operating mode in the given suspend state.
 	  The set of possible operating modes depends on the capabilities of
 	  every hardware so the valid modes are documented on each regulator
-- 
2.7.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 2/5] regulator: make regulator voltage be an array to support more states
  2018-01-12 10:18 [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang
  2018-01-12 10:18 ` [PATCH v3 1/5] bindings: regulator: added support for suspend states Chunyan Zhang
@ 2018-01-12 10:18 ` Chunyan Zhang
  2018-01-12 10:18 ` [PATCH v3 3/5] drivers: regulator: leave one item to record whether regulator is enabled Chunyan Zhang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-12 10:18 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree, linux-kernel, Ulf Hansson, Arnd Bergmann, Chunyan Zhang

Some regulator consumers would like to make the regulator device
keeping a voltage range output when the system entering into
suspend states.

Making regulator voltage be an array can allow consumers to set voltage
for normal state as well as for suspend states through the same code.

Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
 drivers/regulator/core.c     | 63 ++++++++++++++++++++++++--------------------
 drivers/regulator/internal.h | 18 +++++++++++--
 2 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index b64b791..97bc9f7 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -240,22 +240,25 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
  * regulator consumers
  */
 static int regulator_check_consumers(struct regulator_dev *rdev,
-				     int *min_uV, int *max_uV)
+				     int *min_uV, int *max_uV,
+				     suspend_state_t state)
 {
 	struct regulator *regulator;
+	struct regulator_voltage *voltage;
 
 	list_for_each_entry(regulator, &rdev->consumer_list, list) {
+		voltage = &regulator->voltage[state];
 		/*
 		 * Assume consumers that didn't say anything are OK
 		 * with anything in the constraint range.
 		 */
-		if (!regulator->min_uV && !regulator->max_uV)
+		if (!voltage->min_uV && !voltage->max_uV)
 			continue;
 
-		if (*max_uV > regulator->max_uV)
-			*max_uV = regulator->max_uV;
-		if (*min_uV < regulator->min_uV)
-			*min_uV = regulator->min_uV;
+		if (*max_uV > voltage->max_uV)
+			*max_uV = voltage->max_uV;
+		if (*min_uV < voltage->min_uV)
+			*min_uV = voltage->min_uV;
 	}
 
 	if (*min_uV > *max_uV) {
@@ -1356,9 +1359,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
 				   &regulator->uA_load);
 		debugfs_create_u32("min_uV", 0444, regulator->debugfs,
-				   &regulator->min_uV);
+				   &regulator->voltage[PM_SUSPEND_ON].min_uV);
 		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
-				   &regulator->max_uV);
+				   &regulator->voltage[PM_SUSPEND_ON].max_uV);
 		debugfs_create_file("constraint_flags", 0444,
 				    regulator->debugfs, regulator,
 				    &constraint_flags_fops);
@@ -2898,9 +2901,11 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
 }
 
 static int regulator_set_voltage_unlocked(struct regulator *regulator,
-					  int min_uV, int max_uV)
+					  int min_uV, int max_uV,
+					  suspend_state_t state)
 {
 	struct regulator_dev *rdev = regulator->rdev;
+	struct regulator_voltage *voltage = &regulator->voltage[state];
 	int ret = 0;
 	int old_min_uV, old_max_uV;
 	int current_uV;
@@ -2911,7 +2916,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 	 * should be a noop (some cpufreq implementations use the same
 	 * voltage for multiple frequencies, for example).
 	 */
-	if (regulator->min_uV == min_uV && regulator->max_uV == max_uV)
+	if (voltage->min_uV == min_uV && voltage->max_uV == max_uV)
 		goto out;
 
 	/* If we're trying to set a range that overlaps the current voltage,
@@ -2921,8 +2926,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 	if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
 		current_uV = _regulator_get_voltage(rdev);
 		if (min_uV <= current_uV && current_uV <= max_uV) {
-			regulator->min_uV = min_uV;
-			regulator->max_uV = max_uV;
+			voltage->min_uV = min_uV;
+			voltage->max_uV = max_uV;
 			goto out;
 		}
 	}
@@ -2940,12 +2945,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 		goto out;
 
 	/* restore original values in case of error */
-	old_min_uV = regulator->min_uV;
-	old_max_uV = regulator->max_uV;
-	regulator->min_uV = min_uV;
-	regulator->max_uV = max_uV;
+	old_min_uV = voltage->min_uV;
+	old_max_uV = voltage->max_uV;
+	voltage->min_uV = min_uV;
+	voltage->max_uV = max_uV;
 
-	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
+	ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state);
 	if (ret < 0)
 		goto out2;
 
@@ -2982,7 +2987,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 
 	if (supply_change_uV > 0) {
 		ret = regulator_set_voltage_unlocked(rdev->supply,
-				best_supply_uV, INT_MAX);
+				best_supply_uV, INT_MAX, state);
 		if (ret) {
 			dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
 					ret);
@@ -2996,7 +3001,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 
 	if (supply_change_uV < 0) {
 		ret = regulator_set_voltage_unlocked(rdev->supply,
-				best_supply_uV, INT_MAX);
+				best_supply_uV, INT_MAX, state);
 		if (ret)
 			dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n",
 					ret);
@@ -3007,8 +3012,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 out:
 	return ret;
 out2:
-	regulator->min_uV = old_min_uV;
-	regulator->max_uV = old_max_uV;
+	voltage->min_uV = old_min_uV;
+	voltage->max_uV = old_max_uV;
 
 	return ret;
 }
@@ -3037,7 +3042,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
 
 	regulator_lock_supply(regulator->rdev);
 
-	ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV);
+	ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV,
+					     PM_SUSPEND_ON);
 
 	regulator_unlock_supply(regulator->rdev);
 
@@ -3138,6 +3144,7 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
 int regulator_sync_voltage(struct regulator *regulator)
 {
 	struct regulator_dev *rdev = regulator->rdev;
+	struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
 	int ret, min_uV, max_uV;
 
 	mutex_lock(&rdev->mutex);
@@ -3149,20 +3156,20 @@ int regulator_sync_voltage(struct regulator *regulator)
 	}
 
 	/* This is only going to work if we've had a voltage configured. */
-	if (!regulator->min_uV && !regulator->max_uV) {
+	if (!voltage->min_uV && !voltage->max_uV) {
 		ret = -EINVAL;
 		goto out;
 	}
 
-	min_uV = regulator->min_uV;
-	max_uV = regulator->max_uV;
+	min_uV = voltage->min_uV;
+	max_uV = voltage->max_uV;
 
 	/* This should be a paranoia check... */
 	ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
 	if (ret < 0)
 		goto out;
 
-	ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
+	ret = regulator_check_consumers(rdev, &min_uV, &max_uV, 0);
 	if (ret < 0)
 		goto out;
 
@@ -4424,8 +4431,8 @@ static void regulator_summary_show_subtree(struct seq_file *s,
 		switch (rdev->desc->type) {
 		case REGULATOR_VOLTAGE:
 			seq_printf(s, "%37dmV %5dmV",
-				   consumer->min_uV / 1000,
-				   consumer->max_uV / 1000);
+				   consumer->voltage[PM_SUSPEND_ON].min_uV / 1000,
+				   consumer->voltage[PM_SUSPEND_ON].max_uV / 1000);
 			break;
 		case REGULATOR_CURRENT:
 			break;
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h
index 66a8ea0..aba8e414 100644
--- a/drivers/regulator/internal.h
+++ b/drivers/regulator/internal.h
@@ -16,10 +16,25 @@
 #ifndef __REGULATOR_INTERNAL_H
 #define __REGULATOR_INTERNAL_H
 
+#include <linux/suspend.h>
+
+#define REGULATOR_STATES_NUM	(PM_SUSPEND_MAX + 1)
+
+struct regulator_voltage {
+	int min_uV;
+	int max_uV;
+};
+
 /*
  * struct regulator
  *
  * One for each consumer device.
+ * @voltage - a voltage array for each state of runtime, i.e.:
+ *            PM_SUSPEND_ON
+ *            PM_SUSPEND_TO_IDLE
+ *            PM_SUSPEND_STANDBY
+ *            PM_SUSPEND_MEM
+ *            PM_SUSPEND_MAX
  */
 struct regulator {
 	struct device *dev;
@@ -27,8 +42,7 @@ struct regulator {
 	unsigned int always_on:1;
 	unsigned int bypass:1;
 	int uA_load;
-	int min_uV;
-	int max_uV;
+	struct regulator_voltage voltage[REGULATOR_STATES_NUM];
 	const char *supply_name;
 	struct device_attribute dev_attr;
 	struct regulator_dev *rdev;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 3/5] drivers: regulator: leave one item to record whether regulator is enabled
  2018-01-12 10:18 [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang
  2018-01-12 10:18 ` [PATCH v3 1/5] bindings: regulator: added support for suspend states Chunyan Zhang
  2018-01-12 10:18 ` [PATCH v3 2/5] regulator: make regulator voltage be an array to support more states Chunyan Zhang
@ 2018-01-12 10:18 ` Chunyan Zhang
  2018-01-26 15:26   ` Applied "regulator: leave one item to record whether regulator is enabled" to the regulator tree Mark Brown
       [not found] ` <1515752305-15907-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-12 10:18 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree, linux-kernel, Ulf Hansson, Arnd Bergmann, Chunyan Zhang

The items "disabled" and "enabled" are a little redundant, since only one
of them would be set to record if the regulator device should keep on
or be switched to off in suspend states.

So in this patch, the "disabled" was removed, only leave the "enabled":
  - enabled == 1 for regulator-on-in-suspend
  - enabled == 0 for regulator-off-in-suspend
  - enabled == -1 means do nothing when entering suspend mode.

Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
 drivers/regulator/core.c          | 14 ++++++--------
 drivers/regulator/of_regulator.c  |  6 ++++--
 include/linux/regulator/machine.h | 19 +++++++++++++++----
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 97bc9f7..5ea80e9 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -742,21 +742,19 @@ static int suspend_set_state(struct regulator_dev *rdev,
 	 * only warn if the driver implements set_suspend_voltage or
 	 * set_suspend_mode callback.
 	 */
-	if (!rstate->enabled && !rstate->disabled) {
+	if (rstate->enabled != ENABLE_IN_SUSPEND &&
+	    rstate->enabled != DISABLE_IN_SUSPEND) {
 		if (rdev->desc->ops->set_suspend_voltage ||
 		    rdev->desc->ops->set_suspend_mode)
 			rdev_warn(rdev, "No configuration\n");
 		return 0;
 	}
 
-	if (rstate->enabled && rstate->disabled) {
-		rdev_err(rdev, "invalid configuration\n");
-		return -EINVAL;
-	}
-
-	if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
+	if (rstate->enabled == ENABLE_IN_SUSPEND &&
+		rdev->desc->ops->set_suspend_enable)
 		ret = rdev->desc->ops->set_suspend_enable(rdev);
-	else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)
+	else if (rstate->enabled == DISABLE_IN_SUSPEND &&
+		rdev->desc->ops->set_suspend_disable)
 		ret = rdev->desc->ops->set_suspend_disable(rdev);
 	else /* OK if set_suspend_enable or set_suspend_disable is NULL */
 		ret = 0;
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 14637a0..41dad42 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -177,10 +177,12 @@ static void of_get_regulation_constraints(struct device_node *np,
 
 		if (of_property_read_bool(suspend_np,
 					"regulator-on-in-suspend"))
-			suspend_state->enabled = true;
+			suspend_state->enabled = ENABLE_IN_SUSPEND;
 		else if (of_property_read_bool(suspend_np,
 					"regulator-off-in-suspend"))
-			suspend_state->disabled = true;
+			suspend_state->enabled = DISABLE_IN_SUSPEND;
+		else
+			suspend_state->enabled = DO_NOTHING_IN_SUSPEND;
 
 		if (!of_property_read_u32(suspend_np,
 					"regulator-suspend-microvolt", &pval))
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 9cd4fef..ce89c55 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -42,6 +42,16 @@ struct regulator;
 #define REGULATOR_CHANGE_DRMS		0x10
 #define REGULATOR_CHANGE_BYPASS		0x20
 
+/*
+ * operations in suspend mode
+ * DO_NOTHING_IN_SUSPEND - the default value
+ * DISABLE_IN_SUSPEND	- turn off regulator in suspend states
+ * ENABLE_IN_SUSPEND	- keep regulator on in suspend states
+ */
+#define DO_NOTHING_IN_SUSPEND	(-1)
+#define DISABLE_IN_SUSPEND	0
+#define ENABLE_IN_SUSPEND	1
+
 /* Regulator active discharge flags */
 enum regulator_active_discharge {
 	REGULATOR_ACTIVE_DISCHARGE_DEFAULT,
@@ -58,14 +68,15 @@ enum regulator_active_discharge {
  *
  * @uV: Operating voltage during suspend.
  * @mode: Operating mode during suspend.
- * @enabled: Enabled during suspend.
- * @disabled: Disabled during suspend.
+ * @enabled: operations during suspend.
+ *	     - DO_NOTHING_IN_SUSPEND
+ *	     - DISABLE_IN_SUSPEND
+ *	     - ENABLE_IN_SUSPEND
  */
 struct regulator_state {
 	int uV;	/* suspend voltage */
 	unsigned int mode; /* suspend regulator operating mode */
-	int enabled; /* is regulator enabled in this suspend state */
-	int disabled; /* is the regulator disabled in this suspend state */
+	int enabled;
 };
 
 /**
-- 
2.7.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 4/5] drivers: regulator: empty the old suspend functions
       [not found] ` <1515752305-15907-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2018-01-12 10:18   ` Chunyan Zhang
  0 siblings, 0 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-12 10:18 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Arnd Bergmann,
	Chunyan Zhang

Regualtor suspend/resume functions should only be called by PM suspend
core via registering dev_pm_ops, and regulator devices should implement
the callback functions.  Thus, any regulator consumer shouldn't call
the regulator suspend/resume functions directly.

In order to avoid compile errors, two empty functions with the same name
still be left for the time being.

Signed-off-by: Chunyan Zhang <zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/regulator/core.c          | 74 ---------------------------------------
 include/linux/regulator/machine.h |  5 ++-
 2 files changed, 2 insertions(+), 77 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5ea80e9..080c233 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4179,80 +4179,6 @@ void regulator_unregister(struct regulator_dev *rdev)
 }
 EXPORT_SYMBOL_GPL(regulator_unregister);
 
-static int _regulator_suspend_prepare(struct device *dev, void *data)
-{
-	struct regulator_dev *rdev = dev_to_rdev(dev);
-	const suspend_state_t *state = data;
-	int ret;
-
-	mutex_lock(&rdev->mutex);
-	ret = suspend_prepare(rdev, *state);
-	mutex_unlock(&rdev->mutex);
-
-	return ret;
-}
-
-/**
- * regulator_suspend_prepare - prepare regulators for system wide suspend
- * @state: system suspend state
- *
- * Configure each regulator with it's suspend operating parameters for state.
- * This will usually be called by machine suspend code prior to supending.
- */
-int regulator_suspend_prepare(suspend_state_t state)
-{
-	/* ON is handled by regulator active state */
-	if (state == PM_SUSPEND_ON)
-		return -EINVAL;
-
-	return class_for_each_device(&regulator_class, NULL, &state,
-				     _regulator_suspend_prepare);
-}
-EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
-
-static int _regulator_suspend_finish(struct device *dev, void *data)
-{
-	struct regulator_dev *rdev = dev_to_rdev(dev);
-	int ret;
-
-	mutex_lock(&rdev->mutex);
-	if (rdev->use_count > 0  || rdev->constraints->always_on) {
-		if (!_regulator_is_enabled(rdev)) {
-			ret = _regulator_do_enable(rdev);
-			if (ret)
-				dev_err(dev,
-					"Failed to resume regulator %d\n",
-					ret);
-		}
-	} else {
-		if (!have_full_constraints())
-			goto unlock;
-		if (!_regulator_is_enabled(rdev))
-			goto unlock;
-
-		ret = _regulator_do_disable(rdev);
-		if (ret)
-			dev_err(dev, "Failed to suspend regulator %d\n", ret);
-	}
-unlock:
-	mutex_unlock(&rdev->mutex);
-
-	/* Keep processing regulators in spite of any errors */
-	return 0;
-}
-
-/**
- * regulator_suspend_finish - resume regulators from system wide suspend
- *
- * Turn on regulators that might be turned off by regulator_suspend_prepare
- * and that should be turned on according to the regulators properties.
- */
-int regulator_suspend_finish(void)
-{
-	return class_for_each_device(&regulator_class, NULL, NULL,
-				     _regulator_suspend_finish);
-}
-EXPORT_SYMBOL_GPL(regulator_suspend_finish);
 
 /**
  * regulator_has_full_constraints - the system has fully specified constraints
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index ce89c55..c4a56df 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -236,12 +236,12 @@ struct regulator_init_data {
 
 #ifdef CONFIG_REGULATOR
 void regulator_has_full_constraints(void);
-int regulator_suspend_prepare(suspend_state_t state);
-int regulator_suspend_finish(void);
 #else
 static inline void regulator_has_full_constraints(void)
 {
 }
+#endif
+
 static inline int regulator_suspend_prepare(suspend_state_t state)
 {
 	return 0;
@@ -250,6 +250,5 @@ static inline int regulator_suspend_finish(void)
 {
 	return 0;
 }
-#endif
 
 #endif
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 5/5] regulator: add PM suspend and resume hooks
  2018-01-12 10:18 [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang
                   ` (3 preceding siblings ...)
       [not found] ` <1515752305-15907-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2018-01-12 10:18 ` Chunyan Zhang
  2018-01-12 10:23 ` [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang
  5 siblings, 0 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-12 10:18 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree, linux-kernel, Ulf Hansson, Arnd Bergmann, Chunyan Zhang

In this patch, consumers are allowed to set suspend voltage, and this
actually just set the "uV" in constraint::regulator_state, when the
regulator_suspend_late() was called by PM core through callback when
the system is entering into suspend, the regulator device would act
suspend activity then.

And it assumes that if any consumer set suspend voltage, the regulator
device should be enabled in the suspend state.  And if the suspend
voltage of a regulator device for all consumers was set zero, the
regulator device would be off in the suspend state.

This patch also provides a new function hook to regulator devices for
resuming from suspend states.

Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
---
 drivers/regulator/core.c          | 245 +++++++++++++++++++++++++++++++++-----
 drivers/regulator/of_regulator.c  |  14 +++
 include/linux/regulator/driver.h  |   2 +
 include/linux/regulator/machine.h |  13 +-
 4 files changed, 241 insertions(+), 33 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 080c233..0dfa758 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -236,6 +236,12 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
 	return 0;
 }
 
+/* return 0 if the state is valid */
+static int regulator_check_states(suspend_state_t state)
+{
+	return (state > PM_SUSPEND_MAX || state == PM_SUSPEND_TO_IDLE);
+}
+
 /* Make sure we select a voltage that suits the needs of all
  * regulator consumers
  */
@@ -327,6 +333,24 @@ static int regulator_mode_constrain(struct regulator_dev *rdev,
 	return -EINVAL;
 }
 
+static inline struct regulator_state *
+regulator_get_suspend_state(struct regulator_dev *rdev, suspend_state_t state)
+{
+	if (rdev->constraints == NULL)
+		return NULL;
+
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		return &rdev->constraints->state_standby;
+	case PM_SUSPEND_MEM:
+		return &rdev->constraints->state_mem;
+	case PM_SUSPEND_MAX:
+		return &rdev->constraints->state_disk;
+	default:
+		return NULL;
+	}
+}
+
 static ssize_t regulator_uV_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -734,9 +758,14 @@ static int drms_uA_update(struct regulator_dev *rdev)
 }
 
 static int suspend_set_state(struct regulator_dev *rdev,
-	struct regulator_state *rstate)
+				    suspend_state_t state)
 {
 	int ret = 0;
+	struct regulator_state *rstate;
+
+	rstate = regulator_get_suspend_state(rdev, state);
+	if (rstate == NULL)
+		return -EINVAL;
 
 	/* If we have no suspend mode configration don't set anything;
 	 * only warn if the driver implements set_suspend_voltage or
@@ -779,28 +808,8 @@ static int suspend_set_state(struct regulator_dev *rdev,
 			return ret;
 		}
 	}
-	return ret;
-}
-
-/* locks held by caller */
-static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
-{
-	if (!rdev->constraints)
-		return -EINVAL;
 
-	switch (state) {
-	case PM_SUSPEND_STANDBY:
-		return suspend_set_state(rdev,
-			&rdev->constraints->state_standby);
-	case PM_SUSPEND_MEM:
-		return suspend_set_state(rdev,
-			&rdev->constraints->state_mem);
-	case PM_SUSPEND_MAX:
-		return suspend_set_state(rdev,
-			&rdev->constraints->state_disk);
-	default:
-		return -EINVAL;
-	}
+	return ret;
 }
 
 static void print_constraints(struct regulator_dev *rdev)
@@ -1069,7 +1078,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
 
 	/* do we need to setup our suspend state */
 	if (rdev->constraints->initial_state) {
-		ret = suspend_prepare(rdev, rdev->constraints->initial_state);
+		ret = suspend_set_state(rdev, rdev->constraints->initial_state);
 		if (ret < 0) {
 			rdev_err(rdev, "failed to set suspend state\n");
 			return ret;
@@ -2898,6 +2907,32 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
 	return ret;
 }
 
+static int _regulator_do_set_suspend_voltage(struct regulator_dev *rdev,
+				  int min_uV, int max_uV, suspend_state_t state)
+{
+	struct regulator_state *rstate;
+	int uV, sel;
+
+	rstate = regulator_get_suspend_state(rdev, state);
+	if (rstate == NULL)
+		return -EINVAL;
+
+	if (min_uV < rstate->min_uV)
+		min_uV = rstate->min_uV;
+	if (max_uV > rstate->max_uV)
+		max_uV = rstate->max_uV;
+
+	sel = regulator_map_voltage(rdev, min_uV, max_uV);
+	if (sel < 0)
+		return sel;
+
+	uV = rdev->desc->ops->list_voltage(rdev, sel);
+	if (uV >= min_uV && uV <= max_uV)
+		rstate->uV = uV;
+
+	return 0;
+}
+
 static int regulator_set_voltage_unlocked(struct regulator *regulator,
 					  int min_uV, int max_uV,
 					  suspend_state_t state)
@@ -2993,7 +3028,11 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
 		}
 	}
 
-	ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
+	if (state == PM_SUSPEND_ON)
+		ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
+	else
+		ret = _regulator_do_set_suspend_voltage(rdev, min_uV,
+							max_uV, state);
 	if (ret < 0)
 		goto out2;
 
@@ -3049,6 +3088,89 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
 }
 EXPORT_SYMBOL_GPL(regulator_set_voltage);
 
+static inline int regulator_suspend_toggle(struct regulator_dev *rdev,
+					   suspend_state_t state, bool en)
+{
+	struct regulator_state *rstate;
+
+	rstate = regulator_get_suspend_state(rdev, state);
+	if (rstate == NULL)
+		return -EINVAL;
+
+	if (!rstate->changeable)
+		return -EPERM;
+
+	rstate->enabled = en;
+
+	return 0;
+}
+
+int regulator_suspend_enable(struct regulator_dev *rdev,
+				    suspend_state_t state)
+{
+	return regulator_suspend_toggle(rdev, state, true);
+}
+EXPORT_SYMBOL_GPL(regulator_suspend_enable);
+
+int regulator_suspend_disable(struct regulator_dev *rdev,
+				     suspend_state_t state)
+{
+	struct regulator *regulator;
+	struct regulator_voltage *voltage;
+
+	/*
+	 * if any consumer wants this regulator device keeping on in
+	 * suspend states, don't set it as disabled.
+	 */
+	list_for_each_entry(regulator, &rdev->consumer_list, list) {
+		voltage = &regulator->voltage[state];
+		if (voltage->min_uV || voltage->max_uV)
+			return 0;
+	}
+
+	return regulator_suspend_toggle(rdev, state, false);
+}
+EXPORT_SYMBOL_GPL(regulator_suspend_disable);
+
+static int _regulator_set_suspend_voltage(struct regulator *regulator,
+					  int min_uV, int max_uV,
+					  suspend_state_t state)
+{
+	struct regulator_dev *rdev = regulator->rdev;
+	struct regulator_state *rstate;
+
+	rstate = regulator_get_suspend_state(rdev, state);
+	if (rstate == NULL)
+		return -EINVAL;
+
+	if (rstate->min_uV == rstate->max_uV) {
+		rdev_err(rdev, "The suspend voltage can't be changed!\n");
+		return -EPERM;
+	}
+
+	return regulator_set_voltage_unlocked(regulator, min_uV, max_uV, state);
+}
+
+int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
+				  int max_uV, suspend_state_t state)
+{
+	int ret = 0;
+
+	/* PM_SUSPEND_ON is handled by regulator_set_voltage() */
+	if (regulator_check_states(state) || state == PM_SUSPEND_ON)
+		return -EINVAL;
+
+	regulator_lock_supply(regulator->rdev);
+
+	ret = _regulator_set_suspend_voltage(regulator, min_uV,
+					     max_uV, state);
+
+	regulator_unlock_supply(regulator->rdev);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_set_suspend_voltage);
+
 /**
  * regulator_set_voltage_time - get raise/fall time
  * @regulator: regulator source
@@ -3923,12 +4045,6 @@ static void regulator_dev_release(struct device *dev)
 	kfree(rdev);
 }
 
-static struct class regulator_class = {
-	.name = "regulator",
-	.dev_release = regulator_dev_release,
-	.dev_groups = regulator_dev_groups,
-};
-
 static void rdev_init_debugfs(struct regulator_dev *rdev)
 {
 	struct device *parent = rdev->dev.parent;
@@ -4179,7 +4295,76 @@ void regulator_unregister(struct regulator_dev *rdev)
 }
 EXPORT_SYMBOL_GPL(regulator_unregister);
 
+static int _regulator_suspend_late(struct device *dev, void *data)
+{
+	struct regulator_dev *rdev = dev_to_rdev(dev);
+	suspend_state_t *state = data;
+	int ret;
+
+	mutex_lock(&rdev->mutex);
+	ret = suspend_set_state(rdev, *state);
+	mutex_unlock(&rdev->mutex);
 
+	return ret;
+}
+
+/**
+ * regulator_suspend_late - prepare regulators for system wide suspend
+ * @state: system suspend state
+ *
+ * Configure each regulator with it's suspend operating parameters for state.
+ */
+static int regulator_suspend_late(struct device *dev)
+{
+	suspend_state_t state = pm_suspend_target_state;
+
+	return class_for_each_device(&regulator_class, NULL, &state,
+				     _regulator_suspend_late);
+}
+static int _regulator_resume_early(struct device *dev, void *data)
+{
+	int ret = 0;
+	struct regulator_dev *rdev = dev_to_rdev(dev);
+	suspend_state_t *state = data;
+	struct regulator_state *rstate;
+
+	rstate = regulator_get_suspend_state(rdev, *state);
+	if (rstate == NULL)
+		return -EINVAL;
+
+	mutex_lock(&rdev->mutex);
+
+	if (rdev->desc->ops->resume_early &&
+	    (rstate->enabled == ENABLE_IN_SUSPEND ||
+	     rstate->enabled == DISABLE_IN_SUSPEND))
+		ret = rdev->desc->ops->resume_early(rdev);
+
+	mutex_unlock(&rdev->mutex);
+
+	return ret;
+}
+
+static int regulator_resume_early(struct device *dev)
+{
+	suspend_state_t state = pm_suspend_target_state;
+
+	return class_for_each_device(&regulator_class, NULL, &state,
+				     _regulator_resume_early);
+}
+
+static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
+	.suspend_late	= regulator_suspend_late,
+	.resume_early	= regulator_resume_early,
+};
+
+static struct class regulator_class = {
+	.name = "regulator",
+	.dev_release = regulator_dev_release,
+	.dev_groups = regulator_dev_groups,
+#ifdef CONFIG_PM_SLEEP
+	.pm = &regulator_pm_ops,
+#endif
+};
 /**
  * regulator_has_full_constraints - the system has fully specified constraints
  *
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 41dad42..a09ef6c 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -184,9 +184,23 @@ static void of_get_regulation_constraints(struct device_node *np,
 		else
 			suspend_state->enabled = DO_NOTHING_IN_SUSPEND;
 
+		if (!of_property_read_u32(np, "regulator-suspend-min-microvolt",
+					  &pval))
+			suspend_state->min_uV = pval;
+
+		if (!of_property_read_u32(np, "regulator-suspend-max-microvolt",
+					  &pval))
+			suspend_state->max_uV = pval;
+
 		if (!of_property_read_u32(suspend_np,
 					"regulator-suspend-microvolt", &pval))
 			suspend_state->uV = pval;
+		else /* otherwise use min_uV as default suspend voltage */
+			suspend_state->uV = suspend_state->min_uV;
+
+		if (of_property_read_bool(suspend_np,
+					"regulator-changeable-in-suspend"))
+			suspend_state->changeable = true;
 
 		if (i == PM_SUSPEND_MEM)
 			constraints->initial_state = PM_SUSPEND_MEM;
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 94417b4..4c00486 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -214,6 +214,8 @@ struct regulator_ops {
 	/* set regulator suspend operating mode (defined in consumer.h) */
 	int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
 
+	int (*resume_early)(struct regulator_dev *rdev);
+
 	int (*set_pull_down) (struct regulator_dev *);
 };
 
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index c4a56df..93a0489 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -66,17 +66,24 @@ enum regulator_active_discharge {
  * state.  One of enabled or disabled must be set for the
  * configuration to be applied.
  *
- * @uV: Operating voltage during suspend.
+ * @uV: Default operating voltage during suspend, it can be adjusted
+ *	among <min_uV, max_uV>.
+ * @min_uV: Minimum suspend voltage may be set.
+ * @max_uV: Maximum suspend voltage may be set.
  * @mode: Operating mode during suspend.
  * @enabled: operations during suspend.
  *	     - DO_NOTHING_IN_SUSPEND
  *	     - DISABLE_IN_SUSPEND
  *	     - ENABLE_IN_SUSPEND
+ * @changeable: Is this state can be switched between enabled/disabled,
  */
 struct regulator_state {
-	int uV;	/* suspend voltage */
-	unsigned int mode; /* suspend regulator operating mode */
+	int uV;
+	int min_uV;
+	int max_uV;
+	unsigned int mode;
 	int enabled;
+	bool changeable;
 };
 
 /**
-- 
2.7.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3 0/5] Add regulator suspend and resume support
  2018-01-12 10:18 [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang
                   ` (4 preceding siblings ...)
  2018-01-12 10:18 ` [PATCH v3 5/5] regulator: add PM suspend and resume hooks Chunyan Zhang
@ 2018-01-12 10:23 ` Chunyan Zhang
  5 siblings, 0 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-12 10:23 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree, linux-kernel, Ulf Hansson, Arnd Bergmann, Chunyan Zhang

Some systems need to set regulators to specific states when they enter low
power modes, especially around CPUs.

Currently the regulator driver, for suspend and resume features, provides
two functions which are exported for being called directly by any modules
or subsystems when they thought the regulator should be entering into
suspend states.

This patchset adds hooks to PM suspend core and provides suspend/resume
callback functions to regulator device, for those who can be switched
off or set low voltage in suspend states only need to implement the
callback functions in the driver, and set the right configurations for
suspend states via device tree and the APIs which regulator core
driver provides.

Those drivers who use the old interfaces - i.e. regulator_suspend_prepare()
and regulator_suspend_finish() should stop using that, since we leave these
two functions empty and plan to remove them one day in the future.

Any comments would be greatly appreciated.

Thanks,
Chunyan

Changes from V1: (https://lkml.org/lkml/2017/12/21/9)
* Rephrased the commit message of patch 0001;
* Declared the property 'regulator-suspend-microvolt' deperated and documented
  the way recommended;
* Revised of_regulator.c, use suspend_state::min_uV as default suspend
  voltage if the property 'regulator-suspend-microvolt' is not used.

Changes from V2: (https://lkml.org/lkml/2018/1/4/75)
* Correct the typo;
* Removed redundant comments;
* Export regulator_suspend_enable/disable(), don't call these two functions in
  regulator_set_suspend_voltage() instead;
* Checking if rstate->min_uV == rstate->max_uV instead of checking the flag when
  setting the suspend voltage.

Chunyan Zhang (5):
  bindings: regulator: added support for suspend states
  regulator: make regulator voltage be an array to support more states
  drivers: regulator: leave one item to record whether regulator is
    enabled
  drivers: regulator: empty the old suspend functions
  regulator: add PM suspend and resume hooks

 .../devicetree/bindings/regulator/regulator.txt    |  15 +-
 drivers/regulator/core.c                           | 336 ++++++++++++++-------
 drivers/regulator/internal.h                       |  18 +-
 drivers/regulator/of_regulator.c                   |  20 +-
 include/linux/regulator/driver.h                   |   2 +
 include/linux/regulator/machine.h                  |  37 ++-
 6 files changed, 302 insertions(+), 126 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/5] bindings: regulator: added support for suspend states
  2018-01-12 10:18 ` [PATCH v3 1/5] bindings: regulator: added support for suspend states Chunyan Zhang
@ 2018-01-19 22:11   ` Rob Herring
  2018-01-22  2:16     ` Chunyan Zhang
       [not found]   ` <1515752305-15907-2-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  1 sibling, 1 reply; 14+ messages in thread
From: Rob Herring @ 2018-01-19 22:11 UTC (permalink / raw)
  To: Chunyan Zhang
  Cc: Mark Brown, devicetree, linux-kernel, Ulf Hansson, Arnd Bergmann,
	Chunyan Zhang

On Fri, Jan 12, 2018 at 06:18:21PM +0800, Chunyan Zhang wrote:
> Some systems need to set regulators to specific states when they enter
> low power modes, especially around CPUs. There are many of these modes
> depending on the particular runtime state.
> 
> Currently the regulator consumers are not granted permission to change
> suspend state of regulator devices, the constraints are configured at
> startup.  In order to allow changes in a vlotage range, we need to add
> new properties for voltage range and a flag to give permission to
> change the suspend voltage and suspend on/off in suspend mode.
> 
> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
> ---
>  Documentation/devicetree/bindings/regulator/regulator.txt | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
> index 378f6dc..532e286 100644
> --- a/Documentation/devicetree/bindings/regulator/regulator.txt
> +++ b/Documentation/devicetree/bindings/regulator/regulator.txt
> @@ -42,8 +42,19 @@ Optional properties:
>  - regulator-state-[mem/disk] node has following common properties:
>  	- regulator-on-in-suspend: regulator should be on in suspend state.
>  	- regulator-off-in-suspend: regulator should be off in suspend state.
> -	- regulator-suspend-microvolt: regulator should be set to this voltage
> -	  in suspend.
> +	- regulator-suspend-min-microvolt: minimum voltage may be set in
> +	  suspend state.
> +	- regulator-suspend-max-microvolt: maximum voltage may be set in
> +	  suspend state.
> +	- regulator-suspend-microvolt: the default voltage which regulator
> +	  would be set in suspend. The voltage for suspend also can be
> +	  adjusted among {regulator-suspend-min-microvolt,
> +	  regulator-suspend-max-microvolt} by calling
> +	  regulator_set_suspend_voltage(). This property is now deprecated,
> +	  setting voltage for suspend mode via API the regulator driver
> +	  provides is recommended.

Please reword. This is Linux implementation details that shouldn't be in 
the binding.

> +	- regulator-changeable-in-suspend: whether the default voltage and
> +	  the regulator on/off in suspend can be changed in runtime.
>  	- regulator-mode: operating mode in the given suspend state.
>  	  The set of possible operating modes depends on the capabilities of
>  	  every hardware so the valid modes are documented on each regulator
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3 1/5] bindings: regulator: added support for suspend states
  2018-01-19 22:11   ` Rob Herring
@ 2018-01-22  2:16     ` Chunyan Zhang
  0 siblings, 0 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-22  2:16 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Brown, devicetree, linux-kernel, Ulf Hansson, Arnd Bergmann,
	Chunyan Zhang

On 20 January 2018 at 06:11, Rob Herring <robh@kernel.org> wrote:
> On Fri, Jan 12, 2018 at 06:18:21PM +0800, Chunyan Zhang wrote:
>> Some systems need to set regulators to specific states when they enter
>> low power modes, especially around CPUs. There are many of these modes
>> depending on the particular runtime state.
>>
>> Currently the regulator consumers are not granted permission to change
>> suspend state of regulator devices, the constraints are configured at
>> startup.  In order to allow changes in a vlotage range, we need to add
>> new properties for voltage range and a flag to give permission to
>> change the suspend voltage and suspend on/off in suspend mode.
>>
>> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
>> ---
>>  Documentation/devicetree/bindings/regulator/regulator.txt | 15 +++++++++++++--
>>  1 file changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
>> index 378f6dc..532e286 100644
>> --- a/Documentation/devicetree/bindings/regulator/regulator.txt
>> +++ b/Documentation/devicetree/bindings/regulator/regulator.txt
>> @@ -42,8 +42,19 @@ Optional properties:
>>  - regulator-state-[mem/disk] node has following common properties:
>>       - regulator-on-in-suspend: regulator should be on in suspend state.
>>       - regulator-off-in-suspend: regulator should be off in suspend state.
>> -     - regulator-suspend-microvolt: regulator should be set to this voltage
>> -       in suspend.
>> +     - regulator-suspend-min-microvolt: minimum voltage may be set in
>> +       suspend state.
>> +     - regulator-suspend-max-microvolt: maximum voltage may be set in
>> +       suspend state.
>> +     - regulator-suspend-microvolt: the default voltage which regulator
>> +       would be set in suspend. The voltage for suspend also can be
>> +       adjusted among {regulator-suspend-min-microvolt,
>> +       regulator-suspend-max-microvolt} by calling
>> +       regulator_set_suspend_voltage(). This property is now deprecated,
>> +       setting voltage for suspend mode via API the regulator driver
>> +       provides is recommended.
>
> Please reword. This is Linux implementation details that shouldn't be in
> the binding.

Ok, I guess just updating this one instead of the whole patchset for
this minor modification should be fine.

>
>> +     - regulator-changeable-in-suspend: whether the default voltage and
>> +       the regulator on/off in suspend can be changed in runtime.
>>       - regulator-mode: operating mode in the given suspend state.
>>         The set of possible operating modes depends on the capabilities of
>>         every hardware so the valid modes are documented on each regulator
>> --
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH V4 1/5] bindings: regulator: added support for suspend states
       [not found]   ` <1515752305-15907-2-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2018-01-22  7:59     ` Chunyan Zhang
  2018-01-22 19:50       ` Rob Herring
       [not found]       ` <1516607961-379-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  0 siblings, 2 replies; 14+ messages in thread
From: Chunyan Zhang @ 2018-01-22  7:59 UTC (permalink / raw)
  To: Mark Brown, Rob Herring
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Arnd Bergmann,
	Chunyan Zhang

Some systems need to set regulators to specific states when they enter
low power modes, especially around CPUs. There are many of these modes
depending on the particular runtime state.

Currently the regulator consumers are not granted permission to change
suspend state of regulator devices, the constraints are configured at
startup.  In order to allow changes in a vlotage range, we need to add
new properties for voltage range and a flag to give permission to
change the suspend voltage and suspend on/off in suspend mode.

Signed-off-by: Chunyan Zhang <zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 Documentation/devicetree/bindings/regulator/regulator.txt | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 378f6dc..e459226 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -42,8 +42,16 @@ Optional properties:
 - regulator-state-[mem/disk] node has following common properties:
 	- regulator-on-in-suspend: regulator should be on in suspend state.
 	- regulator-off-in-suspend: regulator should be off in suspend state.
-	- regulator-suspend-microvolt: regulator should be set to this voltage
-	  in suspend.
+	- regulator-suspend-min-microvolt: minimum voltage may be set in
+	  suspend state.
+	- regulator-suspend-max-microvolt: maximum voltage may be set in
+	  suspend state.
+	- regulator-suspend-microvolt: the default voltage which regulator
+	  would be set in suspend. This property is now deprecated, instead
+	  setting voltage for suspend mode via the API which regulator
+	  driver provides is recommended.
+	- regulator-changeable-in-suspend: whether the default voltage and
+	  the regulator on/off in suspend can be changed in runtime.
 	- regulator-mode: operating mode in the given suspend state.
 	  The set of possible operating modes depends on the capabilities of
 	  every hardware so the valid modes are documented on each regulator
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/5] bindings: regulator: added support for suspend states
  2018-01-22  7:59     ` [PATCH V4 " Chunyan Zhang
@ 2018-01-22 19:50       ` Rob Herring
  2018-01-23 11:28         ` Mark Brown
       [not found]       ` <1516607961-379-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  1 sibling, 1 reply; 14+ messages in thread
From: Rob Herring @ 2018-01-22 19:50 UTC (permalink / raw)
  To: Chunyan Zhang
  Cc: Mark Brown,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Ulf Hansson, Arnd Bergmann, Chunyan Zhang

On Mon, Jan 22, 2018 at 1:59 AM, Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
> Some systems need to set regulators to specific states when they enter
> low power modes, especially around CPUs. There are many of these modes
> depending on the particular runtime state.
>
> Currently the regulator consumers are not granted permission to change
> suspend state of regulator devices, the constraints are configured at
> startup.  In order to allow changes in a vlotage range, we need to add
> new properties for voltage range and a flag to give permission to
> change the suspend voltage and suspend on/off in suspend mode.
>
> Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
> ---
>  Documentation/devicetree/bindings/regulator/regulator.txt | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH V4 1/5] bindings: regulator: added support for suspend states
  2018-01-22 19:50       ` Rob Herring
@ 2018-01-23 11:28         ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2018-01-23 11:28 UTC (permalink / raw)
  To: Rob Herring
  Cc: Chunyan Zhang,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel, Ulf Hansson, Arnd Bergmann, Chunyan Zhang

[-- Attachment #1: Type: text/plain, Size: 518 bytes --]

On Mon, Jan 22, 2018 at 01:50:35PM -0600, Rob Herring wrote:
> On Mon, Jan 22, 2018 at 1:59 AM, Chunyan Zhang <zhang.chunyan@linaro.org> wrote:
> > Some systems need to set regulators to specific states when they enter
> > low power modes, especially around CPUs. There are many of these modes
> > depending on the particular runtime state.

This v4 appears to have failed to arrive in either my inbox or on my
copy of lkml, not sure what's going on there but can you resend please?
Last I have in either place is v3.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Applied "regulator: leave one item to record whether regulator is enabled" to the regulator tree
  2018-01-12 10:18 ` [PATCH v3 3/5] drivers: regulator: leave one item to record whether regulator is enabled Chunyan Zhang
@ 2018-01-26 15:26   ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2018-01-26 15:26 UTC (permalink / raw)
  To: Chunyan Zhang; +Cc: Mark Brown

The patch

   regulator: leave one item to record whether regulator is enabled

has been applied to the regulator tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 72069f9957a11896e79e95c8b55ec815e97c2187 Mon Sep 17 00:00:00 2001
From: Chunyan Zhang <zhang.chunyan@linaro.org>
Date: Fri, 26 Jan 2018 21:08:45 +0800
Subject: [PATCH] regulator: leave one item to record whether regulator is
 enabled

The items "disabled" and "enabled" are a little redundant, since only one
of them would be set to record if the regulator device should keep on
or be switched to off in suspend states.

So in this patch, the "disabled" was removed, only leave the "enabled":
  - enabled == 1 for regulator-on-in-suspend
  - enabled == 0 for regulator-off-in-suspend
  - enabled == -1 means do nothing when entering suspend mode.

Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/core.c          | 14 ++++++--------
 drivers/regulator/of_regulator.c  |  6 ++++--
 include/linux/regulator/machine.h | 19 +++++++++++++++----
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 97bc9f7adf2f..5ea80e94eb69 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -742,21 +742,19 @@ static int suspend_set_state(struct regulator_dev *rdev,
 	 * only warn if the driver implements set_suspend_voltage or
 	 * set_suspend_mode callback.
 	 */
-	if (!rstate->enabled && !rstate->disabled) {
+	if (rstate->enabled != ENABLE_IN_SUSPEND &&
+	    rstate->enabled != DISABLE_IN_SUSPEND) {
 		if (rdev->desc->ops->set_suspend_voltage ||
 		    rdev->desc->ops->set_suspend_mode)
 			rdev_warn(rdev, "No configuration\n");
 		return 0;
 	}
 
-	if (rstate->enabled && rstate->disabled) {
-		rdev_err(rdev, "invalid configuration\n");
-		return -EINVAL;
-	}
-
-	if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
+	if (rstate->enabled == ENABLE_IN_SUSPEND &&
+		rdev->desc->ops->set_suspend_enable)
 		ret = rdev->desc->ops->set_suspend_enable(rdev);
-	else if (rstate->disabled && rdev->desc->ops->set_suspend_disable)
+	else if (rstate->enabled == DISABLE_IN_SUSPEND &&
+		rdev->desc->ops->set_suspend_disable)
 		ret = rdev->desc->ops->set_suspend_disable(rdev);
 	else /* OK if set_suspend_enable or set_suspend_disable is NULL */
 		ret = 0;
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 14637a01ba2d..41dad42b18f0 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -177,10 +177,12 @@ static void of_get_regulation_constraints(struct device_node *np,
 
 		if (of_property_read_bool(suspend_np,
 					"regulator-on-in-suspend"))
-			suspend_state->enabled = true;
+			suspend_state->enabled = ENABLE_IN_SUSPEND;
 		else if (of_property_read_bool(suspend_np,
 					"regulator-off-in-suspend"))
-			suspend_state->disabled = true;
+			suspend_state->enabled = DISABLE_IN_SUSPEND;
+		else
+			suspend_state->enabled = DO_NOTHING_IN_SUSPEND;
 
 		if (!of_property_read_u32(suspend_np,
 					"regulator-suspend-microvolt", &pval))
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 9cd4fef37203..ce89c5548c89 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -42,6 +42,16 @@ struct regulator;
 #define REGULATOR_CHANGE_DRMS		0x10
 #define REGULATOR_CHANGE_BYPASS		0x20
 
+/*
+ * operations in suspend mode
+ * DO_NOTHING_IN_SUSPEND - the default value
+ * DISABLE_IN_SUSPEND	- turn off regulator in suspend states
+ * ENABLE_IN_SUSPEND	- keep regulator on in suspend states
+ */
+#define DO_NOTHING_IN_SUSPEND	(-1)
+#define DISABLE_IN_SUSPEND	0
+#define ENABLE_IN_SUSPEND	1
+
 /* Regulator active discharge flags */
 enum regulator_active_discharge {
 	REGULATOR_ACTIVE_DISCHARGE_DEFAULT,
@@ -58,14 +68,15 @@ enum regulator_active_discharge {
  *
  * @uV: Operating voltage during suspend.
  * @mode: Operating mode during suspend.
- * @enabled: Enabled during suspend.
- * @disabled: Disabled during suspend.
+ * @enabled: operations during suspend.
+ *	     - DO_NOTHING_IN_SUSPEND
+ *	     - DISABLE_IN_SUSPEND
+ *	     - ENABLE_IN_SUSPEND
  */
 struct regulator_state {
 	int uV;	/* suspend voltage */
 	unsigned int mode; /* suspend regulator operating mode */
-	int enabled; /* is regulator enabled in this suspend state */
-	int disabled; /* is the regulator disabled in this suspend state */
+	int enabled;
 };
 
 /**
-- 
2.15.1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Applied "regulator: added support for suspend states" to the regulator tree
       [not found]       ` <1516607961-379-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2018-01-26 15:26         ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2018-01-26 15:26 UTC (permalink / raw)
  To: Chunyan Zhang; +Cc: Mark Brown

The patch

   regulator: added support for suspend states

has been applied to the regulator tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 057c76440c791eb31eb68f3b003f67d00fcce51a Mon Sep 17 00:00:00 2001
From: Chunyan Zhang <zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Date: Fri, 26 Jan 2018 21:08:43 +0800
Subject: [PATCH] regulator: added support for suspend states

Some systems need to set regulators to specific states when they enter
low power modes, especially around CPUs. There are many of these modes
depending on the particular runtime state.

Currently the regulator consumers are not granted permission to change
suspend state of regulator devices, the constraints are configured at
startup.  In order to allow changes in a vlotage range, we need to add
new properties for voltage range and a flag to give permission to
change the suspend voltage and suspend on/off in suspend mode.

Signed-off-by: Chunyan Zhang <zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Reviewed-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 Documentation/devicetree/bindings/regulator/regulator.txt | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 378f6dc8b8bd..e459226dfac9 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -42,8 +42,16 @@ Optional properties:
 - regulator-state-[mem/disk] node has following common properties:
 	- regulator-on-in-suspend: regulator should be on in suspend state.
 	- regulator-off-in-suspend: regulator should be off in suspend state.
-	- regulator-suspend-microvolt: regulator should be set to this voltage
-	  in suspend.
+	- regulator-suspend-min-microvolt: minimum voltage may be set in
+	  suspend state.
+	- regulator-suspend-max-microvolt: maximum voltage may be set in
+	  suspend state.
+	- regulator-suspend-microvolt: the default voltage which regulator
+	  would be set in suspend. This property is now deprecated, instead
+	  setting voltage for suspend mode via the API which regulator
+	  driver provides is recommended.
+	- regulator-changeable-in-suspend: whether the default voltage and
+	  the regulator on/off in suspend can be changed in runtime.
 	- regulator-mode: operating mode in the given suspend state.
 	  The set of possible operating modes depends on the capabilities of
 	  every hardware so the valid modes are documented on each regulator
-- 
2.15.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-01-26 15:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-12 10:18 [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang
2018-01-12 10:18 ` [PATCH v3 1/5] bindings: regulator: added support for suspend states Chunyan Zhang
2018-01-19 22:11   ` Rob Herring
2018-01-22  2:16     ` Chunyan Zhang
     [not found]   ` <1515752305-15907-2-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2018-01-22  7:59     ` [PATCH V4 " Chunyan Zhang
2018-01-22 19:50       ` Rob Herring
2018-01-23 11:28         ` Mark Brown
     [not found]       ` <1516607961-379-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2018-01-26 15:26         ` Applied "regulator: added support for suspend states" to the regulator tree Mark Brown
2018-01-12 10:18 ` [PATCH v3 2/5] regulator: make regulator voltage be an array to support more states Chunyan Zhang
2018-01-12 10:18 ` [PATCH v3 3/5] drivers: regulator: leave one item to record whether regulator is enabled Chunyan Zhang
2018-01-26 15:26   ` Applied "regulator: leave one item to record whether regulator is enabled" to the regulator tree Mark Brown
     [not found] ` <1515752305-15907-1-git-send-email-zhang.chunyan-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2018-01-12 10:18   ` [PATCH v3 4/5] drivers: regulator: empty the old suspend functions Chunyan Zhang
2018-01-12 10:18 ` [PATCH v3 5/5] regulator: add PM suspend and resume hooks Chunyan Zhang
2018-01-12 10:23 ` [PATCH v3 0/5] Add regulator suspend and resume support Chunyan Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).