aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/core.c92
-rw-r--r--include/linux/regulator/machine.h2
2 files changed, 94 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 8588a2490e0a..01f7702a805d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -28,6 +28,7 @@
28static DEFINE_MUTEX(regulator_list_mutex); 28static DEFINE_MUTEX(regulator_list_mutex);
29static LIST_HEAD(regulator_list); 29static LIST_HEAD(regulator_list);
30static LIST_HEAD(regulator_map_list); 30static LIST_HEAD(regulator_map_list);
31static int has_full_constraints;
31 32
32/* 33/*
33 * struct regulator_map 34 * struct regulator_map
@@ -2143,6 +2144,23 @@ out:
2143EXPORT_SYMBOL_GPL(regulator_suspend_prepare); 2144EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
2144 2145
2145/** 2146/**
2147 * regulator_has_full_constraints - the system has fully specified constraints
2148 *
2149 * Calling this function will cause the regulator API to disable all
2150 * regulators which have a zero use count and don't have an always_on
2151 * constraint in a late_initcall.
2152 *
2153 * The intention is that this will become the default behaviour in a
2154 * future kernel release so users are encouraged to use this facility
2155 * now.
2156 */
2157void regulator_has_full_constraints(void)
2158{
2159 has_full_constraints = 1;
2160}
2161EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
2162
2163/**
2146 * rdev_get_drvdata - get rdev regulator driver data 2164 * rdev_get_drvdata - get rdev regulator driver data
2147 * @rdev: regulator 2165 * @rdev: regulator
2148 * 2166 *
@@ -2209,3 +2227,77 @@ static int __init regulator_init(void)
2209 2227
2210/* init early to allow our consumers to complete system booting */ 2228/* init early to allow our consumers to complete system booting */
2211core_initcall(regulator_init); 2229core_initcall(regulator_init);
2230
2231static int __init regulator_init_complete(void)
2232{
2233 struct regulator_dev *rdev;
2234 struct regulator_ops *ops;
2235 struct regulation_constraints *c;
2236 int enabled, ret;
2237 const char *name;
2238
2239 mutex_lock(&regulator_list_mutex);
2240
2241 /* If we have a full configuration then disable any regulators
2242 * which are not in use or always_on. This will become the
2243 * default behaviour in the future.
2244 */
2245 list_for_each_entry(rdev, &regulator_list, list) {
2246 ops = rdev->desc->ops;
2247 c = rdev->constraints;
2248
2249 if (c->name)
2250 name = c->name;
2251 else if (rdev->desc->name)
2252 name = rdev->desc->name;
2253 else
2254 name = "regulator";
2255
2256 if (!ops->disable || c->always_on)
2257 continue;
2258
2259 mutex_lock(&rdev->mutex);
2260
2261 if (rdev->use_count)
2262 goto unlock;
2263
2264 /* If we can't read the status assume it's on. */
2265 if (ops->is_enabled)
2266 enabled = ops->is_enabled(rdev);
2267 else
2268 enabled = 1;
2269
2270 if (!enabled)
2271 goto unlock;
2272
2273 if (has_full_constraints) {
2274 /* We log since this may kill the system if it
2275 * goes wrong. */
2276 printk(KERN_INFO "%s: disabling %s\n",
2277 __func__, name);
2278 ret = ops->disable(rdev);
2279 if (ret != 0) {
2280 printk(KERN_ERR
2281 "%s: couldn't disable %s: %d\n",
2282 __func__, name, ret);
2283 }
2284 } else {
2285 /* The intention is that in future we will
2286 * assume that full constraints are provided
2287 * so warn even if we aren't going to do
2288 * anything here.
2289 */
2290 printk(KERN_WARNING
2291 "%s: incomplete constraints, leaving %s on\n",
2292 __func__, name);
2293 }
2294
2295unlock:
2296 mutex_unlock(&rdev->mutex);
2297 }
2298
2299 mutex_unlock(&regulator_list_mutex);
2300
2301 return 0;
2302}
2303late_initcall(regulator_init_complete);
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 5de7aa3b02a6..bac64fa390f2 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -166,4 +166,6 @@ struct regulator_init_data {
166 166
167int regulator_suspend_prepare(suspend_state_t state); 167int regulator_suspend_prepare(suspend_state_t state);
168 168
169void regulator_has_full_constraints(void);
170
169#endif 171#endif