aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
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 }