Merge remote-tracking branch 'regulator/for-5.11' into regulator-next
[sfrench/cifs-2.6.git] / drivers / regulator / core.c
index 2d5d5f3bac6243d7ff9ad02a63e22fa513acf655..ca03d8e70bd1359f586e82aaa75878ecf58f75c7 100644 (file)
@@ -1315,7 +1315,6 @@ static int _regulator_do_enable(struct regulator_dev *rdev);
 /**
  * set_machine_constraints - sets regulator constraints
  * @rdev: regulator source
- * @constraints: constraints to apply
  *
  * Allows platform initialisation code to define and constrain
  * regulator circuits e.g. valid voltage/current ranges, etc.  NOTE:
@@ -1323,21 +1322,11 @@ static int _regulator_do_enable(struct regulator_dev *rdev);
  * regulator operations to proceed i.e. set_voltage, set_current_limit,
  * set_mode.
  */
-static int set_machine_constraints(struct regulator_dev *rdev,
-       const struct regulation_constraints *constraints)
+static int set_machine_constraints(struct regulator_dev *rdev)
 {
        int ret = 0;
        const struct regulator_ops *ops = rdev->desc->ops;
 
-       if (constraints)
-               rdev->constraints = kmemdup(constraints, sizeof(*constraints),
-                                           GFP_KERNEL);
-       else
-               rdev->constraints = kzalloc(sizeof(*constraints),
-                                           GFP_KERNEL);
-       if (!rdev->constraints)
-               return -ENOMEM;
-
        ret = machine_constraints_voltage(rdev, rdev->constraints);
        if (ret != 0)
                return ret;
@@ -1852,6 +1841,15 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
                }
        }
 
+       if (r == rdev) {
+               dev_err(dev, "Supply for %s (%s) resolved to itself\n",
+                       rdev->desc->name, rdev->supply_name);
+               if (!have_full_constraints())
+                       return -EINVAL;
+               r = dummy_regulator_rdev;
+               get_device(&r->dev);
+       }
+
        /*
         * If the supply's parent device is not the same as the
         * regulator's parent device, then ensure the parent device
@@ -5156,7 +5154,6 @@ struct regulator_dev *
 regulator_register(const struct regulator_desc *regulator_desc,
                   const struct regulator_config *cfg)
 {
-       const struct regulation_constraints *constraints = NULL;
        const struct regulator_init_data *init_data;
        struct regulator_config *config = NULL;
        static atomic_t regulator_no = ATOMIC_INIT(-1);
@@ -5295,14 +5292,23 @@ regulator_register(const struct regulator_desc *regulator_desc,
 
        /* set regulator constraints */
        if (init_data)
-               constraints = &init_data->constraints;
+               rdev->constraints = kmemdup(&init_data->constraints,
+                                           sizeof(*rdev->constraints),
+                                           GFP_KERNEL);
+       else
+               rdev->constraints = kzalloc(sizeof(*rdev->constraints),
+                                           GFP_KERNEL);
+       if (!rdev->constraints) {
+               ret = -ENOMEM;
+               goto wash;
+       }
 
        if (init_data && init_data->supply_regulator)
                rdev->supply_name = init_data->supply_regulator;
        else if (regulator_desc->supply_name)
                rdev->supply_name = regulator_desc->supply_name;
 
-       ret = set_machine_constraints(rdev, constraints);
+       ret = set_machine_constraints(rdev);
        if (ret == -EPROBE_DEFER) {
                /* Regulator might be in bypass mode and so needs its supply
                 * to set the constraints */
@@ -5313,7 +5319,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
                         rdev->supply_name);
                ret = regulator_resolve_supply(rdev);
                if (!ret)
-                       ret = set_machine_constraints(rdev, constraints);
+                       ret = set_machine_constraints(rdev);
                else
                        rdev_dbg(rdev, "unable to resolve supply early: %pe\n",
                                 ERR_PTR(ret));