aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-21 11:00:23 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2009-09-22 08:32:38 -0400
commit5ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30 (patch)
tree1281ca42478aea061ba5de5be045e2361cd282d5 /drivers/regulator
parentc1b60873ca2078bfca94b73bc88ef1c5adcc928b (diff)
regulator: Add regulator_get_exclusive() API
Some consumers require complete control of the regulator and can't tolerate sharing it with other consumers, most commonly because they need to have the regulator actually disabled so can't have other consumers forcing it on. This new regulator_get_exclusive() API call allows these consumers to explicitly request this, documenting the assumptions that they are making. In order to simplify coding of such consumers the use count for regulators they request is forced to match the enabled state of the regulator when it is requested. This is not possible for consumers which can share regulators due to the need to keep track of the ownership of use counts. A new API call is used rather than an additional argument to the existing regulator_get() in order to avoid merge headaches with driver code in other trees. 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.c88
1 files changed, 74 insertions, 14 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 24e05b7607b4..68549008582c 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1025,25 +1025,15 @@ overflow_err:
1025 return NULL; 1025 return NULL;
1026} 1026}
1027 1027
1028/** 1028/* Internal regulator request function */
1029 * regulator_get - lookup and obtain a reference to a regulator. 1029static struct regulator *_regulator_get(struct device *dev, const char *id,
1030 * @dev: device for regulator "consumer" 1030 int exclusive)
1031 * @id: Supply name or regulator ID.
1032 *
1033 * Returns a struct regulator corresponding to the regulator producer,
1034 * or IS_ERR() condition containing errno.
1035 *
1036 * Use of supply names configured via regulator_set_device_supply() is
1037 * strongly encouraged. It is recommended that the supply name used
1038 * should match the name used for the supply and/or the relevant
1039 * device pins in the datasheet.
1040 */
1041struct regulator *regulator_get(struct device *dev, const char *id)
1042{ 1031{
1043 struct regulator_dev *rdev; 1032 struct regulator_dev *rdev;
1044 struct regulator_map *map; 1033 struct regulator_map *map;
1045 struct regulator *regulator = ERR_PTR(-ENODEV); 1034 struct regulator *regulator = ERR_PTR(-ENODEV);
1046 const char *devname = NULL; 1035 const char *devname = NULL;
1036 int ret;
1047 1037
1048 if (id == NULL) { 1038 if (id == NULL) {
1049 printk(KERN_ERR "regulator: get() with no identifier\n"); 1039 printk(KERN_ERR "regulator: get() with no identifier\n");
@@ -1070,6 +1060,16 @@ struct regulator *regulator_get(struct device *dev, const char *id)
1070 return regulator; 1060 return regulator;
1071 1061
1072found: 1062found:
1063 if (rdev->exclusive) {
1064 regulator = ERR_PTR(-EPERM);
1065 goto out;
1066 }
1067
1068 if (exclusive && rdev->open_count) {
1069 regulator = ERR_PTR(-EBUSY);
1070 goto out;
1071 }
1072
1073 if (!try_module_get(rdev->owner)) 1073 if (!try_module_get(rdev->owner))
1074 goto out; 1074 goto out;
1075 1075
@@ -1079,13 +1079,70 @@ found:
1079 module_put(rdev->owner); 1079 module_put(rdev->owner);
1080 } 1080 }
1081 1081
1082 rdev->open_count++;
1083 if (exclusive) {
1084 rdev->exclusive = 1;
1085
1086 ret = _regulator_is_enabled(rdev);
1087 if (ret > 0)
1088 rdev->use_count = 1;
1089 else
1090 rdev->use_count = 0;
1091 }
1092
1082out: 1093out:
1083 mutex_unlock(&regulator_list_mutex); 1094 mutex_unlock(&regulator_list_mutex);
1095
1084 return regulator; 1096 return regulator;
1085} 1097}
1098
1099/**
1100 * regulator_get - lookup and obtain a reference to a regulator.
1101 * @dev: device for regulator "consumer"
1102 * @id: Supply name or regulator ID.
1103 *
1104 * Returns a struct regulator corresponding to the regulator producer,
1105 * or IS_ERR() condition containing errno.
1106 *
1107 * Use of supply names configured via regulator_set_device_supply() is
1108 * strongly encouraged. It is recommended that the supply name used
1109 * should match the name used for the supply and/or the relevant
1110 * device pins in the datasheet.
1111 */
1112struct regulator *regulator_get(struct device *dev, const char *id)
1113{
1114 return _regulator_get(dev, id, 0);
1115}
1086EXPORT_SYMBOL_GPL(regulator_get); 1116EXPORT_SYMBOL_GPL(regulator_get);
1087 1117
1088/** 1118/**
1119 * regulator_get_exclusive - obtain exclusive access to a regulator.
1120 * @dev: device for regulator "consumer"
1121 * @id: Supply name or regulator ID.
1122 *
1123 * Returns a struct regulator corresponding to the regulator producer,
1124 * or IS_ERR() condition containing errno. Other consumers will be
1125 * unable to obtain this reference is held and the use count for the
1126 * regulator will be initialised to reflect the current state of the
1127 * regulator.
1128 *
1129 * This is intended for use by consumers which cannot tolerate shared
1130 * use of the regulator such as those which need to force the
1131 * regulator off for correct operation of the hardware they are
1132 * controlling.
1133 *
1134 * Use of supply names configured via regulator_set_device_supply() is
1135 * strongly encouraged. It is recommended that the supply name used
1136 * should match the name used for the supply and/or the relevant
1137 * device pins in the datasheet.
1138 */
1139struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
1140{
1141 return _regulator_get(dev, id, 1);
1142}
1143EXPORT_SYMBOL_GPL(regulator_get_exclusive);
1144
1145/**
1089 * regulator_put - "free" the regulator source 1146 * regulator_put - "free" the regulator source
1090 * @regulator: regulator source 1147 * @regulator: regulator source
1091 * 1148 *
@@ -1113,6 +1170,9 @@ void regulator_put(struct regulator *regulator)
1113 list_del(&regulator->list); 1170 list_del(&regulator->list);
1114 kfree(regulator); 1171 kfree(regulator);
1115 1172
1173 rdev->open_count--;
1174 rdev->exclusive = 0;
1175
1116 module_put(rdev->owner); 1176 module_put(rdev->owner);
1117 mutex_unlock(&regulator_list_mutex); 1177 mutex_unlock(&regulator_list_mutex);
1118} 1178}