]> Pileus Git - ~andy/linux/blobdiff - drivers/regulator/core.c
Merge branch 'for-linus' of git://selinuxproject.org/~jmorris/linux-security
[~andy/linux] / drivers / regulator / core.c
index 6f7d411b048b4e677a5885fdeb4311b345eb17c0..ca86f39a0fdc824fba463f0eb30157ce933bbe9c 100644 (file)
@@ -985,9 +985,8 @@ static int set_supply(struct regulator_dev *rdev,
        rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
 
        rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
-       if (IS_ERR(rdev->supply)) {
-               err = PTR_ERR(rdev->supply);
-               rdev->supply = NULL;
+       if (rdev->supply == NULL) {
+               err = -ENOMEM;
                return err;
        }
 
@@ -1282,6 +1281,7 @@ found:
        if (regulator == NULL) {
                regulator = ERR_PTR(-ENOMEM);
                module_put(rdev->owner);
+               goto out;
        }
 
        rdev->open_count++;
@@ -2490,6 +2490,43 @@ err:
 }
 EXPORT_SYMBOL_GPL(regulator_bulk_disable);
 
+/**
+ * regulator_bulk_force_disable - force disable multiple regulator consumers
+ *
+ * @num_consumers: Number of consumers
+ * @consumers:     Consumer data; clients are stored here.
+ * @return         0 on success, an errno on failure
+ *
+ * This convenience API allows consumers to forcibly disable multiple regulator
+ * clients in a single API call.
+ * NOTE: This should be used for situations when device damage will
+ * likely occur if the regulators are not disabled (e.g. over temp).
+ * Although regulator_force_disable function call for some consumers can
+ * return error numbers, the function is called for all consumers.
+ */
+int regulator_bulk_force_disable(int num_consumers,
+                          struct regulator_bulk_data *consumers)
+{
+       int i;
+       int ret;
+
+       for (i = 0; i < num_consumers; i++)
+               consumers[i].ret =
+                           regulator_force_disable(consumers[i].consumer);
+
+       for (i = 0; i < num_consumers; i++) {
+               if (consumers[i].ret != 0) {
+                       ret = consumers[i].ret;
+                       goto out;
+               }
+       }
+
+       return 0;
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_bulk_force_disable);
+
 /**
  * regulator_bulk_free - free multiple regulator consumers
  *
@@ -2802,6 +2839,14 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
                ret = set_supply(rdev, r);
                if (ret < 0)
                        goto scrub;
+
+               /* Enable supply if rail is enabled */
+               if (rdev->desc->ops->is_enabled &&
+                               rdev->desc->ops->is_enabled(rdev)) {
+                       ret = regulator_enable(rdev->supply);
+                       if (ret < 0)
+                               goto scrub;
+               }
        }
 
        /* add consumers devices */