summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/power_supply.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2016-02-12 16:08:32 +0530
committerGreg Kroah-Hartman <gregkh@google.com>2016-02-15 14:53:43 -0800
commit7e9fba8df7606bcace9d22394f59c2047dd55091 (patch)
treecd2bdd34584ce037c17b07183455df9dec6cc0e2 /drivers/staging/greybus/power_supply.c
parent69564dfeacf0728b60e3b2c85b357bc63213116c (diff)
greybus: power_supply: Break supply setup into two parts
This breaks the power supply setup routine into two parts, the first one allocates all the necessary resources and the second on registers supplies to the required frameworks. This is required to enable only TX on the connection, until we have allocated all the resources, otherwise the request handler might get called for partially initialized structures. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Rui Miguel Silva <rui.silva@linaro.org> Reviewed-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/power_supply.c')
-rw-r--r--drivers/staging/greybus/power_supply.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/drivers/staging/greybus/power_supply.c b/drivers/staging/greybus/power_supply.c
index 37bea9c0cea8..c50b30d1a632 100644
--- a/drivers/staging/greybus/power_supply.c
+++ b/drivers/staging/greybus/power_supply.c
@@ -624,31 +624,33 @@ static int gb_power_supply_config(struct gb_power_supplies *supplies, int id)
ret = gb_power_supply_description_get(gbpsy);
if (ret < 0)
- goto out;
+ return ret;
ret = gb_power_supply_prop_descriptors_get(gbpsy);
if (ret < 0)
- goto out;
+ return ret;
/* guarantee that we have an unique name, before register */
- ret = __gb_power_supply_set_name(gbpsy->model_name, gbpsy->name,
- sizeof(gbpsy->name));
- if (ret < 0)
- goto out;
+ return __gb_power_supply_set_name(gbpsy->model_name, gbpsy->name,
+ sizeof(gbpsy->name));
+}
+
+static int gb_power_supply_enable(struct gb_power_supply *gbpsy)
+{
+ int ret;
ret = gb_power_supply_register(gbpsy);
if (ret < 0)
- goto out;
+ return ret;
gbpsy->update_interval = update_interval_init;
INIT_DELAYED_WORK(&gbpsy->work, gb_power_supply_work);
schedule_delayed_work(&gbpsy->work, 0);
-out:
- /* if everything went fine just mark it for release code to know */
- if (ret == 0)
- gbpsy->registered = true;
- return ret;
+ /* everything went fine, mark it for release code to know */
+ gbpsy->registered = true;
+
+ return 0;
}
static int gb_power_supplies_setup(struct gb_power_supplies *supplies)
@@ -685,6 +687,27 @@ out:
return ret;
}
+static int gb_power_supplies_register(struct gb_power_supplies *supplies)
+{
+ struct gb_connection *connection = supplies->connection;
+ int ret = 0;
+ int i;
+
+ mutex_lock(&supplies->supplies_lock);
+
+ for (i = 0; i < supplies->supplies_count; i++) {
+ ret = gb_power_supply_enable(&supplies->supply[i]);
+ if (ret < 0) {
+ dev_err(&connection->bundle->dev,
+ "Fail to enable supplies devices\n");
+ break;
+ }
+ }
+
+ mutex_unlock(&supplies->supplies_lock);
+ return ret;
+}
+
static int gb_power_supply_event_recv(u8 type, struct gb_operation *op)
{
struct gb_connection *connection = op->connection;
@@ -758,8 +781,16 @@ static int gb_power_supply_connection_init(struct gb_connection *connection)
ret = gb_power_supplies_setup(supplies);
if (ret < 0)
- _gb_power_supplies_release(supplies);
+ goto out;
+
+ ret = gb_power_supplies_register(supplies);
+ if (ret < 0)
+ goto out;
+
+ return 0;
+out:
+ _gb_power_supplies_release(supplies);
return ret;
}