Branch data Line data Source code
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 : 0 : static void devm_regulator_release(struct device *dev, void *res) 18 : : { 19 : 0 : regulator_put(*(struct regulator **)res); 20 : 0 : } 21 : : 22 : 0 : 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 : 0 : if (!ptr) 29 : : return ERR_PTR(-ENOMEM); 30 : : 31 : 0 : regulator = _regulator_get(dev, id, get_type); 32 : 0 : if (!IS_ERR(regulator)) { 33 : 0 : *ptr = regulator; 34 : 0 : devres_add(dev, ptr); 35 : : } else { 36 : 0 : devres_free(ptr); 37 : : } 38 : : 39 : 0 : 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 : 0 : struct regulator *devm_regulator_get(struct device *dev, const char *id) 52 : : { 53 : 0 : 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 : 0 : struct regulator *devm_regulator_get_exclusive(struct device *dev, 67 : : const char *id) 68 : : { 69 : 0 : 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 : 0 : struct regulator *devm_regulator_get_optional(struct device *dev, 83 : : const char *id) 84 : : { 85 : 0 : return _devm_regulator_get(dev, id, OPTIONAL_GET); 86 : : } 87 : : EXPORT_SYMBOL_GPL(devm_regulator_get_optional); 88 : : 89 : 0 : static int devm_regulator_match(struct device *dev, void *res, void *data) 90 : : { 91 : : struct regulator **r = res; 92 : 0 : if (!r || !*r) { 93 : 0 : WARN_ON(!r || !*r); 94 : : return 0; 95 : : } 96 : 0 : 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 : 0 : void devm_regulator_put(struct regulator *regulator) 108 : : { 109 : : int rc; 110 : : 111 : 0 : rc = devres_release(regulator->dev, devm_regulator_release, 112 : : devm_regulator_match, regulator); 113 : 0 : if (rc != 0) 114 : 0 : WARN_ON(rc); 115 : 0 : } 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 : 0 : static void devm_regulator_bulk_release(struct device *dev, void *res) 124 : : { 125 : : struct regulator_bulk_devres *devres = res; 126 : : 127 : 0 : regulator_bulk_free(devres->num_consumers, devres->consumers); 128 : 0 : } 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 : 0 : 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 : 0 : if (!devres) 154 : : return -ENOMEM; 155 : : 156 : 0 : ret = regulator_bulk_get(dev, num_consumers, consumers); 157 : 0 : if (!ret) { 158 : 0 : devres->consumers = consumers; 159 : 0 : devres->num_consumers = num_consumers; 160 : 0 : devres_add(dev, devres); 161 : : } else { 162 : 0 : devres_free(devres); 163 : : } 164 : : 165 : 0 : return ret; 166 : : } 167 : : EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); 168 : : 169 : 0 : static void devm_rdev_release(struct device *dev, void *res) 170 : : { 171 : 0 : regulator_unregister(*(struct regulator_dev **)res); 172 : 0 : } 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 : 3 : 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 : 3 : if (!ptr) 193 : : return ERR_PTR(-ENOMEM); 194 : : 195 : 3 : rdev = regulator_register(regulator_desc, config); 196 : 3 : if (!IS_ERR(rdev)) { 197 : 3 : *ptr = rdev; 198 : 3 : devres_add(dev, ptr); 199 : : } else { 200 : 0 : devres_free(ptr); 201 : : } 202 : : 203 : 3 : return rdev; 204 : : } 205 : : EXPORT_SYMBOL_GPL(devm_regulator_register); 206 : : 207 : 0 : static int devm_rdev_match(struct device *dev, void *res, void *data) 208 : : { 209 : : struct regulator_dev **r = res; 210 : 0 : if (!r || !*r) { 211 : 0 : WARN_ON(!r || !*r); 212 : : return 0; 213 : : } 214 : 0 : 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 : 0 : void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev) 226 : : { 227 : : int rc; 228 : : 229 : 0 : rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev); 230 : 0 : if (rc != 0) 231 : 0 : WARN_ON(rc); 232 : 0 : } 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 : 0 : 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 : 0 : return match->dev == target->dev && strcmp(match->id, target->id) == 0; 247 : : } 248 : : 249 : 0 : static void devm_regulator_destroy_supply_alias(struct device *dev, void *res) 250 : : { 251 : : struct regulator_supply_alias_match *match = res; 252 : : 253 : 0 : regulator_unregister_supply_alias(match->dev, match->id); 254 : 0 : } 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 : 0 : 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 : 0 : if (!match) 280 : : return -ENOMEM; 281 : : 282 : 0 : match->dev = dev; 283 : 0 : match->id = id; 284 : : 285 : 0 : ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id); 286 : 0 : if (ret < 0) { 287 : 0 : devres_free(match); 288 : 0 : return ret; 289 : : } 290 : : 291 : 0 : devres_add(dev, match); 292 : : 293 : 0 : 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 : 0 : 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 : 0 : match.dev = dev; 315 : 0 : match.id = id; 316 : : 317 : 0 : rc = devres_release(dev, devm_regulator_destroy_supply_alias, 318 : : devm_regulator_match_supply_alias, &match); 319 : 0 : if (rc != 0) 320 : 0 : WARN_ON(rc); 321 : 0 : } 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 : 0 : 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 : 0 : for (i = 0; i < num_id; ++i) { 353 : 0 : ret = devm_regulator_register_supply_alias(dev, id[i], 354 : : alias_dev, 355 : 0 : alias_id[i]); 356 : 0 : if (ret < 0) 357 : : goto err; 358 : : } 359 : : 360 : : return 0; 361 : : 362 : : err: 363 : 0 : 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 : 0 : while (--i >= 0) 368 : 0 : devm_regulator_unregister_supply_alias(dev, id[i]); 369 : : 370 : 0 : 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 : 0 : 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 : 0 : for (i = 0; i < num_id; ++i) 394 : 0 : devm_regulator_unregister_supply_alias(dev, id[i]); 395 : 0 : } 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 : 0 : 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 : 0 : return match->regulator == target->regulator && match->nb == target->nb; 410 : : } 411 : : 412 : 0 : static void devm_regulator_destroy_notifier(struct device *dev, void *res) 413 : : { 414 : : struct regulator_notifier_match *match = res; 415 : : 416 : 0 : regulator_unregister_notifier(match->regulator, match->nb); 417 : 0 : } 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 : 0 : 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 : 0 : if (!match) 439 : : return -ENOMEM; 440 : : 441 : 0 : match->regulator = regulator; 442 : 0 : match->nb = nb; 443 : : 444 : 0 : ret = regulator_register_notifier(regulator, nb); 445 : 0 : if (ret < 0) { 446 : 0 : devres_free(match); 447 : 0 : return ret; 448 : : } 449 : : 450 : 0 : devres_add(regulator->dev, match); 451 : : 452 : 0 : 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 : 0 : 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 : 0 : match.regulator = regulator; 474 : 0 : match.nb = nb; 475 : : 476 : 0 : rc = devres_release(regulator->dev, devm_regulator_destroy_notifier, 477 : : devm_regulator_match_notifier, &match); 478 : 0 : if (rc != 0) 479 : 0 : WARN_ON(rc); 480 : 0 : } 481 : : EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);