Skip to content

Commit

Permalink
bq20z75: Fix issues with present and suspend
Browse files Browse the repository at this point in the history
There are a few issues found around the battery not being present. If the
battery isn't present, then a few undesirable things happen. The first was
excessive reporting of failed properties. This was fixed by instead
returning ENODATA for all properties other than PRESENT if the battery
isn't present. That way the callers can identify the difference between a
failure and the battery not being there.

The next issue was in the suspend logic. It was found that if the battery
wasn't present, then it would return a failure, preventing the system from
going into suspend. If there is no battery present, the io is expected to
fail, so in that case, we shouldn't return the failure and just
acknowledge that it was expected.

I also found that when a gpio was used, i didn't maintain the internal
is_present state properly. I added a set of that to fix that.

Lastly, the code to see io's fail and figure out that the battery isn't
present when not using a gpio had a problem. In that code, it looked for
the read to fail and if it did, then handled it. The problem is that in
function to get the property, it first writes a value and that write can
fail, causing the code to never reach the logic after the read. Fix is
to move the logic till after the write.

Signed-off-by: Rhyland Klein <rklein@nvidia.com>
Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
  • Loading branch information
Rhyland Klein authored and Anton Vorontsov committed Mar 16, 2011
1 parent a223246 commit a7d9ace
Showing 1 changed file with 21 additions and 11 deletions.
32 changes: 21 additions & 11 deletions drivers/power/bq20z75.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ static int bq20z75_read_word_data(struct i2c_client *client, u8 address)
}

if (ret < 0) {
dev_warn(&client->dev,
dev_dbg(&client->dev,
"%s: i2c read at address 0x%x failed\n",
__func__, address);
return ret;
Expand Down Expand Up @@ -199,7 +199,7 @@ static int bq20z75_write_word_data(struct i2c_client *client, u8 address,
}

if (ret < 0) {
dev_warn(&client->dev,
dev_dbg(&client->dev,
"%s: i2c write to address 0x%x failed\n",
__func__, address);
return ret;
Expand All @@ -223,6 +223,7 @@ static int bq20z75_get_battery_presence_and_health(
val->intval = 1;
else
val->intval = 0;
bq20z75_device->is_present = val->intval;
return ret;
}

Expand All @@ -232,18 +233,17 @@ static int bq20z75_get_battery_presence_and_health(
ret = bq20z75_write_word_data(client,
bq20z75_data[REG_MANUFACTURER_DATA].addr,
MANUFACTURER_ACCESS_STATUS);
if (ret < 0)
return ret;


ret = bq20z75_read_word_data(client,
bq20z75_data[REG_MANUFACTURER_DATA].addr);
if (ret < 0) {
if (psp == POWER_SUPPLY_PROP_PRESENT)
val->intval = 0; /* battery removed */
return ret;
}

ret = bq20z75_read_word_data(client,
bq20z75_data[REG_MANUFACTURER_DATA].addr);
if (ret < 0)
return ret;

if (ret < bq20z75_data[REG_MANUFACTURER_DATA].min_value ||
ret > bq20z75_data[REG_MANUFACTURER_DATA].max_value) {
val->intval = 0;
Expand Down Expand Up @@ -455,6 +455,8 @@ static int bq20z75_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_HEALTH:
ret = bq20z75_get_battery_presence_and_health(client, psp, val);
if (psp == POWER_SUPPLY_PROP_PRESENT)
return 0;
break;

case POWER_SUPPLY_PROP_TECHNOLOGY:
Expand Down Expand Up @@ -516,9 +518,16 @@ static int bq20z75_get_property(struct power_supply *psy,
}

dev_dbg(&client->dev,
"%s: property = %d, value = %d\n", __func__, psp, val->intval);
"%s: property = %d, value = %x\n", __func__, psp, val->intval);

if (ret && bq20z75_device->is_present)
return ret;

/* battery not present, so return NODATA for properties */
if (ret)
return -ENODATA;

return ret;
return 0;
}

static irqreturn_t bq20z75_irq(int irq, void *devid)
Expand Down Expand Up @@ -643,13 +652,14 @@ static int __devexit bq20z75_remove(struct i2c_client *client)
static int bq20z75_suspend(struct i2c_client *client,
pm_message_t state)
{
struct bq20z75_info *bq20z75_device = i2c_get_clientdata(client);
s32 ret;

/* write to manufacturer access with sleep command */
ret = bq20z75_write_word_data(client,
bq20z75_data[REG_MANUFACTURER_DATA].addr,
MANUFACTURER_ACCESS_SLEEP);
if (ret < 0)
if (bq20z75_device->is_present && ret < 0)
return ret;

return 0;
Expand Down

0 comments on commit a7d9ace

Please sign in to comment.