]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Mon, 29 May 2023 02:43:53 +0000 (22:43 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 29 May 2023 02:43:53 +0000 (22:43 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
19 files changed:
queue-5.10/net-mlx5-devcom-only-supports-2-ports.patch [new file with mode: 0644]
queue-5.10/net-mlx5-devcom-serialize-devcom-registration.patch [new file with mode: 0644]
queue-5.10/net-phy-mscc-enable-vsc8501-2-rgmii-rx-clock.patch [new file with mode: 0644]
queue-5.10/power-supply-bq24190-call-power_supply_changed-after.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-add-cache-parameter-to-bq27xxx_.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-after-charger-plug-in-out-wait-.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-ensure-power_supply_changed-is-.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-expose-battery-data-when-ci-1.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-fix-polarity-of-current_now.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-fix-sign-of-current_now-for-new.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-make-status-more-robust.patch [new file with mode: 0644]
queue-5.10/power-supply-bq27xxx-move-bq27xxx_battery_update-dow.patch [new file with mode: 0644]
queue-5.10/power-supply-core-refactor-power_supply_set_input_cu.patch [new file with mode: 0644]
queue-5.10/regulator-add-regmap-helper-for-ramp-delay-setting.patch [new file with mode: 0644]
queue-5.10/regulator-pca9450-convert-to-use-regulator_set_ramp_.patch [new file with mode: 0644]
queue-5.10/regulator-pca9450-fix-buck2-enable_mask.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/x86-cpu-add-raptor-lake-to-intel-family.patch [new file with mode: 0644]
queue-5.10/x86-cpu-drop-spurious-underscore-from-raptor_lake-de.patch [new file with mode: 0644]

diff --git a/queue-5.10/net-mlx5-devcom-only-supports-2-ports.patch b/queue-5.10/net-mlx5-devcom-only-supports-2-ports.patch
new file mode 100644 (file)
index 0000000..b24ded0
--- /dev/null
@@ -0,0 +1,109 @@
+From a2a5045a0c00a990d9ac7117efb782b087e85bf8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 27 Feb 2022 12:23:34 +0000
+Subject: net/mlx5: devcom only supports 2 ports
+
+From: Mark Bloch <mbloch@nvidia.com>
+
+[ Upstream commit 8a6e75e5f57e9ac82268d9bfca3403598d9d0292 ]
+
+Devcom API is intended to be used between 2 devices only add this
+implied assumption into the code and check when it's no true.
+
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 1f893f57a3bf ("net/mlx5: Devcom, serialize devcom registration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/lib/devcom.c | 16 +++++++++-------
+ .../net/ethernet/mellanox/mlx5/core/lib/devcom.h |  2 ++
+ 2 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+index abd066e952286..617eea1b1701b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+@@ -14,7 +14,7 @@ static LIST_HEAD(devcom_list);
+ struct mlx5_devcom_component {
+       struct {
+               void *data;
+-      } device[MLX5_MAX_PORTS];
++      } device[MLX5_DEVCOM_PORTS_SUPPORTED];
+       mlx5_devcom_event_handler_t handler;
+       struct rw_semaphore sem;
+@@ -25,7 +25,7 @@ struct mlx5_devcom_list {
+       struct list_head list;
+       struct mlx5_devcom_component components[MLX5_DEVCOM_NUM_COMPONENTS];
+-      struct mlx5_core_dev *devs[MLX5_MAX_PORTS];
++      struct mlx5_core_dev *devs[MLX5_DEVCOM_PORTS_SUPPORTED];
+ };
+ struct mlx5_devcom {
+@@ -74,13 +74,15 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
+       if (!mlx5_core_is_pf(dev))
+               return NULL;
++      if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
++              return NULL;
+       sguid0 = mlx5_query_nic_system_image_guid(dev);
+       list_for_each_entry(iter, &devcom_list, list) {
+               struct mlx5_core_dev *tmp_dev = NULL;
+               idx = -1;
+-              for (i = 0; i < MLX5_MAX_PORTS; i++) {
++              for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) {
+                       if (iter->devs[i])
+                               tmp_dev = iter->devs[i];
+                       else
+@@ -135,11 +137,11 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
+       kfree(devcom);
+-      for (i = 0; i < MLX5_MAX_PORTS; i++)
++      for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
+               if (priv->devs[i])
+                       break;
+-      if (i != MLX5_MAX_PORTS)
++      if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
+               return;
+       list_del(&priv->list);
+@@ -192,7 +194,7 @@ int mlx5_devcom_send_event(struct mlx5_devcom *devcom,
+       comp = &devcom->priv->components[id];
+       down_write(&comp->sem);
+-      for (i = 0; i < MLX5_MAX_PORTS; i++)
++      for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
+               if (i != devcom->idx && comp->device[i].data) {
+                       err = comp->handler(event, comp->device[i].data,
+                                           event_data);
+@@ -240,7 +242,7 @@ void *mlx5_devcom_get_peer_data(struct mlx5_devcom *devcom,
+               return NULL;
+       }
+-      for (i = 0; i < MLX5_MAX_PORTS; i++)
++      for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++)
+               if (i != devcom->idx)
+                       break;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h
+index 939d5bf1581b5..94313c18bb647 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h
+@@ -6,6 +6,8 @@
+ #include <linux/mlx5/driver.h>
++#define MLX5_DEVCOM_PORTS_SUPPORTED 2
++
+ enum mlx5_devcom_components {
+       MLX5_DEVCOM_ESW_OFFLOADS,
+-- 
+2.39.2
+
diff --git a/queue-5.10/net-mlx5-devcom-serialize-devcom-registration.patch b/queue-5.10/net-mlx5-devcom-serialize-devcom-registration.patch
new file mode 100644 (file)
index 0000000..cb588b3
--- /dev/null
@@ -0,0 +1,100 @@
+From f27003cf979e055aab96eae5c34d01a898f916a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 May 2023 13:36:42 +0300
+Subject: net/mlx5: Devcom, serialize devcom registration
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 1f893f57a3bf9fe1f4bcb25b55aea7f7f9712fe7 ]
+
+From one hand, mlx5 driver is allowing to probe PFs in parallel.
+From the other hand, devcom, which is a share resource between PFs, is
+registered without any lock. This might resulted in memory problems.
+
+Hence, use the global mlx5_dev_list_lock in order to serialize devcom
+registration.
+
+Fixes: fadd59fc50d0 ("net/mlx5: Introduce inter-device communication mechanism")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/lib/devcom.c  | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+index 617eea1b1701b..438be215bbd45 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+@@ -3,6 +3,7 @@
+ #include <linux/mlx5/vport.h>
+ #include "lib/devcom.h"
++#include "mlx5_core.h"
+ static LIST_HEAD(devcom_list);
+@@ -77,6 +78,7 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
+       if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED)
+               return NULL;
++      mlx5_dev_list_lock();
+       sguid0 = mlx5_query_nic_system_image_guid(dev);
+       list_for_each_entry(iter, &devcom_list, list) {
+               struct mlx5_core_dev *tmp_dev = NULL;
+@@ -102,8 +104,10 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
+       if (!priv) {
+               priv = mlx5_devcom_list_alloc();
+-              if (!priv)
+-                      return ERR_PTR(-ENOMEM);
++              if (!priv) {
++                      devcom = ERR_PTR(-ENOMEM);
++                      goto out;
++              }
+               idx = 0;
+               new_priv = true;
+@@ -114,12 +118,14 @@ struct mlx5_devcom *mlx5_devcom_register_device(struct mlx5_core_dev *dev)
+       if (!devcom) {
+               if (new_priv)
+                       kfree(priv);
+-              return ERR_PTR(-ENOMEM);
++              devcom = ERR_PTR(-ENOMEM);
++              goto out;
+       }
+       if (new_priv)
+               list_add(&priv->list, &devcom_list);
+-
++out:
++      mlx5_dev_list_unlock();
+       return devcom;
+ }
+@@ -132,6 +138,7 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
+       if (IS_ERR_OR_NULL(devcom))
+               return;
++      mlx5_dev_list_lock();
+       priv = devcom->priv;
+       priv->devs[devcom->idx] = NULL;
+@@ -142,10 +149,12 @@ void mlx5_devcom_unregister_device(struct mlx5_devcom *devcom)
+                       break;
+       if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
+-              return;
++              goto out;
+       list_del(&priv->list);
+       kfree(priv);
++out:
++      mlx5_dev_list_unlock();
+ }
+ void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
+-- 
+2.39.2
+
diff --git a/queue-5.10/net-phy-mscc-enable-vsc8501-2-rgmii-rx-clock.patch b/queue-5.10/net-phy-mscc-enable-vsc8501-2-rgmii-rx-clock.patch
new file mode 100644 (file)
index 0000000..5d53424
--- /dev/null
@@ -0,0 +1,134 @@
+From abff89d99b02d5d3b2e21337a96a349d35b3f510 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 May 2023 17:31:08 +0200
+Subject: net: phy: mscc: enable VSC8501/2 RGMII RX clock
+
+From: David Epping <david.epping@missinglinkelectronics.com>
+
+[ Upstream commit 71460c9ec5c743e9ffffca3c874d66267c36345e ]
+
+By default the VSC8501 and VSC8502 RGMII/GMII/MII RX_CLK output is
+disabled. To allow packet forwarding towards the MAC it needs to be
+enabled.
+
+For other PHYs supported by this driver the clock output is enabled
+by default.
+
+Fixes: d3169863310d ("net: phy: mscc: add support for VSC8502")
+Signed-off-by: David Epping <david.epping@missinglinkelectronics.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h      |  1 +
+ drivers/net/phy/mscc/mscc_main.c | 54 +++++++++++++++++---------------
+ 2 files changed, 29 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index c2023f93c0b24..79117d281c1ec 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -175,6 +175,7 @@ enum rgmii_clock_delay {
+ #define VSC8502_RGMII_CNTL              20
+ #define VSC8502_RGMII_RX_DELAY_MASK     0x0070
+ #define VSC8502_RGMII_TX_DELAY_MASK     0x0007
++#define VSC8502_RGMII_RX_CLK_DISABLE    0x0800
+ #define MSCC_PHY_WOL_LOWER_MAC_ADDR     21
+ #define MSCC_PHY_WOL_MID_MAC_ADDR       22
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index ffac713afa551..c64ac142509a5 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -527,14 +527,27 @@ static int vsc85xx_mac_if_set(struct phy_device *phydev,
+  *  * 2.0 ns (which causes the data to be sampled at exactly half way between
+  *    clock transitions at 1000 Mbps) if delays should be enabled
+  */
+-static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
+-                                 u16 rgmii_rx_delay_mask,
+-                                 u16 rgmii_tx_delay_mask)
++static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl,
++                                   u16 rgmii_rx_delay_mask,
++                                   u16 rgmii_tx_delay_mask)
+ {
+       u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1;
+       u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1;
+       u16 reg_val = 0;
+-      int rc;
++      u16 mask = 0;
++      int rc = 0;
++
++      /* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit
++       * to be unset for all PHY modes, so do that as part of the paged
++       * register modification.
++       * For some family members (like VSC8530/31/40/41) this bit is reserved
++       * and read-only, and the RX clock is enabled by default.
++       */
++      if (rgmii_cntl == VSC8502_RGMII_CNTL)
++              mask |= VSC8502_RGMII_RX_CLK_DISABLE;
++
++      if (phy_interface_is_rgmii(phydev))
++              mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask;
+       mutex_lock(&phydev->lock);
+@@ -545,10 +558,9 @@ static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
+           phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+               reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos;
+-      rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
+-                            rgmii_cntl,
+-                            rgmii_rx_delay_mask | rgmii_tx_delay_mask,
+-                            reg_val);
++      if (mask)
++              rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
++                                    rgmii_cntl, mask, reg_val);
+       mutex_unlock(&phydev->lock);
+@@ -557,19 +569,11 @@ static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl,
+ static int vsc85xx_default_config(struct phy_device *phydev)
+ {
+-      int rc;
+-
+       phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+-      if (phy_interface_mode_is_rgmii(phydev->interface)) {
+-              rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL,
+-                                           VSC8502_RGMII_RX_DELAY_MASK,
+-                                           VSC8502_RGMII_TX_DELAY_MASK);
+-              if (rc)
+-                      return rc;
+-      }
+-
+-      return 0;
++      return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL,
++                                       VSC8502_RGMII_RX_DELAY_MASK,
++                                       VSC8502_RGMII_TX_DELAY_MASK);
+ }
+ static int vsc85xx_get_tunable(struct phy_device *phydev,
+@@ -1646,13 +1650,11 @@ static int vsc8584_config_init(struct phy_device *phydev)
+       if (ret)
+               return ret;
+-      if (phy_interface_is_rgmii(phydev)) {
+-              ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL,
+-                                            VSC8572_RGMII_RX_DELAY_MASK,
+-                                            VSC8572_RGMII_TX_DELAY_MASK);
+-              if (ret)
+-                      return ret;
+-      }
++      ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL,
++                                      VSC8572_RGMII_RX_DELAY_MASK,
++                                      VSC8572_RGMII_TX_DELAY_MASK);
++      if (ret)
++              return ret;
+       ret = genphy_soft_reset(phydev);
+       if (ret)
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq24190-call-power_supply_changed-after.patch b/queue-5.10/power-supply-bq24190-call-power_supply_changed-after.patch
new file mode 100644 (file)
index 0000000..b2f923b
--- /dev/null
@@ -0,0 +1,47 @@
+From 75614085be7d2a205aaca22c22ab5bb5a9ca92bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Apr 2023 20:23:41 +0200
+Subject: power: supply: bq24190: Call power_supply_changed() after updating
+ input current
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 77c2a3097d7029441e8a91aa0de1b4e5464593da ]
+
+The bq24192 model relies on external charger-type detection and once
+that is done the bq24190_charger code will update the input current.
+
+In this case, when the initial power_supply_changed() call is made
+from the interrupt handler, the input settings are 5V/0.5A which
+on many devices is not enough power to charge (while the device is on).
+
+On many devices the fuel-gauge relies in its external_power_changed
+callback to timely signal userspace about charging <-> discharging
+status changes. Add a power_supply_changed() call after updating
+the input current. This allows the fuel-gauge driver to timely recheck
+if the battery is charging after the new input current has been applied
+and then it can immediately notify userspace about this.
+
+Fixes: 18f8e6f695ac ("power: supply: bq24190_charger: Get input_current_limit from our supplier")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq24190_charger.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c
+index 7a7b03b09ea64..5769b36851c34 100644
+--- a/drivers/power/supply/bq24190_charger.c
++++ b/drivers/power/supply/bq24190_charger.c
+@@ -1215,6 +1215,7 @@ static void bq24190_input_current_limit_work(struct work_struct *work)
+       bq24190_charger_set_property(bdi->charger,
+                                    POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
+                                    &val);
++      power_supply_changed(bdi->charger);
+ }
+ /* Sync the input-current-limit with our parent supply (if we have one) */
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-add-cache-parameter-to-bq27xxx_.patch b/queue-5.10/power-supply-bq27xxx-add-cache-parameter-to-bq27xxx_.patch
new file mode 100644 (file)
index 0000000..babc184
--- /dev/null
@@ -0,0 +1,78 @@
+From 75f2cfa4e6771d4a8bbb4e9e57f4c7c149ba9405 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Apr 2023 20:23:35 +0200
+Subject: power: supply: bq27xxx: Add cache parameter to
+ bq27xxx_battery_current_and_status()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 35092c5819f8c5acc7bafe3fdbb13d6307c4f5e1 ]
+
+Add a cache parameter to bq27xxx_battery_current_and_status() so that
+it can optionally use cached flags instead of re-reading them itself.
+
+This is a preparation patch for making bq27xxx_battery_update() check
+the status and have it call power_supply_changed() on status changes.
+
+Fixes: 297a533b3e62 ("bq27x00: Cache battery registers")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 681fa81f4dbde..d09ce7d6351d9 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1772,7 +1772,8 @@ static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
+ static int bq27xxx_battery_current_and_status(
+       struct bq27xxx_device_info *di,
+       union power_supply_propval *val_curr,
+-      union power_supply_propval *val_status)
++      union power_supply_propval *val_status,
++      struct bq27xxx_reg_cache *cache)
+ {
+       bool single_flags = (di->opts & BQ27XXX_O_ZERO);
+       int curr;
+@@ -1784,10 +1785,14 @@ static int bq27xxx_battery_current_and_status(
+               return curr;
+       }
+-      flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
+-      if (flags < 0) {
+-              dev_err(di->dev, "error reading flags\n");
+-              return flags;
++      if (cache) {
++              flags = cache->flags;
++      } else {
++              flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
++              if (flags < 0) {
++                      dev_err(di->dev, "error reading flags\n");
++                      return flags;
++              }
+       }
+       if (di->opts & BQ27XXX_O_ZERO) {
+@@ -1933,7 +1938,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+-              ret = bq27xxx_battery_current_and_status(di, NULL, val);
++              ret = bq27xxx_battery_current_and_status(di, NULL, val, NULL);
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               ret = bq27xxx_battery_voltage(di, val);
+@@ -1942,7 +1947,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
+               val->intval = di->cache.flags < 0 ? 0 : 1;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+-              ret = bq27xxx_battery_current_and_status(di, val, NULL);
++              ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);
+               break;
+       case POWER_SUPPLY_PROP_CAPACITY:
+               ret = bq27xxx_simple_value(di->cache.capacity, val);
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-after-charger-plug-in-out-wait-.patch b/queue-5.10/power-supply-bq27xxx-after-charger-plug-in-out-wait-.patch
new file mode 100644 (file)
index 0000000..5c7c547
--- /dev/null
@@ -0,0 +1,41 @@
+From 150c44a331a769000a54e7a2f1f210a975731833 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Apr 2023 20:23:38 +0200
+Subject: power: supply: bq27xxx: After charger plug in/out wait 0.5s for
+ things to stabilize
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 59a99cd462fbdf71f4e845e09f37783035088b4f ]
+
+bq27xxx_external_power_changed() gets called when the charger is plugged
+in or out. Rather then immediately scheduling an update wait 0.5 seconds
+for things to stabilize, so that e.g. the (dis)charge current is stable
+when bq27xxx_battery_update() runs.
+
+Fixes: 740b755a3b34 ("bq27x00: Poll battery state")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 8984f66bd2bc3..235647b21af71 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -2022,8 +2022,8 @@ static void bq27xxx_external_power_changed(struct power_supply *psy)
+ {
+       struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);
+-      cancel_delayed_work_sync(&di->work);
+-      schedule_delayed_work(&di->work, 0);
++      /* After charger plug in/out wait 0.5s for things to stabilize */
++      mod_delayed_work(system_wq, &di->work, HZ / 2);
+ }
+ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-ensure-power_supply_changed-is-.patch b/queue-5.10/power-supply-bq27xxx-ensure-power_supply_changed-is-.patch
new file mode 100644 (file)
index 0000000..d041a1f
--- /dev/null
@@ -0,0 +1,98 @@
+From c9685561c3f7636ffb03369059e1f108d8efe549 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Apr 2023 20:23:37 +0200
+Subject: power: supply: bq27xxx: Ensure power_supply_changed() is called on
+ current sign changes
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 939a116142012926e25de0ea6b7e2f8d86a5f1b6 ]
+
+On gauges where the current register is signed, there is no charging
+flag in the flags register. So only checking flags will not result
+in power_supply_changed() getting called when e.g. a charger is plugged
+in and the current sign changes from negative (discharging) to
+positive (charging).
+
+This causes userspace's notion of the status to lag until userspace
+does a poll.
+
+And when a power_supply_leds.c LED trigger is used to indicate charging
+status with a LED, this LED will lag until the capacity percentage
+changes, which may take many minutes (because the LED trigger only is
+updated on power_supply_changed() calls).
+
+Fix this by calling bq27xxx_battery_current_and_status() on gauges with
+a signed current register and checking if the status has changed.
+
+Fixes: 297a533b3e62 ("bq27x00: Cache battery registers")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 13 ++++++++++++-
+ include/linux/power/bq27xxx_battery.h  |  3 +++
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 160ab53065f8e..8984f66bd2bc3 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1762,6 +1762,7 @@ static int bq27xxx_battery_current_and_status(
+ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+ {
++      union power_supply_propval status = di->last_status;
+       struct bq27xxx_reg_cache cache = {0, };
+       bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
+@@ -1786,14 +1787,24 @@ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+               if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
+                       cache.cycle_count = bq27xxx_battery_read_cyct(di);
++              /*
++               * On gauges with signed current reporting the current must be
++               * checked to detect charging <-> discharging status changes.
++               */
++              if (!(di->opts & BQ27XXX_O_ZERO))
++                      bq27xxx_battery_current_and_status(di, NULL, &status, &cache);
++
+               /* We only have to read charge design full once */
+               if (di->charge_design_full <= 0)
+                       di->charge_design_full = bq27xxx_battery_read_dcap(di);
+       }
+       if ((di->cache.capacity != cache.capacity) ||
+-          (di->cache.flags != cache.flags))
++          (di->cache.flags != cache.flags) ||
++          (di->last_status.intval != status.intval)) {
++              di->last_status.intval = status.intval;
+               power_supply_changed(di->bat);
++      }
+       if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
+               di->cache = cache;
+diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h
+index 705b94bd091e3..63964196a436e 100644
+--- a/include/linux/power/bq27xxx_battery.h
++++ b/include/linux/power/bq27xxx_battery.h
+@@ -2,6 +2,8 @@
+ #ifndef __LINUX_BQ27X00_BATTERY_H__
+ #define __LINUX_BQ27X00_BATTERY_H__
++#include <linux/power_supply.h>
++
+ enum bq27xxx_chip {
+       BQ27000 = 1, /* bq27000, bq27200 */
+       BQ27010, /* bq27010, bq27210 */
+@@ -69,6 +71,7 @@ struct bq27xxx_device_info {
+       int charge_design_full;
+       bool removed;
+       unsigned long last_update;
++      union power_supply_propval last_status;
+       struct delayed_work work;
+       struct power_supply *bat;
+       struct list_head list;
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-expose-battery-data-when-ci-1.patch b/queue-5.10/power-supply-bq27xxx-expose-battery-data-when-ci-1.patch
new file mode 100644 (file)
index 0000000..6d491ef
--- /dev/null
@@ -0,0 +1,129 @@
+From aa8193483b61d035aade5d56f7acd4b76c529532 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Apr 2022 14:30:59 +0200
+Subject: power: supply: bq27xxx: expose battery data when CI=1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sicelo A. Mhlongo <absicsz@gmail.com>
+
+[ Upstream commit 68fdbe090c362e8be23890a7333d156e18c27781 ]
+
+When the Capacity Inaccurate flag is set, the chip still provides data
+about the battery, albeit inaccurate. Instead of discarding capacity
+values for CI=1, expose the stale data and use the
+POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED property to indicate that the
+values should be used with care.
+
+Reviewed-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Sicelo A. Mhlongo <absicsz@gmail.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Stable-dep-of: ff4c4a2a4437 ("power: supply: bq27xxx: Move bq27xxx_battery_update() down")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 60 ++++++++++++--------------
+ 1 file changed, 27 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index d09ce7d6351d9..bd6e53525065d 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1507,14 +1507,6 @@ static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg)
+  */
+ static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di)
+ {
+-      int flags;
+-
+-      if (di->opts & BQ27XXX_O_ZERO) {
+-              flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
+-              if (flags >= 0 && (flags & BQ27000_FLAG_CI))
+-                      return -ENODATA;
+-      }
+-
+       return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC);
+ }
+@@ -1668,6 +1660,18 @@ static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
+               return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
+ }
++/*
++ * Returns true if reported battery capacity is inaccurate
++ */
++static bool bq27xxx_battery_capacity_inaccurate(struct bq27xxx_device_info *di,
++                                               u16 flags)
++{
++      if (di->opts & BQ27XXX_O_HAS_CI)
++              return (flags & BQ27000_FLAG_CI);
++      else
++              return false;
++}
++
+ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
+ {
+       /* Unlikely but important to return first */
+@@ -1677,6 +1681,8 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
+               return POWER_SUPPLY_HEALTH_COLD;
+       if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))
+               return POWER_SUPPLY_HEALTH_DEAD;
++      if (unlikely(bq27xxx_battery_capacity_inaccurate(di, di->cache.flags)))
++              return POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
+       return POWER_SUPPLY_HEALTH_GOOD;
+ }
+@@ -1684,7 +1690,6 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
+ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+ {
+       struct bq27xxx_reg_cache cache = {0, };
+-      bool has_ci_flag = di->opts & BQ27XXX_O_HAS_CI;
+       bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
+       cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
+@@ -1692,30 +1697,19 @@ static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+               cache.flags = -1; /* read error */
+       if (cache.flags >= 0) {
+               cache.temperature = bq27xxx_battery_read_temperature(di);
+-              if (has_ci_flag && (cache.flags & BQ27000_FLAG_CI)) {
+-                      dev_info_once(di->dev, "battery is not calibrated! ignoring capacity values\n");
+-                      cache.capacity = -ENODATA;
+-                      cache.energy = -ENODATA;
+-                      cache.time_to_empty = -ENODATA;
+-                      cache.time_to_empty_avg = -ENODATA;
+-                      cache.time_to_full = -ENODATA;
+-                      cache.charge_full = -ENODATA;
+-                      cache.health = -ENODATA;
+-              } else {
+-                      if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
+-                              cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
+-                      if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
+-                              cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
+-                      if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
+-                              cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
+-
+-                      cache.charge_full = bq27xxx_battery_read_fcc(di);
+-                      cache.capacity = bq27xxx_battery_read_soc(di);
+-                      if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
+-                              cache.energy = bq27xxx_battery_read_energy(di);
+-                      di->cache.flags = cache.flags;
+-                      cache.health = bq27xxx_battery_read_health(di);
+-              }
++              if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
++                      cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
++              if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
++                      cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
++              if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
++                      cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
++
++              cache.charge_full = bq27xxx_battery_read_fcc(di);
++              cache.capacity = bq27xxx_battery_read_soc(di);
++              if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
++                      cache.energy = bq27xxx_battery_read_energy(di);
++              di->cache.flags = cache.flags;
++              cache.health = bq27xxx_battery_read_health(di);
+               if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
+                       cache.cycle_count = bq27xxx_battery_read_cyct(di);
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-fix-polarity-of-current_now.patch b/queue-5.10/power-supply-bq27xxx-fix-polarity-of-current_now.patch
new file mode 100644 (file)
index 0000000..6f84fbd
--- /dev/null
@@ -0,0 +1,47 @@
+From 4f758bfee9ae67cb438f7eedfa51485d3e6d8c73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Dec 2020 15:49:50 +0100
+Subject: power: supply: bq27xxx: fix polarity of current_now
+
+From: Andreas Kemnade <andreas@kemnade.info>
+
+[ Upstream commit cd060b4d0868c806c2738a5e64e8ab9bd0fbec07 ]
+
+current_now has to be negative during discharging and positive during
+charging, the behavior seen is the other way round.
+
+Tested on GTA04 with Openmoko battery.
+
+Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Stable-dep-of: 35092c5819f8 ("power: supply: bq27xxx: Add cache parameter to bq27xxx_battery_current_and_status()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index c08dd4e6d35ad..79eee63a2041e 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1773,7 +1773,7 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
+       if (di->opts & BQ27XXX_O_ZERO) {
+               flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
+-              if (flags & BQ27000_FLAG_CHGS) {
++              if (!(flags & BQ27000_FLAG_CHGS)) {
+                       dev_dbg(di->dev, "negative current!\n");
+                       curr = -curr;
+               }
+@@ -1781,7 +1781,7 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
+               val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
+       } else {
+               /* Other gauges return signed value */
+-              val->intval = (int)((s16)curr) * 1000;
++              val->intval = -(int)((s16)curr) * 1000;
+       }
+       return 0;
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-fix-sign-of-current_now-for-new.patch b/queue-5.10/power-supply-bq27xxx-fix-sign-of-current_now-for-new.patch
new file mode 100644 (file)
index 0000000..9c66fa6
--- /dev/null
@@ -0,0 +1,42 @@
+From 6890ae1ff4eac18242eca5b3c82dadc792fb6577 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 10:54:18 +0100
+Subject: power: supply: bq27xxx: fix sign of current_now for newer ICs
+
+From: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+
+[ Upstream commit b67fdcb7099e9c640bad625c4dd6399debb3376a ]
+
+Commit cd060b4d0868 ("power: supply: bq27xxx: fix polarity of current_now")
+changed the sign of current_now for all bq27xxx variants, but on BQ28Z610
+I'm now seeing negated values *with* that patch.
+
+The GTA04/Openmoko device that was used for testing uses a BQ27000 or
+BQ27010 IC, so I assume only the BQ27XXX_O_ZERO code path was incorrect.
+Revert the behaviour for newer ICs.
+
+Fixes: cd060b4d0868 "power: supply: bq27xxx: fix polarity of current_now"
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Stable-dep-of: 35092c5819f8 ("power: supply: bq27xxx: Add cache parameter to bq27xxx_battery_current_and_status()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index 79eee63a2041e..d34f1fceadbb4 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1781,7 +1781,7 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
+               val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
+       } else {
+               /* Other gauges return signed value */
+-              val->intval = -(int)((s16)curr) * 1000;
++              val->intval = (int)((s16)curr) * 1000;
+       }
+       return 0;
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-make-status-more-robust.patch b/queue-5.10/power-supply-bq27xxx-make-status-more-robust.patch
new file mode 100644 (file)
index 0000000..3340eb7
--- /dev/null
@@ -0,0 +1,176 @@
+From 47797c0481b32c1489f34c7f8b3839f6fd26e179 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Mar 2021 10:54:20 +0100
+Subject: power: supply: bq27xxx: make status more robust
+
+From: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+
+[ Upstream commit c3a6d6a1dfc8a9bf12d79a0b1a30cb24c92a2ddf ]
+
+There are multiple issues in bq27xxx_battery_status():
+
+- On BQ28Q610 is was observed that the "full" flag may be set even while
+  the battery is charging or discharging. With the current logic to make
+  "full" override everything else, it look a very long time (>20min) for
+  the status to change from "full" to "discharging" after unplugging the
+  supply on a device with low power consumption
+- The POWER_SUPPLY_STATUS_NOT_CHARGING check depends on
+  power_supply_am_i_supplied(), which will not work when the supply
+  doesn't exist as a separate device known to Linux
+
+We can solve both issues by deriving the status from the current instead
+of the flags field. The flags are now only used to distinguish "full"
+from "not charging", and to determine the sign of the current on
+BQ27XXX_O_ZERO devices.
+
+Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Stable-dep-of: 35092c5819f8 ("power: supply: bq27xxx: Add cache parameter to bq27xxx_battery_current_and_status()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 88 +++++++++++++-------------
+ 1 file changed, 43 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index d34f1fceadbb4..681fa81f4dbde 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1754,14 +1754,27 @@ static void bq27xxx_battery_poll(struct work_struct *work)
+       bq27xxx_battery_update(di);
+ }
++static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
++{
++      if (di->opts & BQ27XXX_O_ZERO)
++              return (flags & BQ27000_FLAG_FC);
++      else if (di->opts & BQ27Z561_O_BITS)
++              return (flags & BQ27Z561_FLAG_FC);
++      else
++              return (flags & BQ27XXX_FLAG_FC);
++}
++
+ /*
+- * Return the battery average current in ÂµA
++ * Return the battery average current in ÂµA and the status
+  * Note that current can be negative signed as well
+  * Or 0 if something fails.
+  */
+-static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
+-                                 union power_supply_propval *val)
++static int bq27xxx_battery_current_and_status(
++      struct bq27xxx_device_info *di,
++      union power_supply_propval *val_curr,
++      union power_supply_propval *val_status)
+ {
++      bool single_flags = (di->opts & BQ27XXX_O_ZERO);
+       int curr;
+       int flags;
+@@ -1771,17 +1784,39 @@ static int bq27xxx_battery_current(struct bq27xxx_device_info *di,
+               return curr;
+       }
++      flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);
++      if (flags < 0) {
++              dev_err(di->dev, "error reading flags\n");
++              return flags;
++      }
++
+       if (di->opts & BQ27XXX_O_ZERO) {
+-              flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, true);
+               if (!(flags & BQ27000_FLAG_CHGS)) {
+                       dev_dbg(di->dev, "negative current!\n");
+                       curr = -curr;
+               }
+-              val->intval = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
++              curr = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
+       } else {
+               /* Other gauges return signed value */
+-              val->intval = (int)((s16)curr) * 1000;
++              curr = (int)((s16)curr) * 1000;
++      }
++
++      if (val_curr)
++              val_curr->intval = curr;
++
++      if (val_status) {
++              if (curr > 0) {
++                      val_status->intval = POWER_SUPPLY_STATUS_CHARGING;
++              } else if (curr < 0) {
++                      val_status->intval = POWER_SUPPLY_STATUS_DISCHARGING;
++              } else {
++                      if (bq27xxx_battery_is_full(di, flags))
++                              val_status->intval = POWER_SUPPLY_STATUS_FULL;
++                      else
++                              val_status->intval =
++                                      POWER_SUPPLY_STATUS_NOT_CHARGING;
++              }
+       }
+       return 0;
+@@ -1813,43 +1848,6 @@ static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di,
+       return 0;
+ }
+-static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
+-                                union power_supply_propval *val)
+-{
+-      int status;
+-
+-      if (di->opts & BQ27XXX_O_ZERO) {
+-              if (di->cache.flags & BQ27000_FLAG_FC)
+-                      status = POWER_SUPPLY_STATUS_FULL;
+-              else if (di->cache.flags & BQ27000_FLAG_CHGS)
+-                      status = POWER_SUPPLY_STATUS_CHARGING;
+-              else
+-                      status = POWER_SUPPLY_STATUS_DISCHARGING;
+-      } else if (di->opts & BQ27Z561_O_BITS) {
+-              if (di->cache.flags & BQ27Z561_FLAG_FC)
+-                      status = POWER_SUPPLY_STATUS_FULL;
+-              else if (di->cache.flags & BQ27Z561_FLAG_DIS_CH)
+-                      status = POWER_SUPPLY_STATUS_DISCHARGING;
+-              else
+-                      status = POWER_SUPPLY_STATUS_CHARGING;
+-      } else {
+-              if (di->cache.flags & BQ27XXX_FLAG_FC)
+-                      status = POWER_SUPPLY_STATUS_FULL;
+-              else if (di->cache.flags & BQ27XXX_FLAG_DSC)
+-                      status = POWER_SUPPLY_STATUS_DISCHARGING;
+-              else
+-                      status = POWER_SUPPLY_STATUS_CHARGING;
+-      }
+-
+-      if ((status == POWER_SUPPLY_STATUS_DISCHARGING) &&
+-          (power_supply_am_i_supplied(di->bat) > 0))
+-              status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+-
+-      val->intval = status;
+-
+-      return 0;
+-}
+-
+ static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,
+                                         union power_supply_propval *val)
+ {
+@@ -1935,7 +1933,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+-              ret = bq27xxx_battery_status(di, val);
++              ret = bq27xxx_battery_current_and_status(di, NULL, val);
+               break;
+       case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+               ret = bq27xxx_battery_voltage(di, val);
+@@ -1944,7 +1942,7 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
+               val->intval = di->cache.flags < 0 ? 0 : 1;
+               break;
+       case POWER_SUPPLY_PROP_CURRENT_NOW:
+-              ret = bq27xxx_battery_current(di, val);
++              ret = bq27xxx_battery_current_and_status(di, val, NULL);
+               break;
+       case POWER_SUPPLY_PROP_CAPACITY:
+               ret = bq27xxx_simple_value(di->cache.capacity, val);
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-bq27xxx-move-bq27xxx_battery_update-dow.patch b/queue-5.10/power-supply-bq27xxx-move-bq27xxx_battery_update-dow.patch
new file mode 100644 (file)
index 0000000..c5a08de
--- /dev/null
@@ -0,0 +1,168 @@
+From b03f67f0f3d5e8ecf8eb9a256f28c4f69a600a0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Apr 2023 20:23:36 +0200
+Subject: power: supply: bq27xxx: Move bq27xxx_battery_update() down
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit ff4c4a2a4437a6d03787c7aafb2617f20c3ef45f ]
+
+Move the bq27xxx_battery_update() functions to below
+the bq27xxx_battery_current_and_status() function.
+
+This is just moving a block of text, no functional changes.
+
+This is a preparation patch for making bq27xxx_battery_update() check
+the status and have it call power_supply_changed() on status changes.
+
+Fixes: 297a533b3e62 ("bq27x00: Cache battery registers")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq27xxx_battery.c | 122 ++++++++++++-------------
+ 1 file changed, 61 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index bd6e53525065d..160ab53065f8e 100644
+--- a/drivers/power/supply/bq27xxx_battery.c
++++ b/drivers/power/supply/bq27xxx_battery.c
+@@ -1687,67 +1687,6 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
+       return POWER_SUPPLY_HEALTH_GOOD;
+ }
+-static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
+-{
+-      struct bq27xxx_reg_cache cache = {0, };
+-      bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
+-
+-      cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
+-      if ((cache.flags & 0xff) == 0xff)
+-              cache.flags = -1; /* read error */
+-      if (cache.flags >= 0) {
+-              cache.temperature = bq27xxx_battery_read_temperature(di);
+-              if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
+-                      cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
+-              if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
+-                      cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
+-              if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
+-                      cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
+-
+-              cache.charge_full = bq27xxx_battery_read_fcc(di);
+-              cache.capacity = bq27xxx_battery_read_soc(di);
+-              if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
+-                      cache.energy = bq27xxx_battery_read_energy(di);
+-              di->cache.flags = cache.flags;
+-              cache.health = bq27xxx_battery_read_health(di);
+-              if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
+-                      cache.cycle_count = bq27xxx_battery_read_cyct(di);
+-
+-              /* We only have to read charge design full once */
+-              if (di->charge_design_full <= 0)
+-                      di->charge_design_full = bq27xxx_battery_read_dcap(di);
+-      }
+-
+-      if ((di->cache.capacity != cache.capacity) ||
+-          (di->cache.flags != cache.flags))
+-              power_supply_changed(di->bat);
+-
+-      if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
+-              di->cache = cache;
+-
+-      di->last_update = jiffies;
+-
+-      if (!di->removed && poll_interval > 0)
+-              mod_delayed_work(system_wq, &di->work, poll_interval * HZ);
+-}
+-
+-void bq27xxx_battery_update(struct bq27xxx_device_info *di)
+-{
+-      mutex_lock(&di->lock);
+-      bq27xxx_battery_update_unlocked(di);
+-      mutex_unlock(&di->lock);
+-}
+-EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
+-
+-static void bq27xxx_battery_poll(struct work_struct *work)
+-{
+-      struct bq27xxx_device_info *di =
+-                      container_of(work, struct bq27xxx_device_info,
+-                                   work.work);
+-
+-      bq27xxx_battery_update(di);
+-}
+-
+ static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)
+ {
+       if (di->opts & BQ27XXX_O_ZERO)
+@@ -1821,6 +1760,67 @@ static int bq27xxx_battery_current_and_status(
+       return 0;
+ }
++static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)
++{
++      struct bq27xxx_reg_cache cache = {0, };
++      bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
++
++      cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
++      if ((cache.flags & 0xff) == 0xff)
++              cache.flags = -1; /* read error */
++      if (cache.flags >= 0) {
++              cache.temperature = bq27xxx_battery_read_temperature(di);
++              if (di->regs[BQ27XXX_REG_TTE] != INVALID_REG_ADDR)
++                      cache.time_to_empty = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE);
++              if (di->regs[BQ27XXX_REG_TTECP] != INVALID_REG_ADDR)
++                      cache.time_to_empty_avg = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP);
++              if (di->regs[BQ27XXX_REG_TTF] != INVALID_REG_ADDR)
++                      cache.time_to_full = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF);
++
++              cache.charge_full = bq27xxx_battery_read_fcc(di);
++              cache.capacity = bq27xxx_battery_read_soc(di);
++              if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
++                      cache.energy = bq27xxx_battery_read_energy(di);
++              di->cache.flags = cache.flags;
++              cache.health = bq27xxx_battery_read_health(di);
++              if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
++                      cache.cycle_count = bq27xxx_battery_read_cyct(di);
++
++              /* We only have to read charge design full once */
++              if (di->charge_design_full <= 0)
++                      di->charge_design_full = bq27xxx_battery_read_dcap(di);
++      }
++
++      if ((di->cache.capacity != cache.capacity) ||
++          (di->cache.flags != cache.flags))
++              power_supply_changed(di->bat);
++
++      if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)
++              di->cache = cache;
++
++      di->last_update = jiffies;
++
++      if (!di->removed && poll_interval > 0)
++              mod_delayed_work(system_wq, &di->work, poll_interval * HZ);
++}
++
++void bq27xxx_battery_update(struct bq27xxx_device_info *di)
++{
++      mutex_lock(&di->lock);
++      bq27xxx_battery_update_unlocked(di);
++      mutex_unlock(&di->lock);
++}
++EXPORT_SYMBOL_GPL(bq27xxx_battery_update);
++
++static void bq27xxx_battery_poll(struct work_struct *work)
++{
++      struct bq27xxx_device_info *di =
++                      container_of(work, struct bq27xxx_device_info,
++                                   work.work);
++
++      bq27xxx_battery_update(di);
++}
++
+ /*
+  * Get the average power in ÂµW
+  * Return < 0 if something fails.
+-- 
+2.39.2
+
diff --git a/queue-5.10/power-supply-core-refactor-power_supply_set_input_cu.patch b/queue-5.10/power-supply-core-refactor-power_supply_set_input_cu.patch
new file mode 100644 (file)
index 0000000..8be62c0
--- /dev/null
@@ -0,0 +1,171 @@
+From a74dd076b6557bccc3a9e9245b29f8aa6a829758 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Feb 2022 14:06:47 +0100
+Subject: power: supply: core: Refactor
+ power_supply_set_input_current_limit_from_supplier()
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+[ Upstream commit 2220af8ca61ae67de4ec3deec1c6395a2f65b9fd ]
+
+Some (USB) charger ICs have variants with USB D+ and D- pins to do their
+own builtin charger-type detection, like e.g. the bq24190 and bq25890 and
+also variants which lack this functionality, e.g. the bq24192 and bq25892.
+
+In case the charger-type; and thus the input-current-limit detection is
+done outside the charger IC then we need some way to communicate this to
+the charger IC. In the past extcon was used for this, but if the external
+detection does e.g. full USB PD negotiation then the extcon cable-types do
+not convey enough information.
+
+For these setups it was decided to model the external charging "brick"
+and the parameters negotiated with it as a power_supply class-device
+itself; and power_supply_set_input_current_limit_from_supplier() was
+introduced to allow drivers to get the input-current-limit this way.
+
+But in some cases psy drivers may want to know other properties, e.g. the
+bq25892 can do "quick-charge" negotiation by pulsing its current draw,
+but this should only be done if the usb_type psy-property of its supplier
+is set to DCP (and device-properties indicate the board allows higher
+voltages).
+
+Instead of adding extra helper functions for each property which
+a psy-driver wants to query from its supplier, refactor
+power_supply_set_input_current_limit_from_supplier() into a
+more generic power_supply_get_property_from_supplier() function.
+
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Stable-dep-of: 77c2a3097d70 ("power: supply: bq24190: Call power_supply_changed() after updating input current")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq24190_charger.c   | 12 ++++-
+ drivers/power/supply/power_supply_core.c | 57 +++++++++++++-----------
+ include/linux/power_supply.h             |  5 ++-
+ 3 files changed, 44 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c
+index 338dd82007e4e..7a7b03b09ea64 100644
+--- a/drivers/power/supply/bq24190_charger.c
++++ b/drivers/power/supply/bq24190_charger.c
+@@ -1203,8 +1203,18 @@ static void bq24190_input_current_limit_work(struct work_struct *work)
+       struct bq24190_dev_info *bdi =
+               container_of(work, struct bq24190_dev_info,
+                            input_current_limit_work.work);
++      union power_supply_propval val;
++      int ret;
++
++      ret = power_supply_get_property_from_supplier(bdi->charger,
++                                                    POWER_SUPPLY_PROP_CURRENT_MAX,
++                                                    &val);
++      if (ret)
++              return;
+-      power_supply_set_input_current_limit_from_supplier(bdi->charger);
++      bq24190_charger_set_property(bdi->charger,
++                                   POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
++                                   &val);
+ }
+ /* Sync the input-current-limit with our parent supply (if we have one) */
+diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
+index 2b644590fa8e0..53e5b3e04be13 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -375,46 +375,49 @@ int power_supply_is_system_supplied(void)
+ }
+ EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
+-static int __power_supply_get_supplier_max_current(struct device *dev,
+-                                                 void *data)
++struct psy_get_supplier_prop_data {
++      struct power_supply *psy;
++      enum power_supply_property psp;
++      union power_supply_propval *val;
++};
++
++static int __power_supply_get_supplier_property(struct device *dev, void *_data)
+ {
+-      union power_supply_propval ret = {0,};
+       struct power_supply *epsy = dev_get_drvdata(dev);
+-      struct power_supply *psy = data;
++      struct psy_get_supplier_prop_data *data = _data;
+-      if (__power_supply_is_supplied_by(epsy, psy))
+-              if (!epsy->desc->get_property(epsy,
+-                                            POWER_SUPPLY_PROP_CURRENT_MAX,
+-                                            &ret))
+-                      return ret.intval;
++      if (__power_supply_is_supplied_by(epsy, data->psy))
++              if (!epsy->desc->get_property(epsy, data->psp, data->val))
++                      return 1; /* Success */
+-      return 0;
++      return 0; /* Continue iterating */
+ }
+-int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy)
++int power_supply_get_property_from_supplier(struct power_supply *psy,
++                                          enum power_supply_property psp,
++                                          union power_supply_propval *val)
+ {
+-      union power_supply_propval val = {0,};
+-      int curr;
+-
+-      if (!psy->desc->set_property)
+-              return -EINVAL;
++      struct psy_get_supplier_prop_data data = {
++              .psy = psy,
++              .psp = psp,
++              .val = val,
++      };
++      int ret;
+       /*
+        * This function is not intended for use with a supply with multiple
+-       * suppliers, we simply pick the first supply to report a non 0
+-       * max-current.
++       * suppliers, we simply pick the first supply to report the psp.
+        */
+-      curr = class_for_each_device(power_supply_class, NULL, psy,
+-                                    __power_supply_get_supplier_max_current);
+-      if (curr <= 0)
+-              return (curr == 0) ? -ENODEV : curr;
+-
+-      val.intval = curr;
++      ret = class_for_each_device(power_supply_class, NULL, &data,
++                                  __power_supply_get_supplier_property);
++      if (ret < 0)
++              return ret;
++      if (ret == 0)
++              return -ENODEV;
+-      return psy->desc->set_property(psy,
+-                              POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
++      return 0;
+ }
+-EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier);
++EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier);
+ int power_supply_set_battery_charged(struct power_supply *psy)
+ {
+diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
+index 81a55e974feb1..e6fe2f581bdaf 100644
+--- a/include/linux/power_supply.h
++++ b/include/linux/power_supply.h
+@@ -413,8 +413,9 @@ power_supply_temp2resist_simple(struct power_supply_resistance_temp_table *table
+                               int table_len, int temp);
+ extern void power_supply_changed(struct power_supply *psy);
+ extern int power_supply_am_i_supplied(struct power_supply *psy);
+-extern int power_supply_set_input_current_limit_from_supplier(
+-                                       struct power_supply *psy);
++int power_supply_get_property_from_supplier(struct power_supply *psy,
++                                          enum power_supply_property psp,
++                                          union power_supply_propval *val);
+ extern int power_supply_set_battery_charged(struct power_supply *psy);
+ #ifdef CONFIG_POWER_SUPPLY
+-- 
+2.39.2
+
diff --git a/queue-5.10/regulator-add-regmap-helper-for-ramp-delay-setting.patch b/queue-5.10/regulator-add-regmap-helper-for-ramp-delay-setting.patch
new file mode 100644 (file)
index 0000000..1259b2a
--- /dev/null
@@ -0,0 +1,123 @@
+From 9293ccb10aadbc6cb4f8d649129c03eb808c74a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Mar 2021 15:59:04 +0300
+Subject: regulator: Add regmap helper for ramp-delay setting
+
+From: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+
+[ Upstream commit fb8fee9efdcf084d9e31ba14cc4734d97e5dd972 ]
+
+Quite a few regulator ICs do support setting ramp-delay by writing a value
+matching the delay to a ramp-delay register.
+
+Provide a simple helper for table-based delay setting.
+
+Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+Link: https://lore.kernel.org/r/f101f1db564cf32cb58719c77af0b00d7236bb89.1617020713.git.matti.vaittinen@fi.rohmeurope.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: d67dada3e252 ("regulator: pca9450: Fix BUCK2 enable_mask")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/helpers.c      | 65 ++++++++++++++++++++++++++++++++
+ include/linux/regulator/driver.h |  5 +++
+ 2 files changed, 70 insertions(+)
+
+diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c
+index e4bb09bbd3fa6..a356f84b1285b 100644
+--- a/drivers/regulator/helpers.c
++++ b/drivers/regulator/helpers.c
+@@ -879,3 +879,68 @@ bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
+       return reg1->rdev == reg2->rdev;
+ }
+ EXPORT_SYMBOL_GPL(regulator_is_equal);
++
++static int find_closest_bigger(unsigned int target, const unsigned int *table,
++                             unsigned int num_sel, unsigned int *sel)
++{
++      unsigned int s, tmp, max, maxsel = 0;
++      bool found = false;
++
++      max = table[0];
++
++      for (s = 0; s < num_sel; s++) {
++              if (table[s] > max) {
++                      max = table[s];
++                      maxsel = s;
++              }
++              if (table[s] >= target) {
++                      if (!found || table[s] - target < tmp - target) {
++                              tmp = table[s];
++                              *sel = s;
++                              found = true;
++                              if (tmp == target)
++                                      break;
++                      }
++              }
++      }
++
++      if (!found) {
++              *sel = maxsel;
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
++/**
++ * regulator_set_ramp_delay_regmap - set_ramp_delay() helper
++ *
++ * @rdev: regulator to operate on
++ *
++ * Regulators that use regmap for their register I/O can set the ramp_reg
++ * and ramp_mask fields in their descriptor and then use this as their
++ * set_ramp_delay operation, saving some code.
++ */
++int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)
++{
++      int ret;
++      unsigned int sel;
++
++      if (!rdev->desc->n_ramp_values)
++              return -EINVAL;
++
++      ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
++                                rdev->desc->n_ramp_values, &sel);
++
++      if (ret) {
++              dev_warn(rdev_get_dev(rdev),
++                       "Can't set ramp-delay %u, setting %u\n", ramp_delay,
++                       rdev->desc->ramp_delay_table[sel]);
++      }
++
++      sel <<= ffs(rdev->desc->ramp_mask) - 1;
++
++      return regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,
++                                rdev->desc->ramp_mask, sel);
++}
++EXPORT_SYMBOL_GPL(regulator_set_ramp_delay_regmap);
+diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
+index 11cade73726ce..633e7a2ab01d0 100644
+--- a/include/linux/regulator/driver.h
++++ b/include/linux/regulator/driver.h
+@@ -370,6 +370,10 @@ struct regulator_desc {
+       unsigned int pull_down_reg;
+       unsigned int pull_down_mask;
+       unsigned int pull_down_val_on;
++      unsigned int ramp_reg;
++      unsigned int ramp_mask;
++      const unsigned int *ramp_delay_table;
++      unsigned int n_ramp_values;
+       unsigned int enable_time;
+@@ -532,6 +536,7 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
+                                      int min_uA, int max_uA);
+ int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
+ void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
++int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay);
+ /*
+  * Helper functions intended to be used by regulator drivers prior registering
+-- 
+2.39.2
+
diff --git a/queue-5.10/regulator-pca9450-convert-to-use-regulator_set_ramp_.patch b/queue-5.10/regulator-pca9450-convert-to-use-regulator_set_ramp_.patch
new file mode 100644 (file)
index 0000000..10a615c
--- /dev/null
@@ -0,0 +1,127 @@
+From 25144b08de0ac10baad9c16735bcc5b5b3b9fc5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 May 2021 20:24:08 +0800
+Subject: regulator: pca9450: Convert to use regulator_set_ramp_delay_regmap
+
+From: Axel Lin <axel.lin@ingics.com>
+
+[ Upstream commit 4c4fce171c4ca08cd98be7db350e6950630b046a ]
+
+Use regulator_set_ramp_delay_regmap instead of open-coded.
+
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Link: https://lore.kernel.org/r/20210526122408.78156-1-axel.lin@ingics.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: d67dada3e252 ("regulator: pca9450: Fix BUCK2 enable_mask")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/pca9450-regulator.c | 51 +++++++++++++--------------
+ 1 file changed, 24 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
+index d38109cc3a011..fd184c6c7c78a 100644
+--- a/drivers/regulator/pca9450-regulator.c
++++ b/drivers/regulator/pca9450-regulator.c
+@@ -65,32 +65,9 @@ static const struct regmap_config pca9450_regmap_config = {
+  * 10: 25mV/4usec
+  * 11: 25mV/8usec
+  */
+-static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev,
+-                                    int ramp_delay)
+-{
+-      int id = rdev_get_id(rdev);
+-      unsigned int ramp_value;
+-
+-      switch (ramp_delay) {
+-      case 1 ... 3125:
+-              ramp_value = BUCK1_RAMP_3P125MV;
+-              break;
+-      case 3126 ... 6250:
+-              ramp_value = BUCK1_RAMP_6P25MV;
+-              break;
+-      case 6251 ... 12500:
+-              ramp_value = BUCK1_RAMP_12P5MV;
+-              break;
+-      case 12501 ... 25000:
+-              ramp_value = BUCK1_RAMP_25MV;
+-              break;
+-      default:
+-              ramp_value = BUCK1_RAMP_25MV;
+-      }
+-
+-      return regmap_update_bits(rdev->regmap, PCA9450_REG_BUCK1CTRL + id * 3,
+-                                BUCK1_RAMP_MASK, ramp_value << 6);
+-}
++static const unsigned int pca9450_dvs_buck_ramp_table[] = {
++      25000, 12500, 6250, 3125
++};
+ static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
+       .enable = regulator_enable_regmap,
+@@ -100,7 +77,7 @@ static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_time_sel = regulator_set_voltage_time_sel,
+-      .set_ramp_delay = pca9450_dvs_set_ramp_delay,
++      .set_ramp_delay = regulator_set_ramp_delay_regmap,
+ };
+ static const struct regulator_ops pca9450_buck_regulator_ops = {
+@@ -251,6 +228,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
+                       .vsel_mask = BUCK1OUT_DVS0_MASK,
+                       .enable_reg = PCA9450_REG_BUCK1CTRL,
+                       .enable_mask = BUCK1_ENMODE_MASK,
++                      .ramp_reg = PCA9450_REG_BUCK1CTRL,
++                      .ramp_mask = BUCK1_RAMP_MASK,
++                      .ramp_delay_table = pca9450_dvs_buck_ramp_table,
++                      .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+                       .owner = THIS_MODULE,
+                       .of_parse_cb = pca9450_set_dvs_levels,
+               },
+@@ -276,6 +257,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
+                       .vsel_mask = BUCK2OUT_DVS0_MASK,
+                       .enable_reg = PCA9450_REG_BUCK2CTRL,
+                       .enable_mask = BUCK1_ENMODE_MASK,
++                      .ramp_reg = PCA9450_REG_BUCK2CTRL,
++                      .ramp_mask = BUCK2_RAMP_MASK,
++                      .ramp_delay_table = pca9450_dvs_buck_ramp_table,
++                      .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+                       .owner = THIS_MODULE,
+                       .of_parse_cb = pca9450_set_dvs_levels,
+               },
+@@ -301,6 +286,10 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
+                       .vsel_mask = BUCK3OUT_DVS0_MASK,
+                       .enable_reg = PCA9450_REG_BUCK3CTRL,
+                       .enable_mask = BUCK3_ENMODE_MASK,
++                      .ramp_reg = PCA9450_REG_BUCK3CTRL,
++                      .ramp_mask = BUCK3_RAMP_MASK,
++                      .ramp_delay_table = pca9450_dvs_buck_ramp_table,
++                      .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+                       .owner = THIS_MODULE,
+                       .of_parse_cb = pca9450_set_dvs_levels,
+               },
+@@ -477,6 +466,10 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
+                       .vsel_mask = BUCK1OUT_DVS0_MASK,
+                       .enable_reg = PCA9450_REG_BUCK1CTRL,
+                       .enable_mask = BUCK1_ENMODE_MASK,
++                      .ramp_reg = PCA9450_REG_BUCK1CTRL,
++                      .ramp_mask = BUCK1_RAMP_MASK,
++                      .ramp_delay_table = pca9450_dvs_buck_ramp_table,
++                      .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+                       .owner = THIS_MODULE,
+                       .of_parse_cb = pca9450_set_dvs_levels,
+               },
+@@ -502,6 +495,10 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
+                       .vsel_mask = BUCK2OUT_DVS0_MASK,
+                       .enable_reg = PCA9450_REG_BUCK2CTRL,
+                       .enable_mask = BUCK1_ENMODE_MASK,
++                      .ramp_reg = PCA9450_REG_BUCK2CTRL,
++                      .ramp_mask = BUCK2_RAMP_MASK,
++                      .ramp_delay_table = pca9450_dvs_buck_ramp_table,
++                      .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+                       .owner = THIS_MODULE,
+                       .of_parse_cb = pca9450_set_dvs_levels,
+               },
+-- 
+2.39.2
+
diff --git a/queue-5.10/regulator-pca9450-fix-buck2-enable_mask.patch b/queue-5.10/regulator-pca9450-fix-buck2-enable_mask.patch
new file mode 100644 (file)
index 0000000..d62b064
--- /dev/null
@@ -0,0 +1,48 @@
+From ec779aaa88ed913a4c7fee7c44137a8bfd2f2bfd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 May 2023 10:19:34 +0200
+Subject: regulator: pca9450: Fix BUCK2 enable_mask
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+[ Upstream commit d67dada3e2524514b09496b9ee1df22d4507a280 ]
+
+This fixes a copy & paste error.
+No functional change intended, BUCK1_ENMODE_MASK equals BUCK2_ENMODE_MASK.
+
+Fixes: 0935ff5f1f0a ("regulator: pca9450: add pca9450 pmic driver")
+Originally-from: Robin Gong <yibin.gong@nxp.com
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com
+Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de
+Link: https://lore.kernel.org/r/20230512081935.2396180-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Mark Brown <broonie@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/pca9450-regulator.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
+index fd184c6c7c78a..b3d206ebb2894 100644
+--- a/drivers/regulator/pca9450-regulator.c
++++ b/drivers/regulator/pca9450-regulator.c
+@@ -256,7 +256,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = {
+                       .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
+                       .vsel_mask = BUCK2OUT_DVS0_MASK,
+                       .enable_reg = PCA9450_REG_BUCK2CTRL,
+-                      .enable_mask = BUCK1_ENMODE_MASK,
++                      .enable_mask = BUCK2_ENMODE_MASK,
+                       .ramp_reg = PCA9450_REG_BUCK2CTRL,
+                       .ramp_mask = BUCK2_RAMP_MASK,
+                       .ramp_delay_table = pca9450_dvs_buck_ramp_table,
+@@ -494,7 +494,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
+                       .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
+                       .vsel_mask = BUCK2OUT_DVS0_MASK,
+                       .enable_reg = PCA9450_REG_BUCK2CTRL,
+-                      .enable_mask = BUCK1_ENMODE_MASK,
++                      .enable_mask = BUCK2_ENMODE_MASK,
+                       .ramp_reg = PCA9450_REG_BUCK2CTRL,
+                       .ramp_mask = BUCK2_RAMP_MASK,
+                       .ramp_delay_table = pca9450_dvs_buck_ramp_table,
+-- 
+2.39.2
+
index 32c0f41f6b6791c2aa46a07ddf497a8eb1593fe9..ef104db1873e0caf8b54f3c38b577065d0e5f292 100644 (file)
@@ -209,3 +209,21 @@ net-mlx5-devcom-fix-error-flow-in-mlx5_devcom_register_device.patch
 arm64-dts-imx8mn-var-som-fix-phy-detection-bug-by-adding-deassert-delay.patch
 3c589_cs-fix-an-error-handling-path-in-tc589_probe.patch
 net-phy-mscc-add-vsc8502-to-module_device_table.patch
+x86-cpu-add-raptor-lake-to-intel-family.patch
+x86-cpu-drop-spurious-underscore-from-raptor_lake-de.patch
+power-supply-bq27xxx-fix-polarity-of-current_now.patch
+power-supply-bq27xxx-fix-sign-of-current_now-for-new.patch
+power-supply-bq27xxx-make-status-more-robust.patch
+power-supply-bq27xxx-add-cache-parameter-to-bq27xxx_.patch
+power-supply-bq27xxx-expose-battery-data-when-ci-1.patch
+power-supply-bq27xxx-move-bq27xxx_battery_update-dow.patch
+power-supply-bq27xxx-ensure-power_supply_changed-is-.patch
+power-supply-bq27xxx-after-charger-plug-in-out-wait-.patch
+power-supply-core-refactor-power_supply_set_input_cu.patch
+power-supply-bq24190-call-power_supply_changed-after.patch
+regulator-add-regmap-helper-for-ramp-delay-setting.patch
+regulator-pca9450-convert-to-use-regulator_set_ramp_.patch
+regulator-pca9450-fix-buck2-enable_mask.patch
+net-mlx5-devcom-only-supports-2-ports.patch
+net-mlx5-devcom-serialize-devcom-registration.patch
+net-phy-mscc-enable-vsc8501-2-rgmii-rx-clock.patch
diff --git a/queue-5.10/x86-cpu-add-raptor-lake-to-intel-family.patch b/queue-5.10/x86-cpu-add-raptor-lake-to-intel-family.patch
new file mode 100644 (file)
index 0000000..a4d3510
--- /dev/null
@@ -0,0 +1,39 @@
+From 731619317c17ed21c3bc2dd2543369abb282b387 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Nov 2021 10:28:35 -0800
+Subject: x86/cpu: Add Raptor Lake to Intel family
+
+From: Tony Luck <tony.luck@intel.com>
+
+[ Upstream commit fbdb5e8f2926ae9636c9fa6f42c7426132ddeeb2 ]
+
+Add model ID for Raptor Lake.
+
+[ dhansen: These get added as soon as possible so that folks doing
+  development can leverage them. ]
+
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Link: https://lkml.kernel.org/r/20211112182835.924977-1-tony.luck@intel.com
+Stable-dep-of: ce0b15d11ad8 ("x86/mm: Avoid incomplete Global INVLPG flushes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/intel-family.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
+index 14b52718917f6..7a602d79bc38d 100644
+--- a/arch/x86/include/asm/intel-family.h
++++ b/arch/x86/include/asm/intel-family.h
+@@ -104,6 +104,8 @@
+ #define INTEL_FAM6_RAPTORLAKE_P               0xBA
+ #define INTEL_FAM6_RAPTORLAKE_S               0xBF
++#define INTEL_FAM6_RAPTOR_LAKE                0xB7
++
+ /* "Small Core" Processors (Atom) */
+ #define INTEL_FAM6_ATOM_BONNELL               0x1C /* Diamondville, Pineview */
+-- 
+2.39.2
+
diff --git a/queue-5.10/x86-cpu-drop-spurious-underscore-from-raptor_lake-de.patch b/queue-5.10/x86-cpu-drop-spurious-underscore-from-raptor_lake-de.patch
new file mode 100644 (file)
index 0000000..68a65f3
--- /dev/null
@@ -0,0 +1,40 @@
+From 6e99821087efa7912004fe7b188939131c8d1e31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Nov 2021 09:08:32 -0800
+Subject: x86/cpu: Drop spurious underscore from RAPTOR_LAKE #define
+
+From: Tony Luck <tony.luck@intel.com>
+
+[ Upstream commit 7d697f0d5737768fa1039b8953b67c08d8d406d1 ]
+
+Convention for all the other "lake" CPUs is all one word.
+
+So s/RAPTOR_LAKE/RAPTORLAKE/
+
+Fixes: fbdb5e8f2926 ("x86/cpu: Add Raptor Lake to Intel family")
+Reported-by: Rui Zhang <rui.zhang@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Link: https://lkml.kernel.org/r/20211119170832.1034220-1-tony.luck@intel.com
+Stable-dep-of: ce0b15d11ad8 ("x86/mm: Avoid incomplete Global INVLPG flushes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/include/asm/intel-family.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
+index 7a602d79bc38d..0de49e33d422e 100644
+--- a/arch/x86/include/asm/intel-family.h
++++ b/arch/x86/include/asm/intel-family.h
+@@ -104,7 +104,7 @@
+ #define INTEL_FAM6_RAPTORLAKE_P               0xBA
+ #define INTEL_FAM6_RAPTORLAKE_S               0xBF
+-#define INTEL_FAM6_RAPTOR_LAKE                0xB7
++#define INTEL_FAM6_RAPTORLAKE         0xB7
+ /* "Small Core" Processors (Atom) */
+-- 
+2.39.2
+