Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Add of_regulator_get_optional() and Fix MTK Power

Merge series from Chen-Yu Tsai <wenst@chromium.org>:

At ELCE, Sebastian told me about his recent work on adding regulator
supply support to the Rockchip power domain driver [2], how the MediaTek
driver has been using the existing devm_regulator_get() API and
reassigning different device nodes to the device doing the lookup, and
how the new of_regulator_get_optional() is the proper fit for this.

Patch 1 adds a new of_regulator_get_optional() function to look up
regulator supplies using device tree nodes.

Patch 2 adds a devres version of the aforementioned function at
Sebastian's request for the two power domain drivers.

+135 -14
+2 -2
drivers/regulator/core.c
··· 1959 1959 regulator_supply_alias(&dev, &supply); 1960 1960 1961 1961 /* first do a dt based lookup */ 1962 - if (dev && dev->of_node) { 1963 - r = of_regulator_dev_lookup(dev, supply); 1962 + if (dev_of_node(dev)) { 1963 + r = of_regulator_dev_lookup(dev, dev_of_node(dev), supply); 1964 1964 if (!IS_ERR(r)) 1965 1965 return r; 1966 1966 if (PTR_ERR(r) == -EPROBE_DEFER)
+39
drivers/regulator/devres.c
··· 749 749 return ptr; 750 750 } 751 751 EXPORT_SYMBOL_GPL(devm_regulator_irq_helper); 752 + 753 + #if IS_ENABLED(CONFIG_OF) 754 + static struct regulator *_devm_of_regulator_get(struct device *dev, struct device_node *node, 755 + const char *id, int get_type) 756 + { 757 + struct regulator **ptr, *regulator; 758 + 759 + ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); 760 + if (!ptr) 761 + return ERR_PTR(-ENOMEM); 762 + 763 + regulator = _of_regulator_get(dev, node, id, get_type); 764 + if (!IS_ERR(regulator)) { 765 + *ptr = regulator; 766 + devres_add(dev, ptr); 767 + } else { 768 + devres_free(ptr); 769 + } 770 + 771 + return regulator; 772 + } 773 + 774 + /** 775 + * devm_of_regulator_get_optional - Resource managed of_regulator_get_optional() 776 + * @dev: device used for dev_printk() messages and resource lifetime management 777 + * @node: device node for regulator "consumer" 778 + * @id: supply name or regulator ID. 779 + * 780 + * Managed regulator_get_optional(). Regulators returned from this 781 + * function are automatically regulator_put() on driver detach. See 782 + * of_regulator_get_optional() for more information. 783 + */ 784 + struct regulator *devm_of_regulator_get_optional(struct device *dev, struct device_node *node, 785 + const char *id) 786 + { 787 + return _devm_of_regulator_get(dev, node, id, OPTIONAL_GET); 788 + } 789 + EXPORT_SYMBOL_GPL(devm_of_regulator_get_optional); 790 + #endif
+12 -6
drivers/regulator/internal.h
··· 65 65 return container_of(dev, struct regulator_dev, dev); 66 66 } 67 67 68 + enum regulator_get_type { 69 + NORMAL_GET, 70 + EXCLUSIVE_GET, 71 + OPTIONAL_GET, 72 + MAX_GET_TYPE 73 + }; 74 + 68 75 #ifdef CONFIG_OF 69 76 struct regulator_dev *of_regulator_dev_lookup(struct device *dev, 77 + struct device_node *np, 70 78 const char *supply); 71 79 struct regulator_init_data *regulator_of_get_init_data(struct device *dev, 72 80 const struct regulator_desc *desc, 73 81 struct regulator_config *config, 74 82 struct device_node **node); 83 + 84 + struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, 85 + const char *id, enum regulator_get_type get_type); 75 86 76 87 struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev, 77 88 int index); ··· 93 82 94 83 #else 95 84 static inline struct regulator_dev *of_regulator_dev_lookup(struct device *dev, 85 + struct device_node *np, 96 86 const char *supply) 97 87 { 98 88 return ERR_PTR(-ENODEV); ··· 126 114 } 127 115 128 116 #endif 129 - enum regulator_get_type { 130 - NORMAL_GET, 131 - EXCLUSIVE_GET, 132 - OPTIONAL_GET, 133 - MAX_GET_TYPE 134 - }; 135 117 136 118 int _regulator_get_common_check(struct device *dev, const char *id, 137 119 enum regulator_get_type get_type);
+45 -6
drivers/regulator/of_regulator.c
··· 588 588 589 589 /** 590 590 * of_get_regulator - get a regulator device node based on supply name 591 - * @dev: Device pointer for the consumer (of regulator) device 591 + * @dev: Device pointer for dev_printk() messages 592 + * @node: Device node pointer for supply property lookup 592 593 * @supply: regulator supply name 593 594 * 594 595 * Extract the regulator device node corresponding to the supply name. ··· 597 596 * Return: Pointer to the &struct device_node corresponding to the regulator 598 597 * if found, or %NULL if not found. 599 598 */ 600 - static struct device_node *of_get_regulator(struct device *dev, const char *supply) 599 + static struct device_node *of_get_regulator(struct device *dev, struct device_node *node, 600 + const char *supply) 601 601 { 602 602 struct device_node *regnode = NULL; 603 603 char prop_name[64]; /* 64 is max size of property name */ 604 604 605 - dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); 605 + dev_dbg(dev, "Looking up %s-supply from device node %pOF\n", supply, node); 606 606 607 607 snprintf(prop_name, 64, "%s-supply", supply); 608 - regnode = of_parse_phandle(dev->of_node, prop_name, 0); 608 + regnode = of_parse_phandle(node, prop_name, 0); 609 609 if (regnode) 610 610 return regnode; 611 611 ··· 630 628 /** 631 629 * of_regulator_dev_lookup - lookup a regulator device with device tree only 632 630 * @dev: Device pointer for regulator supply lookup. 631 + * @np: Device node pointer for regulator supply lookup. 633 632 * @supply: Supply name or regulator ID. 634 633 * 635 634 * Return: Pointer to the &struct regulator_dev on success, or ERR_PTR() ··· 645 642 * * -%ENODEV if lookup fails permanently. 646 643 * * -%EPROBE_DEFER if lookup could succeed in the future. 647 644 */ 648 - struct regulator_dev *of_regulator_dev_lookup(struct device *dev, 645 + struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_node *np, 649 646 const char *supply) 650 647 { 651 648 struct regulator_dev *r; 652 649 struct device_node *node; 653 650 654 - node = of_get_regulator(dev, supply); 651 + node = of_get_regulator(dev, np, supply); 655 652 if (node) { 656 653 r = of_find_regulator_by_node(node); 657 654 of_node_put(node); ··· 667 664 668 665 return ERR_PTR(-ENODEV); 669 666 } 667 + 668 + struct regulator *_of_regulator_get(struct device *dev, struct device_node *node, 669 + const char *id, enum regulator_get_type get_type) 670 + { 671 + struct regulator_dev *r; 672 + int ret; 673 + 674 + ret = _regulator_get_common_check(dev, id, get_type); 675 + if (ret) 676 + return ERR_PTR(ret); 677 + 678 + r = of_regulator_dev_lookup(dev, node, id); 679 + return _regulator_get_common(r, dev, id, get_type); 680 + } 681 + 682 + /** 683 + * of_regulator_get_optional - get optional regulator via device tree lookup 684 + * @dev: device used for dev_printk() messages 685 + * @node: device node for regulator "consumer" 686 + * @id: Supply name 687 + * 688 + * Return: pointer to struct regulator corresponding to the regulator producer, 689 + * or PTR_ERR() encoded error number. 690 + * 691 + * This is intended for use by consumers that want to get a regulator 692 + * supply directly from a device node, and can and want to deal with 693 + * absence of such supplies. This will _not_ consider supply aliases. 694 + * See regulator_dev_lookup(). 695 + */ 696 + struct regulator *of_regulator_get_optional(struct device *dev, 697 + struct device_node *node, 698 + const char *id) 699 + { 700 + return _of_regulator_get(dev, node, id, OPTIONAL_GET); 701 + } 702 + EXPORT_SYMBOL_GPL(of_regulator_get_optional); 670 703 671 704 /* 672 705 * Returns number of regulators coupled with rdev.
+37
include/linux/regulator/consumer.h
··· 168 168 void regulator_put(struct regulator *regulator); 169 169 void devm_regulator_put(struct regulator *regulator); 170 170 171 + #if IS_ENABLED(CONFIG_OF) 172 + struct regulator *__must_check of_regulator_get_optional(struct device *dev, 173 + struct device_node *node, 174 + const char *id); 175 + struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, 176 + struct device_node *node, 177 + const char *id); 178 + #else 179 + static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, 180 + struct device_node *node, 181 + const char *id) 182 + { 183 + return ERR_PTR(-ENODEV); 184 + } 185 + 186 + static inline struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, 187 + struct device_node *node, 188 + const char *id) 189 + { 190 + return ERR_PTR(-ENODEV); 191 + } 192 + #endif 193 + 171 194 int regulator_register_supply_alias(struct device *dev, const char *id, 172 195 struct device *alias_dev, 173 196 const char *alias_id); ··· 369 346 370 347 static inline struct regulator *__must_check 371 348 devm_regulator_get_optional(struct device *dev, const char *id) 349 + { 350 + return ERR_PTR(-ENODEV); 351 + } 352 + 353 + static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev, 354 + struct device_node *node, 355 + const char *id) 356 + { 357 + return ERR_PTR(-ENODEV); 358 + } 359 + 360 + static inline struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev, 361 + struct device_node *node, 362 + const char *id) 372 363 { 373 364 return ERR_PTR(-ENODEV); 374 365 }