Loading drivers/regulator/core.c +74 −71 Original line number Diff line number Diff line Loading @@ -1455,12 +1455,14 @@ static struct regulator_dev *regulator_lookup_by_name(const char *name) * lookup could succeed in the future. * * If successful, returns a struct regulator_dev that corresponds to the name * @supply and with the embedded struct device refcount incremented by one, * or NULL on failure. The refcount must be dropped by calling put_device(). * @supply and with the embedded struct device refcount incremented by one. * The refcount must be dropped by calling put_device(). * On failure one of the following ERR-PTR-encoded values is returned: * -ENODEV if lookup fails permanently, -EPROBE_DEFER if lookup could succeed * in the future. */ static struct regulator_dev *regulator_dev_lookup(struct device *dev, const char *supply, int *ret) const char *supply) { struct regulator_dev *r; struct device_node *node; Loading @@ -1476,16 +1478,12 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, r = of_find_regulator_by_node(node); if (r) return r; *ret = -EPROBE_DEFER; return NULL; } else { /* * If we couldn't even get the node then it's * not just that the device didn't register * yet, there's no node and we'll never * succeed. * We have a node, but there is no device. * assume it has not registered yet. */ *ret = -ENODEV; return ERR_PTR(-EPROBE_DEFER); } } Loading @@ -1506,13 +1504,16 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, if (strcmp(map->supply, supply) == 0 && get_device(&map->regulator->dev)) { mutex_unlock(®ulator_list_mutex); return map->regulator; r = map->regulator; break; } } mutex_unlock(®ulator_list_mutex); return NULL; if (r) return r; return ERR_PTR(-ENODEV); } static int regulator_resolve_supply(struct regulator_dev *rdev) Loading @@ -1529,8 +1530,10 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) if (rdev->supply) return 0; r = regulator_dev_lookup(dev, rdev->supply_name, &ret); if (!r) { r = regulator_dev_lookup(dev, rdev->supply_name); if (IS_ERR(r)) { ret = PTR_ERR(r); if (ret == -ENODEV) { /* * No supply was specified for this regulator and Loading Loading @@ -1580,69 +1583,72 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) } /* Internal regulator request function */ static struct regulator *_regulator_get(struct device *dev, const char *id, bool exclusive, bool allow_dummy) struct regulator *_regulator_get(struct device *dev, const char *id, enum regulator_get_type get_type) { struct regulator_dev *rdev; struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); const char *devname = NULL; struct regulator *regulator; const char *devname = dev ? dev_name(dev) : "deviceless"; int ret; if (get_type >= MAX_GET_TYPE) { dev_err(dev, "invalid type %d in %s\n", get_type, __func__); return ERR_PTR(-EINVAL); } if (id == NULL) { pr_err("get() with no identifier\n"); return ERR_PTR(-EINVAL); } if (dev) devname = dev_name(dev); if (have_full_constraints()) ret = -ENODEV; else ret = -EPROBE_DEFER; rdev = regulator_dev_lookup(dev, id, &ret); if (rdev) goto found; regulator = ERR_PTR(ret); rdev = regulator_dev_lookup(dev, id); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); /* * If we have return value from dev_lookup fail, we do not expect to * succeed, so, quit with appropriate error value * If regulator_dev_lookup() fails with error other * than -ENODEV our job here is done, we simply return it. */ if (ret && ret != -ENODEV) return regulator; if (ret != -ENODEV) return ERR_PTR(ret); if (!devname) devname = "deviceless"; if (!have_full_constraints()) { dev_warn(dev, "incomplete constraints, dummy supplies not allowed\n"); return ERR_PTR(-ENODEV); } switch (get_type) { case NORMAL_GET: /* * Assume that a regulator is physically present and enabled * even if it isn't hooked up and just provide a dummy. * Assume that a regulator is physically present and * enabled, even if it isn't hooked up, and just * provide a dummy. */ if (have_full_constraints() && allow_dummy) { pr_warn("%s supply %s not found, using dummy regulator\n", dev_warn(dev, "%s supply %s not found, using dummy regulator\n", devname, id); rdev = dummy_regulator_rdev; get_device(&rdev->dev); goto found; /* Don't log an error when called from regulator_get_optional() */ } else if (!have_full_constraints() || exclusive) { dev_warn(dev, "dummy supplies not allowed\n"); } break; return regulator; case EXCLUSIVE_GET: dev_warn(dev, "dummy supplies not allowed for exclusive requests\n"); /* fall through */ default: return ERR_PTR(-ENODEV); } } found: if (rdev->exclusive) { regulator = ERR_PTR(-EPERM); put_device(&rdev->dev); return regulator; } if (exclusive && rdev->open_count) { if (get_type == EXCLUSIVE_GET && rdev->open_count) { regulator = ERR_PTR(-EBUSY); put_device(&rdev->dev); return regulator; Loading @@ -1656,6 +1662,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, } if (!try_module_get(rdev->owner)) { regulator = ERR_PTR(-EPROBE_DEFER); put_device(&rdev->dev); return regulator; } Loading @@ -1669,7 +1676,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, } rdev->open_count++; if (exclusive) { if (get_type == EXCLUSIVE_GET) { rdev->exclusive = 1; ret = _regulator_is_enabled(rdev); Loading Loading @@ -1697,7 +1704,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, */ struct regulator *regulator_get(struct device *dev, const char *id) { return _regulator_get(dev, id, false, true); return _regulator_get(dev, id, NORMAL_GET); } EXPORT_SYMBOL_GPL(regulator_get); Loading @@ -1724,7 +1731,7 @@ EXPORT_SYMBOL_GPL(regulator_get); */ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) { return _regulator_get(dev, id, true, false); return _regulator_get(dev, id, EXCLUSIVE_GET); } EXPORT_SYMBOL_GPL(regulator_get_exclusive); Loading @@ -1750,7 +1757,7 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive); */ struct regulator *regulator_get_optional(struct device *dev, const char *id) { return _regulator_get(dev, id, false, false); return _regulator_get(dev, id, OPTIONAL_GET); } EXPORT_SYMBOL_GPL(regulator_get_optional); Loading Loading @@ -3660,7 +3667,7 @@ int regulator_bulk_disable(int num_consumers, for (++i; i < num_consumers; ++i) { r = regulator_enable(consumers[i].consumer); if (r != 0) pr_err("Failed to reename %s: %d\n", pr_err("Failed to re-enable %s: %d\n", consumers[i].supply, r); } Loading @@ -3686,21 +3693,17 @@ int regulator_bulk_force_disable(int num_consumers, struct regulator_bulk_data *consumers) { int i; int ret; int ret = 0; for (i = 0; i < num_consumers; i++) 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) { /* Store first error for reporting */ if (consumers[i].ret && !ret) ret = consumers[i].ret; goto out; } } return 0; out: return ret; } EXPORT_SYMBOL_GPL(regulator_bulk_force_disable); Loading drivers/regulator/devres.c +26 −40 Original line number Diff line number Diff line Loading @@ -19,12 +19,6 @@ #include "internal.h" enum { NORMAL_GET, EXCLUSIVE_GET, OPTIONAL_GET, }; static void devm_regulator_release(struct device *dev, void *res) { regulator_put(*(struct regulator **)res); Loading @@ -39,20 +33,7 @@ static struct regulator *_devm_regulator_get(struct device *dev, const char *id, if (!ptr) return ERR_PTR(-ENOMEM); switch (get_type) { case NORMAL_GET: regulator = regulator_get(dev, id); break; case EXCLUSIVE_GET: regulator = regulator_get_exclusive(dev, id); break; case OPTIONAL_GET: regulator = regulator_get_optional(dev, id); break; default: regulator = ERR_PTR(-EINVAL); } regulator = _regulator_get(dev, id, get_type); if (!IS_ERR(regulator)) { *ptr = regulator; devres_add(dev, ptr); Loading Loading @@ -139,6 +120,18 @@ void devm_regulator_put(struct regulator *regulator) } EXPORT_SYMBOL_GPL(devm_regulator_put); struct regulator_bulk_devres { struct regulator_bulk_data *consumers; int num_consumers; }; static void devm_regulator_bulk_release(struct device *dev, void *res) { struct regulator_bulk_devres *devres = res; regulator_bulk_free(devres->num_consumers, devres->consumers); } /** * devm_regulator_bulk_get - managed get multiple regulator consumers * Loading @@ -157,29 +150,22 @@ EXPORT_SYMBOL_GPL(devm_regulator_put); int devm_regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers) { int i; struct regulator_bulk_devres *devres; int ret; for (i = 0; i < num_consumers; i++) consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { consumers[i].consumer = devm_regulator_get(dev, consumers[i].supply); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); dev_err(dev, "Failed to get supply '%s': %d\n", consumers[i].supply, ret); consumers[i].consumer = NULL; goto err; } } return 0; devres = devres_alloc(devm_regulator_bulk_release, sizeof(*devres), GFP_KERNEL); if (!devres) return -ENOMEM; err: for (i = 0; i < num_consumers && consumers[i].consumer; i++) devm_regulator_put(consumers[i].consumer); ret = regulator_bulk_get(dev, num_consumers, consumers); if (!ret) { devres->consumers = consumers; devres->num_consumers = num_consumers; devres_add(dev, devres); } else { devres_free(devres); } return ret; } Loading drivers/regulator/internal.h +10 −0 Original line number Diff line number Diff line Loading @@ -51,4 +51,14 @@ regulator_of_get_init_data(struct device *dev, } #endif enum regulator_get_type { NORMAL_GET, EXCLUSIVE_GET, OPTIONAL_GET, MAX_GET_TYPE }; struct regulator *_regulator_get(struct device *dev, const char *id, enum regulator_get_type get_type); #endif Loading
drivers/regulator/core.c +74 −71 Original line number Diff line number Diff line Loading @@ -1455,12 +1455,14 @@ static struct regulator_dev *regulator_lookup_by_name(const char *name) * lookup could succeed in the future. * * If successful, returns a struct regulator_dev that corresponds to the name * @supply and with the embedded struct device refcount incremented by one, * or NULL on failure. The refcount must be dropped by calling put_device(). * @supply and with the embedded struct device refcount incremented by one. * The refcount must be dropped by calling put_device(). * On failure one of the following ERR-PTR-encoded values is returned: * -ENODEV if lookup fails permanently, -EPROBE_DEFER if lookup could succeed * in the future. */ static struct regulator_dev *regulator_dev_lookup(struct device *dev, const char *supply, int *ret) const char *supply) { struct regulator_dev *r; struct device_node *node; Loading @@ -1476,16 +1478,12 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, r = of_find_regulator_by_node(node); if (r) return r; *ret = -EPROBE_DEFER; return NULL; } else { /* * If we couldn't even get the node then it's * not just that the device didn't register * yet, there's no node and we'll never * succeed. * We have a node, but there is no device. * assume it has not registered yet. */ *ret = -ENODEV; return ERR_PTR(-EPROBE_DEFER); } } Loading @@ -1506,13 +1504,16 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, if (strcmp(map->supply, supply) == 0 && get_device(&map->regulator->dev)) { mutex_unlock(®ulator_list_mutex); return map->regulator; r = map->regulator; break; } } mutex_unlock(®ulator_list_mutex); return NULL; if (r) return r; return ERR_PTR(-ENODEV); } static int regulator_resolve_supply(struct regulator_dev *rdev) Loading @@ -1529,8 +1530,10 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) if (rdev->supply) return 0; r = regulator_dev_lookup(dev, rdev->supply_name, &ret); if (!r) { r = regulator_dev_lookup(dev, rdev->supply_name); if (IS_ERR(r)) { ret = PTR_ERR(r); if (ret == -ENODEV) { /* * No supply was specified for this regulator and Loading Loading @@ -1580,69 +1583,72 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) } /* Internal regulator request function */ static struct regulator *_regulator_get(struct device *dev, const char *id, bool exclusive, bool allow_dummy) struct regulator *_regulator_get(struct device *dev, const char *id, enum regulator_get_type get_type) { struct regulator_dev *rdev; struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); const char *devname = NULL; struct regulator *regulator; const char *devname = dev ? dev_name(dev) : "deviceless"; int ret; if (get_type >= MAX_GET_TYPE) { dev_err(dev, "invalid type %d in %s\n", get_type, __func__); return ERR_PTR(-EINVAL); } if (id == NULL) { pr_err("get() with no identifier\n"); return ERR_PTR(-EINVAL); } if (dev) devname = dev_name(dev); if (have_full_constraints()) ret = -ENODEV; else ret = -EPROBE_DEFER; rdev = regulator_dev_lookup(dev, id, &ret); if (rdev) goto found; regulator = ERR_PTR(ret); rdev = regulator_dev_lookup(dev, id); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); /* * If we have return value from dev_lookup fail, we do not expect to * succeed, so, quit with appropriate error value * If regulator_dev_lookup() fails with error other * than -ENODEV our job here is done, we simply return it. */ if (ret && ret != -ENODEV) return regulator; if (ret != -ENODEV) return ERR_PTR(ret); if (!devname) devname = "deviceless"; if (!have_full_constraints()) { dev_warn(dev, "incomplete constraints, dummy supplies not allowed\n"); return ERR_PTR(-ENODEV); } switch (get_type) { case NORMAL_GET: /* * Assume that a regulator is physically present and enabled * even if it isn't hooked up and just provide a dummy. * Assume that a regulator is physically present and * enabled, even if it isn't hooked up, and just * provide a dummy. */ if (have_full_constraints() && allow_dummy) { pr_warn("%s supply %s not found, using dummy regulator\n", dev_warn(dev, "%s supply %s not found, using dummy regulator\n", devname, id); rdev = dummy_regulator_rdev; get_device(&rdev->dev); goto found; /* Don't log an error when called from regulator_get_optional() */ } else if (!have_full_constraints() || exclusive) { dev_warn(dev, "dummy supplies not allowed\n"); } break; return regulator; case EXCLUSIVE_GET: dev_warn(dev, "dummy supplies not allowed for exclusive requests\n"); /* fall through */ default: return ERR_PTR(-ENODEV); } } found: if (rdev->exclusive) { regulator = ERR_PTR(-EPERM); put_device(&rdev->dev); return regulator; } if (exclusive && rdev->open_count) { if (get_type == EXCLUSIVE_GET && rdev->open_count) { regulator = ERR_PTR(-EBUSY); put_device(&rdev->dev); return regulator; Loading @@ -1656,6 +1662,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, } if (!try_module_get(rdev->owner)) { regulator = ERR_PTR(-EPROBE_DEFER); put_device(&rdev->dev); return regulator; } Loading @@ -1669,7 +1676,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, } rdev->open_count++; if (exclusive) { if (get_type == EXCLUSIVE_GET) { rdev->exclusive = 1; ret = _regulator_is_enabled(rdev); Loading Loading @@ -1697,7 +1704,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, */ struct regulator *regulator_get(struct device *dev, const char *id) { return _regulator_get(dev, id, false, true); return _regulator_get(dev, id, NORMAL_GET); } EXPORT_SYMBOL_GPL(regulator_get); Loading @@ -1724,7 +1731,7 @@ EXPORT_SYMBOL_GPL(regulator_get); */ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) { return _regulator_get(dev, id, true, false); return _regulator_get(dev, id, EXCLUSIVE_GET); } EXPORT_SYMBOL_GPL(regulator_get_exclusive); Loading @@ -1750,7 +1757,7 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive); */ struct regulator *regulator_get_optional(struct device *dev, const char *id) { return _regulator_get(dev, id, false, false); return _regulator_get(dev, id, OPTIONAL_GET); } EXPORT_SYMBOL_GPL(regulator_get_optional); Loading Loading @@ -3660,7 +3667,7 @@ int regulator_bulk_disable(int num_consumers, for (++i; i < num_consumers; ++i) { r = regulator_enable(consumers[i].consumer); if (r != 0) pr_err("Failed to reename %s: %d\n", pr_err("Failed to re-enable %s: %d\n", consumers[i].supply, r); } Loading @@ -3686,21 +3693,17 @@ int regulator_bulk_force_disable(int num_consumers, struct regulator_bulk_data *consumers) { int i; int ret; int ret = 0; for (i = 0; i < num_consumers; i++) 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) { /* Store first error for reporting */ if (consumers[i].ret && !ret) ret = consumers[i].ret; goto out; } } return 0; out: return ret; } EXPORT_SYMBOL_GPL(regulator_bulk_force_disable); Loading
drivers/regulator/devres.c +26 −40 Original line number Diff line number Diff line Loading @@ -19,12 +19,6 @@ #include "internal.h" enum { NORMAL_GET, EXCLUSIVE_GET, OPTIONAL_GET, }; static void devm_regulator_release(struct device *dev, void *res) { regulator_put(*(struct regulator **)res); Loading @@ -39,20 +33,7 @@ static struct regulator *_devm_regulator_get(struct device *dev, const char *id, if (!ptr) return ERR_PTR(-ENOMEM); switch (get_type) { case NORMAL_GET: regulator = regulator_get(dev, id); break; case EXCLUSIVE_GET: regulator = regulator_get_exclusive(dev, id); break; case OPTIONAL_GET: regulator = regulator_get_optional(dev, id); break; default: regulator = ERR_PTR(-EINVAL); } regulator = _regulator_get(dev, id, get_type); if (!IS_ERR(regulator)) { *ptr = regulator; devres_add(dev, ptr); Loading Loading @@ -139,6 +120,18 @@ void devm_regulator_put(struct regulator *regulator) } EXPORT_SYMBOL_GPL(devm_regulator_put); struct regulator_bulk_devres { struct regulator_bulk_data *consumers; int num_consumers; }; static void devm_regulator_bulk_release(struct device *dev, void *res) { struct regulator_bulk_devres *devres = res; regulator_bulk_free(devres->num_consumers, devres->consumers); } /** * devm_regulator_bulk_get - managed get multiple regulator consumers * Loading @@ -157,29 +150,22 @@ EXPORT_SYMBOL_GPL(devm_regulator_put); int devm_regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers) { int i; struct regulator_bulk_devres *devres; int ret; for (i = 0; i < num_consumers; i++) consumers[i].consumer = NULL; for (i = 0; i < num_consumers; i++) { consumers[i].consumer = devm_regulator_get(dev, consumers[i].supply); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); dev_err(dev, "Failed to get supply '%s': %d\n", consumers[i].supply, ret); consumers[i].consumer = NULL; goto err; } } return 0; devres = devres_alloc(devm_regulator_bulk_release, sizeof(*devres), GFP_KERNEL); if (!devres) return -ENOMEM; err: for (i = 0; i < num_consumers && consumers[i].consumer; i++) devm_regulator_put(consumers[i].consumer); ret = regulator_bulk_get(dev, num_consumers, consumers); if (!ret) { devres->consumers = consumers; devres->num_consumers = num_consumers; devres_add(dev, devres); } else { devres_free(devres); } return ret; } Loading
drivers/regulator/internal.h +10 −0 Original line number Diff line number Diff line Loading @@ -51,4 +51,14 @@ regulator_of_get_init_data(struct device *dev, } #endif enum regulator_get_type { NORMAL_GET, EXCLUSIVE_GET, OPTIONAL_GET, MAX_GET_TYPE }; struct regulator *_regulator_get(struct device *dev, const char *id, enum regulator_get_type get_type); #endif