regulator: core: Provide hints to the core about optional supplies
While the majority of supplies on devices are mandatory and can't be physically omitted for electrical reasons some devices do have optional supplies and need to know if they are missing, MMC being the most common of these. Currently the core accurately reports all errors when regulators are requested since it does not know if the supply is one that must be provided even if by a regulator software does not know about or if it is one that may genuinely be disconnected. In order to allow this behaviour to be changed and stub regulators to be provided in the former case add a new regulator request function regulator_get_optional() which provides a hint to the core that the regulator may genuinely not be connected. Currently the implementation is identical to the current behaviour, future patches will add support in the core for returning stub regulators in the case where normal regulator_get() fails and the board has requested it. Signed-off-by: Mark Brown <broonie@linaro.org> Acked-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
parent
4bdfb2729c
commit
de1dd9fd21
|
@ -1409,6 +1409,65 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_get_exclusive);
|
||||
|
||||
/**
|
||||
* regulator_get_optional - obtain optional access to a regulator.
|
||||
* @dev: device for regulator "consumer"
|
||||
* @id: Supply name or regulator ID.
|
||||
*
|
||||
* Returns a struct regulator corresponding to the regulator producer,
|
||||
* or IS_ERR() condition containing errno. Other consumers will be
|
||||
* unable to obtain this reference is held and the use count for the
|
||||
* regulator will be initialised to reflect the current state of the
|
||||
* regulator.
|
||||
*
|
||||
* This is intended for use by consumers for devices which can have
|
||||
* some supplies unconnected in normal use, such as some MMC devices.
|
||||
* It can allow the regulator core to provide stub supplies for other
|
||||
* supplies requested using normal regulator_get() calls without
|
||||
* disrupting the operation of drivers that can handle absent
|
||||
* supplies.
|
||||
*
|
||||
* Use of supply names configured via regulator_set_device_supply() is
|
||||
* strongly encouraged. It is recommended that the supply name used
|
||||
* should match the name used for the supply and/or the relevant
|
||||
* device pins in the datasheet.
|
||||
*/
|
||||
struct regulator *regulator_get_optional(struct device *dev, const char *id)
|
||||
{
|
||||
return _regulator_get(dev, id, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_get_optional);
|
||||
|
||||
/**
|
||||
* devm_regulator_get_optional - Resource managed regulator_get_optional()
|
||||
* @dev: device for regulator "consumer"
|
||||
* @id: Supply name or regulator ID.
|
||||
*
|
||||
* Managed regulator_get_optional(). Regulators returned from this
|
||||
* function are automatically regulator_put() on driver detach. See
|
||||
* regulator_get_optional() for more information.
|
||||
*/
|
||||
struct regulator *devm_regulator_get_optional(struct device *dev,
|
||||
const char *id)
|
||||
{
|
||||
struct regulator **ptr, *regulator;
|
||||
|
||||
ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
regulator = regulator_get_optional(dev, id);
|
||||
if (!IS_ERR(regulator)) {
|
||||
*ptr = regulator;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return regulator;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
|
||||
|
||||
/* Locks held by regulator_put() */
|
||||
static void _regulator_put(struct regulator *regulator)
|
||||
{
|
||||
|
|
|
@ -137,6 +137,10 @@ struct regulator *__must_check devm_regulator_get(struct device *dev,
|
|||
const char *id);
|
||||
struct regulator *__must_check regulator_get_exclusive(struct device *dev,
|
||||
const char *id);
|
||||
struct regulator *__must_check regulator_get_optional(struct device *dev,
|
||||
const char *id);
|
||||
struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
|
||||
const char *id);
|
||||
void regulator_put(struct regulator *regulator);
|
||||
void devm_regulator_put(struct regulator *regulator);
|
||||
|
||||
|
@ -211,15 +215,27 @@ static inline struct regulator *__must_check regulator_get(struct device *dev,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct regulator *__must_check
|
||||
devm_regulator_get(struct device *dev, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct regulator *__must_check
|
||||
regulator_get_exclusive(struct device *dev, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct regulator *__must_check
|
||||
regulator_get_optional(struct device *dev, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static inline struct regulator *__must_check
|
||||
devm_regulator_get(struct device *dev, const char *id)
|
||||
devm_regulator_get_optional(struct device *dev, const char *id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue