aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-11-29 10:55:17 -0500
committerLiam Girdwood <lrg@slimlogic.co.uk>2011-01-12 09:33:01 -0500
commitf8c12fe329c8da9f50d8b2b1183eeaa4d587e747 (patch)
tree8ec2dee6efcf6a6a96e161bf9a86c6d9befb2a58
parentf4d6adf11b0a596ac4fee2fb2591f286de35c088 (diff)
regulator: Copy constraints from regulators when initialising them
Currently the regulator API uses the constraints structure passed in to the core throughout the lifetime of the object. This means that it is not possible to mark the constraints as __initdata so if the kernel supports many boards the constraints for all of them are kept around throughout the lifetime of the system, consuming memory needlessly. By copying constraints that are actually used we allow the use of __initdata, saving memory when multiple boards are supported. This also means the constraints can be const. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--drivers/regulator/core.c19
-rw-r--r--include/linux/regulator/driver.h2
2 files changed, 13 insertions, 8 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 64a56a7a1f9d..40cf7b9ea943 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -813,23 +813,26 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
813 * set_mode. 813 * set_mode.
814 */ 814 */
815static int set_machine_constraints(struct regulator_dev *rdev, 815static int set_machine_constraints(struct regulator_dev *rdev,
816 struct regulation_constraints *constraints) 816 const struct regulation_constraints *constraints)
817{ 817{
818 int ret = 0; 818 int ret = 0;
819 const char *name; 819 const char *name;
820 struct regulator_ops *ops = rdev->desc->ops; 820 struct regulator_ops *ops = rdev->desc->ops;
821 821
822 rdev->constraints = constraints; 822 rdev->constraints = kmemdup(constraints, sizeof(*constraints),
823 GFP_KERNEL);
824 if (!rdev->constraints)
825 return -ENOMEM;
823 826
824 name = rdev_get_name(rdev); 827 name = rdev_get_name(rdev);
825 828
826 ret = machine_constraints_voltage(rdev, constraints); 829 ret = machine_constraints_voltage(rdev, rdev->constraints);
827 if (ret != 0) 830 if (ret != 0)
828 goto out; 831 goto out;
829 832
830 /* do we need to setup our suspend state */ 833 /* do we need to setup our suspend state */
831 if (constraints->initial_state) { 834 if (constraints->initial_state) {
832 ret = suspend_prepare(rdev, constraints->initial_state); 835 ret = suspend_prepare(rdev, rdev->constraints->initial_state);
833 if (ret < 0) { 836 if (ret < 0) {
834 pr_err("failed to set suspend state for %s\n", 837 pr_err("failed to set suspend state for %s\n",
835 name); 838 name);
@@ -846,7 +849,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
846 goto out; 849 goto out;
847 } 850 }
848 851
849 ret = ops->set_mode(rdev, constraints->initial_mode); 852 ret = ops->set_mode(rdev, rdev->constraints->initial_mode);
850 if (ret < 0) { 853 if (ret < 0) {
851 pr_err("failed to set initial mode for %s: %d\n", 854 pr_err("failed to set initial mode for %s: %d\n",
852 name, ret); 855 name, ret);
@@ -857,7 +860,8 @@ static int set_machine_constraints(struct regulator_dev *rdev,
857 /* If the constraints say the regulator should be on at this point 860 /* If the constraints say the regulator should be on at this point
858 * and we have control then make sure it is enabled. 861 * and we have control then make sure it is enabled.
859 */ 862 */
860 if ((constraints->always_on || constraints->boot_on) && ops->enable) { 863 if ((rdev->constraints->always_on || rdev->constraints->boot_on) &&
864 ops->enable) {
861 ret = ops->enable(rdev); 865 ret = ops->enable(rdev);
862 if (ret < 0) { 866 if (ret < 0) {
863 pr_err("failed to enable %s\n", name); 867 pr_err("failed to enable %s\n", name);
@@ -2289,7 +2293,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
2289 * Returns 0 on success. 2293 * Returns 0 on success.
2290 */ 2294 */
2291struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, 2295struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
2292 struct device *dev, struct regulator_init_data *init_data, 2296 struct device *dev, const struct regulator_init_data *init_data,
2293 void *driver_data) 2297 void *driver_data)
2294{ 2298{
2295 static atomic_t regulator_no = ATOMIC_INIT(0); 2299 static atomic_t regulator_no = ATOMIC_INIT(0);
@@ -2444,6 +2448,7 @@ void regulator_unregister(struct regulator_dev *rdev)
2444 if (rdev->supply) 2448 if (rdev->supply)
2445 sysfs_remove_link(&rdev->dev.kobj, "supply"); 2449 sysfs_remove_link(&rdev->dev.kobj, "supply");
2446 device_unregister(&rdev->dev); 2450 device_unregister(&rdev->dev);
2451 kfree(rdev->constraints);
2447 mutex_unlock(&regulator_list_mutex); 2452 mutex_unlock(&regulator_list_mutex);
2448} 2453}
2449EXPORT_SYMBOL_GPL(regulator_unregister); 2454EXPORT_SYMBOL_GPL(regulator_unregister);
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 4275cd475eac..cce575359712 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -192,7 +192,7 @@ struct regulator_dev {
192}; 192};
193 193
194struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, 194struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
195 struct device *dev, struct regulator_init_data *init_data, 195 struct device *dev, const struct regulator_init_data *init_data,
196 void *driver_data); 196 void *driver_data);
197void regulator_unregister(struct regulator_dev *rdev); 197void regulator_unregister(struct regulator_dev *rdev);
198 198