diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/core.c | 88 |
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. | 1029 | static 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 | */ | ||
1041 | struct 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 | ||
1072 | found: | 1062 | found: |
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 | |||
1082 | out: | 1093 | out: |
1083 | mutex_unlock(®ulator_list_mutex); | 1094 | mutex_unlock(®ulator_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 | */ | ||
1112 | struct regulator *regulator_get(struct device *dev, const char *id) | ||
1113 | { | ||
1114 | return _regulator_get(dev, id, 0); | ||
1115 | } | ||
1086 | EXPORT_SYMBOL_GPL(regulator_get); | 1116 | EXPORT_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 | */ | ||
1139 | struct regulator *regulator_get_exclusive(struct device *dev, const char *id) | ||
1140 | { | ||
1141 | return _regulator_get(dev, id, 1); | ||
1142 | } | ||
1143 | EXPORT_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(®ulator->list); | 1170 | list_del(®ulator->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(®ulator_list_mutex); | 1177 | mutex_unlock(®ulator_list_mutex); |
1118 | } | 1178 | } |