* [PATCH 1/3] regulator: core: Reduce rdev locking region when releasing regulator
@ 2015-08-12 12:20 Mark Brown
2015-08-12 12:20 ` [PATCH 2/3] regulator: core: Move more deallocation into class unregister Mark Brown
2015-08-12 12:20 ` [PATCH 3/3] regulator: core: Use class device list for regulator_list in late init Mark Brown
0 siblings, 2 replies; 3+ messages in thread
From: Mark Brown @ 2015-08-12 12:20 UTC (permalink / raw)
To: Liam Girdwood; +Cc: linux-kernel, Mark Brown
When we release a regulator we need to remove references to it from the
rdev which means locking the rdev. Currently we also free resources
associated with the regulator inside the rdev lock but there is no need
to do this, we can reduce the region the lock is held by restricting it
to just actions that affect the rdev.
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/regulator/core.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 62e4f3b..89be8e2 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1601,14 +1601,15 @@ static void _regulator_put(struct regulator *regulator)
if (regulator->dev)
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
mutex_lock(&rdev->mutex);
- kfree(regulator->supply_name);
list_del(®ulator->list);
- kfree(regulator);
rdev->open_count--;
rdev->exclusive = 0;
mutex_unlock(&rdev->mutex);
+ kfree(regulator->supply_name);
+ kfree(regulator);
+
module_put(rdev->owner);
}
--
2.5.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/3] regulator: core: Move more deallocation into class unregister
2015-08-12 12:20 [PATCH 1/3] regulator: core: Reduce rdev locking region when releasing regulator Mark Brown
@ 2015-08-12 12:20 ` Mark Brown
2015-08-12 12:20 ` [PATCH 3/3] regulator: core: Use class device list for regulator_list in late init Mark Brown
1 sibling, 0 replies; 3+ messages in thread
From: Mark Brown @ 2015-08-12 12:20 UTC (permalink / raw)
To: Liam Girdwood; +Cc: linux-kernel, Mark Brown
We really ought to be using the class dvice lifetime management features
more than we are rather than open coding them so take a step towards that
by moving some of the simplest deallocations to the dev_release() function.
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/regulator/core.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 89be8e2..01a0a78 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3598,6 +3598,9 @@ static const struct attribute_group *regulator_dev_groups[] = {
static void regulator_dev_release(struct device *dev)
{
struct regulator_dev *rdev = dev_get_drvdata(dev);
+
+ kfree(rdev->constraints);
+ of_node_put(rdev->dev.of_node);
kfree(rdev);
}
@@ -3829,9 +3832,7 @@ void regulator_unregister(struct regulator_dev *rdev)
unset_regulator_supplies(rdev);
list_del(&rdev->list);
mutex_unlock(®ulator_list_mutex);
- kfree(rdev->constraints);
regulator_ena_gpio_free(rdev);
- of_node_put(rdev->dev.of_node);
device_unregister(&rdev->dev);
}
EXPORT_SYMBOL_GPL(regulator_unregister);
--
2.5.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 3/3] regulator: core: Use class device list for regulator_list in late init
2015-08-12 12:20 [PATCH 1/3] regulator: core: Reduce rdev locking region when releasing regulator Mark Brown
2015-08-12 12:20 ` [PATCH 2/3] regulator: core: Move more deallocation into class unregister Mark Brown
@ 2015-08-12 12:20 ` Mark Brown
1 sibling, 0 replies; 3+ messages in thread
From: Mark Brown @ 2015-08-12 12:20 UTC (permalink / raw)
To: Liam Girdwood; +Cc: linux-kernel, Mark Brown
The regulator_list has exactly the same contents as the list that the
driver core maintains of regulator_class members so is redundant. As a
first step in converting over to use the class device list convert our
iteration in late_initcall() to use the class device iterator.
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/regulator/core.c | 106 ++++++++++++++++++++++++-----------------------
1 file changed, 55 insertions(+), 51 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 01a0a78..0bfbada 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -110,6 +110,11 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev,
const char *supply_name);
+static struct regulator_dev *dev_to_rdev(struct device *dev)
+{
+ return container_of(dev, struct regulator_dev, dev);
+}
+
static const char *rdev_get_name(struct regulator_dev *rdev)
{
if (rdev->constraints && rdev->constraints->name)
@@ -4152,13 +4157,57 @@ static int __init regulator_init(void)
/* init early to allow our consumers to complete system booting */
core_initcall(regulator_init);
-static int __init regulator_init_complete(void)
+static int regulator_late_cleanup(struct device *dev, void *data)
{
- struct regulator_dev *rdev;
- const struct regulator_ops *ops;
- struct regulation_constraints *c;
+ struct regulator_dev *rdev = dev_to_rdev(dev);
+ const struct regulator_ops *ops = rdev->desc->ops;
+ struct regulation_constraints *c = rdev->constraints;
int enabled, ret;
+ if (c && c->always_on)
+ return 0;
+
+ if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
+ return 0;
+
+ mutex_lock(&rdev->mutex);
+
+ if (rdev->use_count)
+ goto unlock;
+
+ /* If we can't read the status assume it's on. */
+ if (ops->is_enabled)
+ enabled = ops->is_enabled(rdev);
+ else
+ enabled = 1;
+
+ if (!enabled)
+ goto unlock;
+
+ if (have_full_constraints()) {
+ /* We log since this may kill the system if it goes
+ * wrong. */
+ rdev_info(rdev, "disabling\n");
+ ret = _regulator_do_disable(rdev);
+ if (ret != 0)
+ rdev_err(rdev, "couldn't disable: %d\n", ret);
+ } else {
+ /* The intention is that in future we will
+ * assume that full constraints are provided
+ * so warn even if we aren't going to do
+ * anything here.
+ */
+ rdev_warn(rdev, "incomplete constraints, leaving on\n");
+ }
+
+unlock:
+ mutex_unlock(&rdev->mutex);
+
+ return 0;
+}
+
+static int __init regulator_init_complete(void)
+{
/*
* Since DT doesn't provide an idiomatic mechanism for
* enabling full constraints and since it's much more natural
@@ -4168,58 +4217,13 @@ static int __init regulator_init_complete(void)
if (of_have_populated_dt())
has_full_constraints = true;
- mutex_lock(®ulator_list_mutex);
-
/* If we have a full configuration then disable any regulators
* we have permission to change the status for and which are
* not in use or always_on. This is effectively the default
* for DT and ACPI as they have full constraints.
*/
- list_for_each_entry(rdev, ®ulator_list, list) {
- ops = rdev->desc->ops;
- c = rdev->constraints;
-
- if (c && c->always_on)
- continue;
-
- if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
- continue;
-
- mutex_lock(&rdev->mutex);
-
- if (rdev->use_count)
- goto unlock;
-
- /* If we can't read the status assume it's on. */
- if (ops->is_enabled)
- enabled = ops->is_enabled(rdev);
- else
- enabled = 1;
-
- if (!enabled)
- goto unlock;
-
- if (have_full_constraints()) {
- /* We log since this may kill the system if it
- * goes wrong. */
- rdev_info(rdev, "disabling\n");
- ret = _regulator_do_disable(rdev);
- if (ret != 0)
- rdev_err(rdev, "couldn't disable: %d\n", ret);
- } else {
- /* The intention is that in future we will
- * assume that full constraints are provided
- * so warn even if we aren't going to do
- * anything here.
- */
- rdev_warn(rdev, "incomplete constraints, leaving on\n");
- }
-
-unlock:
- mutex_unlock(&rdev->mutex);
- }
-
- mutex_unlock(®ulator_list_mutex);
+ class_for_each_device(®ulator_class, NULL, NULL,
+ regulator_late_cleanup);
return 0;
}
--
2.5.0
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-08-12 12:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-12 12:20 [PATCH 1/3] regulator: core: Reduce rdev locking region when releasing regulator Mark Brown
2015-08-12 12:20 ` [PATCH 2/3] regulator: core: Move more deallocation into class unregister Mark Brown
2015-08-12 12:20 ` [PATCH 3/3] regulator: core: Use class device list for regulator_list in late init Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®