Skip to content

Commit 36ec3f4

Browse files
wensbroonie
authored andcommitted
regulator: Add devres version of of_regulator_get_optional()
There are existing uses for a devres version of of_regulator_get_optional() in power domain drivers. On MediaTek platforms, power domains may have regulator supplies tied to them. The driver currently tries to use devm_regulator_get() to not have to manage the lifecycle, but ends up doing it in a very hacky way by replacing the device node of the power domain controller device to the device node of the power domain that is currently being registered, getting the supply, and reverting the device node. Provide a better API so that the hack can be replaced. Signed-off-by: Chen-Yu Tsai <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 5441b69 commit 36ec3f4

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed

drivers/regulator/devres.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,3 +749,42 @@ void *devm_regulator_irq_helper(struct device *dev,
749749
return ptr;
750750
}
751751
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

drivers/regulator/internal.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ static inline struct regulator_dev *dev_to_rdev(struct device *dev)
6565
return container_of(dev, struct regulator_dev, dev);
6666
}
6767

68+
enum regulator_get_type {
69+
NORMAL_GET,
70+
EXCLUSIVE_GET,
71+
OPTIONAL_GET,
72+
MAX_GET_TYPE
73+
};
74+
6875
#ifdef CONFIG_OF
6976
struct regulator_dev *of_regulator_dev_lookup(struct device *dev,
7077
struct device_node *np,
@@ -74,6 +81,9 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
7481
struct regulator_config *config,
7582
struct device_node **node);
7683

84+
struct regulator *_of_regulator_get(struct device *dev, struct device_node *node,
85+
const char *id, enum regulator_get_type get_type);
86+
7787
struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev,
7888
int index);
7989

@@ -116,12 +126,6 @@ static inline bool of_check_coupling_data(struct regulator_dev *rdev)
116126
}
117127

118128
#endif
119-
enum regulator_get_type {
120-
NORMAL_GET,
121-
EXCLUSIVE_GET,
122-
OPTIONAL_GET,
123-
MAX_GET_TYPE
124-
};
125129

126130
int _regulator_get_common_check(struct device *dev, const char *id,
127131
enum regulator_get_type get_type);

drivers/regulator/of_regulator.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,8 @@ struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_
668668
return ERR_PTR(-ENODEV);
669669
}
670670

671-
static struct regulator *_of_regulator_get(struct device *dev, struct device_node *node,
672-
const char *id, enum regulator_get_type get_type)
671+
struct regulator *_of_regulator_get(struct device *dev, struct device_node *node,
672+
const char *id, enum regulator_get_type get_type)
673673
{
674674
struct regulator_dev *r;
675675
int ret;

include/linux/regulator/consumer.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,23 @@ void devm_regulator_put(struct regulator *regulator);
172172
struct regulator *__must_check of_regulator_get_optional(struct device *dev,
173173
struct device_node *node,
174174
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);
175178
#else
176179
static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev,
177180
struct device_node *node,
178181
const char *id)
179182
{
180183
return ERR_PTR(-ENODEV);
181184
}
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+
}
182192
#endif
183193

184194
int regulator_register_supply_alias(struct device *dev, const char *id,
@@ -370,6 +380,13 @@ static inline struct regulator *__must_check of_regulator_get_optional(struct de
370380
return ERR_PTR(-ENODEV);
371381
}
372382

383+
static inline struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev,
384+
struct device_node *node,
385+
const char *id)
386+
{
387+
return ERR_PTR(-ENODEV);
388+
}
389+
373390
static inline void regulator_put(struct regulator *regulator)
374391
{
375392
}

0 commit comments

Comments
 (0)