Skip to content

Commit eb03e31

Browse files
committed
Merge tag 'for-v6.4-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply fixes from Sebastian Reichel: - Fix power_supply_get_battery_info for devices without parent devices resulting in NULL pointer dereference - Fix desktop systems reporting to run on battery once a power-supply device with device scope appears (e.g. a HID keyboard with a battery) - Ratelimit debug print about driver not providing data - Fix race condition related to external_power_changed in multiple drivers (ab8500, axp288, bq25890, sc27xx, bq27xxx) - Fix LED trigger switching from blinking to solid-on when charging finishes - Fix multiple races in bq27xxx battery driver - mt6360: handle potential ENOMEM from devm_work_autocancel - sbs-charger: Fix SBS_CHARGER_STATUS_CHARGE_INHIBITED bit - rt9467: avoid passing 0 to dev_err_probe * tag 'for-v6.4-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (21 commits) power: supply: Fix logic checking if system is running from battery power: supply: mt6360: add a check of devm_work_autocancel in mt6360_charger_probe power: supply: sbs-charger: Fix INHIBITED bit for Status reg power: supply: rt9467: Fix passing zero to 'dev_err_probe' power: supply: Ratelimit no data debug output power: supply: Fix power_supply_get_battery_info() if parent is NULL power: supply: bq24190: Call power_supply_changed() after updating input current power: supply: bq25890: Call power_supply_changed() after updating input current or voltage power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + schedule() power: supply: bq27xxx: After charger plug in/out wait 0.5s for things to stabilize power: supply: bq27xxx: Ensure power_supply_changed() is called on current sign changes power: supply: bq27xxx: Move bq27xxx_battery_update() down power: supply: bq27xxx: Add cache parameter to bq27xxx_battery_current_and_status() power: supply: bq27xxx: Fix poll_interval handling and races on remove power: supply: bq27xxx: Fix I2C IRQ race on remove power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition power: supply: leds: Fix blink to LED on transition power: supply: sc27xx: Fix external_power_changed race power: supply: bq25890: Fix external_power_changed race power: supply: axp288_fuel_gauge: Fix external_power_changed race ...
2 parents 029c77f + 95339f4 commit eb03e31

15 files changed

+136
-112
lines changed

drivers/power/supply/ab8500_btemp.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -624,10 +624,8 @@ static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data)
624624
*/
625625
static void ab8500_btemp_external_power_changed(struct power_supply *psy)
626626
{
627-
struct ab8500_btemp *di = power_supply_get_drvdata(psy);
628-
629-
class_for_each_device(power_supply_class, NULL,
630-
di->btemp_psy, ab8500_btemp_get_ext_psy_data);
627+
class_for_each_device(power_supply_class, NULL, psy,
628+
ab8500_btemp_get_ext_psy_data);
631629
}
632630

633631
/* ab8500 btemp driver interrupts and their respective isr */

drivers/power/supply/ab8500_fg.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2407,10 +2407,8 @@ static int ab8500_fg_init_hw_registers(struct ab8500_fg *di)
24072407
*/
24082408
static void ab8500_fg_external_power_changed(struct power_supply *psy)
24092409
{
2410-
struct ab8500_fg *di = power_supply_get_drvdata(psy);
2411-
2412-
class_for_each_device(power_supply_class, NULL,
2413-
di->fg_psy, ab8500_fg_get_ext_psy_data);
2410+
class_for_each_device(power_supply_class, NULL, psy,
2411+
ab8500_fg_get_ext_psy_data);
24142412
}
24152413

24162414
/**

drivers/power/supply/axp288_fuel_gauge.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ static void fuel_gauge_external_power_changed(struct power_supply *psy)
507507
mutex_lock(&info->lock);
508508
info->valid = 0; /* Force updating of the cached registers */
509509
mutex_unlock(&info->lock);
510-
power_supply_changed(info->bat);
510+
power_supply_changed(psy);
511511
}
512512

513513
static struct power_supply_desc fuel_gauge_desc = {

drivers/power/supply/bq24190_charger.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,7 @@ static void bq24190_input_current_limit_work(struct work_struct *work)
12621262
bq24190_charger_set_property(bdi->charger,
12631263
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
12641264
&val);
1265+
power_supply_changed(bdi->charger);
12651266
}
12661267

12671268
/* Sync the input-current-limit with our parent supply (if we have one) */

drivers/power/supply/bq25890_charger.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ static void bq25890_charger_external_power_changed(struct power_supply *psy)
750750
if (bq->chip_version != BQ25892)
751751
return;
752752

753-
ret = power_supply_get_property_from_supplier(bq->charger,
753+
ret = power_supply_get_property_from_supplier(psy,
754754
POWER_SUPPLY_PROP_USB_TYPE,
755755
&val);
756756
if (ret)
@@ -775,6 +775,7 @@ static void bq25890_charger_external_power_changed(struct power_supply *psy)
775775
}
776776

777777
bq25890_field_write(bq, F_IINLIM, input_current_limit);
778+
power_supply_changed(psy);
778779
}
779780

780781
static int bq25890_get_chip_state(struct bq25890_device *bq,
@@ -1106,6 +1107,8 @@ static void bq25890_pump_express_work(struct work_struct *data)
11061107
dev_info(bq->dev, "Hi-voltage charging requested, input voltage is %d mV\n",
11071108
voltage);
11081109

1110+
power_supply_changed(bq->charger);
1111+
11091112
return;
11101113
error_print:
11111114
bq25890_field_write(bq, F_PUMPX_EN, 0);

drivers/power/supply/bq27xxx_battery.c

Lines changed: 98 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,10 +1083,8 @@ static int poll_interval_param_set(const char *val, const struct kernel_param *k
10831083
return ret;
10841084

10851085
mutex_lock(&bq27xxx_list_lock);
1086-
list_for_each_entry(di, &bq27xxx_battery_devices, list) {
1087-
cancel_delayed_work_sync(&di->work);
1088-
schedule_delayed_work(&di->work, 0);
1089-
}
1086+
list_for_each_entry(di, &bq27xxx_battery_devices, list)
1087+
mod_delayed_work(system_wq, &di->work, 0);
10901088
mutex_unlock(&bq27xxx_list_lock);
10911089

10921090
return ret;
@@ -1761,60 +1759,6 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
17611759
return POWER_SUPPLY_HEALTH_GOOD;
17621760
}
17631761

1764-
void bq27xxx_battery_update(struct bq27xxx_device_info *di)
1765-
{
1766-
struct bq27xxx_reg_cache cache = {0, };
1767-
bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
1768-
1769-
cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
1770-
if ((cache.flags & 0xff) == 0xff)
1771-
cache.flags = -1; /* read error */
1772-
if (cache.flags >= 0) {
1773-
cache.temperature = bq27xxx_battery_read_temperature(di);
1774-
if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
1775-
cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
1776-
if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
1777-
cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
1778-
if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
1779-
cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
1780-
1781-
cache.charge_full = bq27xxx_battery_read_fcc(di);
1782-
cache.capacity = bq27xxx_battery_read_soc(di);
1783-
if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
1784-
cache.energy = bq27xxx_battery_read_energy(di);
1785-
di->cache.flags = cache.flags;
1786-
cache.health = bq27xxx_battery_read_health(di);
1787-
if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
1788-
cache.cycle_count = bq27xxx_battery_read_cyct(di);
1789-
1790-
/* We only have to read charge design full once */
1791-
if (di->charge_design_full <= 0)
1792-
di->charge_design_full = bq27xxx_battery_read_dcap(di);
1793-
}
1794-
1795-
if ((di->cache.capacity != cache.capacity) ||
1796-
(di->cache.flags != cache.flags))
1797-
power_supply_changed(di->bat);
1798-
1799-
if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
1800-
di->cache = cache;
1801-
1802-
di->last_update = jiffies;
1803-
}
1804-
EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
1805-
1806-
static void bq27xxx_battery_poll(struct work_struct *work)
1807-
{
1808-
struct bq27xxx_device_info *di =
1809-
container_of(work, struct bq27xxx_device_info,
1810-
work.work);
1811-
1812-
bq27xxx_battery_update(di);
1813-
1814-
if (poll_interval > 0)
1815-
schedule_delayed_work(&di->work, poll_interval * HZ);
1816-
}
1817-
18181762
static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
18191763
{
18201764
if (di->opts & BQ27XXX_O_ZERO)
@@ -1833,7 +1777,8 @@ static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
18331777
static int bq27xxx_battery_current_and_status(
18341778
struct bq27xxx_device_info *di,
18351779
union power_supply_propval *val_curr,
1836-
union power_supply_propval *val_status)
1780+
union power_supply_propval *val_status,
1781+
struct bq27xxx_reg_cache *cache)
18371782
{
18381783
bool single_flags = (di->opts & BQ27XXX_O_ZERO);
18391784
int curr;
@@ -1845,10 +1790,14 @@ static int bq27xxx_battery_current_and_status(
18451790
return curr;
18461791
}
18471792

1848-
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
1849-
if (flags < 0) {
1850-
dev_err(di->dev, "error reading flags\n");
1851-
return flags;
1793+
if (cache) {
1794+
flags = cache->flags;
1795+
} else {
1796+
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
1797+
if (flags < 0) {
1798+
dev_err(di->dev, "error reading flags\n");
1799+
return flags;
1800+
}
18521801
}
18531802

18541803
if (di->opts & BQ27XXX_O_ZERO) {
@@ -1883,6 +1832,78 @@ static int bq27xxx_battery_current_and_status(
18831832
return 0;
18841833
}
18851834

1835+
static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
1836+
{
1837+
union power_supply_propval status = di->last_status;
1838+
struct bq27xxx_reg_cache cache = {0, };
1839+
bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
1840+
1841+
cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
1842+
if ((cache.flags & 0xff) == 0xff)
1843+
cache.flags = -1; /* read error */
1844+
if (cache.flags >= 0) {
1845+
cache.temperature = bq27xxx_battery_read_temperature(di);
1846+
if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
1847+
cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
1848+
if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
1849+
cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
1850+
if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
1851+
cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
1852+
1853+
cache.charge_full = bq27xxx_battery_read_fcc(di);
1854+
cache.capacity = bq27xxx_battery_read_soc(di);
1855+
if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
1856+
cache.energy = bq27xxx_battery_read_energy(di);
1857+
di->cache.flags = cache.flags;
1858+
cache.health = bq27xxx_battery_read_health(di);
1859+
if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
1860+
cache.cycle_count = bq27xxx_battery_read_cyct(di);
1861+
1862+
/*
1863+
* On gauges with signed current reporting the current must be
1864+
* checked to detect charging <-> discharging status changes.
1865+
*/
1866+
if (!(di->opts & BQ27XXX_O_ZERO))
1867+
bq27xxx_battery_current_and_status(di, NULL, &status, &cache);
1868+
1869+
/* We only have to read charge design full once */
1870+
if (di->charge_design_full <= 0)
1871+
di->charge_design_full = bq27xxx_battery_read_dcap(di);
1872+
}
1873+
1874+
if ((di->cache.capacity != cache.capacity) ||
1875+
(di->cache.flags != cache.flags) ||
1876+
(di->last_status.intval != status.intval)) {
1877+
di->last_status.intval = status.intval;
1878+
power_supply_changed(di->bat);
1879+
}
1880+
1881+
if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
1882+
di->cache = cache;
1883+
1884+
di->last_update = jiffies;
1885+
1886+
if (!di->removed && poll_interval > 0)
1887+
mod_delayed_work(system_wq, &di->work, poll_interval * HZ);
1888+
}
1889+
1890+
void bq27xxx_battery_update(struct bq27xxx_device_info *di)
1891+
{
1892+
mutex_lock(&di->lock);
1893+
bq27xxx_battery_update_unlocked(di);
1894+
mutex_unlock(&di->lock);
1895+
}
1896+
EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
1897+
1898+
static void bq27xxx_battery_poll(struct work_struct *work)
1899+
{
1900+
struct bq27xxx_device_info *di =
1901+
container_of(work, struct bq27xxx_device_info,
1902+
work.work);
1903+
1904+
bq27xxx_battery_update(di);
1905+
}
1906+
18861907
/*
18871908
* Get the average power in µW
18881909
* Return < 0 if something fails.
@@ -1985,18 +2006,16 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
19852006
struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
19862007

19872008
mutex_lock(&di->lock);
1988-
if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
1989-
cancel_delayed_work_sync(&di->work);
1990-
bq27xxx_battery_poll(&di->work.work);
1991-
}
2009+
if (time_is_before_jiffies(di->last_update + 5 * HZ))
2010+
bq27xxx_battery_update_unlocked(di);
19922011
mutex_unlock(&di->lock);
19932012

19942013
if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)
19952014
return -ENODEV;
19962015

19972016
switch (psp) {
19982017
case POWER_SUPPLY_PROP_STATUS:
1999-
ret = bq27xxx_battery_current_and_status(di, NULL, val);
2018+
ret = bq27xxx_battery_current_and_status(di, NULL, val, NULL);
20002019
break;
20012020
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
20022021
ret = bq27xxx_battery_voltage(di, val);
@@ -2005,7 +2024,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
20052024
val->intval = di->cache.flags < 0 ? 0 : 1;
20062025
break;
20072026
case POWER_SUPPLY_PROP_CURRENT_NOW:
2008-
ret = bq27xxx_battery_current_and_status(di, val, NULL);
2027+
ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);
20092028
break;
20102029
case POWER_SUPPLY_PROP_CAPACITY:
20112030
ret = bq27xxx_simple_value(di->cache.capacity, val);
@@ -2078,8 +2097,8 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
20782097
{
20792098
struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
20802099

2081-
cancel_delayed_work_sync(&di->work);
2082-
schedule_delayed_work(&di->work, 0);
2100+
/* After charger plug in/out wait 0.5s for things to stabilize */
2101+
mod_delayed_work(system_wq, &di->work, HZ / 2);
20832102
}
20842103

20852104
int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
@@ -2127,22 +2146,18 @@ EXPORT_SYMBOL_GPL(bq27xxx_battery_setup);
21272146

21282147
void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
21292148
{
2130-
/*
2131-
* power_supply_unregister call bq27xxx_battery_get_property which
2132-
* call bq27xxx_battery_poll.
2133-
* Make sure that bq27xxx_battery_poll will not call
2134-
* schedule_delayed_work again after unregister (which cause OOPS).
2135-
*/
2136-
poll_interval = 0;
2137-
2138-
cancel_delayed_work_sync(&di->work);
2139-
2140-
power_supply_unregister(di->bat);
2141-
21422149
mutex_lock(&bq27xxx_list_lock);
21432150
list_del(&di->list);
21442151
mutex_unlock(&bq27xxx_list_lock);
21452152

2153+
/* Set removed to avoid bq27xxx_battery_update() re-queuing the work */
2154+
mutex_lock(&di->lock);
2155+
di->removed = true;
2156+
mutex_unlock(&di->lock);
2157+
2158+
cancel_delayed_work_sync(&di->work);
2159+
2160+
power_supply_unregister(di->bat);
21462161
mutex_destroy(&di->lock);
21472162
}
21482163
EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);

drivers/power/supply/bq27xxx_battery_i2c.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client)
179179
i2c_set_clientdata(client, di);
180180

181181
if (client->irq) {
182-
ret = devm_request_threaded_irq(&client->dev, client->irq,
182+
ret = request_threaded_irq(client->irq,
183183
NULL, bq27xxx_battery_irq_handler_thread,
184184
IRQF_ONESHOT,
185185
di->name, di);
@@ -209,6 +209,7 @@ static void bq27xxx_battery_i2c_remove(struct i2c_client *client)
209209
{
210210
struct bq27xxx_device_info *di = i2c_get_clientdata(client);
211211

212+
free_irq(client->irq, di);
212213
bq27xxx_battery_teardown(di);
213214

214215
mutex_lock(&battery_mutex);

drivers/power/supply/mt6360_charger.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,9 @@ static int mt6360_charger_probe(struct platform_device *pdev)
796796
mci->vinovp = 6500000;
797797
mutex_init(&mci->chgdet_lock);
798798
platform_set_drvdata(pdev, mci);
799-
devm_work_autocancel(&pdev->dev, &mci->chrdet_work, mt6360_chrdet_work);
799+
ret = devm_work_autocancel(&pdev->dev, &mci->chrdet_work, mt6360_chrdet_work);
800+
if (ret)
801+
return dev_err_probe(&pdev->dev, ret, "Failed to set delayed work\n");
800802

801803
ret = device_property_read_u32(&pdev->dev, "richtek,vinovp-microvolt", &mci->vinovp);
802804
if (ret)

0 commit comments

Comments
 (0)