Skip to content

Commit f385e6e

Browse files
tmlindsre
authored andcommitted
power: bq24190_charger: Use PM runtime autosuspend
We can get quite a few interrupts when the battery is trickle charging. Let's enable PM runtime autosuspend to avoid constantly toggling device driver PM runtime state. Let's use a 600 ms timeout as that's how long the USB chager detection might take. Acked-by: Mark Greer <mgreer@animalcreek.com> Acked-by: Liam Breck <kernel@networkimprov.net> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Sebastian Reichel <sre@kernel.org>
1 parent 35c3c19 commit f385e6e

File tree

1 file changed

+114
-42
lines changed

1 file changed

+114
-42
lines changed

drivers/power/supply/bq24190_charger.c

Lines changed: 114 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -420,18 +420,28 @@ static ssize_t bq24190_sysfs_show(struct device *dev,
420420
struct power_supply *psy = dev_get_drvdata(dev);
421421
struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
422422
struct bq24190_sysfs_field_info *info;
423+
ssize_t count;
423424
int ret;
424425
u8 v;
425426

426427
info = bq24190_sysfs_field_lookup(attr->attr.name);
427428
if (!info)
428429
return -EINVAL;
429430

431+
ret = pm_runtime_get_sync(bdi->dev);
432+
if (ret < 0)
433+
return ret;
434+
430435
ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
431436
if (ret)
432-
return ret;
437+
count = ret;
438+
else
439+
count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
433440

434-
return scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
441+
pm_runtime_mark_last_busy(bdi->dev);
442+
pm_runtime_put_autosuspend(bdi->dev);
443+
444+
return count;
435445
}
436446

437447
static ssize_t bq24190_sysfs_store(struct device *dev,
@@ -451,9 +461,16 @@ static ssize_t bq24190_sysfs_store(struct device *dev,
451461
if (ret < 0)
452462
return ret;
453463

464+
ret = pm_runtime_get_sync(bdi->dev);
465+
if (ret < 0)
466+
return ret;
467+
454468
ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
455469
if (ret)
456-
return ret;
470+
count = ret;
471+
472+
pm_runtime_mark_last_busy(bdi->dev);
473+
pm_runtime_put_autosuspend(bdi->dev);
457474

458475
return count;
459476
}
@@ -795,7 +812,9 @@ static int bq24190_charger_get_property(struct power_supply *psy,
795812

796813
dev_dbg(bdi->dev, "prop: %d\n", psp);
797814

798-
pm_runtime_get_sync(bdi->dev);
815+
ret = pm_runtime_get_sync(bdi->dev);
816+
if (ret < 0)
817+
return ret;
799818

800819
switch (psp) {
801820
case POWER_SUPPLY_PROP_CHARGE_TYPE:
@@ -835,7 +854,9 @@ static int bq24190_charger_get_property(struct power_supply *psy,
835854
ret = -ENODATA;
836855
}
837856

838-
pm_runtime_put_sync(bdi->dev);
857+
pm_runtime_mark_last_busy(bdi->dev);
858+
pm_runtime_put_autosuspend(bdi->dev);
859+
839860
return ret;
840861
}
841862

@@ -848,7 +869,9 @@ static int bq24190_charger_set_property(struct power_supply *psy,
848869

849870
dev_dbg(bdi->dev, "prop: %d\n", psp);
850871

851-
pm_runtime_get_sync(bdi->dev);
872+
ret = pm_runtime_get_sync(bdi->dev);
873+
if (ret < 0)
874+
return ret;
852875

853876
switch (psp) {
854877
case POWER_SUPPLY_PROP_CHARGE_TYPE:
@@ -864,7 +887,9 @@ static int bq24190_charger_set_property(struct power_supply *psy,
864887
ret = -EINVAL;
865888
}
866889

867-
pm_runtime_put_sync(bdi->dev);
890+
pm_runtime_mark_last_busy(bdi->dev);
891+
pm_runtime_put_autosuspend(bdi->dev);
892+
868893
return ret;
869894
}
870895

@@ -1065,7 +1090,9 @@ static int bq24190_battery_get_property(struct power_supply *psy,
10651090

10661091
dev_dbg(bdi->dev, "prop: %d\n", psp);
10671092

1068-
pm_runtime_get_sync(bdi->dev);
1093+
ret = pm_runtime_get_sync(bdi->dev);
1094+
if (ret < 0)
1095+
return ret;
10691096

10701097
switch (psp) {
10711098
case POWER_SUPPLY_PROP_STATUS:
@@ -1093,7 +1120,9 @@ static int bq24190_battery_get_property(struct power_supply *psy,
10931120
ret = -ENODATA;
10941121
}
10951122

1096-
pm_runtime_put_sync(bdi->dev);
1123+
pm_runtime_mark_last_busy(bdi->dev);
1124+
pm_runtime_put_autosuspend(bdi->dev);
1125+
10971126
return ret;
10981127
}
10991128

@@ -1106,7 +1135,9 @@ static int bq24190_battery_set_property(struct power_supply *psy,
11061135

11071136
dev_dbg(bdi->dev, "prop: %d\n", psp);
11081137

1109-
pm_runtime_get_sync(bdi->dev);
1138+
ret = pm_runtime_get_sync(bdi->dev);
1139+
if (ret < 0)
1140+
return ret;
11101141

11111142
switch (psp) {
11121143
case POWER_SUPPLY_PROP_ONLINE:
@@ -1119,7 +1150,9 @@ static int bq24190_battery_set_property(struct power_supply *psy,
11191150
ret = -EINVAL;
11201151
}
11211152

1122-
pm_runtime_put_sync(bdi->dev);
1153+
pm_runtime_mark_last_busy(bdi->dev);
1154+
pm_runtime_put_autosuspend(bdi->dev);
1155+
11231156
return ret;
11241157
}
11251158

@@ -1234,11 +1267,17 @@ static void bq24190_check_status(struct bq24190_dev_info *bdi)
12341267
static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
12351268
{
12361269
struct bq24190_dev_info *bdi = data;
1270+
int ret;
12371271

12381272
bdi->irq_event = true;
1239-
pm_runtime_get_sync(bdi->dev);
1273+
ret = pm_runtime_get_sync(bdi->dev);
1274+
if (ret < 0) {
1275+
dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
1276+
return IRQ_NONE;
1277+
}
12401278
bq24190_check_status(bdi);
1241-
pm_runtime_put_sync(bdi->dev);
1279+
pm_runtime_mark_last_busy(bdi->dev);
1280+
pm_runtime_put_autosuspend(bdi->dev);
12421281
bdi->irq_event = false;
12431282

12441283
return IRQ_HANDLED;
@@ -1249,33 +1288,26 @@ static int bq24190_hw_init(struct bq24190_dev_info *bdi)
12491288
u8 v;
12501289
int ret;
12511290

1252-
pm_runtime_get_sync(bdi->dev);
1253-
12541291
/* First check that the device really is what its supposed to be */
12551292
ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
12561293
BQ24190_REG_VPRS_PN_MASK,
12571294
BQ24190_REG_VPRS_PN_SHIFT,
12581295
&v);
12591296
if (ret < 0)
1260-
goto out;
1297+
return ret;
12611298

1262-
if (v != bdi->model) {
1263-
ret = -ENODEV;
1264-
goto out;
1265-
}
1299+
if (v != bdi->model)
1300+
return -ENODEV;
12661301

12671302
ret = bq24190_register_reset(bdi);
12681303
if (ret < 0)
1269-
goto out;
1304+
return ret;
12701305

12711306
ret = bq24190_set_mode_host(bdi);
12721307
if (ret < 0)
1273-
goto out;
1308+
return ret;
12741309

1275-
ret = bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1276-
out:
1277-
pm_runtime_put_sync(bdi->dev);
1278-
return ret;
1310+
return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
12791311
}
12801312

12811313
#ifdef CONFIG_OF
@@ -1364,12 +1396,16 @@ static int bq24190_probe(struct i2c_client *client,
13641396
}
13651397

13661398
pm_runtime_enable(dev);
1367-
pm_runtime_resume(dev);
1399+
pm_runtime_use_autosuspend(dev);
1400+
pm_runtime_set_autosuspend_delay(dev, 600);
1401+
ret = pm_runtime_get_sync(dev);
1402+
if (ret < 0)
1403+
goto out1;
13681404

13691405
ret = bq24190_hw_init(bdi);
13701406
if (ret < 0) {
13711407
dev_err(dev, "Hardware init failed\n");
1372-
goto out1;
1408+
goto out2;
13731409
}
13741410

13751411
charger_cfg.drv_data = bdi;
@@ -1380,7 +1416,7 @@ static int bq24190_probe(struct i2c_client *client,
13801416
if (IS_ERR(bdi->charger)) {
13811417
dev_err(dev, "Can't register charger\n");
13821418
ret = PTR_ERR(bdi->charger);
1383-
goto out1;
1419+
goto out2;
13841420
}
13851421

13861422
battery_cfg.drv_data = bdi;
@@ -1389,13 +1425,13 @@ static int bq24190_probe(struct i2c_client *client,
13891425
if (IS_ERR(bdi->battery)) {
13901426
dev_err(dev, "Can't register battery\n");
13911427
ret = PTR_ERR(bdi->battery);
1392-
goto out2;
1428+
goto out3;
13931429
}
13941430

13951431
ret = bq24190_sysfs_create_group(bdi);
13961432
if (ret) {
13971433
dev_err(dev, "Can't create sysfs entries\n");
1398-
goto out3;
1434+
goto out4;
13991435
}
14001436

14011437
bdi->initialized = true;
@@ -1406,21 +1442,30 @@ static int bq24190_probe(struct i2c_client *client,
14061442
"bq24190-charger", bdi);
14071443
if (ret < 0) {
14081444
dev_err(dev, "Can't set up irq handler\n");
1409-
goto out4;
1445+
goto out5;
14101446
}
14111447

1448+
enable_irq_wake(bdi->irq);
1449+
1450+
pm_runtime_mark_last_busy(dev);
1451+
pm_runtime_put_autosuspend(dev);
1452+
14121453
return 0;
14131454

1414-
out4:
1455+
out5:
14151456
bq24190_sysfs_remove_group(bdi);
14161457

1417-
out3:
1458+
out4:
14181459
power_supply_unregister(bdi->battery);
14191460

1420-
out2:
1461+
out3:
14211462
power_supply_unregister(bdi->charger);
14221463

1464+
out2:
1465+
pm_runtime_put_sync(dev);
1466+
14231467
out1:
1468+
pm_runtime_dont_use_autosuspend(dev);
14241469
pm_runtime_disable(dev);
14251470
if (bdi->gpio_int)
14261471
gpio_free(bdi->gpio_int);
@@ -1430,14 +1475,21 @@ static int bq24190_probe(struct i2c_client *client,
14301475
static int bq24190_remove(struct i2c_client *client)
14311476
{
14321477
struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1478+
int error;
14331479

1434-
pm_runtime_get_sync(bdi->dev);
1435-
bq24190_register_reset(bdi);
1436-
pm_runtime_put_sync(bdi->dev);
1480+
error = pm_runtime_get_sync(bdi->dev);
1481+
if (error < 0) {
1482+
dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1483+
pm_runtime_put_noidle(bdi->dev);
1484+
}
14371485

1486+
bq24190_register_reset(bdi);
14381487
bq24190_sysfs_remove_group(bdi);
14391488
power_supply_unregister(bdi->battery);
14401489
power_supply_unregister(bdi->charger);
1490+
if (error >= 0)
1491+
pm_runtime_put_sync(bdi->dev);
1492+
pm_runtime_dont_use_autosuspend(bdi->dev);
14411493
pm_runtime_disable(bdi->dev);
14421494

14431495
if (bdi->gpio_int)
@@ -1480,10 +1532,20 @@ static int bq24190_pm_suspend(struct device *dev)
14801532
{
14811533
struct i2c_client *client = to_i2c_client(dev);
14821534
struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1535+
int error;
1536+
1537+
error = pm_runtime_get_sync(bdi->dev);
1538+
if (error < 0) {
1539+
dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1540+
pm_runtime_put_noidle(bdi->dev);
1541+
}
14831542

1484-
pm_runtime_get_sync(bdi->dev);
14851543
bq24190_register_reset(bdi);
1486-
pm_runtime_put_sync(bdi->dev);
1544+
1545+
if (error >= 0) {
1546+
pm_runtime_mark_last_busy(bdi->dev);
1547+
pm_runtime_put_autosuspend(bdi->dev);
1548+
}
14871549

14881550
return 0;
14891551
}
@@ -1492,15 +1554,25 @@ static int bq24190_pm_resume(struct device *dev)
14921554
{
14931555
struct i2c_client *client = to_i2c_client(dev);
14941556
struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
1557+
int error;
14951558

14961559
bdi->f_reg = 0;
14971560
bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
14981561

1499-
pm_runtime_get_sync(bdi->dev);
1562+
error = pm_runtime_get_sync(bdi->dev);
1563+
if (error < 0) {
1564+
dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
1565+
pm_runtime_put_noidle(bdi->dev);
1566+
}
1567+
15001568
bq24190_register_reset(bdi);
15011569
bq24190_set_mode_host(bdi);
15021570
bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
1503-
pm_runtime_put_sync(bdi->dev);
1571+
1572+
if (error >= 0) {
1573+
pm_runtime_mark_last_busy(bdi->dev);
1574+
pm_runtime_put_autosuspend(bdi->dev);
1575+
}
15041576

15051577
/* Things may have changed while suspended so alert upper layer */
15061578
power_supply_changed(bdi->charger);

0 commit comments

Comments
 (0)