1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * devres.c -- Voltage/Current Regulator framework devres implementation. 4 * 5 * Copyright 2013 Linaro Ltd 6 */ 7 8 #include <linux/kernel.h> 9 #include <linux/err.h> 10 #include <linux/regmap.h> 11 #include <linux/regulator/consumer.h> 12 #include <linux/regulator/driver.h> 13 #include <linux/module.h> 14 15 #include "internal.h" 16 17 static void devm_regulator_release(struct device *dev, void *res) 18 { 19 regulator_put(*(struct regulator **)res); 20 } 21 22 static struct regulator *_devm_regulator_get(struct device *dev, const char *id, 23 int get_type) 24 { 25 struct regulator **ptr, *regulator; 26 27 ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); 28 if (!ptr) 29 return ERR_PTR(-ENOMEM); 30 31 regulator = _regulator_get(dev, id, get_type); 32 if (!IS_ERR(regulator)) { 33 *ptr = regulator; 34 devres_add(dev, ptr); 35 } else { 36 devres_free(ptr); 37 } 38 39 return regulator; 40 } 41 42 /** 43 * devm_regulator_get - Resource managed regulator_get() 44 * @dev: device for regulator "consumer" 45 * @id: Supply name or regulator ID. 46 * 47 * Managed regulator_get(). Regulators returned from this function are 48 * automatically regulator_put() on driver detach. See regulator_get() for more 49 * information. 50 */ 51 struct regulator *devm_regulator_get(struct device *dev, const char *id) 52 { 53 return _devm_regulator_get(dev, id, NORMAL_GET); 54 } 55 EXPORT_SYMBOL_GPL(devm_regulator_get); 56 57 /** 58 * devm_regulator_get_exclusive - Resource managed regulator_get_exclusive() 59 * @dev: device for regulator "consumer" 60 * @id: Supply name or regulator ID. 61 * 62 * Managed regulator_get_exclusive(). Regulators returned from this function 63 * are automatically regulator_put() on driver detach. See regulator_get() for 64 * more information. 65 */ 66 struct regulator *devm_regulator_get_exclusive(struct device *dev, 67 const char *id) 68 { 69 return _devm_regulator_get(dev, id, EXCLUSIVE_GET); 70 } 71 EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive); 72 73 /** 74 * devm_regulator_get_optional - Resource managed regulator_get_optional() 75 * @dev: device for regulator "consumer" 76 * @id: Supply name or regulator ID. 77 * 78 * Managed regulator_get_optional(). Regulators returned from this 79 * function are automatically regulator_put() on driver detach. See 80 * regulator_get_optional() for more information. 81 */ 82 struct regulator *devm_regulator_get_optional(struct device *dev, 83 const char *id) 84 { 85 return _devm_regulator_get(dev, id, OPTIONAL_GET); 86 } 87 EXPORT_SYMBOL_GPL(devm_regulator_get_optional); 88 89 static int devm_regulator_match(struct device *dev, void *res, void *data) 90 { 91 struct regulator **r = res; 92 if (!r || !*r) { 93 WARN_ON(!r || !*r); 94 return 0; 95 } 96 return *r == data; 97 } 98 99 /** 100 * devm_regulator_put - Resource managed regulator_put() 101 * @regulator: regulator to free 102 * 103 * Deallocate a regulator allocated with devm_regulator_get(). Normally 104 * this function will not need to be called and the resource management 105 * code will ensure that the resource is freed. 106 */ 107 void devm_regulator_put(struct regulator *regulator) 108 { 109 int rc; 110 111 rc = devres_release(regulator->dev, devm_regulator_release, 112 devm_regulator_match, regulator); 113 if (rc != 0) 114 WARN_ON(rc); 115 } 116 EXPORT_SYMBOL_GPL(devm_regulator_put); 117 118 struct regulator_bulk_devres { 119 struct regulator_bulk_data *consumers; 120 int num_consumers; 121 }; 122 123 static void devm_regulator_bulk_release(struct device *dev, void *res) 124 { 125 struct regulator_bulk_devres *devres = res; 126 127 regulator_bulk_free(devres->num_consumers, devres->consumers); 128 } 129 130 /** 131 * devm_regulator_bulk_get - managed get multiple regulator consumers 132 * 133 * @dev: Device to supply 134 * @num_consumers: Number of consumers to register 135 * @consumers: Configuration of consumers; clients are stored here. 136 * 137 * @return 0 on success, an errno on failure. 138 * 139 * This helper function allows drivers to get several regulator 140 * consumers in one operation with management, the regulators will 141 * automatically be freed when the device is unbound. If any of the 142 * regulators cannot be acquired then any regulators that were 143 * allocated will be freed before returning to the caller. 144 */ 145 int devm_regulator_bulk_get(struct device *dev, int num_consumers, 146 struct regulator_bulk_data *consumers) 147 { 148 struct regulator_bulk_devres *devres; 149 int ret; 150 151 devres = devres_alloc(devm_regulator_bulk_release, 152 sizeof(*devres), GFP_KERNEL); 153 if (!devres) 154 return -ENOMEM; 155 156 ret = regulator_bulk_get(dev, num_consumers, consumers); 157 if (!ret) { 158 devres->consumers = consumers; 159 devres->num_consumers = num_consumers; 160 devres_add(dev, devres); 161 } else { 162 devres_free(devres); 163 } 164 165 return ret; 166 } 167 EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); 168 169 static void devm_rdev_release(struct device *dev, void *res) 170 { 171 regulator_unregister(*(struct regulator_dev **)res); 172 } 173 174 /** 175 * devm_regulator_register - Resource managed regulator_register() 176 * @regulator_desc: regulator to register 177 * @config: runtime configuration for regulator 178 * 179 * Called by regulator drivers to register a regulator. Returns a 180 * valid pointer to struct regulator_dev on success or an ERR_PTR() on 181 * error. The regulator will automatically be released when the device 182 * is unbound. 183 */ 184 struct regulator_dev *devm_regulator_register(struct device *dev, 185 const struct regulator_desc *regulator_desc, 186 const struct regulator_config *config) 187 { 188 struct regulator_dev **ptr, *rdev; 189 190 ptr = devres_alloc(devm_rdev_release, sizeof(*ptr), 191 GFP_KERNEL); 192 if (!ptr) 193 return ERR_PTR(-ENOMEM); 194 195 rdev = regulator_register(regulator_desc, config); 196 if (!IS_ERR(rdev)) { 197 *ptr = rdev; 198 devres_add(dev, ptr); 199 } else { 200 devres_free(ptr); 201 } 202 203 return rdev; 204 } 205 EXPORT_SYMBOL_GPL(devm_regulator_register); 206 207 static int devm_rdev_match(struct device *dev, void *res, void *data) 208 { 209 struct regulator_dev **r = res; 210 if (!r || !*r) { 211 WARN_ON(!r || !*r); 212 return 0; 213 } 214 return *r == data; 215 } 216 217 /** 218 * devm_regulator_unregister - Resource managed regulator_unregister() 219 * @regulator: regulator to free 220 * 221 * Unregister a regulator registered with devm_regulator_register(). 222 * Normally this function will not need to be called and the resource 223 * management code will ensure that the resource is freed. 224 */ 225 void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev) 226 { 227 int rc; 228 229 rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev); 230 if (rc != 0) 231 WARN_ON(rc); 232 } 233 EXPORT_SYMBOL_GPL(devm_regulator_unregister); 234 235 struct regulator_supply_alias_match { 236 struct device *dev; 237 const char *id; 238 }; 239 240 static int devm_regulator_match_supply_alias(struct device *dev, void *res, 241 void *data) 242 { 243 struct regulator_supply_alias_match *match = res; 244 struct regulator_supply_alias_match *target = data; 245 246 return match->dev == target->dev && strcmp(match->id, target->id) == 0; 247 } 248 249 static void devm_regulator_destroy_supply_alias(struct device *dev, void *res) 250 { 251 struct regulator_supply_alias_match *match = res; 252 253 regulator_unregister_supply_alias(match->dev, match->id); 254 } 255 256 /** 257 * devm_regulator_register_supply_alias - Resource managed 258 * regulator_register_supply_alias() 259 * 260 * @dev: device that will be given as the regulator "consumer" 261 * @id: Supply name or regulator ID 262 * @alias_dev: device that should be used to lookup the supply 263 * @alias_id: Supply name or regulator ID that should be used to lookup the 264 * supply 265 * 266 * The supply alias will automatically be unregistered when the source 267 * device is unbound. 268 */ 269 int devm_regulator_register_supply_alias(struct device *dev, const char *id, 270 struct device *alias_dev, 271 const char *alias_id) 272 { 273 struct regulator_supply_alias_match *match; 274 int ret; 275 276 match = devres_alloc(devm_regulator_destroy_supply_alias, 277 sizeof(struct regulator_supply_alias_match), 278 GFP_KERNEL); 279 if (!match) 280 return -ENOMEM; 281 282 match->dev = dev; 283 match->id = id; 284 285 ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id); 286 if (ret < 0) { 287 devres_free(match); 288 return ret; 289 } 290 291 devres_add(dev, match); 292 293 return 0; 294 } 295 EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias); 296 297 /** 298 * devm_regulator_unregister_supply_alias - Resource managed 299 * regulator_unregister_supply_alias() 300 * 301 * @dev: device that will be given as the regulator "consumer" 302 * @id: Supply name or regulator ID 303 * 304 * Unregister an alias registered with 305 * devm_regulator_register_supply_alias(). Normally this function 306 * will not need to be called and the resource management code 307 * will ensure that the resource is freed. 308 */ 309 void devm_regulator_unregister_supply_alias(struct device *dev, const char *id) 310 { 311 struct regulator_supply_alias_match match; 312 int rc; 313 314 match.dev = dev; 315 match.id = id; 316 317 rc = devres_release(dev, devm_regulator_destroy_supply_alias, 318 devm_regulator_match_supply_alias, &match); 319 if (rc != 0) 320 WARN_ON(rc); 321 } 322 EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias); 323 324 /** 325 * devm_regulator_bulk_register_supply_alias - Managed register 326 * multiple aliases 327 * 328 * @dev: device that will be given as the regulator "consumer" 329 * @id: List of supply names or regulator IDs 330 * @alias_dev: device that should be used to lookup the supply 331 * @alias_id: List of supply names or regulator IDs that should be used to 332 * lookup the supply 333 * @num_id: Number of aliases to register 334 * 335 * @return 0 on success, an errno on failure. 336 * 337 * This helper function allows drivers to register several supply 338 * aliases in one operation, the aliases will be automatically 339 * unregisters when the source device is unbound. If any of the 340 * aliases cannot be registered any aliases that were registered 341 * will be removed before returning to the caller. 342 */ 343 int devm_regulator_bulk_register_supply_alias(struct device *dev, 344 const char *const *id, 345 struct device *alias_dev, 346 const char *const *alias_id, 347 int num_id) 348 { 349 int i; 350 int ret; 351 352 for (i = 0; i < num_id; ++i) { 353 ret = devm_regulator_register_supply_alias(dev, id[i], 354 alias_dev, 355 alias_id[i]); 356 if (ret < 0) 357 goto err; 358 } 359 360 return 0; 361 362 err: 363 dev_err(dev, 364 "Failed to create supply alias %s,%s -> %s,%s\n", 365 id[i], dev_name(dev), alias_id[i], dev_name(alias_dev)); 366 367 while (--i >= 0) 368 devm_regulator_unregister_supply_alias(dev, id[i]); 369 370 return ret; 371 } 372 EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias); 373 374 /** 375 * devm_regulator_bulk_unregister_supply_alias - Managed unregister 376 * multiple aliases 377 * 378 * @dev: device that will be given as the regulator "consumer" 379 * @id: List of supply names or regulator IDs 380 * @num_id: Number of aliases to unregister 381 * 382 * Unregister aliases registered with 383 * devm_regulator_bulk_register_supply_alias(). Normally this function 384 * will not need to be called and the resource management code 385 * will ensure that the resource is freed. 386 */ 387 void devm_regulator_bulk_unregister_supply_alias(struct device *dev, 388 const char *const *id, 389 int num_id) 390 { 391 int i; 392 393 for (i = 0; i < num_id; ++i) 394 devm_regulator_unregister_supply_alias(dev, id[i]); 395 } 396 EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias); 397 398 struct regulator_notifier_match { 399 struct regulator *regulator; 400 struct notifier_block *nb; 401 }; 402 403 static int devm_regulator_match_notifier(struct device *dev, void *res, 404 void *data) 405 { 406 struct regulator_notifier_match *match = res; 407 struct regulator_notifier_match *target = data; 408 409 return match->regulator == target->regulator && match->nb == target->nb; 410 } 411 412 static void devm_regulator_destroy_notifier(struct device *dev, void *res) 413 { 414 struct regulator_notifier_match *match = res; 415 416 regulator_unregister_notifier(match->regulator, match->nb); 417 } 418 419 /** 420 * devm_regulator_register_notifier - Resource managed 421 * regulator_register_notifier 422 * 423 * @regulator: regulator source 424 * @nb: notifier block 425 * 426 * The notifier will be registers under the consumer device and be 427 * automatically be unregistered when the source device is unbound. 428 */ 429 int devm_regulator_register_notifier(struct regulator *regulator, 430 struct notifier_block *nb) 431 { 432 struct regulator_notifier_match *match; 433 int ret; 434 435 match = devres_alloc(devm_regulator_destroy_notifier, 436 sizeof(struct regulator_notifier_match), 437 GFP_KERNEL); 438 if (!match) 439 return -ENOMEM; 440 441 match->regulator = regulator; 442 match->nb = nb; 443 444 ret = regulator_register_notifier(regulator, nb); 445 if (ret < 0) { 446 devres_free(match); 447 return ret; 448 } 449 450 devres_add(regulator->dev, match); 451 452 return 0; 453 } 454 EXPORT_SYMBOL_GPL(devm_regulator_register_notifier); 455 456 /** 457 * devm_regulator_unregister_notifier - Resource managed 458 * regulator_unregister_notifier() 459 * 460 * @regulator: regulator source 461 * @nb: notifier block 462 * 463 * Unregister a notifier registered with devm_regulator_register_notifier(). 464 * Normally this function will not need to be called and the resource 465 * management code will ensure that the resource is freed. 466 */ 467 void devm_regulator_unregister_notifier(struct regulator *regulator, 468 struct notifier_block *nb) 469 { 470 struct regulator_notifier_match match; 471 int rc; 472 473 match.regulator = regulator; 474 match.nb = nb; 475 476 rc = devres_release(regulator->dev, devm_regulator_destroy_notifier, 477 devm_regulator_match_notifier, &match); 478 if (rc != 0) 479 WARN_ON(rc); 480 } 481 EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier); 482