0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/err.h>
0010 #include <linux/regmap.h>
0011 #include <linux/regulator/consumer.h>
0012 #include <linux/regulator/driver.h>
0013 #include <linux/module.h>
0014
0015 #include "internal.h"
0016
0017 static void devm_regulator_release(struct device *dev, void *res)
0018 {
0019 regulator_put(*(struct regulator **)res);
0020 }
0021
0022 static struct regulator *_devm_regulator_get(struct device *dev, const char *id,
0023 int get_type)
0024 {
0025 struct regulator **ptr, *regulator;
0026
0027 ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
0028 if (!ptr)
0029 return ERR_PTR(-ENOMEM);
0030
0031 regulator = _regulator_get(dev, id, get_type);
0032 if (!IS_ERR(regulator)) {
0033 *ptr = regulator;
0034 devres_add(dev, ptr);
0035 } else {
0036 devres_free(ptr);
0037 }
0038
0039 return regulator;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 struct regulator *devm_regulator_get(struct device *dev, const char *id)
0052 {
0053 return _devm_regulator_get(dev, id, NORMAL_GET);
0054 }
0055 EXPORT_SYMBOL_GPL(devm_regulator_get);
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 struct regulator *devm_regulator_get_exclusive(struct device *dev,
0067 const char *id)
0068 {
0069 return _devm_regulator_get(dev, id, EXCLUSIVE_GET);
0070 }
0071 EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 struct regulator *devm_regulator_get_optional(struct device *dev,
0083 const char *id)
0084 {
0085 return _devm_regulator_get(dev, id, OPTIONAL_GET);
0086 }
0087 EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
0088
0089 static int devm_regulator_match(struct device *dev, void *res, void *data)
0090 {
0091 struct regulator **r = res;
0092 if (!r || !*r) {
0093 WARN_ON(!r || !*r);
0094 return 0;
0095 }
0096 return *r == data;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 void devm_regulator_put(struct regulator *regulator)
0108 {
0109 int rc;
0110
0111 rc = devres_release(regulator->dev, devm_regulator_release,
0112 devm_regulator_match, regulator);
0113 if (rc != 0)
0114 WARN_ON(rc);
0115 }
0116 EXPORT_SYMBOL_GPL(devm_regulator_put);
0117
0118 struct regulator_bulk_devres {
0119 struct regulator_bulk_data *consumers;
0120 int num_consumers;
0121 };
0122
0123 static void devm_regulator_bulk_release(struct device *dev, void *res)
0124 {
0125 struct regulator_bulk_devres *devres = res;
0126
0127 regulator_bulk_free(devres->num_consumers, devres->consumers);
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 int devm_regulator_bulk_get(struct device *dev, int num_consumers,
0146 struct regulator_bulk_data *consumers)
0147 {
0148 struct regulator_bulk_devres *devres;
0149 int ret;
0150
0151 devres = devres_alloc(devm_regulator_bulk_release,
0152 sizeof(*devres), GFP_KERNEL);
0153 if (!devres)
0154 return -ENOMEM;
0155
0156 ret = regulator_bulk_get(dev, num_consumers, consumers);
0157 if (!ret) {
0158 devres->consumers = consumers;
0159 devres->num_consumers = num_consumers;
0160 devres_add(dev, devres);
0161 } else {
0162 devres_free(devres);
0163 }
0164
0165 return ret;
0166 }
0167 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 int devm_regulator_bulk_get_const(struct device *dev, int num_consumers,
0184 const struct regulator_bulk_data *in_consumers,
0185 struct regulator_bulk_data **out_consumers)
0186 {
0187 *out_consumers = devm_kmemdup(dev, in_consumers,
0188 num_consumers * sizeof(*in_consumers),
0189 GFP_KERNEL);
0190 if (*out_consumers == NULL)
0191 return -ENOMEM;
0192
0193 return devm_regulator_bulk_get(dev, num_consumers, *out_consumers);
0194 }
0195 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get_const);
0196
0197 static void devm_rdev_release(struct device *dev, void *res)
0198 {
0199 regulator_unregister(*(struct regulator_dev **)res);
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 struct regulator_dev *devm_regulator_register(struct device *dev,
0214 const struct regulator_desc *regulator_desc,
0215 const struct regulator_config *config)
0216 {
0217 struct regulator_dev **ptr, *rdev;
0218
0219 ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
0220 GFP_KERNEL);
0221 if (!ptr)
0222 return ERR_PTR(-ENOMEM);
0223
0224 rdev = regulator_register(regulator_desc, config);
0225 if (!IS_ERR(rdev)) {
0226 *ptr = rdev;
0227 devres_add(dev, ptr);
0228 } else {
0229 devres_free(ptr);
0230 }
0231
0232 return rdev;
0233 }
0234 EXPORT_SYMBOL_GPL(devm_regulator_register);
0235
0236 struct regulator_supply_alias_match {
0237 struct device *dev;
0238 const char *id;
0239 };
0240
0241 static int devm_regulator_match_supply_alias(struct device *dev, void *res,
0242 void *data)
0243 {
0244 struct regulator_supply_alias_match *match = res;
0245 struct regulator_supply_alias_match *target = data;
0246
0247 return match->dev == target->dev && strcmp(match->id, target->id) == 0;
0248 }
0249
0250 static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
0251 {
0252 struct regulator_supply_alias_match *match = res;
0253
0254 regulator_unregister_supply_alias(match->dev, match->id);
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 int devm_regulator_register_supply_alias(struct device *dev, const char *id,
0271 struct device *alias_dev,
0272 const char *alias_id)
0273 {
0274 struct regulator_supply_alias_match *match;
0275 int ret;
0276
0277 match = devres_alloc(devm_regulator_destroy_supply_alias,
0278 sizeof(struct regulator_supply_alias_match),
0279 GFP_KERNEL);
0280 if (!match)
0281 return -ENOMEM;
0282
0283 match->dev = dev;
0284 match->id = id;
0285
0286 ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id);
0287 if (ret < 0) {
0288 devres_free(match);
0289 return ret;
0290 }
0291
0292 devres_add(dev, match);
0293
0294 return 0;
0295 }
0296 EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
0297
0298 static void devm_regulator_unregister_supply_alias(struct device *dev,
0299 const char *id)
0300 {
0301 struct regulator_supply_alias_match match;
0302 int rc;
0303
0304 match.dev = dev;
0305 match.id = id;
0306
0307 rc = devres_release(dev, devm_regulator_destroy_supply_alias,
0308 devm_regulator_match_supply_alias, &match);
0309 if (rc != 0)
0310 WARN_ON(rc);
0311 }
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332 int devm_regulator_bulk_register_supply_alias(struct device *dev,
0333 const char *const *id,
0334 struct device *alias_dev,
0335 const char *const *alias_id,
0336 int num_id)
0337 {
0338 int i;
0339 int ret;
0340
0341 for (i = 0; i < num_id; ++i) {
0342 ret = devm_regulator_register_supply_alias(dev, id[i],
0343 alias_dev,
0344 alias_id[i]);
0345 if (ret < 0)
0346 goto err;
0347 }
0348
0349 return 0;
0350
0351 err:
0352 dev_err(dev,
0353 "Failed to create supply alias %s,%s -> %s,%s\n",
0354 id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
0355
0356 while (--i >= 0)
0357 devm_regulator_unregister_supply_alias(dev, id[i]);
0358
0359 return ret;
0360 }
0361 EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
0362
0363 struct regulator_notifier_match {
0364 struct regulator *regulator;
0365 struct notifier_block *nb;
0366 };
0367
0368 static int devm_regulator_match_notifier(struct device *dev, void *res,
0369 void *data)
0370 {
0371 struct regulator_notifier_match *match = res;
0372 struct regulator_notifier_match *target = data;
0373
0374 return match->regulator == target->regulator && match->nb == target->nb;
0375 }
0376
0377 static void devm_regulator_destroy_notifier(struct device *dev, void *res)
0378 {
0379 struct regulator_notifier_match *match = res;
0380
0381 regulator_unregister_notifier(match->regulator, match->nb);
0382 }
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 int devm_regulator_register_notifier(struct regulator *regulator,
0395 struct notifier_block *nb)
0396 {
0397 struct regulator_notifier_match *match;
0398 int ret;
0399
0400 match = devres_alloc(devm_regulator_destroy_notifier,
0401 sizeof(struct regulator_notifier_match),
0402 GFP_KERNEL);
0403 if (!match)
0404 return -ENOMEM;
0405
0406 match->regulator = regulator;
0407 match->nb = nb;
0408
0409 ret = regulator_register_notifier(regulator, nb);
0410 if (ret < 0) {
0411 devres_free(match);
0412 return ret;
0413 }
0414
0415 devres_add(regulator->dev, match);
0416
0417 return 0;
0418 }
0419 EXPORT_SYMBOL_GPL(devm_regulator_register_notifier);
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432 void devm_regulator_unregister_notifier(struct regulator *regulator,
0433 struct notifier_block *nb)
0434 {
0435 struct regulator_notifier_match match;
0436 int rc;
0437
0438 match.regulator = regulator;
0439 match.nb = nb;
0440
0441 rc = devres_release(regulator->dev, devm_regulator_destroy_notifier,
0442 devm_regulator_match_notifier, &match);
0443 if (rc != 0)
0444 WARN_ON(rc);
0445 }
0446 EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
0447
0448 static void regulator_irq_helper_drop(void *res)
0449 {
0450 regulator_irq_helper_cancel(&res);
0451 }
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478 void *devm_regulator_irq_helper(struct device *dev,
0479 const struct regulator_irq_desc *d, int irq,
0480 int irq_flags, int common_errs,
0481 int *per_rdev_errs,
0482 struct regulator_dev **rdev, int rdev_amount)
0483 {
0484 void *ptr;
0485 int ret;
0486
0487 ptr = regulator_irq_helper(dev, d, irq, irq_flags, common_errs,
0488 per_rdev_errs, rdev, rdev_amount);
0489 if (IS_ERR(ptr))
0490 return ptr;
0491
0492 ret = devm_add_action_or_reset(dev, regulator_irq_helper_drop, ptr);
0493 if (ret)
0494 return ERR_PTR(ret);
0495
0496 return ptr;
0497 }
0498 EXPORT_SYMBOL_GPL(devm_regulator_irq_helper);