|
@@ -20,6 +20,7 @@
|
|
|
#include <linux/debugfs.h>
|
|
|
#include <linux/device.h>
|
|
|
#include <linux/slab.h>
|
|
|
+#include <linux/async.h>
|
|
|
#include <linux/err.h>
|
|
|
#include <linux/mutex.h>
|
|
|
#include <linux/suspend.h>
|
|
@@ -2264,6 +2265,13 @@ err:
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(regulator_bulk_get);
|
|
|
|
|
|
+static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
|
|
|
+{
|
|
|
+ struct regulator_bulk_data *bulk = data;
|
|
|
+
|
|
|
+ bulk->ret = regulator_enable(bulk->consumer);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* regulator_bulk_enable - enable multiple regulator consumers
|
|
|
*
|
|
@@ -2279,21 +2287,33 @@ EXPORT_SYMBOL_GPL(regulator_bulk_get);
|
|
|
int regulator_bulk_enable(int num_consumers,
|
|
|
struct regulator_bulk_data *consumers)
|
|
|
{
|
|
|
+ LIST_HEAD(async_domain);
|
|
|
int i;
|
|
|
- int ret;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ for (i = 0; i < num_consumers; i++)
|
|
|
+ async_schedule_domain(regulator_bulk_enable_async,
|
|
|
+ &consumers[i], &async_domain);
|
|
|
+
|
|
|
+ async_synchronize_full_domain(&async_domain);
|
|
|
|
|
|
+ /* If any consumer failed we need to unwind any that succeeded */
|
|
|
for (i = 0; i < num_consumers; i++) {
|
|
|
- ret = regulator_enable(consumers[i].consumer);
|
|
|
- if (ret != 0)
|
|
|
+ if (consumers[i].ret != 0) {
|
|
|
+ ret = consumers[i].ret;
|
|
|
goto err;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
err:
|
|
|
- pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
|
|
|
- for (--i; i >= 0; --i)
|
|
|
- regulator_disable(consumers[i].consumer);
|
|
|
+ for (i = 0; i < num_consumers; i++)
|
|
|
+ if (consumers[i].ret == 0)
|
|
|
+ regulator_disable(consumers[i].consumer);
|
|
|
+ else
|
|
|
+ pr_err("Failed to enable %s: %d\n",
|
|
|
+ consumers[i].supply, consumers[i].ret);
|
|
|
|
|
|
return ret;
|
|
|
}
|