hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/power/supply/bq27xxx_battery.c
....@@ -1018,10 +1018,8 @@
10181018 return ret;
10191019
10201020 mutex_lock(&bq27xxx_list_lock);
1021
- list_for_each_entry(di, &bq27xxx_battery_devices, list) {
1022
- cancel_delayed_work_sync(&di->work);
1023
- schedule_delayed_work(&di->work, 0);
1024
- }
1021
+ list_for_each_entry(di, &bq27xxx_battery_devices, list)
1022
+ mod_delayed_work(system_wq, &di->work, 0);
10251023 mutex_unlock(&bq27xxx_list_lock);
10261024
10271025 return ret;
....@@ -1507,14 +1505,6 @@
15071505 */
15081506 static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
15091507 {
1510
- int flags;
1511
-
1512
- if (di->opts & BQ27XXX_O_ZERO) {
1513
- flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
1514
- if (flags >= 0 && (flags & BQ27000_FLAG_CI))
1515
- return -ENODATA;
1516
- }
1517
-
15181508 return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
15191509 }
15201510
....@@ -1668,6 +1658,18 @@
16681658 return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
16691659 }
16701660
1661
+/*
1662
+ * Returns true if reported battery capacity is inaccurate
1663
+ */
1664
+static bool bq27xxx_battery_capacity_inaccurate(struct bq27xxx_device_info *di,
1665
+ u16 flags)
1666
+{
1667
+ if (di->opts & BQ27XXX_O_HAS_CI)
1668
+ return (flags & BQ27000_FLAG_CI);
1669
+ else
1670
+ return false;
1671
+}
1672
+
16711673 static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
16721674 {
16731675 /* Unlikely but important to return first */
....@@ -1677,14 +1679,89 @@
16771679 return POWER_SUPPLY_HEALTH_COLD;
16781680 if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))
16791681 return POWER_SUPPLY_HEALTH_DEAD;
1682
+ if (unlikely(bq27xxx_battery_capacity_inaccurate(di, di->cache.flags)))
1683
+ return POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
16801684
16811685 return POWER_SUPPLY_HEALTH_GOOD;
16821686 }
16831687
1684
-void bq27xxx_battery_update(struct bq27xxx_device_info *di)
1688
+static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
16851689 {
1690
+ if (di->opts & BQ27XXX_O_ZERO)
1691
+ return (flags & BQ27000_FLAG_FC);
1692
+ else if (di->opts & BQ27Z561_O_BITS)
1693
+ return (flags & BQ27Z561_FLAG_FC);
1694
+ else
1695
+ return (flags & BQ27XXX_FLAG_FC);
1696
+}
1697
+
1698
+/*
1699
+ * Return the battery average current in µA and the status
1700
+ * Note that current can be negative signed as well
1701
+ * Or 0 if something fails.
1702
+ */
1703
+static int bq27xxx_battery_current_and_status(
1704
+ struct bq27xxx_device_info *di,
1705
+ union power_supply_propval *val_curr,
1706
+ union power_supply_propval *val_status,
1707
+ struct bq27xxx_reg_cache *cache)
1708
+{
1709
+ bool single_flags = (di->opts & BQ27XXX_O_ZERO);
1710
+ int curr;
1711
+ int flags;
1712
+
1713
+ curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
1714
+ if (curr < 0) {
1715
+ dev_err(di->dev, "error reading current\n");
1716
+ return curr;
1717
+ }
1718
+
1719
+ if (cache) {
1720
+ flags = cache->flags;
1721
+ } else {
1722
+ flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
1723
+ if (flags < 0) {
1724
+ dev_err(di->dev, "error reading flags\n");
1725
+ return flags;
1726
+ }
1727
+ }
1728
+
1729
+ if (di->opts & BQ27XXX_O_ZERO) {
1730
+ if (!(flags & BQ27000_FLAG_CHGS)) {
1731
+ dev_dbg(di->dev, "negative current!\n");
1732
+ curr = -curr;
1733
+ }
1734
+
1735
+ curr = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
1736
+ } else {
1737
+ /* Other gauges return signed value */
1738
+ curr = (int)((s16)curr) * 1000;
1739
+ }
1740
+
1741
+ if (val_curr)
1742
+ val_curr->intval = curr;
1743
+
1744
+ if (val_status) {
1745
+ if (curr > 0) {
1746
+ val_status->intval = POWER_SUPPLY_STATUS_CHARGING;
1747
+ } else if (curr < 0) {
1748
+ val_status->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1749
+ } else {
1750
+ if (bq27xxx_battery_is_full(di, flags))
1751
+ val_status->intval = POWER_SUPPLY_STATUS_FULL;
1752
+ else
1753
+ val_status->intval =
1754
+ POWER_SUPPLY_STATUS_NOT_CHARGING;
1755
+ }
1756
+ }
1757
+
1758
+ return 0;
1759
+}
1760
+
1761
+static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
1762
+{
1763
+ union power_supply_propval status = di->last_status;
16861764 struct bq27xxx_reg_cache cache = {0, };
1687
- bool has_ci_flag = di->opts & BQ27XXX_O_HAS_CI;
16881765 bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
16891766
16901767 cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
....@@ -1692,32 +1769,28 @@
16921769 cache.flags = -1; /* read error */
16931770 if (cache.flags >= 0) {
16941771 cache.temperature = bq27xxx_battery_read_temperature(di);
1695
- if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
1696
- dev_info_once(di->dev, "battery is not calibrated! ignoring capacity values\n");
1697
- cache.capacity = -ENODATA;
1698
- cache.energy = -ENODATA;
1699
- cache.time_to_empty = -ENODATA;
1700
- cache.time_to_empty_avg = -ENODATA;
1701
- cache.time_to_full = -ENODATA;
1702
- cache.charge_full = -ENODATA;
1703
- cache.health = -ENODATA;
1704
- } else {
1705
- if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
1706
- cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
1707
- if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
1708
- cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
1709
- if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
1710
- cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
1772
+ if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
1773
+ cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
1774
+ if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
1775
+ cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
1776
+ if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
1777
+ cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
17111778
1712
- cache.charge_full = bq27xxx_battery_read_fcc(di);
1713
- cache.capacity = bq27xxx_battery_read_soc(di);
1714
- if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
1715
- cache.energy = bq27xxx_battery_read_energy(di);
1716
- di->cache.flags = cache.flags;
1717
- cache.health = bq27xxx_battery_read_health(di);
1718
- }
1779
+ cache.charge_full = bq27xxx_battery_read_fcc(di);
1780
+ cache.capacity = bq27xxx_battery_read_soc(di);
1781
+ if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
1782
+ cache.energy = bq27xxx_battery_read_energy(di);
1783
+ di->cache.flags = cache.flags;
1784
+ cache.health = bq27xxx_battery_read_health(di);
17191785 if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
17201786 cache.cycle_count = bq27xxx_battery_read_cyct(di);
1787
+
1788
+ /*
1789
+ * On gauges with signed current reporting the current must be
1790
+ * checked to detect charging <-> discharging status changes.
1791
+ */
1792
+ if (!(di->opts & BQ27XXX_O_ZERO))
1793
+ bq27xxx_battery_current_and_status(di, NULL, &status, &cache);
17211794
17221795 /* We only have to read charge design full once */
17231796 if (di->charge_design_full <= 0)
....@@ -1725,13 +1798,26 @@
17251798 }
17261799
17271800 if ((di->cache.capacity != cache.capacity) ||
1728
- (di->cache.flags != cache.flags))
1801
+ (di->cache.flags != cache.flags) ||
1802
+ (di->last_status.intval != status.intval)) {
1803
+ di->last_status.intval = status.intval;
17291804 power_supply_changed(di->bat);
1805
+ }
17301806
17311807 if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
17321808 di->cache = cache;
17331809
17341810 di->last_update = jiffies;
1811
+
1812
+ if (!di->removed && poll_interval > 0)
1813
+ mod_delayed_work(system_wq, &di->work, poll_interval * HZ);
1814
+}
1815
+
1816
+void bq27xxx_battery_update(struct bq27xxx_device_info *di)
1817
+{
1818
+ mutex_lock(&di->lock);
1819
+ bq27xxx_battery_update_unlocked(di);
1820
+ mutex_unlock(&di->lock);
17351821 }
17361822 EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
17371823
....@@ -1742,42 +1828,6 @@
17421828 work.work);
17431829
17441830 bq27xxx_battery_update(di);
1745
-
1746
- if (poll_interval > 0)
1747
- schedule_delayed_work(&di->work, poll_interval * HZ);
1748
-}
1749
-
1750
-/*
1751
- * Return the battery average current in µA
1752
- * Note that current can be negative signed as well
1753
- * Or 0 if something fails.
1754
- */
1755
-static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
1756
- union power_supply_propval *val)
1757
-{
1758
- int curr;
1759
- int flags;
1760
-
1761
- curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
1762
- if (curr < 0) {
1763
- dev_err(di->dev, "error reading current\n");
1764
- return curr;
1765
- }
1766
-
1767
- if (di->opts & BQ27XXX_O_ZERO) {
1768
- flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
1769
- if (flags & BQ27000_FLAG_CHGS) {
1770
- dev_dbg(di->dev, "negative current!\n");
1771
- curr = -curr;
1772
- }
1773
-
1774
- val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
1775
- } else {
1776
- /* Other gauges return signed value */
1777
- val->intval = (int)((s16)curr) * 1000;
1778
- }
1779
-
1780
- return 0;
17811831 }
17821832
17831833 /*
....@@ -1802,43 +1852,6 @@
18021852 else
18031853 /* Other gauges return a signed value in units of 10mW */
18041854 val->intval = (int)((s16)power) * 10000;
1805
-
1806
- return 0;
1807
-}
1808
-
1809
-static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
1810
- union power_supply_propval *val)
1811
-{
1812
- int status;
1813
-
1814
- if (di->opts & BQ27XXX_O_ZERO) {
1815
- if (di->cache.flags & BQ27000_FLAG_FC)
1816
- status = POWER_SUPPLY_STATUS_FULL;
1817
- else if (di->cache.flags & BQ27000_FLAG_CHGS)
1818
- status = POWER_SUPPLY_STATUS_CHARGING;
1819
- else
1820
- status = POWER_SUPPLY_STATUS_DISCHARGING;
1821
- } else if (di->opts & BQ27Z561_O_BITS) {
1822
- if (di->cache.flags & BQ27Z561_FLAG_FC)
1823
- status = POWER_SUPPLY_STATUS_FULL;
1824
- else if (di->cache.flags & BQ27Z561_FLAG_DIS_CH)
1825
- status = POWER_SUPPLY_STATUS_DISCHARGING;
1826
- else
1827
- status = POWER_SUPPLY_STATUS_CHARGING;
1828
- } else {
1829
- if (di->cache.flags & BQ27XXX_FLAG_FC)
1830
- status = POWER_SUPPLY_STATUS_FULL;
1831
- else if (di->cache.flags & BQ27XXX_FLAG_DSC)
1832
- status = POWER_SUPPLY_STATUS_DISCHARGING;
1833
- else
1834
- status = POWER_SUPPLY_STATUS_CHARGING;
1835
- }
1836
-
1837
- if ((status == POWER_SUPPLY_STATUS_DISCHARGING) &&
1838
- (power_supply_am_i_supplied(di->bat) > 0))
1839
- status = POWER_SUPPLY_STATUS_NOT_CHARGING;
1840
-
1841
- val->intval = status;
18421855
18431856 return 0;
18441857 }
....@@ -1919,10 +1932,8 @@
19191932 struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
19201933
19211934 mutex_lock(&di->lock);
1922
- if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
1923
- cancel_delayed_work_sync(&di->work);
1924
- bq27xxx_battery_poll(&di->work.work);
1925
- }
1935
+ if (time_is_before_jiffies(di->last_update + 5 * HZ))
1936
+ bq27xxx_battery_update_unlocked(di);
19261937 mutex_unlock(&di->lock);
19271938
19281939 if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)
....@@ -1930,7 +1941,7 @@
19301941
19311942 switch (psp) {
19321943 case POWER_SUPPLY_PROP_STATUS:
1933
- ret = bq27xxx_battery_status(di, val);
1944
+ ret = bq27xxx_battery_current_and_status(di, NULL, val, NULL);
19341945 break;
19351946 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
19361947 ret = bq27xxx_battery_voltage(di, val);
....@@ -1939,7 +1950,7 @@
19391950 val->intval = di->cache.flags < 0 ? 0 : 1;
19401951 break;
19411952 case POWER_SUPPLY_PROP_CURRENT_NOW:
1942
- ret = bq27xxx_battery_current(di, val);
1953
+ ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);
19431954 break;
19441955 case POWER_SUPPLY_PROP_CAPACITY:
19451956 ret = bq27xxx_simple_value(di->cache.capacity, val);
....@@ -2009,8 +2020,8 @@
20092020 {
20102021 struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
20112022
2012
- cancel_delayed_work_sync(&di->work);
2013
- schedule_delayed_work(&di->work, 0);
2023
+ /* After charger plug in/out wait 0.5s for things to stabilize */
2024
+ mod_delayed_work(system_wq, &di->work, HZ / 2);
20142025 }
20152026
20162027 int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
....@@ -2058,22 +2069,18 @@
20582069
20592070 void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)
20602071 {
2061
- /*
2062
- * power_supply_unregister call bq27xxx_battery_get_property which
2063
- * call bq27xxx_battery_poll.
2064
- * Make sure that bq27xxx_battery_poll will not call
2065
- * schedule_delayed_work again after unregister (which cause OOPS).
2066
- */
2067
- poll_interval = 0;
2068
-
2069
- cancel_delayed_work_sync(&di->work);
2070
-
2071
- power_supply_unregister(di->bat);
2072
-
20732072 mutex_lock(&bq27xxx_list_lock);
20742073 list_del(&di->list);
20752074 mutex_unlock(&bq27xxx_list_lock);
20762075
2076
+ /* Set removed to avoid bq27xxx_battery_update() re-queuing the work */
2077
+ mutex_lock(&di->lock);
2078
+ di->removed = true;
2079
+ mutex_unlock(&di->lock);
2080
+
2081
+ cancel_delayed_work_sync(&di->work);
2082
+
2083
+ power_supply_unregister(di->bat);
20772084 mutex_destroy(&di->lock);
20782085 }
20792086 EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);