Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95b8a4b5 authored by Saravana Kannan's avatar Saravana Kannan
Browse files

ANDROID: GKI: regulator: core: Add support for regulator providers with sync state



Regulator providers whose drivers have sync_state() implemented will
disable their regulators once all their consumers have probed. So during
late_initcall_sync(), don't disable unused regulators of these regulator
providers.

Also, provide a regulator_sync_state() API that regulator providers can
use to disable all their unused regulators once the get their
sync_state() callback.

Bug: 144127090
Bug: 150508586
Signed-off-by: default avatarSaravana Kannan <saravanak@google.com>
Change-Id: I5cc32730214c8e769c2a55cbe3b702cf6bb9016a
parent 4bad67ba
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -4490,6 +4490,30 @@ void regulator_unregister(struct regulator_dev *rdev)
}
EXPORT_SYMBOL_GPL(regulator_unregister);

static int regulator_sync_supply(struct device *dev, void *data)
{
	struct regulator_dev *rdev = dev_to_rdev(dev);

	if (rdev->dev.parent != data)
		return 0;

	if (!rdev->proxy_consumer)
		return 0;

	dev_dbg(data, "Removing regulator proxy consumer requests\n");
	regulator_proxy_consumer_unregister(rdev->proxy_consumer);
	rdev->proxy_consumer = NULL;

	return 0;
}

void regulator_sync_state(struct device *dev)
{
	class_for_each_device(&regulator_class, NULL, dev,
			      regulator_sync_supply);
}
EXPORT_SYMBOL_GPL(regulator_sync_state);

#ifdef CONFIG_SUSPEND
static int _regulator_suspend(struct device *dev, void *data)
{
+7 −5
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ struct proxy_consumer *regulator_proxy_consumer_register(struct device *reg_dev,
	const char *reg_name = "";
	u32 voltage[2] = {0};
	int rc;
	bool no_sync_state = !reg_dev->driver->sync_state;

	/* Return immediately if no proxy consumer properties are specified. */
	if (!of_find_property(reg_node, "qcom,proxy-consumer-enable", NULL)
@@ -60,7 +61,7 @@ struct proxy_consumer *regulator_proxy_consumer_register(struct device *reg_dev,
	mutex_lock(&proxy_consumer_list_mutex);

	/* Do not register new consumers if they cannot be removed later. */
	if (proxy_consumers_removed) {
	if (proxy_consumers_removed && no_sync_state) {
		rc = -EPERM;
		goto unlock;
	}
@@ -74,6 +75,7 @@ struct proxy_consumer *regulator_proxy_consumer_register(struct device *reg_dev,
		goto unlock;
	}

	INIT_LIST_HEAD(&consumer->list);
	consumer->enable
		= of_property_read_bool(reg_node, "qcom,proxy-consumer-enable");
	of_property_read_u32(reg_node, "qcom,proxy-consumer-current",
@@ -125,6 +127,7 @@ struct proxy_consumer *regulator_proxy_consumer_register(struct device *reg_dev,
		}
	}

	if (no_sync_state)
		list_add(&consumer->list, &proxy_consumer_list);
	mutex_unlock(&proxy_consumer_list_mutex);

@@ -190,7 +193,6 @@ int regulator_proxy_consumer_unregister(struct proxy_consumer *consumer)
		return 0;

	mutex_lock(&proxy_consumer_list_mutex);
	if (!proxy_consumers_removed)
	rc = regulator_proxy_consumer_remove(consumer);
	mutex_unlock(&proxy_consumer_list_mutex);

@@ -210,7 +212,7 @@ static int __init regulator_proxy_consumer_remove_all(void)
	proxy_consumers_removed = true;

	if (!list_empty(&proxy_consumer_list))
		pr_info("removing regulator proxy consumer requests\n");
		pr_info("removing legacy regulator proxy consumer requests\n");

	list_for_each_entry_safe(consumer, temp, &proxy_consumer_list, list) {
		regulator_proxy_consumer_remove(consumer);
+1 −0
Original line number Diff line number Diff line
@@ -487,6 +487,7 @@ devm_regulator_register(struct device *dev,
			const struct regulator_desc *regulator_desc,
			const struct regulator_config *config);
void regulator_unregister(struct regulator_dev *rdev);
void regulator_sync_state(struct device *dev);
void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev);

int regulator_notifier_call_chain(struct regulator_dev *rdev,