public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:5.10 commit in: /
Date: Mon,  5 Jun 2023 11:50:08 +0000 (UTC)	[thread overview]
Message-ID: <1685965797.26f8bf35b6fb51a168b7ee50e07ac0f8b7f60a0d.mpagano@gentoo> (raw)

commit:     26f8bf35b6fb51a168b7ee50e07ac0f8b7f60a0d
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Jun  5 11:49:57 2023 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Jun  5 11:49:57 2023 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=26f8bf35

Linux patch 5.10.182

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README               |    4 +
 1181_linux-5.10.182.patch | 1150 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1154 insertions(+)

diff --git a/0000_README b/0000_README
index 366c0d03..0400be74 100644
--- a/0000_README
+++ b/0000_README
@@ -767,6 +767,10 @@ Patch:  1180_linux-5.10.181.patch
 From:   https://www.kernel.org
 Desc:   Linux 5.10.181
 
+Patch:  1181_linux-5.10.182.patch
+From:   https://www.kernel.org
+Desc:   Linux 5.10.182
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1181_linux-5.10.182.patch b/1181_linux-5.10.182.patch
new file mode 100644
index 00000000..75cca61c
--- /dev/null
+++ b/1181_linux-5.10.182.patch
@@ -0,0 +1,1150 @@
+diff --git a/Makefile b/Makefile
+index 4e8289113a81f..2f0efde219023 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 10
+-SUBLEVEL = 181
++SUBLEVEL = 182
+ EXTRAVERSION =
+ NAME = Dare mighty things
+ 
+diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
+index 14b52718917f6..0de49e33d422e 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_RAPTORLAKE		0xB7
++
+ /* "Small Core" Processors (Atom) */
+ 
+ #define INTEL_FAM6_ATOM_BONNELL		0x1C /* Diamondville, Pineview */
+diff --git a/drivers/android/binder.c b/drivers/android/binder.c
+index b403c7f063b00..dbae98f096580 100644
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -2267,24 +2267,23 @@ static void binder_deferred_fd_close(int fd)
+ static void binder_transaction_buffer_release(struct binder_proc *proc,
+ 					      struct binder_thread *thread,
+ 					      struct binder_buffer *buffer,
+-					      binder_size_t failed_at,
++					      binder_size_t off_end_offset,
+ 					      bool is_failure)
+ {
+ 	int debug_id = buffer->debug_id;
+-	binder_size_t off_start_offset, buffer_offset, off_end_offset;
++	binder_size_t off_start_offset, buffer_offset;
+ 
+ 	binder_debug(BINDER_DEBUG_TRANSACTION,
+ 		     "%d buffer release %d, size %zd-%zd, failed at %llx\n",
+ 		     proc->pid, buffer->debug_id,
+ 		     buffer->data_size, buffer->offsets_size,
+-		     (unsigned long long)failed_at);
++		     (unsigned long long)off_end_offset);
+ 
+ 	if (buffer->target_node)
+ 		binder_dec_node(buffer->target_node, 1, 0);
+ 
+ 	off_start_offset = ALIGN(buffer->data_size, sizeof(void *));
+-	off_end_offset = is_failure && failed_at ? failed_at :
+-				off_start_offset + buffer->offsets_size;
++
+ 	for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
+ 	     buffer_offset += sizeof(binder_size_t)) {
+ 		struct binder_object_header *hdr;
+@@ -2444,6 +2443,21 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
+ 	}
+ }
+ 
++/* Clean up all the objects in the buffer */
++static inline void binder_release_entire_buffer(struct binder_proc *proc,
++						struct binder_thread *thread,
++						struct binder_buffer *buffer,
++						bool is_failure)
++{
++	binder_size_t off_end_offset;
++
++	off_end_offset = ALIGN(buffer->data_size, sizeof(void *));
++	off_end_offset += buffer->offsets_size;
++
++	binder_transaction_buffer_release(proc, thread, buffer,
++					  off_end_offset, is_failure);
++}
++
+ static int binder_translate_binder(struct flat_binder_object *fp,
+ 				   struct binder_transaction *t,
+ 				   struct binder_thread *thread)
+@@ -3926,7 +3940,7 @@ binder_free_buf(struct binder_proc *proc,
+ 		binder_node_inner_unlock(buf_node);
+ 	}
+ 	trace_binder_transaction_buffer_release(buffer);
+-	binder_transaction_buffer_release(proc, thread, buffer, 0, is_failure);
++	binder_release_entire_buffer(proc, thread, buffer, is_failure);
+ 	binder_alloc_free_buf(&proc->alloc, buffer);
+ }
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+index abd066e952286..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);
+ 
+@@ -14,7 +15,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 +26,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 +75,16 @@ 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;
+ 
++	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;
+ 
+ 		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
+@@ -100,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;
+@@ -112,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;
+ }
+ 
+@@ -130,20 +138,23 @@ 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;
+ 
+ 	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)
+-		return;
++	if (i != MLX5_DEVCOM_PORTS_SUPPORTED)
++		goto out;
+ 
+ 	list_del(&priv->list);
+ 	kfree(priv);
++out:
++	mlx5_dev_list_unlock();
+ }
+ 
+ void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
+@@ -192,7 +203,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 +251,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,
+ 
+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 @@ out_unlock:
+  *  * 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)
+diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c
+index 338dd82007e4e..5769b36851c34 100644
+--- a/drivers/power/supply/bq24190_charger.c
++++ b/drivers/power/supply/bq24190_charger.c
+@@ -1203,8 +1203,19 @@ 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;
+ 
+-	power_supply_set_input_current_limit_from_supplier(bdi->charger);
++	ret = power_supply_get_property_from_supplier(bdi->charger,
++						      POWER_SUPPLY_PROP_CURRENT_MAX,
++						      &val);
++	if (ret)
++		return;
++
++	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) */
+diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
+index c08dd4e6d35ad..235647b21af71 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,14 +1681,89 @@ 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;
+ }
+ 
++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 and the status
++ * Note that current can be negative signed as well
++ * Or 0 if something fails.
++ */
++static int bq27xxx_battery_current_and_status(
++	struct bq27xxx_device_info *di,
++	union power_supply_propval *val_curr,
++	union power_supply_propval *val_status,
++	struct bq27xxx_reg_cache *cache)
++{
++	bool single_flags = (di->opts & BQ27XXX_O_ZERO);
++	int curr;
++	int flags;
++
++	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
++	if (curr < 0) {
++		dev_err(di->dev, "error reading current\n");
++		return curr;
++	}
++
++	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) {
++		if (!(flags & BQ27000_FLAG_CHGS)) {
++			dev_dbg(di->dev, "negative current!\n");
++			curr = -curr;
++		}
++
++		curr = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;
++	} else {
++		/* Other gauges return signed value */
++		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;
++}
++
+ 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_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,41 +1771,40 @@ 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);
+ 
++		/*
++		 * 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;
+@@ -1754,39 +1832,6 @@ static void bq27xxx_battery_poll(struct work_struct *work)
+ 	bq27xxx_battery_update(di);
+ }
+ 
+-/*
+- * Return the battery average current in µA
+- * 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)
+-{
+-	int curr;
+-	int flags;
+-
+-	curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);
+-	if (curr < 0) {
+-		dev_err(di->dev, "error reading current\n");
+-		return curr;
+-	}
+-
+-	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;
+-	} else {
+-		/* Other gauges return signed value */
+-		val->intval = (int)((s16)curr) * 1000;
+-	}
+-
+-	return 0;
+-}
+-
+ /*
+  * Get the average power in µW
+  * Return < 0 if something fails.
+@@ -1813,43 +1858,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 +1943,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, NULL);
+ 		break;
+ 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ 		ret = bq27xxx_battery_voltage(di, val);
+@@ -1944,7 +1952,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, NULL);
+ 		break;
+ 	case POWER_SUPPLY_PROP_CAPACITY:
+ 		ret = bq27xxx_simple_value(di->cache.capacity, val);
+@@ -2014,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)
+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/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/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
+index d38109cc3a011..b3d206ebb2894 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,
+ 		},
+@@ -275,7 +256,11 @@ 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,
++			.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,
+ 		},
+@@ -501,7 +494,11 @@ 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,
++			.n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+ 			.owner = THIS_MODULE,
+ 			.of_parse_cb = pca9450_set_dvs_levels,
+ 		},
+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;
+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
+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
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 4b775af572688..8d1173577fb5c 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -75,6 +75,7 @@ struct ipcm_cookie {
+ 	__be32			addr;
+ 	int			oif;
+ 	struct ip_options_rcu	*opt;
++	__u8			protocol;
+ 	__u8			ttl;
+ 	__s16			tos;
+ 	char			priority;
+@@ -95,6 +96,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
+ 	ipcm->sockc.tsflags = inet->sk.sk_tsflags;
+ 	ipcm->oif = inet->sk.sk_bound_dev_if;
+ 	ipcm->addr = inet->inet_saddr;
++	ipcm->protocol = inet->inet_num;
+ }
+ 
+ #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
+diff --git a/include/uapi/linux/in.h b/include/uapi/linux/in.h
+index d1b327036ae43..3960bc3da6b30 100644
+--- a/include/uapi/linux/in.h
++++ b/include/uapi/linux/in.h
+@@ -159,6 +159,8 @@ struct in_addr {
+ #define MCAST_MSFILTER			48
+ #define IP_MULTICAST_ALL		49
+ #define IP_UNICAST_IF			50
++#define IP_LOCAL_PORT_RANGE		51
++#define IP_PROTOCOL			52
+ 
+ #define MCAST_EXCLUDE	0
+ #define MCAST_INCLUDE	1
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 4dcc1a8a8954f..eafb2bebc12cb 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -980,6 +980,34 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
+ 
+ 	BT_DBG("cmd %x arg %lx", cmd, arg);
+ 
++	/* Make sure the cmd is valid before doing anything */
++	switch (cmd) {
++	case HCIGETDEVLIST:
++	case HCIGETDEVINFO:
++	case HCIGETCONNLIST:
++	case HCIDEVUP:
++	case HCIDEVDOWN:
++	case HCIDEVRESET:
++	case HCIDEVRESTAT:
++	case HCISETSCAN:
++	case HCISETAUTH:
++	case HCISETENCRYPT:
++	case HCISETPTYPE:
++	case HCISETLINKPOL:
++	case HCISETLINKMODE:
++	case HCISETACLMTU:
++	case HCISETSCOMTU:
++	case HCIINQUIRY:
++	case HCISETRAW:
++	case HCIGETCONNINFO:
++	case HCIGETAUTHINFO:
++	case HCIBLOCKADDR:
++	case HCIUNBLOCKADDR:
++		break;
++	default:
++		return -ENOIOCTLCMD;
++	}
++
+ 	lock_sock(sk);
+ 
+ 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index 4cc39c62af55d..1b35afd326b8d 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -317,7 +317,14 @@ int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
+ 			ipc->tos = val;
+ 			ipc->priority = rt_tos2priority(ipc->tos);
+ 			break;
+-
++		case IP_PROTOCOL:
++			if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
++				return -EINVAL;
++			val = *(int *)CMSG_DATA(cmsg);
++			if (val < 1 || val > 255)
++				return -EINVAL;
++			ipc->protocol = val;
++			break;
+ 		default:
+ 			return -EINVAL;
+ 		}
+@@ -1724,6 +1731,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
+ 	case IP_MINTTL:
+ 		val = inet->min_ttl;
+ 		break;
++	case IP_PROTOCOL:
++		val = inet_sk(sk)->inet_num;
++		break;
+ 	default:
+ 		release_sock(sk);
+ 		return -ENOPROTOOPT;
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index 4899ebe569eb6..650da4d8f7ad1 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -559,6 +559,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ 	}
+ 
+ 	ipcm_init_sk(&ipc, inet);
++	/* Keep backward compat */
++	if (hdrincl)
++		ipc.protocol = IPPROTO_RAW;
+ 
+ 	if (msg->msg_controllen) {
+ 		err = ip_cmsg_send(sk, msg, &ipc, false);
+@@ -626,7 +629,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ 
+ 	flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
+ 			   RT_SCOPE_UNIVERSE,
+-			   hdrincl ? IPPROTO_RAW : sk->sk_protocol,
++			   hdrincl ? ipc.protocol : sk->sk_protocol,
+ 			   inet_sk_flowi_flags(sk) |
+ 			    (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
+ 			   daddr, saddr, 0, 0, sk->sk_uid);
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index 69f0f9c05d028..7ff06fa7ed19a 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -828,7 +828,8 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ 
+ 		if (!proto)
+ 			proto = inet->inet_num;
+-		else if (proto != inet->inet_num)
++		else if (proto != inet->inet_num &&
++			 inet->inet_num != IPPROTO_RAW)
+ 			return -EINVAL;
+ 
+ 		if (proto > 255)
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index c9ca857f1068d..6a055a2216831 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -1493,9 +1493,6 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
+ 
+ static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
+ {
+-	if (test_bit(IPS_OFFLOAD_BIT, &ct->status))
+-		return 0;
+-
+ 	return ctnetlink_filter_match(ct, data);
+ }
+ 
+@@ -1561,11 +1558,6 @@ static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl,
+ 
+ 	ct = nf_ct_tuplehash_to_ctrack(h);
+ 
+-	if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) {
+-		nf_ct_put(ct);
+-		return -EBUSY;
+-	}
+-
+ 	if (cda[CTA_ID]) {
+ 		__be32 id = nla_get_be32(cda[CTA_ID]);
+ 


             reply	other threads:[~2023-06-05 11:50 UTC|newest]

Thread overview: 312+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-05 11:50 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2025-10-02 13:27 [gentoo-commits] proj/linux-patches:5.10 commit in: / Arisu Tachibana
2025-09-12  3:58 Arisu Tachibana
2025-09-10  5:33 Arisu Tachibana
2025-09-04 15:19 Arisu Tachibana
2025-09-04 14:32 Arisu Tachibana
2025-08-29  9:13 Arisu Tachibana
2025-08-28 16:55 Arisu Tachibana
2025-07-18 12:07 Arisu Tachibana
2025-06-27 11:21 Mike Pagano
2025-06-04 18:15 Mike Pagano
2025-05-02 10:58 Mike Pagano
2025-04-10 13:16 Mike Pagano
2025-03-13 12:58 Mike Pagano
2025-02-01 23:10 Mike Pagano
2025-01-09 13:58 Mike Pagano
2024-12-19 18:10 Mike Pagano
2024-12-14 23:50 Mike Pagano
2024-11-30 17:35 Mike Pagano
2024-11-17 18:19 Mike Pagano
2024-11-08 17:46 Mike Pagano
2024-10-22 17:00 Mike Pagano
2024-10-17 14:11 Mike Pagano
2024-10-17 14:08 Mike Pagano
2024-09-12 12:42 Mike Pagano
2024-09-04 13:53 Mike Pagano
2024-08-19 10:44 Mike Pagano
2024-07-27  9:20 Mike Pagano
2024-07-27  9:17 Mike Pagano
2024-07-18 12:17 Mike Pagano
2024-07-05 10:53 Mike Pagano
2024-07-05 10:51 Mike Pagano
2024-06-21 14:08 Mike Pagano
2024-06-16 14:35 Mike Pagano
2024-05-25 15:14 Mike Pagano
2024-05-17 11:38 Mike Pagano
2024-05-05 18:14 Mike Pagano
2024-05-02 15:03 Mike Pagano
2024-04-27 22:57 Mike Pagano
2024-04-13 13:09 Mike Pagano
2024-03-27 11:26 Mike Pagano
2024-03-15 22:02 Mike Pagano
2024-03-06 18:09 Mike Pagano
2024-03-01 13:09 Mike Pagano
2024-02-23 12:45 Mike Pagano
2024-02-23 12:39 Mike Pagano
2024-01-25 23:34 Mike Pagano
2024-01-15 18:49 Mike Pagano
2024-01-12 20:35 Mike Pagano
2024-01-05 14:29 Mike Pagano
2023-12-20 15:21 Mike Pagano
2023-12-13 18:29 Mike Pagano
2023-12-08 11:16 Mike Pagano
2023-12-01 17:47 Mike Pagano
2023-11-28 17:52 Mike Pagano
2023-11-20 11:25 Mike Pagano
2023-11-08 17:28 Mike Pagano
2023-10-25 11:38 Mike Pagano
2023-10-18 20:16 Mike Pagano
2023-10-10 20:34 Mike Pagano
2023-10-05 14:24 Mike Pagano
2023-09-23 10:19 Mike Pagano
2023-09-21 11:29 Mike Pagano
2023-09-19 13:22 Mike Pagano
2023-09-02  9:59 Mike Pagano
2023-08-30 14:45 Mike Pagano
2023-08-26 15:21 Mike Pagano
2023-08-16 17:01 Mike Pagano
2023-08-11 11:56 Mike Pagano
2023-08-08 18:42 Mike Pagano
2023-07-27 11:50 Mike Pagano
2023-07-24 20:28 Mike Pagano
2023-06-28 10:27 Mike Pagano
2023-06-21 14:55 Alice Ferrazzi
2023-06-14 10:34 Mike Pagano
2023-06-14 10:20 Mike Pagano
2023-06-09 11:31 Mike Pagano
2023-05-30 12:56 Mike Pagano
2023-05-17 11:25 Mike Pagano
2023-05-17 10:59 Mike Pagano
2023-05-10 17:56 Mike Pagano
2023-04-27 14:11 Mike Pagano
2023-04-26  9:50 Alice Ferrazzi
2023-04-20 11:17 Alice Ferrazzi
2023-04-05 10:01 Alice Ferrazzi
2023-03-22 14:15 Alice Ferrazzi
2023-03-17 10:45 Mike Pagano
2023-03-13 11:32 Alice Ferrazzi
2023-03-11 16:05 Mike Pagano
2023-03-03 15:01 Mike Pagano
2023-03-03 12:30 Mike Pagano
2023-02-25 11:44 Mike Pagano
2023-02-24  3:06 Alice Ferrazzi
2023-02-22 14:04 Alice Ferrazzi
2023-02-15 16:40 Mike Pagano
2023-02-06 12:47 Mike Pagano
2023-02-02 19:11 Mike Pagano
2023-02-01  8:09 Alice Ferrazzi
2023-01-24  7:13 Alice Ferrazzi
2023-01-18 11:09 Mike Pagano
2023-01-14 13:52 Mike Pagano
2023-01-04 11:39 Mike Pagano
2022-12-21 19:00 Alice Ferrazzi
2022-12-19 12:33 Alice Ferrazzi
2022-12-14 12:14 Mike Pagano
2022-12-08 11:51 Alice Ferrazzi
2022-12-02 17:26 Mike Pagano
2022-11-25 17:06 Mike Pagano
2022-11-16 12:08 Alice Ferrazzi
2022-11-10 18:05 Mike Pagano
2022-11-03 15:17 Mike Pagano
2022-10-30  9:33 Mike Pagano
2022-10-28 13:38 Mike Pagano
2022-10-26 11:46 Mike Pagano
2022-10-17 16:46 Mike Pagano
2022-10-15 10:05 Mike Pagano
2022-10-05 11:58 Mike Pagano
2022-09-28  9:30 Mike Pagano
2022-09-23 12:40 Mike Pagano
2022-09-20 12:01 Mike Pagano
2022-09-15 10:31 Mike Pagano
2022-09-08 10:46 Mike Pagano
2022-09-05 12:04 Mike Pagano
2022-08-31 15:39 Mike Pagano
2022-08-29 10:46 Mike Pagano
2022-08-25 10:33 Mike Pagano
2022-08-21 16:52 Mike Pagano
2022-08-11 12:34 Mike Pagano
2022-08-03 14:24 Alice Ferrazzi
2022-07-29 16:37 Mike Pagano
2022-07-25 10:19 Alice Ferrazzi
2022-07-21 20:08 Mike Pagano
2022-07-15 10:03 Mike Pagano
2022-07-12 15:59 Mike Pagano
2022-07-07 16:17 Mike Pagano
2022-07-02 16:10 Mike Pagano
2022-06-29 11:08 Mike Pagano
2022-06-27 11:12 Mike Pagano
2022-06-25 19:45 Mike Pagano
2022-06-22 12:45 Mike Pagano
2022-06-16 11:44 Mike Pagano
2022-06-14 17:12 Mike Pagano
2022-06-09 11:27 Mike Pagano
2022-06-06 11:03 Mike Pagano
2022-05-30 13:59 Mike Pagano
2022-05-25 11:54 Mike Pagano
2022-05-18  9:48 Mike Pagano
2022-05-15 22:10 Mike Pagano
2022-05-12 11:29 Mike Pagano
2022-05-09 10:56 Mike Pagano
2022-04-27 12:24 Mike Pagano
2022-04-27 12:20 Mike Pagano
2022-04-26 12:17 Mike Pagano
2022-04-20 12:07 Mike Pagano
2022-04-13 20:20 Mike Pagano
2022-04-13 19:48 Mike Pagano
2022-04-12 19:08 Mike Pagano
2022-04-08 13:16 Mike Pagano
2022-03-28 10:58 Mike Pagano
2022-03-23 11:55 Mike Pagano
2022-03-19 13:20 Mike Pagano
2022-03-16 13:33 Mike Pagano
2022-03-11 11:31 Mike Pagano
2022-03-08 18:32 Mike Pagano
2022-03-02 13:06 Mike Pagano
2022-02-26 20:27 Mike Pagano
2022-02-23 12:37 Mike Pagano
2022-02-16 12:46 Mike Pagano
2022-02-11 12:35 Mike Pagano
2022-02-08 17:54 Mike Pagano
2022-02-05 19:04 Mike Pagano
2022-02-05 12:13 Mike Pagano
2022-02-01 17:23 Mike Pagano
2022-01-31 12:25 Mike Pagano
2022-01-29 17:43 Mike Pagano
2022-01-27 11:37 Mike Pagano
2022-01-20 10:00 Mike Pagano
2022-01-16 10:21 Mike Pagano
2022-01-11 14:50 Mike Pagano
2022-01-05 12:53 Mike Pagano
2021-12-29 13:06 Mike Pagano
2021-12-22 14:05 Mike Pagano
2021-12-21 19:37 Mike Pagano
2021-12-17 11:55 Mike Pagano
2021-12-16 16:04 Mike Pagano
2021-12-14 12:51 Mike Pagano
2021-12-14 12:12 Mike Pagano
2021-12-08 12:53 Mike Pagano
2021-12-01 12:49 Mike Pagano
2021-11-26 11:57 Mike Pagano
2021-11-21 20:42 Mike Pagano
2021-11-18 15:33 Mike Pagano
2021-11-12 14:18 Mike Pagano
2021-11-06 13:36 Mike Pagano
2021-11-02 19:30 Mike Pagano
2021-10-27 14:55 Mike Pagano
2021-10-27 11:57 Mike Pagano
2021-10-20 13:23 Mike Pagano
2021-10-18 21:17 Mike Pagano
2021-10-17 13:11 Mike Pagano
2021-10-13  9:35 Alice Ferrazzi
2021-10-09 21:31 Mike Pagano
2021-10-06 14:18 Mike Pagano
2021-09-30 10:48 Mike Pagano
2021-09-26 14:12 Mike Pagano
2021-09-22 11:38 Mike Pagano
2021-09-20 22:02 Mike Pagano
2021-09-18 16:07 Mike Pagano
2021-09-17 12:50 Mike Pagano
2021-09-17 12:46 Mike Pagano
2021-09-16 11:20 Mike Pagano
2021-09-15 12:00 Mike Pagano
2021-09-12 14:38 Mike Pagano
2021-09-08 13:00 Alice Ferrazzi
2021-09-03 11:47 Mike Pagano
2021-09-03 11:20 Mike Pagano
2021-08-26 14:34 Mike Pagano
2021-08-25 16:23 Mike Pagano
2021-08-24 21:33 Mike Pagano
2021-08-24 21:32 Mike Pagano
2021-08-21 14:17 Mike Pagano
2021-08-19 11:56 Mike Pagano
2021-08-18 12:46 Mike Pagano
2021-08-15 20:05 Mike Pagano
2021-08-12 11:53 Mike Pagano
2021-08-10 11:49 Mike Pagano
2021-08-10 11:49 Mike Pagano
2021-08-08 13:36 Mike Pagano
2021-08-04 11:52 Mike Pagano
2021-08-03 11:03 Mike Pagano
2021-08-02 22:35 Mike Pagano
2021-07-31 10:30 Alice Ferrazzi
2021-07-28 13:22 Mike Pagano
2021-07-25 17:28 Mike Pagano
2021-07-25 17:26 Mike Pagano
2021-07-20 15:44 Alice Ferrazzi
2021-07-19 11:17 Mike Pagano
2021-07-14 16:31 Mike Pagano
2021-07-14 16:21 Mike Pagano
2021-07-13 12:37 Mike Pagano
2021-07-12 17:25 Mike Pagano
2021-07-11 15:11 Mike Pagano
2021-07-11 14:43 Mike Pagano
2021-07-08 12:27 Mike Pagano
2021-07-08  3:27 Alice Ferrazzi
2021-07-07 13:13 Mike Pagano
2021-07-02 19:38 Mike Pagano
2021-07-01 14:32 Mike Pagano
2021-06-30 14:23 Mike Pagano
2021-06-23 15:12 Mike Pagano
2021-06-18 11:37 Mike Pagano
2021-06-16 12:24 Mike Pagano
2021-06-11 17:34 Mike Pagano
2021-06-10 13:14 Mike Pagano
2021-06-10 12:09 Mike Pagano
2021-06-08 22:42 Mike Pagano
2021-06-03 10:26 Alice Ferrazzi
2021-05-28 12:15 Alice Ferrazzi
2021-05-26 12:07 Mike Pagano
2021-05-22 16:59 Mike Pagano
2021-05-19 12:24 Mike Pagano
2021-05-14 14:07 Alice Ferrazzi
2021-05-11 14:20 Mike Pagano
2021-05-07 11:27 Alice Ferrazzi
2021-05-02 16:03 Mike Pagano
2021-04-30 18:58 Mike Pagano
2021-04-28 12:03 Alice Ferrazzi
2021-04-21 11:42 Mike Pagano
2021-04-16 11:02 Alice Ferrazzi
2021-04-14 11:07 Alice Ferrazzi
2021-04-10 13:26 Mike Pagano
2021-04-07 13:27 Mike Pagano
2021-03-30 12:57 Alice Ferrazzi
2021-03-25  9:04 Alice Ferrazzi
2021-03-22 15:57 Mike Pagano
2021-03-20 14:35 Mike Pagano
2021-03-17 17:00 Mike Pagano
2021-03-11 15:08 Mike Pagano
2021-03-09 12:18 Mike Pagano
2021-03-07 15:17 Mike Pagano
2021-03-04 12:04 Alice Ferrazzi
2021-02-26 13:22 Mike Pagano
2021-02-26 10:42 Alice Ferrazzi
2021-02-23 15:16 Alice Ferrazzi
2021-02-18 20:45 Mike Pagano
2021-02-18 14:48 Mike Pagano
2021-02-17 11:14 Alice Ferrazzi
2021-02-13 15:51 Mike Pagano
2021-02-13 15:48 Mike Pagano
2021-02-13 14:42 Alice Ferrazzi
2021-02-10 10:23 Alice Ferrazzi
2021-02-10  9:51 Alice Ferrazzi
2021-02-09 19:10 Mike Pagano
2021-02-07 15:20 Alice Ferrazzi
2021-02-03 23:43 Alice Ferrazzi
2021-01-30 13:27 Alice Ferrazzi
2021-01-27 11:29 Mike Pagano
2021-01-23 16:38 Mike Pagano
2021-01-19 20:31 Mike Pagano
2021-01-17 16:18 Mike Pagano
2021-01-12 20:03 Mike Pagano
2021-01-09 17:58 Mike Pagano
2021-01-09  0:14 Mike Pagano
2021-01-06 14:54 Mike Pagano
2020-12-30 12:54 Mike Pagano
2020-12-26 15:32 Mike Pagano
2020-12-26 15:29 Mike Pagano
2020-12-21 13:26 Mike Pagano
2020-12-18 16:08 Mike Pagano
2020-12-14 20:45 Mike Pagano
2020-12-13 16:09 Mike Pagano
2020-11-19 13:03 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1685965797.26f8bf35b6fb51a168b7ee50e07ac0f8b7f60a0d.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox