greybus: power_supply: Add runtime pm support

Modify Power_supply greybus driver to support runtime PM framework.

During charging state, the driver will block remote device of suspending,
and then enables runtime suspend when remote device is in none chargin
state.

Testing Done: Compiled and verified on EVT2, EVT2 1x2 GPB test module
              and Device class daughter board.

Signed-off-by: Philip Yang <yang_philip@projectara.com>
Reviewed-by: Rui Miguel Silva <rui.silva@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Philip Yang 2016-08-31 11:11:18 +08:00 коммит произвёл Greg Kroah-Hartman
Родитель 6a57ddc97a
Коммит 4e013b64c1
1 изменённых файлов: 59 добавлений и 3 удалений

Просмотреть файл

@ -50,6 +50,8 @@ struct gb_power_supply {
bool changed;
struct gb_power_supply_prop *props;
enum power_supply_property *props_raw;
bool pm_acquired;
struct mutex supply_lock;
};
struct gb_power_supplies {
@ -75,10 +77,13 @@ struct gb_power_supply_changes {
struct gb_power_supply_prop *prop);
};
static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
struct gb_power_supply_prop *prop);
static const struct gb_power_supply_changes psy_props_changes[] = {
{ .prop = GB_POWER_SUPPLY_PROP_STATUS,
.tolerance_change = 0,
.prop_changed = NULL,
.prop_changed = gb_power_supply_state_change,
},
{ .prop = GB_POWER_SUPPLY_PROP_TEMP,
.tolerance_change = 500,
@ -349,6 +354,40 @@ static void __gb_power_supply_changed(struct gb_power_supply *gbpsy)
}
#endif
static void gb_power_supply_state_change(struct gb_power_supply *gbpsy,
struct gb_power_supply_prop *prop)
{
struct gb_connection *connection = get_conn_from_psy(gbpsy);
int ret;
/*
* Check gbpsy->pm_acquired to make sure only one pair of 'get_sync'
* and 'put_autosuspend' runtime pm call for state property change.
*/
mutex_lock(&gbpsy->supply_lock);
if ((prop->val == GB_POWER_SUPPLY_STATUS_CHARGING) &&
!gbpsy->pm_acquired) {
ret = gb_pm_runtime_get_sync(connection->bundle);
if (ret)
dev_err(&connection->bundle->dev,
"Fail to set wake lock for charging state\n");
else
gbpsy->pm_acquired = true;
} else {
if (gbpsy->pm_acquired) {
ret = gb_pm_runtime_put_autosuspend(connection->bundle);
if (ret)
dev_err(&connection->bundle->dev,
"Fail to set wake unlock for none charging\n");
else
gbpsy->pm_acquired = false;
}
}
mutex_unlock(&gbpsy->supply_lock);
}
static void check_changed(struct gb_power_supply *gbpsy,
struct gb_power_supply_prop *prop)
{
@ -655,12 +694,17 @@ static int is_cache_valid(struct gb_power_supply *gbpsy)
static int gb_power_supply_status_get(struct gb_power_supply *gbpsy)
{
struct gb_connection *connection = get_conn_from_psy(gbpsy);
int ret = 0;
int i;
if (is_cache_valid(gbpsy))
return 0;
ret = gb_pm_runtime_get_sync(connection->bundle);
if (ret)
return ret;
for (i = 0; i < gbpsy->properties_count; i++) {
ret = __gb_power_supply_property_update(gbpsy,
gbpsy->props[i].prop);
@ -671,6 +715,7 @@ static int gb_power_supply_status_get(struct gb_power_supply *gbpsy)
if (ret == 0)
gbpsy->last_update = jiffies;
gb_pm_runtime_put_autosuspend(connection->bundle);
return ret;
}
@ -725,9 +770,16 @@ static int gb_power_supply_property_set(struct gb_power_supply *gbpsy,
struct gb_power_supply_set_property_request req;
int ret;
ret = gb_pm_runtime_get_sync(connection->bundle);
if (ret)
return ret;
prop = get_psy_prop(gbpsy, psp);
if (!prop)
return -EINVAL;
if (!prop) {
ret = -EINVAL;
goto out;
}
req.psy_id = gbpsy->id;
req.property = prop->gb_prop;
req.prop_val = cpu_to_le32((s32)val);
@ -741,6 +793,7 @@ static int gb_power_supply_property_set(struct gb_power_supply *gbpsy,
prop->val = val;
out:
gb_pm_runtime_put_autosuspend(connection->bundle);
return ret;
}
@ -883,6 +936,8 @@ static int gb_power_supply_enable(struct gb_power_supply *gbpsy)
if (ret < 0)
return ret;
mutex_init(&gbpsy->supply_lock);
ret = gb_power_supply_register(gbpsy);
if (ret < 0)
return ret;
@ -1067,6 +1122,7 @@ static int gb_power_supply_probe(struct gb_bundle *bundle,
if (ret < 0)
goto error_connection_disable;
gb_pm_runtime_put_autosuspend(bundle);
return 0;
error_connection_disable: