aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-06-17 12:56:39 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2009-09-22 08:32:36 -0400
commit40f9244f4da8976eeb6d5ed6313c635ba238a9d3 (patch)
treeced24007caae264ca2423a5b968fb13af230e413 /drivers/regulator
parenta5d2abce4373810c0109c5939c0094ac16698625 (diff)
regulator: Allow consumer supplies to be set up with dev_name()
Follow the approach suggested by Russell King and implemented by him in the clkdev API and allow consumer device supply mapings to be set up using the dev_name() for the consumer instead of the struct device. In order to avoid making existing machines instabuggy and creating merge issues the use of struct device is still supported for the time being. This resolves problems working with buses such as I2C which make the struct device available late providing that the final device name is known, which is the case for most embedded systems with fixed setups. Consumers must still use the struct device when calling regulator_get(). Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/core.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 91ba9bfaa706..24e05b7607b4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -37,7 +37,7 @@ static int has_full_constraints;
37 */ 37 */
38struct regulator_map { 38struct regulator_map {
39 struct list_head list; 39 struct list_head list;
40 struct device *dev; 40 const char *dev_name; /* The dev_name() for the consumer */
41 const char *supply; 41 const char *supply;
42 struct regulator_dev *regulator; 42 struct regulator_dev *regulator;
43}; 43};
@@ -857,23 +857,33 @@ out:
857 * set_consumer_device_supply: Bind a regulator to a symbolic supply 857 * set_consumer_device_supply: Bind a regulator to a symbolic supply
858 * @rdev: regulator source 858 * @rdev: regulator source
859 * @consumer_dev: device the supply applies to 859 * @consumer_dev: device the supply applies to
860 * @consumer_dev_name: dev_name() string for device supply applies to
860 * @supply: symbolic name for supply 861 * @supply: symbolic name for supply
861 * 862 *
862 * Allows platform initialisation code to map physical regulator 863 * Allows platform initialisation code to map physical regulator
863 * sources to symbolic names for supplies for use by devices. Devices 864 * sources to symbolic names for supplies for use by devices. Devices
864 * should use these symbolic names to request regulators, avoiding the 865 * should use these symbolic names to request regulators, avoiding the
865 * need to provide board-specific regulator names as platform data. 866 * need to provide board-specific regulator names as platform data.
867 *
868 * Only one of consumer_dev and consumer_dev_name may be specified.
866 */ 869 */
867static int set_consumer_device_supply(struct regulator_dev *rdev, 870static int set_consumer_device_supply(struct regulator_dev *rdev,
868 struct device *consumer_dev, const char *supply) 871 struct device *consumer_dev, const char *consumer_dev_name,
872 const char *supply)
869{ 873{
870 struct regulator_map *node; 874 struct regulator_map *node;
871 875
876 if (consumer_dev && consumer_dev_name)
877 return -EINVAL;
878
879 if (!consumer_dev_name && consumer_dev)
880 consumer_dev_name = dev_name(consumer_dev);
881
872 if (supply == NULL) 882 if (supply == NULL)
873 return -EINVAL; 883 return -EINVAL;
874 884
875 list_for_each_entry(node, &regulator_map_list, list) { 885 list_for_each_entry(node, &regulator_map_list, list) {
876 if (consumer_dev != node->dev) 886 if (consumer_dev_name != node->dev_name)
877 continue; 887 continue;
878 if (strcmp(node->supply, supply) != 0) 888 if (strcmp(node->supply, supply) != 0)
879 continue; 889 continue;
@@ -891,25 +901,38 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
891 return -ENOMEM; 901 return -ENOMEM;
892 902
893 node->regulator = rdev; 903 node->regulator = rdev;
894 node->dev = consumer_dev; 904 node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
895 node->supply = supply; 905 node->supply = supply;
896 906
907 if (node->dev_name == NULL) {
908 kfree(node);
909 return -ENOMEM;
910 }
911
897 list_add(&node->list, &regulator_map_list); 912 list_add(&node->list, &regulator_map_list);
898 return 0; 913 return 0;
899} 914}
900 915
901static void unset_consumer_device_supply(struct regulator_dev *rdev, 916static void unset_consumer_device_supply(struct regulator_dev *rdev,
902 struct device *consumer_dev) 917 const char *consumer_dev_name, struct device *consumer_dev)
903{ 918{
904 struct regulator_map *node, *n; 919 struct regulator_map *node, *n;
905 920
921 if (consumer_dev && !consumer_dev_name)
922 consumer_dev_name = dev_name(consumer_dev);
923
906 list_for_each_entry_safe(node, n, &regulator_map_list, list) { 924 list_for_each_entry_safe(node, n, &regulator_map_list, list) {
907 if (rdev == node->regulator && 925 if (rdev != node->regulator)
908 consumer_dev == node->dev) { 926 continue;
909 list_del(&node->list); 927
910 kfree(node); 928 if (consumer_dev_name && node->dev_name &&
911 return; 929 strcmp(consumer_dev_name, node->dev_name))
912 } 930 continue;
931
932 list_del(&node->list);
933 kfree(node->dev_name);
934 kfree(node);
935 return;
913 } 936 }
914} 937}
915 938
@@ -920,6 +943,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
920 list_for_each_entry_safe(node, n, &regulator_map_list, list) { 943 list_for_each_entry_safe(node, n, &regulator_map_list, list) {
921 if (rdev == node->regulator) { 944 if (rdev == node->regulator) {
922 list_del(&node->list); 945 list_del(&node->list);
946 kfree(node->dev_name);
923 kfree(node); 947 kfree(node);
924 return; 948 return;
925 } 949 }
@@ -1019,17 +1043,25 @@ struct regulator *regulator_get(struct device *dev, const char *id)
1019 struct regulator_dev *rdev; 1043 struct regulator_dev *rdev;
1020 struct regulator_map *map; 1044 struct regulator_map *map;
1021 struct regulator *regulator = ERR_PTR(-ENODEV); 1045 struct regulator *regulator = ERR_PTR(-ENODEV);
1046 const char *devname = NULL;
1022 1047
1023 if (id == NULL) { 1048 if (id == NULL) {
1024 printk(KERN_ERR "regulator: get() with no identifier\n"); 1049 printk(KERN_ERR "regulator: get() with no identifier\n");
1025 return regulator; 1050 return regulator;
1026 } 1051 }
1027 1052
1053 if (dev)
1054 devname = dev_name(dev);
1055
1028 mutex_lock(&regulator_list_mutex); 1056 mutex_lock(&regulator_list_mutex);
1029 1057
1030 list_for_each_entry(map, &regulator_map_list, list) { 1058 list_for_each_entry(map, &regulator_map_list, list) {
1031 if (dev == map->dev && 1059 /* If the mapping has a device set up it must match */
1032 strcmp(map->supply, id) == 0) { 1060 if (map->dev_name &&
1061 (!devname || strcmp(map->dev_name, devname)))
1062 continue;
1063
1064 if (strcmp(map->supply, id) == 0) {
1033 rdev = map->regulator; 1065 rdev = map->regulator;
1034 goto found; 1066 goto found;
1035 } 1067 }
@@ -2091,11 +2123,13 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
2091 for (i = 0; i < init_data->num_consumer_supplies; i++) { 2123 for (i = 0; i < init_data->num_consumer_supplies; i++) {
2092 ret = set_consumer_device_supply(rdev, 2124 ret = set_consumer_device_supply(rdev,
2093 init_data->consumer_supplies[i].dev, 2125 init_data->consumer_supplies[i].dev,
2126 init_data->consumer_supplies[i].dev_name,
2094 init_data->consumer_supplies[i].supply); 2127 init_data->consumer_supplies[i].supply);
2095 if (ret < 0) { 2128 if (ret < 0) {
2096 for (--i; i >= 0; i--) 2129 for (--i; i >= 0; i--)
2097 unset_consumer_device_supply(rdev, 2130 unset_consumer_device_supply(rdev,
2098 init_data->consumer_supplies[i].dev); 2131 init_data->consumer_supplies[i].dev_name,
2132 init_data->consumer_supplies[i].dev);
2099 goto scrub; 2133 goto scrub;
2100 } 2134 }
2101 } 2135 }