diff options
author | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2015-01-05 06:48:41 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-01-08 15:15:44 -0500 |
commit | 1b3de223385d6bf2ab9bf2e9e80aebb26fedd426 (patch) | |
tree | df211408227bee0a34a932cfe9bc4263141d8174 /drivers/regulator | |
parent | 97bf6af1f928216fd6c5a66e8a57bfa95a659672 (diff) |
regulator: Copy config passed during registration
Copy the 'regulator_config' structure passed to regulator_register()
function so the driver could safely modify it after parsing init data.
The driver may want to change the config as a result of specific init
data parsed by regulator core (e.g. when core handled parsing device
tree).
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/core.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e225711bb8bc..c13b557a560e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -3581,20 +3581,21 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) | |||
3581 | */ | 3581 | */ |
3582 | struct regulator_dev * | 3582 | struct regulator_dev * |
3583 | regulator_register(const struct regulator_desc *regulator_desc, | 3583 | regulator_register(const struct regulator_desc *regulator_desc, |
3584 | const struct regulator_config *config) | 3584 | const struct regulator_config *cfg) |
3585 | { | 3585 | { |
3586 | const struct regulation_constraints *constraints = NULL; | 3586 | const struct regulation_constraints *constraints = NULL; |
3587 | const struct regulator_init_data *init_data; | 3587 | const struct regulator_init_data *init_data; |
3588 | struct regulator_config *config = NULL; | ||
3588 | static atomic_t regulator_no = ATOMIC_INIT(0); | 3589 | static atomic_t regulator_no = ATOMIC_INIT(0); |
3589 | struct regulator_dev *rdev; | 3590 | struct regulator_dev *rdev; |
3590 | struct device *dev; | 3591 | struct device *dev; |
3591 | int ret, i; | 3592 | int ret, i; |
3592 | const char *supply = NULL; | 3593 | const char *supply = NULL; |
3593 | 3594 | ||
3594 | if (regulator_desc == NULL || config == NULL) | 3595 | if (regulator_desc == NULL || cfg == NULL) |
3595 | return ERR_PTR(-EINVAL); | 3596 | return ERR_PTR(-EINVAL); |
3596 | 3597 | ||
3597 | dev = config->dev; | 3598 | dev = cfg->dev; |
3598 | WARN_ON(!dev); | 3599 | WARN_ON(!dev); |
3599 | 3600 | ||
3600 | if (regulator_desc->name == NULL || regulator_desc->ops == NULL) | 3601 | if (regulator_desc->name == NULL || regulator_desc->ops == NULL) |
@@ -3624,6 +3625,16 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3624 | if (rdev == NULL) | 3625 | if (rdev == NULL) |
3625 | return ERR_PTR(-ENOMEM); | 3626 | return ERR_PTR(-ENOMEM); |
3626 | 3627 | ||
3628 | /* | ||
3629 | * Duplicate the config so the driver could override it after | ||
3630 | * parsing init data. | ||
3631 | */ | ||
3632 | config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL); | ||
3633 | if (config == NULL) { | ||
3634 | kfree(rdev); | ||
3635 | return ERR_PTR(-ENOMEM); | ||
3636 | } | ||
3637 | |||
3627 | init_data = regulator_of_get_init_data(dev, regulator_desc, | 3638 | init_data = regulator_of_get_init_data(dev, regulator_desc, |
3628 | &rdev->dev.of_node); | 3639 | &rdev->dev.of_node); |
3629 | if (!init_data) { | 3640 | if (!init_data) { |
@@ -3752,6 +3763,7 @@ add_dev: | |||
3752 | rdev_init_debugfs(rdev); | 3763 | rdev_init_debugfs(rdev); |
3753 | out: | 3764 | out: |
3754 | mutex_unlock(®ulator_list_mutex); | 3765 | mutex_unlock(®ulator_list_mutex); |
3766 | kfree(config); | ||
3755 | return rdev; | 3767 | return rdev; |
3756 | 3768 | ||
3757 | unset_supplies: | 3769 | unset_supplies: |