]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/regulator/core.c
Merge branches 'pm-core', 'pm-qos', 'pm-domains' and 'pm-opp'
[linux.git] / drivers / regulator / core.c
index a62f5b725061c2f8e8f0dcc69029f7c1c93480e2..53d4fc70dbd0981cdb73eabdc815346c25963b6b 100644 (file)
@@ -1556,6 +1556,19 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
                }
        }
 
+       /*
+        * If the supply's parent device is not the same as the
+        * regulator's parent device, then ensure the parent device
+        * is bound before we resolve the supply, in case the parent
+        * device get probe deferred and unregisters the supply.
+        */
+       if (r->dev.parent && r->dev.parent != rdev->dev.parent) {
+               if (!device_is_bound(r->dev.parent)) {
+                       put_device(&r->dev);
+                       return -EPROBE_DEFER;
+               }
+       }
+
        /* Recursively resolve the supply of the supply */
        ret = regulator_resolve_supply(r);
        if (ret < 0) {
@@ -4394,12 +4407,13 @@ static void regulator_summary_show_subtree(struct seq_file *s,
        seq_puts(s, "\n");
 
        list_for_each_entry(consumer, &rdev->consumer_list, list) {
-               if (consumer->dev->class == &regulator_class)
+               if (consumer->dev && consumer->dev->class == &regulator_class)
                        continue;
 
                seq_printf(s, "%*s%-*s ",
                           (level + 1) * 3 + 1, "",
-                          30 - (level + 1) * 3, dev_name(consumer->dev));
+                          30 - (level + 1) * 3,
+                          consumer->dev ? dev_name(consumer->dev) : "deviceless");
 
                switch (rdev->desc->type) {
                case REGULATOR_VOLTAGE:
@@ -4543,6 +4557,16 @@ static int __init regulator_init_complete(void)
        if (of_have_populated_dt())
                has_full_constraints = true;
 
+       /*
+        * Regulators may had failed to resolve their input supplies
+        * when were registered, either because the input supply was
+        * not registered yet or because its parent device was not
+        * bound yet. So attempt to resolve the input supplies for
+        * pending regulators before trying to disable unused ones.
+        */
+       class_for_each_device(&regulator_class, NULL, NULL,
+                             regulator_register_resolve_supply);
+
        /* 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