regulator: core: Add devres versions of notifier registration
Add devm_regulator_register_notifier, this adds the resource against the device for the consumer supply we are registering the notifier for. There seem to be few use-cases where this wouldn't be the users intention and this ensures the notifiers will always be removed at the correct time. Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
c517d838eb
commit
046db763aa
|
@ -413,3 +413,88 @@ void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
|
|||
devm_regulator_unregister_supply_alias(dev, id[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);
|
||||
|
||||
struct regulator_notifier_match {
|
||||
struct regulator *regulator;
|
||||
struct notifier_block *nb;
|
||||
};
|
||||
|
||||
static int devm_regulator_match_notifier(struct device *dev, void *res,
|
||||
void *data)
|
||||
{
|
||||
struct regulator_notifier_match *match = res;
|
||||
struct regulator_notifier_match *target = data;
|
||||
|
||||
return match->regulator == target->regulator && match->nb == target->nb;
|
||||
}
|
||||
|
||||
static void devm_regulator_destroy_notifier(struct device *dev, void *res)
|
||||
{
|
||||
struct regulator_notifier_match *match = res;
|
||||
|
||||
regulator_unregister_notifier(match->regulator, match->nb);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_regulator_register_notifier - Resource managed
|
||||
* regulator_register_notifier
|
||||
*
|
||||
* @regulator: regulator source
|
||||
* @nb: notifier block
|
||||
*
|
||||
* The notifier will be registers under the consumer device and be
|
||||
* automatically be unregistered when the source device is unbound.
|
||||
*/
|
||||
int devm_regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
struct regulator_notifier_match *match;
|
||||
int ret;
|
||||
|
||||
match = devres_alloc(devm_regulator_destroy_notifier,
|
||||
sizeof(struct regulator_notifier_match),
|
||||
GFP_KERNEL);
|
||||
if (!match)
|
||||
return -ENOMEM;
|
||||
|
||||
match->regulator = regulator;
|
||||
match->nb = nb;
|
||||
|
||||
ret = regulator_register_notifier(regulator, nb);
|
||||
if (ret < 0) {
|
||||
devres_free(match);
|
||||
return ret;
|
||||
}
|
||||
|
||||
devres_add(regulator->dev, match);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regulator_register_notifier);
|
||||
|
||||
/**
|
||||
* devm_regulator_unregister_notifier - Resource managed
|
||||
* regulator_unregister_notifier()
|
||||
*
|
||||
* @regulator: regulator source
|
||||
* @nb: notifier block
|
||||
*
|
||||
* Unregister a notifier registered with devm_regulator_register_notifier().
|
||||
* Normally this function will not need to be called and the resource
|
||||
* management code will ensure that the resource is freed.
|
||||
*/
|
||||
void devm_regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
struct regulator_notifier_match match;
|
||||
int rc;
|
||||
|
||||
match.regulator = regulator;
|
||||
match.nb = nb;
|
||||
|
||||
rc = devres_release(regulator->dev, devm_regulator_destroy_notifier,
|
||||
devm_regulator_match_notifier, &match);
|
||||
if (rc != 0)
|
||||
WARN_ON(rc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_regulator_unregister_notifier);
|
||||
|
|
|
@ -252,8 +252,12 @@ int regulator_list_hardware_vsel(struct regulator *regulator,
|
|||
/* regulator notifier block */
|
||||
int regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
int devm_regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
int regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
void devm_regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
|
||||
/* driver data - core doesn't touch */
|
||||
void *regulator_get_drvdata(struct regulator *regulator);
|
||||
|
@ -515,12 +519,24 @@ static inline int regulator_register_notifier(struct regulator *regulator,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int devm_regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int devm_regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void *regulator_get_drvdata(struct regulator *regulator)
|
||||
{
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue