diff options
Diffstat (limited to 'drivers')
131 files changed, 845 insertions, 415 deletions
diff --git a/drivers/acpi/acpi_mrrm.c b/drivers/acpi/acpi_mrrm.c index 47ea3ccc2142..a6dbf623e557 100644 --- a/drivers/acpi/acpi_mrrm.c +++ b/drivers/acpi/acpi_mrrm.c @@ -63,6 +63,9 @@ static __init int acpi_parse_mrrm(struct acpi_table_header *table)  	if (!mrrm)  		return -ENODEV; +	if (mrrm->header.revision != 1) +		return -EINVAL; +  	if (mrrm->flags & ACPI_MRRM_FLAGS_REGION_ASSIGNMENT_OS)  		return -EOPNOTSUPP; diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 103f29661576..be8e7e18abca 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -1959,8 +1959,10 @@ static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video)  	struct acpi_video_device *dev;  	mutex_lock(&video->device_list_lock); -	list_for_each_entry(dev, &video->video_device_list, entry) +	list_for_each_entry(dev, &video->video_device_list, entry) {  		acpi_video_dev_remove_notify_handler(dev); +		cancel_delayed_work_sync(&dev->switch_brightness_work); +	}  	mutex_unlock(&video->device_list_lock);  	acpi_video_bus_stop_devices(video); diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 0a7026040188..3c6dd9b4ba0a 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -619,8 +619,10 @@ static int acpi_button_add(struct acpi_device *device)  	input_set_drvdata(input, device);  	error = input_register_device(input); -	if (error) +	if (error) { +		input_free_device(input);  		goto err_remove_fs; +	}  	switch (device->device_type) {  	case ACPI_BUS_TYPE_POWER_BUTTON: diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h index 8a28a72a7c6a..bedbab0e8e4e 100644 --- a/drivers/acpi/fan.h +++ b/drivers/acpi/fan.h @@ -49,6 +49,7 @@ struct acpi_fan_fst {  };  struct acpi_fan { +	acpi_handle handle;  	bool acpi4;  	bool has_fst;  	struct acpi_fan_fif fif; @@ -59,14 +60,14 @@ struct acpi_fan {  	struct device_attribute fine_grain_control;  }; -int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst); +int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst);  int acpi_fan_create_attributes(struct acpi_device *device);  void acpi_fan_delete_attributes(struct acpi_device *device);  #if IS_REACHABLE(CONFIG_HWMON) -int devm_acpi_fan_create_hwmon(struct acpi_device *device); +int devm_acpi_fan_create_hwmon(struct device *dev);  #else -static inline int devm_acpi_fan_create_hwmon(struct acpi_device *device) { return 0; }; +static inline int devm_acpi_fan_create_hwmon(struct device *dev) { return 0; };  #endif  #endif diff --git a/drivers/acpi/fan_attr.c b/drivers/acpi/fan_attr.c index c1afb7b5ed3d..9b7fa52f3c2a 100644 --- a/drivers/acpi/fan_attr.c +++ b/drivers/acpi/fan_attr.c @@ -55,7 +55,7 @@ static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr,  	struct acpi_fan_fst fst;  	int status; -	status = acpi_fan_get_fst(acpi_dev, &fst); +	status = acpi_fan_get_fst(acpi_dev->handle, &fst);  	if (status)  		return status; diff --git a/drivers/acpi/fan_core.c b/drivers/acpi/fan_core.c index 04ff608f2ff0..46e7fe7a506d 100644 --- a/drivers/acpi/fan_core.c +++ b/drivers/acpi/fan_core.c @@ -44,25 +44,30 @@ static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long  	return 0;  } -int acpi_fan_get_fst(struct acpi_device *device, struct acpi_fan_fst *fst) +int acpi_fan_get_fst(acpi_handle handle, struct acpi_fan_fst *fst)  {  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };  	union acpi_object *obj;  	acpi_status status;  	int ret = 0; -	status = acpi_evaluate_object(device->handle, "_FST", NULL, &buffer); -	if (ACPI_FAILURE(status)) { -		dev_err(&device->dev, "Get fan state failed\n"); -		return -ENODEV; -	} +	status = acpi_evaluate_object(handle, "_FST", NULL, &buffer); +	if (ACPI_FAILURE(status)) +		return -EIO;  	obj = buffer.pointer; -	if (!obj || obj->type != ACPI_TYPE_PACKAGE || -	    obj->package.count != 3 || -	    obj->package.elements[1].type != ACPI_TYPE_INTEGER) { -		dev_err(&device->dev, "Invalid _FST data\n"); -		ret = -EINVAL; +	if (!obj) +		return -ENODATA; + +	if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) { +		ret = -EPROTO; +		goto err; +	} + +	if (obj->package.elements[0].type != ACPI_TYPE_INTEGER || +	    obj->package.elements[1].type != ACPI_TYPE_INTEGER || +	    obj->package.elements[2].type != ACPI_TYPE_INTEGER) { +		ret = -EPROTO;  		goto err;  	} @@ -81,7 +86,7 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)  	struct acpi_fan_fst fst;  	int status, i; -	status = acpi_fan_get_fst(device, &fst); +	status = acpi_fan_get_fst(device->handle, &fst);  	if (status)  		return status; @@ -311,11 +316,16 @@ static int acpi_fan_probe(struct platform_device *pdev)  	struct acpi_device *device = ACPI_COMPANION(&pdev->dev);  	char *name; +	if (!device) +		return -ENODEV; +  	fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);  	if (!fan) {  		dev_err(&device->dev, "No memory for fan\n");  		return -ENOMEM;  	} + +	fan->handle = device->handle;  	device->driver_data = fan;  	platform_set_drvdata(pdev, fan); @@ -337,7 +347,7 @@ static int acpi_fan_probe(struct platform_device *pdev)  	}  	if (fan->has_fst) { -		result = devm_acpi_fan_create_hwmon(device); +		result = devm_acpi_fan_create_hwmon(&pdev->dev);  		if (result)  			return result; diff --git a/drivers/acpi/fan_hwmon.c b/drivers/acpi/fan_hwmon.c index e8d90605106e..4b2c2007f2d7 100644 --- a/drivers/acpi/fan_hwmon.c +++ b/drivers/acpi/fan_hwmon.c @@ -93,13 +93,12 @@ static umode_t acpi_fan_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_  static int acpi_fan_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,  			       int channel, long *val)  { -	struct acpi_device *adev = to_acpi_device(dev->parent);  	struct acpi_fan *fan = dev_get_drvdata(dev);  	struct acpi_fan_fps *fps;  	struct acpi_fan_fst fst;  	int ret; -	ret = acpi_fan_get_fst(adev, &fst); +	ret = acpi_fan_get_fst(fan->handle, &fst);  	if (ret < 0)  		return ret; @@ -167,12 +166,12 @@ static const struct hwmon_chip_info acpi_fan_hwmon_chip_info = {  	.info = acpi_fan_hwmon_info,  }; -int devm_acpi_fan_create_hwmon(struct acpi_device *device) +int devm_acpi_fan_create_hwmon(struct device *dev)  { -	struct acpi_fan *fan = acpi_driver_data(device); +	struct acpi_fan *fan = dev_get_drvdata(dev);  	struct device *hdev; -	hdev = devm_hwmon_device_register_with_info(&device->dev, "acpi_fan", fan, -						    &acpi_fan_hwmon_chip_info, NULL); +	hdev = devm_hwmon_device_register_with_info(dev, "acpi_fan", fan, &acpi_fan_hwmon_chip_info, +						    NULL);  	return PTR_ERR_OR_ZERO(hdev);  } diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c index d4d52d5e9016..73cb933fdc89 100644 --- a/drivers/acpi/spcr.c +++ b/drivers/acpi/spcr.c @@ -155,7 +155,7 @@ int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)  	 * Baud Rate field. If this field is zero or not present, Configured  	 * Baud Rate is used.  	 */ -	if (table->precise_baudrate) +	if (table->header.revision >= 4 && table->precise_baudrate)  		baud_rate = table->precise_baudrate;  	else switch (table->baud_rate) {  	case 0: diff --git a/drivers/base/regmap/regmap-slimbus.c b/drivers/base/regmap/regmap-slimbus.c index 54eb7d227cf4..e523fae73004 100644 --- a/drivers/base/regmap/regmap-slimbus.c +++ b/drivers/base/regmap/regmap-slimbus.c @@ -48,8 +48,7 @@ struct regmap *__regmap_init_slimbus(struct slim_device *slimbus,  	if (IS_ERR(bus))  		return ERR_CAST(bus); -	return __regmap_init(&slimbus->dev, bus, &slimbus->dev, config, -			     lock_key, lock_name); +	return __regmap_init(&slimbus->dev, bus, slimbus, config, lock_key, lock_name);  }  EXPORT_SYMBOL_GPL(__regmap_init_slimbus); @@ -63,8 +62,7 @@ struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus,  	if (IS_ERR(bus))  		return ERR_CAST(bus); -	return __devm_regmap_init(&slimbus->dev, bus, &slimbus, config, -				  lock_key, lock_name); +	return __devm_regmap_init(&slimbus->dev, bus, slimbus, config, lock_key, lock_name);  }  EXPORT_SYMBOL_GPL(__devm_regmap_init_slimbus); diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 6ecfc821cf83..72f045e6ed51 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -294,6 +294,8 @@ static int bcma_register_devices(struct bcma_bus *bus)  	int err;  	list_for_each_entry(core, &bus->cores, list) { +		struct device_node *np; +  		/* We support that core ourselves */  		switch (core->id.id) {  		case BCMA_CORE_4706_CHIPCOMMON: @@ -311,6 +313,10 @@ static int bcma_register_devices(struct bcma_bus *bus)  		if (bcma_is_core_needed_early(core->id.id))  			continue; +		np = core->dev.of_node; +		if (np && !of_device_is_available(np)) +			continue; +  		/* Only first GMAC core on BCM4706 is connected and working */  		if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&  		    core->core_unit > 0) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index f982027e8c85..0ee55f889cfd 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -1949,6 +1949,7 @@ static int null_add_dev(struct nullb_device *dev)  		.logical_block_size	= dev->blocksize,  		.physical_block_size	= dev->blocksize,  		.max_hw_sectors		= dev->max_sectors, +		.dma_alignment		= dev->blocksize - 1,  	};  	struct nullb *nullb; diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index b7ba667a3d09..e305d04aac9d 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -41,6 +41,7 @@ struct bpa10x_data {  	struct usb_anchor rx_anchor;  	struct sk_buff *rx_skb[2]; +	struct hci_uart hu;  };  static void bpa10x_tx_complete(struct urb *urb) @@ -96,7 +97,7 @@ static void bpa10x_rx_complete(struct urb *urb)  	if (urb->status == 0) {  		bool idx = usb_pipebulk(urb->pipe); -		data->rx_skb[idx] = h4_recv_buf(hdev, data->rx_skb[idx], +		data->rx_skb[idx] = h4_recv_buf(&data->hu, data->rx_skb[idx],  						urb->transfer_buffer,  						urb->actual_length,  						bpa10x_recv_pkts, @@ -388,6 +389,7 @@ static int bpa10x_probe(struct usb_interface *intf,  	hci_set_drvdata(hdev, data);  	data->hdev = hdev; +	data->hu.hdev = hdev;  	SET_HCIDEV_DEV(hdev, &intf->dev); diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index 6d3963bd56a9..a075d8ec4677 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -1467,11 +1467,6 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)  	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP1)  		btintel_pcie_msix_gp1_handler(data); -	/* This interrupt is triggered by the firmware after updating -	 * boot_stage register and image_response register -	 */ -	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0) -		btintel_pcie_msix_gp0_handler(data);  	/* For TX */  	if (intr_fh & BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0) { @@ -1487,6 +1482,12 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)  			btintel_pcie_msix_tx_handle(data);  	} +	/* This interrupt is triggered by the firmware after updating +	 * boot_stage register and image_response register +	 */ +	if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0) +		btintel_pcie_msix_gp0_handler(data); +  	/*  	 * Before sending the interrupt the HW disables it to prevent a nested  	 * interrupt. This is done by writing 1 to the corresponding bit in diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 50abefba6d04..62db31bd6592 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -1270,6 +1270,12 @@ static void btmtksdio_reset(struct hci_dev *hdev)  	sdio_claim_host(bdev->func); +	/* set drv_pmctrl if BT is closed before doing reset */ +	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) { +		sdio_enable_func(bdev->func); +		btmtksdio_drv_pmctrl(bdev); +	} +  	sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);  	skb_queue_purge(&bdev->txq);  	cancel_work_sync(&bdev->txrx_work); @@ -1285,6 +1291,12 @@ static void btmtksdio_reset(struct hci_dev *hdev)  		goto err;  	} +	/* set fw_pmctrl back if BT is closed after doing reset */ +	if (!test_bit(BTMTKSDIO_FUNC_ENABLED, &bdev->tx_state)) { +		btmtksdio_fw_pmctrl(bdev); +		sdio_disable_func(bdev->func); +	} +  	clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);  err:  	sdio_release_host(bdev->func); diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c index d9b90ea2ad38..27aa48ff3ac2 100644 --- a/drivers/bluetooth/btmtkuart.c +++ b/drivers/bluetooth/btmtkuart.c @@ -79,6 +79,7 @@ struct btmtkuart_dev {  	u16	stp_dlen;  	const struct btmtkuart_data *data; +	struct hci_uart hu;  };  #define btmtkuart_is_standalone(bdev)	\ @@ -368,7 +369,7 @@ static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count)  		sz_left -= adv;  		p_left += adv; -		bdev->rx_skb = h4_recv_buf(bdev->hdev, bdev->rx_skb, p_h4, +		bdev->rx_skb = h4_recv_buf(&bdev->hu, bdev->rx_skb, p_h4,  					   sz_h4, mtk_recv_pkts,  					   ARRAY_SIZE(mtk_recv_pkts));  		if (IS_ERR(bdev->rx_skb)) { @@ -858,6 +859,7 @@ static int btmtkuart_probe(struct serdev_device *serdev)  	}  	bdev->hdev = hdev; +	bdev->hu.hdev = hdev;  	hdev->bus = HCI_UART;  	hci_set_drvdata(hdev, bdev); diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index d5153fed0518..3b1e9224e965 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -212,6 +212,7 @@ struct btnxpuart_dev {  	struct ps_data psdata;  	struct btnxpuart_data *nxp_data;  	struct reset_control *pdn; +	struct hci_uart hu;  };  #define NXP_V1_FW_REQ_PKT	0xa5 @@ -1756,7 +1757,7 @@ static size_t btnxpuart_receive_buf(struct serdev_device *serdev,  	ps_start_timer(nxpdev); -	nxpdev->rx_skb = h4_recv_buf(nxpdev->hdev, nxpdev->rx_skb, data, count, +	nxpdev->rx_skb = h4_recv_buf(&nxpdev->hu, nxpdev->rx_skb, data, count,  				     nxp_recv_pkts, ARRAY_SIZE(nxp_recv_pkts));  	if (IS_ERR(nxpdev->rx_skb)) {  		int err = PTR_ERR(nxpdev->rx_skb); @@ -1875,6 +1876,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev)  	reset_control_deassert(nxpdev->pdn);  	nxpdev->hdev = hdev; +	nxpdev->hu.hdev = hdev;  	hdev->bus = HCI_UART;  	hci_set_drvdata(hdev, nxpdev); diff --git a/drivers/bluetooth/hci_ag6xx.c b/drivers/bluetooth/hci_ag6xx.c index 2d40302409ff..94588676510f 100644 --- a/drivers/bluetooth/hci_ag6xx.c +++ b/drivers/bluetooth/hci_ag6xx.c @@ -105,7 +105,7 @@ static int ag6xx_recv(struct hci_uart *hu, const void *data, int count)  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))  		return -EUNATCH; -	ag6xx->rx_skb = h4_recv_buf(hu->hdev, ag6xx->rx_skb, data, count, +	ag6xx->rx_skb = h4_recv_buf(hu, ag6xx->rx_skb, data, count,  				    ag6xx_recv_pkts,  				    ARRAY_SIZE(ag6xx_recv_pkts));  	if (IS_ERR(ag6xx->rx_skb)) { diff --git a/drivers/bluetooth/hci_aml.c b/drivers/bluetooth/hci_aml.c index 707e90f80130..b1f32c5a8a3f 100644 --- a/drivers/bluetooth/hci_aml.c +++ b/drivers/bluetooth/hci_aml.c @@ -650,7 +650,7 @@ static int aml_recv(struct hci_uart *hu, const void *data, int count)  	struct aml_data *aml_data = hu->priv;  	int err; -	aml_data->rx_skb = h4_recv_buf(hu->hdev, aml_data->rx_skb, data, count, +	aml_data->rx_skb = h4_recv_buf(hu, aml_data->rx_skb, data, count,  				       aml_recv_pkts,  				       ARRAY_SIZE(aml_recv_pkts));  	if (IS_ERR(aml_data->rx_skb)) { diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index dbfe34664633..8d2b5e7f0d6a 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -191,7 +191,7 @@ static int ath_recv(struct hci_uart *hu, const void *data, int count)  {  	struct ath_struct *ath = hu->priv; -	ath->rx_skb = h4_recv_buf(hu->hdev, ath->rx_skb, data, count, +	ath->rx_skb = h4_recv_buf(hu, ath->rx_skb, data, count,  				  ath_recv_pkts, ARRAY_SIZE(ath_recv_pkts));  	if (IS_ERR(ath->rx_skb)) {  		int err = PTR_ERR(ath->rx_skb); diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index f96617b85d87..fff845ed44e3 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -698,7 +698,7 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count)  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))  		return -EUNATCH; -	bcm->rx_skb = h4_recv_buf(hu->hdev, bcm->rx_skb, data, count, +	bcm->rx_skb = h4_recv_buf(hu, bcm->rx_skb, data, count,  				  bcm_recv_pkts, ARRAY_SIZE(bcm_recv_pkts));  	if (IS_ERR(bcm->rx_skb)) {  		int err = PTR_ERR(bcm->rx_skb); diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index 9070e31a68bf..ec017df8572c 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -112,7 +112,7 @@ static int h4_recv(struct hci_uart *hu, const void *data, int count)  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))  		return -EUNATCH; -	h4->rx_skb = h4_recv_buf(hu->hdev, h4->rx_skb, data, count, +	h4->rx_skb = h4_recv_buf(hu, h4->rx_skb, data, count,  				 h4_recv_pkts, ARRAY_SIZE(h4_recv_pkts));  	if (IS_ERR(h4->rx_skb)) {  		int err = PTR_ERR(h4->rx_skb); @@ -151,12 +151,12 @@ int __exit h4_deinit(void)  	return hci_uart_unregister_proto(&h4p);  } -struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, +struct sk_buff *h4_recv_buf(struct hci_uart *hu, struct sk_buff *skb,  			    const unsigned char *buffer, int count,  			    const struct h4_recv_pkt *pkts, int pkts_count)  { -	struct hci_uart *hu = hci_get_drvdata(hdev);  	u8 alignment = hu->alignment ? hu->alignment : 1; +	struct hci_dev *hdev = hu->hdev;  	/* Check for error from previous call */  	if (IS_ERR(skb)) diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 9b353c3d6442..1d6e09508f1f 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -972,7 +972,7 @@ static int intel_recv(struct hci_uart *hu, const void *data, int count)  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))  		return -EUNATCH; -	intel->rx_skb = h4_recv_buf(hu->hdev, intel->rx_skb, data, count, +	intel->rx_skb = h4_recv_buf(hu, intel->rx_skb, data, count,  				    intel_recv_pkts,  				    ARRAY_SIZE(intel_recv_pkts));  	if (IS_ERR(intel->rx_skb)) { diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 7044c86325ce..6f4e25917b86 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -429,7 +429,7 @@ static int ll_recv(struct hci_uart *hu, const void *data, int count)  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))  		return -EUNATCH; -	ll->rx_skb = h4_recv_buf(hu->hdev, ll->rx_skb, data, count, +	ll->rx_skb = h4_recv_buf(hu, ll->rx_skb, data, count,  				 ll_recv_pkts, ARRAY_SIZE(ll_recv_pkts));  	if (IS_ERR(ll->rx_skb)) {  		int err = PTR_ERR(ll->rx_skb); diff --git a/drivers/bluetooth/hci_mrvl.c b/drivers/bluetooth/hci_mrvl.c index e08222395772..8767522ec4c6 100644 --- a/drivers/bluetooth/hci_mrvl.c +++ b/drivers/bluetooth/hci_mrvl.c @@ -264,9 +264,9 @@ static int mrvl_recv(struct hci_uart *hu, const void *data, int count)  				!test_bit(STATE_FW_LOADED, &mrvl->flags))  		return count; -	mrvl->rx_skb = h4_recv_buf(hu->hdev, mrvl->rx_skb, data, count, -				    mrvl_recv_pkts, -				    ARRAY_SIZE(mrvl_recv_pkts)); +	mrvl->rx_skb = h4_recv_buf(hu, mrvl->rx_skb, data, count, +				   mrvl_recv_pkts, +				   ARRAY_SIZE(mrvl_recv_pkts));  	if (IS_ERR(mrvl->rx_skb)) {  		int err = PTR_ERR(mrvl->rx_skb);  		bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c index cd7575c20f65..1e65b541f8ad 100644 --- a/drivers/bluetooth/hci_nokia.c +++ b/drivers/bluetooth/hci_nokia.c @@ -624,8 +624,8 @@ static int nokia_recv(struct hci_uart *hu, const void *data, int count)  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))  		return -EUNATCH; -	btdev->rx_skb = h4_recv_buf(hu->hdev, btdev->rx_skb, data, count, -				  nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts)); +	btdev->rx_skb = h4_recv_buf(hu, btdev->rx_skb, data, count, +				    nokia_recv_pkts, ARRAY_SIZE(nokia_recv_pkts));  	if (IS_ERR(btdev->rx_skb)) {  		err = PTR_ERR(btdev->rx_skb);  		dev_err(dev, "Frame reassembly failed (%d)", err); diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 4cff4d9be313..888176b0faa9 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1277,7 +1277,7 @@ static int qca_recv(struct hci_uart *hu, const void *data, int count)  	if (!test_bit(HCI_UART_REGISTERED, &hu->flags))  		return -EUNATCH; -	qca->rx_skb = h4_recv_buf(hu->hdev, qca->rx_skb, data, count, +	qca->rx_skb = h4_recv_buf(hu, qca->rx_skb, data, count,  				  qca_recv_pkts, ARRAY_SIZE(qca_recv_pkts));  	if (IS_ERR(qca->rx_skb)) {  		int err = PTR_ERR(qca->rx_skb); diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index cbbe79b241ce..48ac7ca9334e 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -162,7 +162,7 @@ struct h4_recv_pkt {  int h4_init(void);  int h4_deinit(void); -struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb, +struct sk_buff *h4_recv_buf(struct hci_uart *hu, struct sk_buff *skb,  			    const unsigned char *buffer, int count,  			    const struct h4_recv_pkt *pkts, int pkts_count);  #endif diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 7d21fb5a72f4..23239b0c04f9 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -318,10 +318,13 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,  		/*  		 * Use a physical idle state, not busy polling, unless a timer -		 * is going to trigger soon enough. +		 * is going to trigger soon enough or the exit latency of the +		 * idle state in question is greater than the predicted idle +		 * duration.  		 */  		if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && -		    s->target_residency_ns <= data->next_timer_ns) { +		    s->target_residency_ns <= data->next_timer_ns && +		    s->exit_latency_ns <= predicted_ns) {  			predicted_ns = s->target_residency_ns;  			idx = i;  			break; diff --git a/drivers/crypto/aspeed/aspeed-acry.c b/drivers/crypto/aspeed/aspeed-acry.c index 8d1c79aaca07..5993bcba9716 100644 --- a/drivers/crypto/aspeed/aspeed-acry.c +++ b/drivers/crypto/aspeed/aspeed-acry.c @@ -787,7 +787,6 @@ static int aspeed_acry_probe(struct platform_device *pdev)  err_engine_rsa_start:  	crypto_engine_exit(acry_dev->crypt_engine_rsa);  clk_exit: -	clk_disable_unprepare(acry_dev->clk);  	return rc;  } @@ -799,7 +798,6 @@ static void aspeed_acry_remove(struct platform_device *pdev)  	aspeed_acry_unregister(acry_dev);  	crypto_engine_exit(acry_dev->crypt_engine_rsa);  	tasklet_kill(&acry_dev->done_task); -	clk_disable_unprepare(acry_dev->clk);  }  MODULE_DEVICE_TABLE(of, aspeed_acry_of_matches); diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 3f78c56b58dc..39e6f93dc310 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -1141,7 +1141,7 @@ const char __rcu *dma_fence_timeline_name(struct dma_fence *fence)  			 "RCU protection is required for safe access to returned string");  	if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) -		return fence->ops->get_driver_name(fence); +		return fence->ops->get_timeline_name(fence);  	else  		return "signaled-timeline";  } diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 74c1f0ca95f2..a4153bcb6dcf 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -1559,16 +1559,18 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)  		return -EMSGSIZE;  	}  	pin = dpll_pin_find_from_nlattr(info); -	if (!IS_ERR(pin)) { -		if (!dpll_pin_available(pin)) { -			nlmsg_free(msg); -			return -ENODEV; -		} -		ret = dpll_msg_add_pin_handle(msg, pin); -		if (ret) { -			nlmsg_free(msg); -			return ret; -		} +	if (IS_ERR(pin)) { +		nlmsg_free(msg); +		return PTR_ERR(pin); +	} +	if (!dpll_pin_available(pin)) { +		nlmsg_free(msg); +		return -ENODEV; +	} +	ret = dpll_msg_add_pin_handle(msg, pin); +	if (ret) { +		nlmsg_free(msg); +		return ret;  	}  	genlmsg_end(msg, hdr); @@ -1735,12 +1737,14 @@ int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)  	}  	dpll = dpll_device_find_from_nlattr(info); -	if (!IS_ERR(dpll)) { -		ret = dpll_msg_add_dev_handle(msg, dpll); -		if (ret) { -			nlmsg_free(msg); -			return ret; -		} +	if (IS_ERR(dpll)) { +		nlmsg_free(msg); +		return PTR_ERR(dpll); +	} +	ret = dpll_msg_add_dev_handle(msg, dpll); +	if (ret) { +		nlmsg_free(msg); +		return ret;  	}  	genlmsg_end(msg, hdr); diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c index 93dc93eec79e..f93f9a458324 100644 --- a/drivers/dpll/zl3073x/dpll.c +++ b/drivers/dpll/zl3073x/dpll.c @@ -1904,7 +1904,7 @@ zl3073x_dpll_pin_is_registrable(struct zl3073x_dpll *zldpll,  		}  		is_diff = zl3073x_out_is_diff(zldev, out); -		is_enabled = zl3073x_out_is_enabled(zldev, out); +		is_enabled = zl3073x_output_pin_is_enabled(zldev, index);  	}  	/* Skip N-pin if the corresponding input/output is differential */ diff --git a/drivers/edac/versalnet_edac.c b/drivers/edac/versalnet_edac.c index 7c5db8bf0595..1ded4c3f0213 100644 --- a/drivers/edac/versalnet_edac.c +++ b/drivers/edac/versalnet_edac.c @@ -433,7 +433,7 @@ static void handle_error(struct mc_priv  *priv, struct ecc_status *stat,  	phys_addr_t pfn;  	int err; -	if (WARN_ON_ONCE(ctl_num > NUM_CONTROLLERS)) +	if (WARN_ON_ONCE(ctl_num >= NUM_CONTROLLERS))  		return;  	mci = priv->mci[ctl_num]; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c index ef996493115f..425a3e564360 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: MIT  /*   * Copyright 2025 Advanced Micro Devices, Inc.   * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.h index bcb97d245673..353421807387 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cper.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: MIT */  /*   * Copyright 2025 Advanced Micro Devices, Inc.   * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c index 474bfe36c0c2..aa78c2ee9e21 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c @@ -322,6 +322,26 @@ static int vpe_early_init(struct amdgpu_ip_block *ip_block)  	return 0;  } +static bool vpe_need_dpm0_at_power_down(struct amdgpu_device *adev) +{ +	switch (amdgpu_ip_version(adev, VPE_HWIP, 0)) { +	case IP_VERSION(6, 1, 1): +		return adev->pm.fw_version < 0x0a640500; +	default: +		return false; +	} +} + +static int vpe_get_dpm_level(struct amdgpu_device *adev) +{ +	struct amdgpu_vpe *vpe = &adev->vpe; + +	if (!adev->pm.dpm_enabled) +		return 0; + +	return RREG32(vpe_get_reg_offset(vpe, 0, vpe->regs.dpm_request_lv)); +} +  static void vpe_idle_work_handler(struct work_struct *work)  {  	struct amdgpu_device *adev = @@ -329,11 +349,17 @@ static void vpe_idle_work_handler(struct work_struct *work)  	unsigned int fences = 0;  	fences += amdgpu_fence_count_emitted(&adev->vpe.ring); +	if (fences) +		goto reschedule; -	if (fences == 0) -		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, AMD_PG_STATE_GATE); -	else -		schedule_delayed_work(&adev->vpe.idle_work, VPE_IDLE_TIMEOUT); +	if (vpe_need_dpm0_at_power_down(adev) && vpe_get_dpm_level(adev) != 0) +		goto reschedule; + +	amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE, AMD_PG_STATE_GATE); +	return; + +reschedule: +	schedule_delayed_work(&adev->vpe.idle_work, VPE_IDLE_TIMEOUT);  }  static int vpe_common_init(struct amdgpu_vpe *vpe) diff --git a/drivers/gpu/drm/amd/amdgpu/cyan_skillfish_reg_init.c b/drivers/gpu/drm/amd/amdgpu/cyan_skillfish_reg_init.c index 96616a865aac..ed1e25661706 100644 --- a/drivers/gpu/drm/amd/amdgpu/cyan_skillfish_reg_init.c +++ b/drivers/gpu/drm/amd/amdgpu/cyan_skillfish_reg_init.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: MIT  /*   * Copyright 2018 Advanced Micro Devices, Inc.   * diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 1ec9d03ad747..38f9ea313dcb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -248,6 +248,8 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work)  	struct vblank_control_work *vblank_work =  		container_of(work, struct vblank_control_work, work);  	struct amdgpu_display_manager *dm = vblank_work->dm; +	struct amdgpu_device *adev = drm_to_adev(dm->ddev); +	int r;  	mutex_lock(&dm->dc_lock); @@ -277,7 +279,16 @@ static void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work)  	if (dm->active_vblank_irq_count == 0) {  		dc_post_update_surfaces_to_stream(dm->dc); + +		r = amdgpu_dpm_pause_power_profile(adev, true); +		if (r) +			dev_warn(adev->dev, "failed to set default power profile mode\n"); +  		dc_allow_idle_optimizations(dm->dc, true); + +		r = amdgpu_dpm_pause_power_profile(adev, false); +		if (r) +			dev_warn(adev->dev, "failed to restore the power profile mode\n");  	}  	mutex_unlock(&dm->dc_lock); @@ -297,8 +308,12 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)  	int irq_type;  	int rc = 0; -	if (acrtc->otg_inst == -1) -		goto skip; +	if (enable && !acrtc->base.enabled) { +		drm_dbg_vbl(crtc->dev, +				"Reject vblank enable on unconfigured CRTC %d (enabled=%d)\n", +				acrtc->crtc_id, acrtc->base.enabled); +		return -EINVAL; +	}  	irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id); @@ -383,7 +398,7 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)  			return rc;  	}  #endif -skip: +  	if (amdgpu_in_reset(adev))  		return 0; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index fe100e4c9801..cc21337a182f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -83,6 +83,7 @@ static void apply_edid_quirks(struct drm_device *dev, struct edid *edid, struct  		edid_caps->panel_patch.remove_sink_ext_caps = true;  		break;  	case drm_edid_encode_panel_id('S', 'D', 'C', 0x4154): +	case drm_edid_encode_panel_id('S', 'D', 'C', 0x4171):  		drm_dbg_driver(dev, "Disabling VSC on monitor with panel id %X\n", panel_id);  		edid_caps->panel_patch.disable_colorimetry = true;  		break; diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c index 09be2a90cc79..4f569cd8a5d6 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c @@ -578,9 +578,6 @@ static void dpp3_power_on_blnd_lut(  			dpp_base->ctx->dc->optimized_required = true;  			dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true;  		} -	} else { -		REG_SET(CM_MEM_PWR_CTRL, 0, -				BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);  	}  } diff --git a/drivers/gpu/drm/amd/include/amd_cper.h b/drivers/gpu/drm/amd/include/amd_cper.h index 086869264425..a252ee4c7874 100644 --- a/drivers/gpu/drm/amd/include/amd_cper.h +++ b/drivers/gpu/drm/amd/include/amd_cper.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: MIT */  /*   * Copyright 2025 Advanced Micro Devices, Inc.   * diff --git a/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_5_0.h b/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_5_0.h index 64b553e7de1a..e7fdcee22a71 100644 --- a/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_5_0.h +++ b/drivers/gpu/drm/amd/include/ivsrcid/vcn/irqsrcs_vcn_5_0.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: MIT */  /*   * Copyright 2024 Advanced Micro Devices, Inc. All rights reserved. diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c index d2dbd90bb427..0a876c840c79 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c @@ -2024,7 +2024,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)  	table->VoltageResponseTime = 0;  	table->PhaseResponseTime = 0;  	table->MemoryThermThrottleEnable = 1; -	table->PCIeBootLinkLevel = 0;      /* 0:Gen1 1:Gen2 2:Gen3*/ +	table->PCIeBootLinkLevel = (uint8_t) (data->dpm_table.pcie_speed_table.count);  	table->PCIeGenInterval = 1;  	table->VRConfig = 0; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c index 1f50f1e74c48..aa3ae9b115c4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c @@ -2028,7 +2028,7 @@ static int iceland_init_smc_table(struct pp_hwmgr *hwmgr)  	table->VoltageResponseTime  = 0;  	table->PhaseResponseTime  = 0;  	table->MemoryThermThrottleEnable  = 1; -	table->PCIeBootLinkLevel = 0; +	table->PCIeBootLinkLevel = (uint8_t) (data->dpm_table.pcie_speed_table.count);  	table->PCIeGenInterval = 1;  	result = iceland_populate_smc_svi2_config(hwmgr, table); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index f532f7c69259..a8961a8f5c42 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -969,7 +969,7 @@ int smu_cmn_update_table(struct smu_context *smu,  						      table_index);  	uint32_t table_size;  	int ret = 0; -	if (!table_data || table_id >= SMU_TABLE_COUNT || table_id < 0) +	if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0)  		return -EINVAL;  	table_size = smu_table->tables[table_index].size; diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index c15aef014f69..d41bd876167c 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -282,13 +282,13 @@ static inline void __ast_write8_i(void __iomem *addr, u32 reg, u8 index, u8 val)  	__ast_write8(addr, reg + 1, val);  } -static inline void __ast_write8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 read_mask, +static inline void __ast_write8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 preserve_mask,  					 u8 val)  { -	u8 tmp = __ast_read8_i_masked(addr, reg, index, read_mask); +	u8 tmp = __ast_read8_i_masked(addr, reg, index, preserve_mask); -	tmp |= val; -	__ast_write8_i(addr, reg, index, tmp); +	val &= ~preserve_mask; +	__ast_write8_i(addr, reg, index, tmp | val);  }  static inline u32 ast_read32(struct ast_device *ast, u32 reg) diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml index d502d146b177..56638814bb28 100644 --- a/drivers/gpu/drm/ci/gitlab-ci.yml +++ b/drivers/gpu/drm/ci/gitlab-ci.yml @@ -280,7 +280,7 @@ sanity:      GIT_STRATEGY: none    script:      # ci-fairy check-commits --junit-xml=check-commits.xml -    - ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request.xml +    # - ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-merge-request.xml      - |        set -eu        image_tags=( diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c index ebf305fb24f0..6fb55601252f 100644 --- a/drivers/gpu/drm/drm_gem_atomic_helper.c +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -310,8 +310,12 @@ EXPORT_SYMBOL(drm_gem_destroy_shadow_plane_state);  void __drm_gem_reset_shadow_plane(struct drm_plane *plane,  				  struct drm_shadow_plane_state *shadow_plane_state)  { -	__drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base); -	drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state); +	if (shadow_plane_state) { +		__drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base); +		drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state); +	} else { +		__drm_atomic_helper_plane_reset(plane, NULL); +	}  }  EXPORT_SYMBOL(__drm_gem_reset_shadow_plane); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c index b13a17276d07..88385dc3b30d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c @@ -347,7 +347,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,  	u32 link_target, link_dwords;  	bool switch_context = gpu->exec_state != exec_state;  	bool switch_mmu_context = gpu->mmu_context != mmu_context; -	unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq); +	unsigned int new_flush_seq = READ_ONCE(mmu_context->flush_seq);  	bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq;  	bool has_blt = !!(gpu->identity.minor_features5 &  			  chipMinorFeatures5_BLT_ENGINE); diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 77a0199f9ea5..4a4cace1f879 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -546,6 +546,36 @@ static bool is_event_handler(struct intel_display *display,  		REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == event_id;  } +static bool fixup_dmc_evt(struct intel_display *display, +			  enum intel_dmc_id dmc_id, +			  i915_reg_t reg_ctl, u32 *data_ctl, +			  i915_reg_t reg_htp, u32 *data_htp) +{ +	if (!is_dmc_evt_ctl_reg(display, dmc_id, reg_ctl)) +		return false; + +	if (!is_dmc_evt_htp_reg(display, dmc_id, reg_htp)) +		return false; + +	/* make sure reg_ctl and reg_htp are for the same event */ +	if (i915_mmio_reg_offset(reg_ctl) - i915_mmio_reg_offset(DMC_EVT_CTL(display, dmc_id, 0)) != +	    i915_mmio_reg_offset(reg_htp) - i915_mmio_reg_offset(DMC_EVT_HTP(display, dmc_id, 0))) +		return false; + +	/* +	 * On ADL-S the HRR event handler is not restored after DC6. +	 * Clear it to zero from the beginning to avoid mismatches later. +	 */ +	if (display->platform.alderlake_s && dmc_id == DMC_FW_MAIN && +	    is_event_handler(display, dmc_id, MAINDMC_EVENT_VBLANK_A, reg_ctl, *data_ctl)) { +		*data_ctl = 0; +		*data_htp = 0; +		return true; +	} + +	return false; +} +  static bool disable_dmc_evt(struct intel_display *display,  			    enum intel_dmc_id dmc_id,  			    i915_reg_t reg, u32 data) @@ -1064,9 +1094,32 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,  	for (i = 0; i < mmio_count; i++) {  		dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]);  		dmc_info->mmiodata[i] = mmiodata[i]; +	} + +	for (i = 0; i < mmio_count - 1; i++) { +		u32 orig_mmiodata[2] = { +			dmc_info->mmiodata[i], +			dmc_info->mmiodata[i+1], +		}; + +		if (!fixup_dmc_evt(display, dmc_id, +				   dmc_info->mmioaddr[i], &dmc_info->mmiodata[i], +				   dmc_info->mmioaddr[i+1], &dmc_info->mmiodata[i+1])) +			continue; + +		drm_dbg_kms(display->drm, +			    " mmio[%d]: 0x%x = 0x%x->0x%x (EVT_CTL)\n", +			    i, i915_mmio_reg_offset(dmc_info->mmioaddr[i]), +			    orig_mmiodata[0], dmc_info->mmiodata[i]); +		drm_dbg_kms(display->drm, +			    " mmio[%d]: 0x%x = 0x%x->0x%x (EVT_HTP)\n", +			    i+1, i915_mmio_reg_offset(dmc_info->mmioaddr[i+1]), +			    orig_mmiodata[1], dmc_info->mmiodata[i+1]); +	} +	for (i = 0; i < mmio_count; i++) {  		drm_dbg_kms(display->drm, " mmio[%d]: 0x%x = 0x%x%s%s\n", -			    i, mmioaddr[i], mmiodata[i], +			    i, i915_mmio_reg_offset(dmc_info->mmioaddr[i]), dmc_info->mmiodata[i],  			    is_dmc_evt_ctl_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_CTL)" :  			    is_dmc_evt_htp_reg(display, dmc_id, dmc_info->mmioaddr[i]) ? " (EVT_HTP)" : "",  			    disable_dmc_evt(display, dmc_id, dmc_info->mmioaddr[i], diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c index 6d8325c76697..7fc6af703307 100644 --- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -25,19 +25,18 @@  struct imx_parallel_display_encoder {  	struct drm_encoder encoder; -	struct drm_bridge bridge; -	struct imx_parallel_display *pd;  };  struct imx_parallel_display {  	struct device *dev;  	u32 bus_format;  	struct drm_bridge *next_bridge; +	struct drm_bridge bridge;  };  static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge *b)  { -	return container_of(b, struct imx_parallel_display_encoder, bridge)->pd; +	return container_of(b, struct imx_parallel_display, bridge);  }  static const u32 imx_pd_bus_fmts[] = { @@ -195,15 +194,13 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)  	if (IS_ERR(imxpd_encoder))  		return PTR_ERR(imxpd_encoder); -	imxpd_encoder->pd = imxpd;  	encoder = &imxpd_encoder->encoder; -	bridge = &imxpd_encoder->bridge; +	bridge = &imxpd->bridge;  	ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node);  	if (ret)  		return ret; -	bridge->funcs = &imx_pd_bridge_funcs;  	drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);  	connector = drm_bridge_connector_init(drm, encoder); @@ -228,9 +225,10 @@ static int imx_pd_probe(struct platform_device *pdev)  	u32 bus_format = 0;  	const char *fmt; -	imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL); -	if (!imxpd) -		return -ENOMEM; +	imxpd = devm_drm_bridge_alloc(dev, struct imx_parallel_display, bridge, +				      &imx_pd_bridge_funcs); +	if (IS_ERR(imxpd)) +		return PTR_ERR(imxpd);  	/* port@1 is the output port */  	imxpd->next_bridge = devm_drm_of_get_bridge(dev, np, 1, 0); @@ -258,6 +256,8 @@ static int imx_pd_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, imxpd); +	devm_drm_bridge_add(dev, &imxpd->bridge); +  	return component_add(dev, &imx_pd_ops);  } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index eb5537f0ac90..31ff2922758a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -686,10 +686,6 @@ err_free:  	for (i = 0; i < private->data->mmsys_dev_num; i++)  		private->all_drm_private[i]->drm = NULL;  err_put_dev: -	for (i = 0; i < private->data->mmsys_dev_num; i++) { -		/* For device_find_child in mtk_drm_get_all_priv() */ -		put_device(private->all_drm_private[i]->dev); -	}  	put_device(private->mutex_dev);  	return ret;  } @@ -697,18 +693,12 @@ err_put_dev:  static void mtk_drm_unbind(struct device *dev)  {  	struct mtk_drm_private *private = dev_get_drvdata(dev); -	int i;  	/* for multi mmsys dev, unregister drm dev in mmsys master */  	if (private->drm_master) {  		drm_dev_unregister(private->drm);  		mtk_drm_kms_deinit(private->drm);  		drm_dev_put(private->drm); - -		for (i = 0; i < private->data->mmsys_dev_num; i++) { -			/* For device_find_child in mtk_drm_get_all_priv() */ -			put_device(private->all_drm_private[i]->dev); -		}  		put_device(private->mutex_dev);  	}  	private->mtk_drm_bound = false; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index fc62fef2fed8..4e6dc16e4a4c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -780,6 +780,9 @@ static bool fw_block_mem(struct a6xx_gmu_bo *bo, const struct block_header *blk)  	return true;  } +#define NEXT_BLK(blk) \ +	((const struct block_header *)((const char *)(blk) + sizeof(*(blk)) + (blk)->size)) +  static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)  {  	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); @@ -811,7 +814,7 @@ static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)  	for (blk = (const struct block_header *) fw_image->data;  	     (const u8*) blk < fw_image->data + fw_image->size; -	     blk = (const struct block_header *) &blk->data[blk->size >> 2]) { +	     blk = NEXT_BLK(blk)) {  		if (blk->size == 0)  			continue; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index afaa3cfefd35..4b5a4edd0702 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -348,13 +348,6 @@ int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,  	return 0;  } -static bool -adreno_smmu_has_prr(struct msm_gpu *gpu) -{ -	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(&gpu->pdev->dev); -	return adreno_smmu && adreno_smmu->set_prr_addr; -} -  int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,  		     uint32_t param, uint64_t *value, uint32_t *len)  { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 4b970a59deaf..2f8156051d9b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1545,6 +1545,9 @@ static enum drm_mode_status dpu_crtc_mode_valid(struct drm_crtc *crtc,  	adjusted_mode_clk = dpu_core_perf_adjusted_mode_clk(mode->clock,  							    dpu_kms->perf.perf_cfg); +	if (dpu_kms->catalog->caps->has_3d_merge) +		adjusted_mode_clk /= 2; +  	/*  	 * The given mode, adjusted for the perf clock factor, should not exceed  	 * the max core clock rate diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 6641455c4ec6..9f8d1bba9139 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -267,8 +267,8 @@ static const u32 wb2_formats_rgb_yuv[] = {  		.base = 0x200, .len = 0xa0,}, \  	.csc_blk = {.name = "csc", \  		.base = 0x320, .len = 0x100,}, \ -	.format_list = plane_formats_yuv, \ -	.num_formats = ARRAY_SIZE(plane_formats_yuv), \ +	.format_list = plane_formats, \ +	.num_formats = ARRAY_SIZE(plane_formats), \  	.rotation_cfg = NULL, \  	} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index f54cf0faa1c7..905524ceeb1f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -500,13 +500,15 @@ static void _dpu_plane_setup_pixel_ext(struct dpu_hw_scaler3_cfg *scale_cfg,  	int i;  	for (i = 0; i < DPU_MAX_PLANES; i++) { +		uint32_t w = src_w, h = src_h; +  		if (i == DPU_SSPP_COMP_1_2 || i == DPU_SSPP_COMP_2) { -			src_w /= chroma_subsmpl_h; -			src_h /= chroma_subsmpl_v; +			w /= chroma_subsmpl_h; +			h /= chroma_subsmpl_v;  		} -		pixel_ext->num_ext_pxls_top[i] = src_h; -		pixel_ext->num_ext_pxls_left[i] = src_w; +		pixel_ext->num_ext_pxls_top[i] = h; +		pixel_ext->num_ext_pxls_left[i] = w;  	}  } @@ -740,7 +742,7 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,  	 * We already have verified scaling against platform limitations.  	 * Now check if the SSPP supports scaling at all.  	 */ -	if (!sblk->scaler_blk.len && +	if (!(sblk->scaler_blk.len && pipe->sspp->ops.setup_scaler) &&  	    ((drm_rect_width(&new_plane_state->src) >> 16 !=  	      drm_rect_width(&new_plane_state->dst)) ||  	     (drm_rect_height(&new_plane_state->src) >> 16 != @@ -1278,7 +1280,7 @@ int dpu_assign_plane_resources(struct dpu_global_state *global_state,  							     state, plane_state,  							     prev_adjacent_plane_state);  		if (ret) -			break; +			return ret;  		prev_adjacent_plane_state = plane_state;  	} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 2c77c74fac0f..d9c3b0a1d091 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -842,7 +842,7 @@ struct dpu_hw_sspp *dpu_rm_reserve_sspp(struct dpu_rm *rm,  	if (!reqs->scale && !reqs->yuv)  		hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_DMA); -	if (!hw_sspp && reqs->scale) +	if (!hw_sspp && !reqs->yuv)  		hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_RGB);  	if (!hw_sspp)  		hw_sspp = dpu_rm_try_sspp(rm, global_state, crtc, reqs, SSPP_TYPE_VIG); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c index cd73468e369a..7545c0293efb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c @@ -72,6 +72,9 @@ static int dpu_wb_conn_atomic_check(struct drm_connector *connector,  		DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n",  			  fb->width, dpu_wb_conn->maxlinewidth);  		return -EINVAL; +	} else if (fb->modifier != DRM_FORMAT_MOD_LINEAR) { +		DPU_ERROR("unsupported fb modifier:%#llx\n", fb->modifier); +		return -EINVAL;  	}  	return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index e391505fdaf0..3cbf08231492 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -109,7 +109,6 @@ struct msm_dsi_phy {  	struct msm_dsi_dphy_timing timing;  	const struct msm_dsi_phy_cfg *cfg;  	void *tuning_cfg; -	void *pll_data;  	enum msm_dsi_phy_usecase usecase;  	bool regulator_ldo_mode; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 32f06edd21a9..c5e1d2016bcc 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -426,11 +426,8 @@ static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)  	u32 data;  	spin_lock_irqsave(&pll->pll_enable_lock, flags); -	if (pll->pll_enable_cnt++) { -		spin_unlock_irqrestore(&pll->pll_enable_lock, flags); -		WARN_ON(pll->pll_enable_cnt == INT_MAX); -		return; -	} +	pll->pll_enable_cnt++; +	WARN_ON(pll->pll_enable_cnt == INT_MAX);  	data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);  	data |= DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB; @@ -876,7 +873,6 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)  	spin_lock_init(&pll_7nm->pll_enable_lock);  	pll_7nm->phy = phy; -	phy->pll_data = pll_7nm;  	ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);  	if (ret) { @@ -965,10 +961,8 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  	u32 const delay_us = 5;  	u32 const timeout_us = 1000;  	struct msm_dsi_dphy_timing *timing = &phy->timing; -	struct dsi_pll_7nm *pll = phy->pll_data;  	void __iomem *base = phy->base;  	bool less_than_1500_mhz; -	unsigned long flags;  	u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;  	u32 glbl_pemph_ctrl_0;  	u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0; @@ -1090,13 +1084,10 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,  		glbl_rescode_bot_ctrl = 0x3c;  	} -	spin_lock_irqsave(&pll->pll_enable_lock, flags); -	pll->pll_enable_cnt = 1;  	/* de-assert digital and pll power down */  	data = DSI_7nm_PHY_CMN_CTRL_0_DIGTOP_PWRDN_B |  	       DSI_7nm_PHY_CMN_CTRL_0_PLL_SHUTDOWNB;  	writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0); -	spin_unlock_irqrestore(&pll->pll_enable_lock, flags);  	/* Assert PLL core reset */  	writel(0x00, base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL); @@ -1209,9 +1200,7 @@ static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)  static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)  { -	struct dsi_pll_7nm *pll = phy->pll_data;  	void __iomem *base = phy->base; -	unsigned long flags;  	u32 data;  	DBG(""); @@ -1238,11 +1227,8 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)  	writel(data, base + REG_DSI_7nm_PHY_CMN_CTRL_0);  	writel(0, base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0); -	spin_lock_irqsave(&pll->pll_enable_lock, flags); -	pll->pll_enable_cnt = 0;  	/* Turn off all PHY blocks */  	writel(0x00, base + REG_DSI_7nm_PHY_CMN_CTRL_0); -	spin_unlock_irqrestore(&pll->pll_enable_lock, flags);  	/* make sure phy is turned off */  	wmb(); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 07d8cdd6bb2e..9f7fbe577abb 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1120,12 +1120,16 @@ static void msm_gem_free_object(struct drm_gem_object *obj)  		put_pages(obj);  	} -	if (obj->resv != &obj->_resv) { +	/* +	 * In error paths, we could end up here before msm_gem_new_handle() +	 * has changed obj->resv to point to the shared resv.  In this case, +	 * we don't want to drop a ref to the shared r_obj that we haven't +	 * taken yet. +	 */ +	if ((msm_obj->flags & MSM_BO_NO_SHARE) && (obj->resv != &obj->_resv)) {  		struct drm_gem_object *r_obj =  			container_of(obj->resv, struct drm_gem_object, _resv); -		WARN_ON(!(msm_obj->flags & MSM_BO_NO_SHARE)); -  		/* Drop reference we hold to shared resv obj: */  		drm_gem_object_put(r_obj);  	} diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 3ab3b27134f9..75d9f3574370 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -414,6 +414,11 @@ static void submit_attach_object_fences(struct msm_gem_submit *submit)  					 submit->user_fence,  					 DMA_RESV_USAGE_BOOKKEEP,  					 DMA_RESV_USAGE_BOOKKEEP); + +		last_fence = vm->last_fence; +		vm->last_fence = dma_fence_unwrap_merge(submit->user_fence, last_fence); +		dma_fence_put(last_fence); +  		return;  	} @@ -427,10 +432,6 @@ static void submit_attach_object_fences(struct msm_gem_submit *submit)  			dma_resv_add_fence(obj->resv, submit->user_fence,  					   DMA_RESV_USAGE_READ);  	} - -	last_fence = vm->last_fence; -	vm->last_fence = dma_fence_unwrap_merge(submit->user_fence, last_fence); -	dma_fence_put(last_fence);  }  static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 8316af1723c2..89a95977f41e 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -971,6 +971,7 @@ static int  lookup_op(struct msm_vm_bind_job *job, const struct drm_msm_vm_bind_op *op)  {  	struct drm_device *dev = job->vm->drm; +	struct msm_drm_private *priv = dev->dev_private;  	int i = job->nr_ops++;  	int ret = 0; @@ -1017,6 +1018,11 @@ lookup_op(struct msm_vm_bind_job *job, const struct drm_msm_vm_bind_op *op)  		break;  	} +	if ((op->op == MSM_VM_BIND_OP_MAP_NULL) && +	    !adreno_smmu_has_prr(priv->gpu)) { +		ret = UERR(EINVAL, dev, "PRR not supported\n"); +	} +  	return ret;  } @@ -1421,7 +1427,7 @@ msm_ioctl_vm_bind(struct drm_device *dev, void *data, struct drm_file *file)  	 * Maybe we could allow just UNMAP ops?  OTOH userspace should just  	 * immediately close the device file and all will be torn down.  	 */ -	if (to_msm_vm(ctx->vm)->unusable) +	if (to_msm_vm(msm_context_vm(dev, ctx))->unusable)  		return UERR(EPIPE, dev, "context is unusable");  	/* diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index a597f2bee30b..2894fc118485 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -299,6 +299,17 @@ static inline struct msm_gpu *dev_to_gpu(struct device *dev)  	return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);  } +static inline bool +adreno_smmu_has_prr(struct msm_gpu *gpu) +{ +	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(&gpu->pdev->dev); + +	if (!adreno_smmu) +		return false; + +	return adreno_smmu && adreno_smmu->set_prr_addr; +} +  /* It turns out that all targets use the same ringbuffer size */  #define MSM_GPU_RINGBUFFER_SZ SZ_32K  #define MSM_GPU_RINGBUFFER_BLKSIZE 32 diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 0e18619f96cb..a188617653e8 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -338,6 +338,8 @@ msm_iommu_pagetable_prealloc_allocate(struct msm_mmu *mmu, struct msm_mmu_preall  	ret = kmem_cache_alloc_bulk(pt_cache, GFP_KERNEL, p->count, p->pages);  	if (ret != p->count) { +		kfree(p->pages); +		p->pages = NULL;  		p->count = ret;  		return -ENOMEM;  	} @@ -351,6 +353,9 @@ msm_iommu_pagetable_prealloc_cleanup(struct msm_mmu *mmu, struct msm_mmu_preallo  	struct kmem_cache *pt_cache = get_pt_cache(mmu);  	uint32_t remaining_pt_count = p->count - p->ptr; +	if (!p->pages) +		return; +  	if (p->count > 0)  		trace_msm_mmu_prealloc_cleanup(p->count, remaining_pt_count); diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c b/drivers/gpu/drm/nouveau/nouveau_sched.c index e60f7892f5ce..a7bf539e5d86 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sched.c +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c @@ -482,6 +482,17 @@ nouveau_sched_create(struct nouveau_sched **psched, struct nouveau_drm *drm,  	return 0;  } +static bool +nouveau_sched_job_list_empty(struct nouveau_sched *sched) +{ +	bool empty; + +	spin_lock(&sched->job.list.lock); +	empty = list_empty(&sched->job.list.head); +	spin_unlock(&sched->job.list.lock); + +	return empty; +}  static void  nouveau_sched_fini(struct nouveau_sched *sched) @@ -489,8 +500,7 @@ nouveau_sched_fini(struct nouveau_sched *sched)  	struct drm_gpu_scheduler *drm_sched = &sched->base;  	struct drm_sched_entity *entity = &sched->entity; -	rmb(); /* for list_empty to work without lock */ -	wait_event(sched->job.wq, list_empty(&sched->job.list.head)); +	wait_event(sched->job.wq, nouveau_sched_job_list_empty(sched));  	drm_sched_entity_fini(entity);  	drm_sched_fini(drm_sched); diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c index 2fc7b0779b37..893af9b16756 100644 --- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c +++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c @@ -359,7 +359,7 @@ static int kingdisplay_panel_probe(struct mipi_dsi_device *dsi)  	dsi->lanes = 4;  	dsi->format = MIPI_DSI_FMT_RGB888;  	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | -			  MIPI_DSI_MODE_LPM; +			  MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET;  	kingdisplay = devm_drm_panel_alloc(&dsi->dev, __typeof(*kingdisplay), base,  					   &kingdisplay_panel_funcs, diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c index 04d91929eedd..d5f821d6b23c 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7789v.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7789v.c @@ -249,6 +249,11 @@ static const struct drm_display_mode default_mode = {  	.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,  }; +/* + * The mode data for this panel has been reverse engineered without access + * to the panel datasheet / manual. Using DRM_MODE_FLAG_PHSYNC like all + * other panels results in garbage data on the display. + */  static const struct drm_display_mode t28cp45tn89_mode = {  	.clock = 6008,  	.hdisplay = 240, @@ -261,7 +266,7 @@ static const struct drm_display_mode t28cp45tn89_mode = {  	.vtotal = 320 + 8 + 4 + 4,  	.width_mm = 43,  	.height_mm = 57, -	.flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC, +	.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,  };  static const struct drm_display_mode et028013dma_mode = { diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 88e821d67af7..9c8907bc61d9 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -314,17 +314,17 @@ static int radeon_pci_probe(struct pci_dev *pdev,  	ret = pci_enable_device(pdev);  	if (ret) -		goto err_free; +		return ret;  	pci_set_drvdata(pdev, ddev);  	ret = radeon_driver_load_kms(ddev, flags);  	if (ret) -		goto err_agp; +		goto err;  	ret = drm_dev_register(ddev, flags);  	if (ret) -		goto err_agp; +		goto err;  	if (rdev->mc.real_vram_size <= (8 * 1024 * 1024))  		format = drm_format_info(DRM_FORMAT_C8); @@ -337,30 +337,14 @@ static int radeon_pci_probe(struct pci_dev *pdev,  	return 0; -err_agp: +err:  	pci_disable_device(pdev); -err_free: -	drm_dev_put(ddev);  	return ret;  }  static void -radeon_pci_remove(struct pci_dev *pdev) -{ -	struct drm_device *dev = pci_get_drvdata(pdev); - -	drm_put_dev(dev); -} - -static void  radeon_pci_shutdown(struct pci_dev *pdev)  { -	/* if we are running in a VM, make sure the device -	 * torn down properly on reboot/shutdown -	 */ -	if (radeon_device_is_virtual()) -		radeon_pci_remove(pdev); -  #if defined(CONFIG_PPC64) || defined(CONFIG_MACH_LOONGSON64)  	/*  	 * Some adapters need to be suspended before a @@ -613,7 +597,6 @@ static struct pci_driver radeon_kms_pci_driver = {  	.name = DRIVER_NAME,  	.id_table = pciidlist,  	.probe = radeon_pci_probe, -	.remove = radeon_pci_remove,  	.shutdown = radeon_pci_shutdown,  	.driver.pm = &radeon_pm_ops,  }; diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 645e33bf7947..ba1446acd703 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -84,7 +84,6 @@ void radeon_driver_unload_kms(struct drm_device *dev)  	rdev->agp = NULL;  done_free: -	kfree(rdev);  	dev->dev_private = NULL;  } diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 5a4697f636f2..c8e949f4a568 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -70,6 +70,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,  	entity->guilty = guilty;  	entity->num_sched_list = num_sched_list;  	entity->priority = priority; +	entity->last_user = current->group_leader;  	/*  	 * It's perfectly valid to initialize an entity without having a valid  	 * scheduler attached. It's just not valid to use the scheduler before it @@ -302,7 +303,7 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)  	/* For a killed process disallow further enqueueing of jobs. */  	last_user = cmpxchg(&entity->last_user, current->group_leader, NULL); -	if ((!last_user || last_user == current->group_leader) && +	if (last_user == current->group_leader &&  	    (current->flags & PF_EXITING) && (current->exit_code == SIGKILL))  		drm_sched_entity_kill(entity); @@ -552,10 +553,11 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)  		drm_sched_rq_remove_entity(entity->rq, entity);  		entity->rq = rq;  	} -	spin_unlock(&entity->lock);  	if (entity->num_sched_list == 1)  		entity->sched_list = NULL; + +	spin_unlock(&entity->lock);  }  /** diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 3e0ad7e5b5df..6d3db5e55d98 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -813,12 +813,16 @@ static int gt_reset(struct xe_gt *gt)  	unsigned int fw_ref;  	int err; -	if (xe_device_wedged(gt_to_xe(gt))) -		return -ECANCELED; +	if (xe_device_wedged(gt_to_xe(gt))) { +		err = -ECANCELED; +		goto err_pm_put; +	}  	/* We only support GT resets with GuC submission */ -	if (!xe_device_uc_enabled(gt_to_xe(gt))) -		return -ENODEV; +	if (!xe_device_uc_enabled(gt_to_xe(gt))) { +		err = -ENODEV; +		goto err_pm_put; +	}  	xe_gt_info(gt, "reset started\n"); @@ -826,8 +830,6 @@ static int gt_reset(struct xe_gt *gt)  	if (!err)  		xe_gt_warn(gt, "reset block failed to get lifted"); -	xe_pm_runtime_get(gt_to_xe(gt)); -  	if (xe_fault_inject_gt_reset()) {  		err = -ECANCELED;  		goto err_fail; @@ -874,6 +876,7 @@ err_fail:  	xe_gt_err(gt, "reset failed (%pe)\n", ERR_PTR(err));  	xe_device_declare_wedged(gt_to_xe(gt)); +err_pm_put:  	xe_pm_runtime_put(gt_to_xe(gt));  	return err; @@ -895,7 +898,9 @@ void xe_gt_reset_async(struct xe_gt *gt)  		return;  	xe_gt_info(gt, "reset queued\n"); -	queue_work(gt->ordered_wq, >->reset.worker); +	xe_pm_runtime_get_noresume(gt_to_xe(gt)); +	if (!queue_work(gt->ordered_wq, >->reset.worker)) +		xe_pm_runtime_put(gt_to_xe(gt));  }  void xe_gt_suspend_prepare(struct xe_gt *gt) diff --git a/drivers/gpu/drm/xe/xe_validation.h b/drivers/gpu/drm/xe/xe_validation.h index fec331d791e7..b2d09c596714 100644 --- a/drivers/gpu/drm/xe/xe_validation.h +++ b/drivers/gpu/drm/xe/xe_validation.h @@ -166,10 +166,10 @@ xe_validation_device_init(struct xe_validation_device *val)   */  DEFINE_CLASS(xe_validation, struct xe_validation_ctx *,  	     if (_T) xe_validation_ctx_fini(_T);, -	     ({_ret = xe_validation_ctx_init(_ctx, _val, _exec, _flags); -	       _ret ? NULL : _ctx; }), +	     ({*_ret = xe_validation_ctx_init(_ctx, _val, _exec, _flags); +	       *_ret ? NULL : _ctx; }),  	     struct xe_validation_ctx *_ctx, struct xe_validation_device *_val, -	     struct drm_exec *_exec, const struct xe_val_flags _flags, int _ret); +	     struct drm_exec *_exec, const struct xe_val_flags _flags, int *_ret);  static inline void *class_xe_validation_lock_ptr(class_xe_validation_t *_T)  {return *_T; }  #define class_xe_validation_is_conditional true @@ -186,7 +186,7 @@ static inline void *class_xe_validation_lock_ptr(class_xe_validation_t *_T)   * exhaustive eviction.   */  #define xe_validation_guard(_ctx, _val, _exec, _flags, _ret)		\ -	scoped_guard(xe_validation, _ctx, _val, _exec, _flags, _ret) \ +	scoped_guard(xe_validation, _ctx, _val, _exec, _flags, &_ret) \  	drm_exec_until_all_locked(_exec)  #endif diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c index ecd9a0bd5e18..49b57bb5fac1 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c +++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c @@ -290,9 +290,15 @@ static int ch_ipsec_xfrm_add_state(struct net_device *dev,  		return -EINVAL;  	} +	if (unlikely(!try_module_get(THIS_MODULE))) { +		NL_SET_ERR_MSG_MOD(extack, "Failed to acquire module reference"); +		return -ENODEV; +	} +  	sa_entry = kzalloc(sizeof(*sa_entry), GFP_KERNEL);  	if (!sa_entry) {  		res = -ENOMEM; +		module_put(THIS_MODULE);  		goto out;  	} @@ -301,7 +307,6 @@ static int ch_ipsec_xfrm_add_state(struct net_device *dev,  		sa_entry->esn = 1;  	ch_ipsec_setkey(x, sa_entry);  	x->xso.offload_handle = (unsigned long)sa_entry; -	try_module_get(THIS_MODULE);  out:  	return res;  } diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h index ea09a09c451b..2097e4c2b3d7 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h @@ -17,6 +17,7 @@  #define HBG_PCU_CACHE_LINE_SIZE		32  #define HBG_TX_TIMEOUT_BUF_LEN		1024  #define HBG_RX_DESCR			0x01 +#define HBG_NO_PHY			0xFF  #define HBG_PACKET_HEAD_SIZE	((HBG_RX_SKIP1 + HBG_RX_SKIP2 + \  				  HBG_RX_DESCR) * HBG_PCU_CACHE_LINE_SIZE) diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c index 83cf75bf7a17..e11495b7ee98 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_err.c @@ -136,12 +136,11 @@ static pci_ers_result_t hbg_pci_err_detected(struct pci_dev *pdev,  {  	struct net_device *netdev = pci_get_drvdata(pdev); -	netif_device_detach(netdev); - -	if (state == pci_channel_io_perm_failure) +	if (state == pci_channel_io_perm_failure) { +		netif_device_detach(netdev);  		return PCI_ERS_RESULT_DISCONNECT; +	} -	pci_disable_device(pdev);  	return PCI_ERS_RESULT_NEED_RESET;  } @@ -150,6 +149,9 @@ static pci_ers_result_t hbg_pci_err_slot_reset(struct pci_dev *pdev)  	struct net_device *netdev = pci_get_drvdata(pdev);  	struct hbg_priv *priv = netdev_priv(netdev); +	netif_device_detach(netdev); +	pci_disable_device(pdev); +  	if (pci_enable_device(pdev)) {  		dev_err(&pdev->dev,  			"failed to re-enable PCI device after reset\n"); diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c index d0aa0661ecd4..d6e8ce8e351a 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_hw.c @@ -244,6 +244,9 @@ void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex)  	hbg_hw_mac_enable(priv, HBG_STATUS_ENABLE); +	if (priv->mac.phy_addr == HBG_NO_PHY) +		return; +  	/* wait MAC link up */  	ret = readl_poll_timeout(priv->io_base + HBG_REG_AN_NEG_STATE_ADDR,  				 link_status, diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c index 8af0bc4cca21..ae4cb35186d8 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_irq.c @@ -32,6 +32,7 @@ static void hbg_irq_handle_rx_buf_val(struct hbg_priv *priv,  				      const struct hbg_irq_info *irq_info)  {  	priv->stats.rx_fifo_less_empty_thrsld_cnt++; +	hbg_hw_irq_enable(priv, irq_info->mask, true);  }  #define HBG_IRQ_I(name, handle) \ diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c index 37791de47f6f..b6f0a2780ea8 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c @@ -20,7 +20,6 @@  #define HBG_MDIO_OP_INTERVAL_US		(5 * 1000)  #define HBG_NP_LINK_FAIL_RETRY_TIMES	5 -#define HBG_NO_PHY			0xFF  static void hbg_mdio_set_command(struct hbg_mac *mac, u32 cmd)  { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 9d34d28ff168..782bb48c9f3d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -9429,8 +9429,7 @@ static int hclge_mii_ioctl(struct hclge_dev *hdev, struct ifreq *ifr, int cmd)  		/* this command reads phy id and register at the same time */  		fallthrough;  	case SIOCGMIIREG: -		data->val_out = hclge_read_phy_reg(hdev, data->reg_num); -		return 0; +		return hclge_read_phy_reg(hdev, data->reg_num, &data->val_out);  	case SIOCSMIIREG:  		return hclge_write_phy_reg(hdev, data->reg_num, data->val_in); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c index 96553109f44c..cf881108fa57 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c @@ -274,7 +274,7 @@ void hclge_mac_stop_phy(struct hclge_dev *hdev)  	phy_stop(phydev);  } -u16 hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr) +int hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr, u16 *val)  {  	struct hclge_phy_reg_cmd *req;  	struct hclge_desc desc; @@ -286,11 +286,14 @@ u16 hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr)  	req->reg_addr = cpu_to_le16(reg_addr);  	ret = hclge_cmd_send(&hdev->hw, &desc, 1); -	if (ret) +	if (ret) {  		dev_err(&hdev->pdev->dev,  			"failed to read phy reg, ret = %d.\n", ret); +		return ret; +	} -	return le16_to_cpu(req->reg_val); +	*val = le16_to_cpu(req->reg_val); +	return 0;  }  int hclge_write_phy_reg(struct hclge_dev *hdev, u16 reg_addr, u16 val) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h index 4200d0b6d931..21d434c82475 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.h @@ -13,7 +13,7 @@ int hclge_mac_connect_phy(struct hnae3_handle *handle);  void hclge_mac_disconnect_phy(struct hnae3_handle *handle);  void hclge_mac_start_phy(struct hclge_dev *hdev);  void hclge_mac_stop_phy(struct hclge_dev *hdev); -u16 hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr); +int hclge_read_phy_reg(struct hclge_dev *hdev, u16 reg_addr, u16 *val);  int hclge_write_phy_reg(struct hclge_dev *hdev, u16 reg_addr, u16 val);  #endif diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 2250426ec91b..2532b6f82e97 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -4382,6 +4382,15 @@ int ice_get_phy_lane_number(struct ice_hw *hw)  	unsigned int lane;  	int err; +	/* E82X does not have sequential IDs, lane number is PF ID. +	 * For E825 device, the exception is the variant with external +	 * PHY (0x579F), in which there is also 1:1 pf_id -> lane_number +	 * mapping. +	 */ +	if (hw->mac_type == ICE_MAC_GENERIC || +	    hw->device_id == ICE_DEV_ID_E825C_SGMII) +		return hw->pf_id; +  	options = kcalloc(ICE_AQC_PORT_OPT_MAX, sizeof(*options), GFP_KERNEL);  	if (!options)  		return -ENOMEM; @@ -6497,6 +6506,28 @@ u32 ice_get_link_speed(u16 index)  }  /** + * ice_get_dest_cgu - get destination CGU dev for given HW + * @hw: pointer to the HW struct + * + * Get CGU client id for CGU register read/write operations. + * + * Return: CGU device id to use in SBQ transactions. + */ +static enum ice_sbq_dev_id ice_get_dest_cgu(struct ice_hw *hw) +{ +	/* On dual complex E825 only complex 0 has functional CGU powering all +	 * the PHYs. +	 * SBQ destination device cgu points to CGU on a current complex and to +	 * access primary CGU from the secondary complex, the driver should use +	 * cgu_peer as a destination device. +	 */ +	if (hw->mac_type == ICE_MAC_GENERIC_3K_E825 && ice_is_dual(hw) && +	    !ice_is_primary(hw)) +		return ice_sbq_dev_cgu_peer; +	return ice_sbq_dev_cgu; +} + +/**   * ice_read_cgu_reg - Read a CGU register   * @hw: Pointer to the HW struct   * @addr: Register address to read @@ -6510,8 +6541,8 @@ u32 ice_get_link_speed(u16 index)  int ice_read_cgu_reg(struct ice_hw *hw, u32 addr, u32 *val)  {  	struct ice_sbq_msg_input cgu_msg = { +		.dest_dev = ice_get_dest_cgu(hw),  		.opcode = ice_sbq_msg_rd, -		.dest_dev = ice_sbq_dev_cgu,  		.msg_addr_low = addr  	};  	int err; @@ -6542,8 +6573,8 @@ int ice_read_cgu_reg(struct ice_hw *hw, u32 addr, u32 *val)  int ice_write_cgu_reg(struct ice_hw *hw, u32 addr, u32 val)  {  	struct ice_sbq_msg_input cgu_msg = { +		.dest_dev = ice_get_dest_cgu(hw),  		.opcode = ice_sbq_msg_wr, -		.dest_dev = ice_sbq_dev_cgu,  		.msg_addr_low = addr,  		.data = val  	}; diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c index 363ae79a3620..013c93b6605e 100644 --- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c +++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c @@ -1479,7 +1479,7 @@ static void ice_init_prof_masks(struct ice_hw *hw, enum ice_block blk)  	per_pf = ICE_PROF_MASK_COUNT / hw->dev_caps.num_funcs;  	hw->blk[blk].masks.count = per_pf; -	hw->blk[blk].masks.first = hw->pf_id * per_pf; +	hw->blk[blk].masks.first = hw->logical_pf_id * per_pf;  	memset(hw->blk[blk].masks.masks, 0, sizeof(hw->blk[blk].masks.masks)); diff --git a/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h b/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h index 183dd5457d6a..21bb861febbf 100644 --- a/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h +++ b/drivers/net/ethernet/intel/ice/ice_sbq_cmd.h @@ -50,6 +50,7 @@ enum ice_sbq_dev_id {  	ice_sbq_dev_phy_0	= 0x02,  	ice_sbq_dev_cgu		= 0x06,  	ice_sbq_dev_phy_0_peer	= 0x0D, +	ice_sbq_dev_cgu_peer	= 0x0F,  };  enum ice_sbq_msg_opcode { diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index f8a208c84f15..10e2445e0ded 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -2281,7 +2281,7 @@ static int igb_get_sset_count(struct net_device *netdev, int sset)  	case ETH_SS_PRIV_FLAGS:  		return IGB_PRIV_FLAGS_STR_LEN;  	default: -		return -ENOTSUPP; +		return -EOPNOTSUPP;  	}  } diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index f3e7218ba6f3..bb783042d1af 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -810,7 +810,7 @@ static int igc_ethtool_get_sset_count(struct net_device *netdev, int sset)  	case ETH_SS_PRIV_FLAGS:  		return IGC_PRIV_FLAGS_STR_LEN;  	default: -		return -ENOTSUPP; +		return -EOPNOTSUPP;  	}  } @@ -2094,6 +2094,9 @@ static void igc_ethtool_diag_test(struct net_device *netdev,  		netdev_info(adapter->netdev, "Offline testing starting");  		set_bit(__IGC_TESTING, &adapter->state); +		/* power up PHY for link test */ +		igc_power_up_phy_copper(&adapter->hw); +  		/* Link test performed before hardware reset so autoneg doesn't  		 * interfere with test result  		 */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index ca1ccc630001..3190ce7e44c7 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -11507,10 +11507,10 @@ static int ixgbe_recovery_probe(struct ixgbe_adapter *adapter)  shutdown_aci:  	mutex_destroy(&adapter->hw.aci.lock);  	ixgbe_release_hw_control(adapter); -	devlink_free(adapter->devlink);  clean_up_probe:  	disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state);  	free_netdev(netdev); +	devlink_free(adapter->devlink);  	pci_release_mem_regions(pdev);  	if (disable_dev)  		pci_disable_device(pdev); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 114dd88fc71c..6885d2343c48 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -641,7 +641,7 @@ static int ixgbe_ptp_feature_enable(struct ptp_clock_info *ptp,  	 * disabled  	 */  	if (rq->type != PTP_CLK_REQ_PPS || !adapter->ptp_setup_sdp) -		return -ENOTSUPP; +		return -EOPNOTSUPP;  	if (on)  		adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c index d7a11ff9bbdb..da2d1eb52c13 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c @@ -320,7 +320,6 @@ err_dma_unmap:  err_free:  	kfree(buf);  err_out: -	priv_rx->rq_stats->tls_resync_req_skip++;  	return err;  } @@ -339,14 +338,19 @@ static void resync_handle_work(struct work_struct *work)  	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags))) {  		mlx5e_ktls_priv_rx_put(priv_rx); +		priv_rx->rq_stats->tls_resync_req_skip++; +		tls_offload_rx_resync_async_request_cancel(&resync->core);  		return;  	}  	c = resync->priv->channels.c[priv_rx->rxq];  	sq = &c->async_icosq; -	if (resync_post_get_progress_params(sq, priv_rx)) +	if (resync_post_get_progress_params(sq, priv_rx)) { +		priv_rx->rq_stats->tls_resync_req_skip++; +		tls_offload_rx_resync_async_request_cancel(&resync->core);  		mlx5e_ktls_priv_rx_put(priv_rx); +	}  }  static void resync_init(struct mlx5e_ktls_rx_resync_ctx *resync, @@ -425,14 +429,21 @@ void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,  {  	struct mlx5e_ktls_rx_resync_buf *buf = wi->tls_get_params.buf;  	struct mlx5e_ktls_offload_context_rx *priv_rx; +	struct tls_offload_resync_async *async_resync; +	struct tls_offload_context_rx *rx_ctx;  	u8 tracker_state, auth_state, *ctx;  	struct device *dev;  	u32 hw_seq;  	priv_rx = buf->priv_rx;  	dev = mlx5_core_dma_dev(sq->channel->mdev); -	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags))) +	rx_ctx = tls_offload_ctx_rx(tls_get_ctx(priv_rx->sk)); +	async_resync = rx_ctx->resync_async; +	if (unlikely(test_bit(MLX5E_PRIV_RX_FLAG_DELETING, priv_rx->flags))) { +		priv_rx->rq_stats->tls_resync_req_skip++; +		tls_offload_rx_resync_async_request_cancel(async_resync);  		goto out; +	}  	dma_sync_single_for_cpu(dev, buf->dma_addr, PROGRESS_PARAMS_PADDED_SIZE,  				DMA_FROM_DEVICE); @@ -443,11 +454,13 @@ void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,  	if (tracker_state != MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING ||  	    auth_state != MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD) {  		priv_rx->rq_stats->tls_resync_req_skip++; +		tls_offload_rx_resync_async_request_cancel(async_resync);  		goto out;  	}  	hw_seq = MLX5_GET(tls_progress_params, ctx, hw_resync_tcp_sn); -	tls_offload_rx_resync_async_request_end(priv_rx->sk, cpu_to_be32(hw_seq)); +	tls_offload_rx_resync_async_request_end(async_resync, +						cpu_to_be32(hw_seq));  	priv_rx->rq_stats->tls_resync_req_end++;  out:  	mlx5e_ktls_priv_rx_put(priv_rx); @@ -472,8 +485,10 @@ static bool resync_queue_get_psv(struct sock *sk)  	resync = &priv_rx->resync;  	mlx5e_ktls_priv_rx_get(priv_rx); -	if (unlikely(!queue_work(resync->priv->tls->rx_wq, &resync->work))) +	if (unlikely(!queue_work(resync->priv->tls->rx_wq, &resync->work))) {  		mlx5e_ktls_priv_rx_put(priv_rx); +		return false; +	}  	return true;  } @@ -482,6 +497,7 @@ static bool resync_queue_get_psv(struct sock *sk)  static void resync_update_sn(struct mlx5e_rq *rq, struct sk_buff *skb)  {  	struct ethhdr *eth = (struct ethhdr *)(skb->data); +	struct tls_offload_resync_async *resync_async;  	struct net_device *netdev = rq->netdev;  	struct net *net = dev_net(netdev);  	struct sock *sk = NULL; @@ -527,7 +543,8 @@ static void resync_update_sn(struct mlx5e_rq *rq, struct sk_buff *skb)  	seq = th->seq;  	datalen = skb->len - depth; -	tls_offload_rx_resync_async_request_start(sk, seq, datalen); +	resync_async = tls_offload_ctx_rx(tls_get_ctx(sk))->resync_async; +	tls_offload_rx_resync_async_request_start(resync_async, seq, datalen);  	rq->stats->tls_resync_req_start++;  unref: @@ -556,6 +573,18 @@ void mlx5e_ktls_rx_resync(struct net_device *netdev, struct sock *sk,  	resync_handle_seq_match(priv_rx, c);  } +void +mlx5e_ktls_rx_resync_async_request_cancel(struct mlx5e_icosq_wqe_info *wi) +{ +	struct mlx5e_ktls_offload_context_rx *priv_rx; +	struct mlx5e_ktls_rx_resync_buf *buf; + +	buf = wi->tls_get_params.buf; +	priv_rx = buf->priv_rx; +	priv_rx->rq_stats->tls_resync_req_skip++; +	tls_offload_rx_resync_async_request_cancel(&priv_rx->resync.core); +} +  /* End of resync section */  void mlx5e_ktls_handle_rx_skb(struct mlx5e_rq *rq, struct sk_buff *skb, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h index f87b65c560ea..cb08799769ee 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h @@ -29,6 +29,10 @@ void mlx5e_ktls_handle_get_psv_completion(struct mlx5e_icosq_wqe_info *wi,  void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq,  					   struct mlx5e_tx_wqe_info *wi,  					   u32 *dma_fifo_cc); + +void +mlx5e_ktls_rx_resync_async_request_cancel(struct mlx5e_icosq_wqe_info *wi); +  static inline bool  mlx5e_ktls_tx_try_handle_resync_dump_comp(struct mlx5e_txqsq *sq,  					  struct mlx5e_tx_wqe_info *wi, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 1c79adc51a04..26621a2972ec 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -1036,6 +1036,10 @@ int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)  				netdev_WARN_ONCE(cq->netdev,  						 "Bad OP in ICOSQ CQE: 0x%x\n",  						 get_cqe_opcode(cqe)); +#ifdef CONFIG_MLX5_EN_TLS +				if (wi->wqe_type == MLX5E_ICOSQ_WQE_GET_PSV_TLS) +					mlx5e_ktls_rx_resync_async_request_cancel(wi); +#endif  				mlx5e_dump_error_cqe(&sq->cq, sq->sqn,  						     (struct mlx5_err_cqe *)cqe);  				mlx5_wq_cyc_wqe_dump(&sq->wq, ci, wi->num_wqebbs); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c index 76382626ad41..929adeb50a98 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c @@ -66,7 +66,6 @@ static void esw_destroy_legacy_fdb_table(struct mlx5_eswitch *esw)  	esw->fdb_table.legacy.addr_grp = NULL;  	esw->fdb_table.legacy.allmulti_grp = NULL;  	esw->fdb_table.legacy.promisc_grp = NULL; -	atomic64_set(&esw->user_count, 0);  }  static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 34749814f19b..44a142a041b2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -1978,7 +1978,6 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)  	/* Holds true only as long as DMFS is the default */  	mlx5_flow_namespace_set_mode(esw->fdb_table.offloads.ns,  				     MLX5_FLOW_STEERING_MODE_DMFS); -	atomic64_set(&esw->user_count, 0);  }  static int esw_get_nr_ft_offloads_steering_src_ports(struct mlx5_eswitch *esw) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 132626a3f9f7..9ef72f294117 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -2557,14 +2557,16 @@ nfp_net_alloc(struct pci_dev *pdev, const struct nfp_dev_info *dev_info,  	err = nfp_net_tlv_caps_parse(&nn->pdev->dev, nn->dp.ctrl_bar,  				     &nn->tlv_caps);  	if (err) -		goto err_free_nn; +		goto err_free_xsk_pools;  	err = nfp_ccm_mbox_alloc(nn);  	if (err) -		goto err_free_nn; +		goto err_free_xsk_pools;  	return nn; +err_free_xsk_pools: +	kfree(nn->dp.xsk_pools);  err_free_nn:  	if (nn->dp.netdev)  		free_netdev(nn->dp.netdev); diff --git a/drivers/net/ethernet/sfc/mae.c b/drivers/net/ethernet/sfc/mae.c index 6fd0c1e9a7d5..7cfd9000f79d 100644 --- a/drivers/net/ethernet/sfc/mae.c +++ b/drivers/net/ethernet/sfc/mae.c @@ -1090,6 +1090,9 @@ void efx_mae_remove_mport(void *desc, void *arg)  	kfree(mport);  } +/* + * Takes ownership of @desc, even if it returns an error + */  static int efx_mae_process_mport(struct efx_nic *efx,  				 struct mae_mport_desc *desc)  { @@ -1100,6 +1103,7 @@ static int efx_mae_process_mport(struct efx_nic *efx,  	if (!IS_ERR_OR_NULL(mport)) {  		netif_err(efx, drv, efx->net_dev,  			  "mport with id %u does exist!!!\n", desc->mport_id); +		kfree(desc);  		return -EEXIST;  	} diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 650d75b73e0b..7b90ecd3a55e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -4089,18 +4089,11 @@ static int stmmac_release(struct net_device *dev)  static bool stmmac_vlan_insert(struct stmmac_priv *priv, struct sk_buff *skb,  			       struct stmmac_tx_queue *tx_q)  { -	u16 tag = 0x0, inner_tag = 0x0; -	u32 inner_type = 0x0;  	struct dma_desc *p; +	u16 tag = 0x0; -	if (!priv->dma_cap.vlins) +	if (!priv->dma_cap.vlins || !skb_vlan_tag_present(skb))  		return false; -	if (!skb_vlan_tag_present(skb)) -		return false; -	if (skb->vlan_proto == htons(ETH_P_8021AD)) { -		inner_tag = skb_vlan_tag_get(skb); -		inner_type = STMMAC_VLAN_INSERT; -	}  	tag = skb_vlan_tag_get(skb); @@ -4109,7 +4102,7 @@ static bool stmmac_vlan_insert(struct stmmac_priv *priv, struct sk_buff *skb,  	else  		p = &tx_q->dma_tx[tx_q->cur_tx]; -	if (stmmac_set_desc_vlan_tag(priv, p, tag, inner_tag, inner_type)) +	if (stmmac_set_desc_vlan_tag(priv, p, tag, 0x0, 0x0))  		return false;  	stmmac_set_tx_owner(priv, p); @@ -4507,6 +4500,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)  	bool has_vlan, set_ic;  	int entry, first_tx;  	dma_addr_t des; +	u32 sdu_len;  	tx_q = &priv->dma_conf.tx_queue[queue];  	txq_stats = &priv->xstats.txq_stats[queue]; @@ -4524,10 +4518,15 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)  	}  	if (priv->est && priv->est->enable && -	    priv->est->max_sdu[queue] && -	    skb->len > priv->est->max_sdu[queue]){ -		priv->xstats.max_sdu_txq_drop[queue]++; -		goto max_sdu_err; +	    priv->est->max_sdu[queue]) { +		sdu_len = skb->len; +		/* Add VLAN tag length if VLAN tag insertion offload is requested */ +		if (priv->dma_cap.vlins && skb_vlan_tag_present(skb)) +			sdu_len += VLAN_HLEN; +		if (sdu_len > priv->est->max_sdu[queue]) { +			priv->xstats.max_sdu_txq_drop[queue]++; +			goto max_sdu_err; +		}  	}  	if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) { @@ -7573,11 +7572,8 @@ int stmmac_dvr_probe(struct device *device,  		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;  		ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;  	} -	if (priv->dma_cap.vlins) { +	if (priv->dma_cap.vlins)  		ndev->features |= NETIF_F_HW_VLAN_CTAG_TX; -		if (priv->dma_cap.dvlan) -			ndev->features |= NETIF_F_HW_VLAN_STAG_TX; -	}  #endif  	priv->msg_enable = netif_msg_init(debug, default_msg_level); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index 97e89a604abd..3b4d4696afe9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -981,7 +981,7 @@ static int tc_taprio_configure(struct stmmac_priv *priv,  	if (qopt->cmd == TAPRIO_CMD_DESTROY)  		goto disable; -	if (qopt->num_entries >= dep) +	if (qopt->num_entries > dep)  		return -EINVAL;  	if (!qopt->cycle_time)  		return -ERANGE; @@ -1012,7 +1012,7 @@ static int tc_taprio_configure(struct stmmac_priv *priv,  		s64 delta_ns = qopt->entries[i].interval;  		u32 gates = qopt->entries[i].gate_mask; -		if (delta_ns > GENMASK(wid, 0)) +		if (delta_ns > GENMASK(wid - 1, 0))  			return -ERANGE;  		if (gates > GENMASK(31 - wid, 0))  			return -ERANGE; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c index 0b6f6228ae35..ff02a79c00d4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c @@ -212,7 +212,7 @@ static void vlan_enable(struct mac_device_info *hw, u32 type)  	value = readl(ioaddr + VLAN_INCL);  	value |= VLAN_VLTI; -	value |= VLAN_CSVL; /* Only use SVLAN */ +	value &= ~VLAN_CSVL; /* Only use CVLAN */  	value &= ~VLAN_VLC;  	value |= (type << VLAN_VLC_SHIFT) & VLAN_VLC;  	writel(value, ioaddr + VLAN_INCL); diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c index 36ccc53b1797..ef860cfc629f 100644 --- a/drivers/net/mctp/mctp-usb.c +++ b/drivers/net/mctp/mctp-usb.c @@ -96,11 +96,13 @@ static netdev_tx_t mctp_usb_start_xmit(struct sk_buff *skb,  			  skb->data, skb->len,  			  mctp_usb_out_complete, skb); +	/* Stops TX queue first to prevent race condition with URB complete */ +	netif_stop_queue(dev);  	rc = usb_submit_urb(urb, GFP_ATOMIC); -	if (rc) +	if (rc) { +		netif_wake_queue(dev);  		goto err_drop; -	else -		netif_stop_queue(dev); +	}  	return NETDEV_TX_OK; diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 194570443493..5d8d0214786c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -886,8 +886,11 @@ static ssize_t userdatum_value_show(struct config_item *item, char *buf)  static void update_userdata(struct netconsole_target *nt)  { -	int complete_idx = 0, child_count = 0;  	struct list_head *entry; +	int child_count = 0; +	unsigned long flags; + +	spin_lock_irqsave(&target_list_lock, flags);  	/* Clear the current string in case the last userdatum was deleted */  	nt->userdata_length = 0; @@ -897,8 +900,11 @@ static void update_userdata(struct netconsole_target *nt)  		struct userdatum *udm_item;  		struct config_item *item; -		if (WARN_ON_ONCE(child_count >= MAX_EXTRADATA_ITEMS)) -			break; +		if (child_count >= MAX_EXTRADATA_ITEMS) { +			spin_unlock_irqrestore(&target_list_lock, flags); +			WARN_ON_ONCE(1); +			return; +		}  		child_count++;  		item = container_of(entry, struct config_item, ci_entry); @@ -912,12 +918,11 @@ static void update_userdata(struct netconsole_target *nt)  		 * one entry length (1/MAX_EXTRADATA_ITEMS long), entry count is  		 * checked to not exceed MAX items with child_count above  		 */ -		complete_idx += scnprintf(&nt->extradata_complete[complete_idx], -					  MAX_EXTRADATA_ENTRY_LEN, " %s=%s\n", -					  item->ci_name, udm_item->value); +		nt->userdata_length += scnprintf(&nt->extradata_complete[nt->userdata_length], +						 MAX_EXTRADATA_ENTRY_LEN, " %s=%s\n", +						 item->ci_name, udm_item->value);  	} -	nt->userdata_length = strnlen(nt->extradata_complete, -				      sizeof(nt->extradata_complete)); +	spin_unlock_irqrestore(&target_list_lock, flags);  }  static ssize_t userdatum_value_store(struct config_item *item, const char *buf, diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index deeefb962566..36a0c1b7f59c 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -738,6 +738,12 @@ static int dp83867_config_init(struct phy_device *phydev)  			return ret;  	} +	/* Although the DP83867 reports EEE capability through the +	 * MDIO_PCS_EEE_ABLE and MDIO_AN_EEE_ADV registers, the feature +	 * is not actually implemented in hardware. +	 */ +	phy_disable_eee(phydev); +  	if (phy_interface_is_rgmii(phydev) ||  	    phydev->interface == PHY_INTERFACE_MODE_SGMII) {  		val = phy_read(phydev, MII_DP83867_PHYCTRL); diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c index a2cd1cc35cde..1f381d7b13ff 100644 --- a/drivers/net/phy/dp83869.c +++ b/drivers/net/phy/dp83869.c @@ -84,7 +84,7 @@  #define DP83869_CLK_DELAY_DEF			7  /* STRAP_STS1 bits */ -#define DP83869_STRAP_OP_MODE_MASK		GENMASK(2, 0) +#define DP83869_STRAP_OP_MODE_MASK		GENMASK(11, 9)  #define DP83869_STRAP_STS1_RESERVED		BIT(11)  #define DP83869_STRAP_MIRROR_ENABLED           BIT(12) @@ -528,7 +528,7 @@ static int dp83869_set_strapped_mode(struct phy_device *phydev)  	if (val < 0)  		return val; -	dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK; +	dp83869->mode = FIELD_GET(DP83869_STRAP_OP_MODE_MASK, val);  	return 0;  } diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 85bd5d845409..232bbd79a4de 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -230,7 +230,9 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)  	int i;  	unsigned long gpio_bits = dev->driver_info->data; -	usbnet_get_endpoints(dev,intf); +	ret = usbnet_get_endpoints(dev, intf); +	if (ret) +		goto out;  	/* Toggle the GPIOs in a manufacturer/model specific way */  	for (i = 2; i >= 0; i--) { @@ -848,7 +850,9 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)  	dev->driver_priv = priv; -	usbnet_get_endpoints(dev, intf); +	ret = usbnet_get_endpoints(dev, intf); +	if (ret) +		return ret;  	/* Maybe the boot loader passed the MAC address via device tree */  	if (!eth_platform_get_mac_address(&dev->udev->dev, buf)) { @@ -1281,7 +1285,9 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)  	int ret;  	u8 buf[ETH_ALEN] = {0}; -	usbnet_get_endpoints(dev,intf); +	ret = usbnet_get_endpoints(dev, intf); +	if (ret) +		return ret;  	/* Get the MAC address */  	ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index bf01f2728531..697cd9d866d3 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1659,6 +1659,8 @@ void usbnet_disconnect (struct usb_interface *intf)  	net = dev->net;  	unregister_netdev (net); +	cancel_work_sync(&dev->kevent); +  	while ((urb = usb_get_from_anchor(&dev->deferred))) {  		dev_kfree_skb(urb->context);  		kfree(urb->sg); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a757cbcab87f..8e8a179aaa49 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1379,9 +1379,14 @@ static struct sk_buff *virtnet_receive_xsk_merge(struct net_device *dev, struct  	ret = XDP_PASS;  	rcu_read_lock();  	prog = rcu_dereference(rq->xdp_prog); -	/* TODO: support multi buffer. */ -	if (prog && num_buf == 1) -		ret = virtnet_xdp_handler(prog, xdp, dev, xdp_xmit, stats); +	if (prog) { +		/* TODO: support multi buffer. */ +		if (num_buf == 1) +			ret = virtnet_xdp_handler(prog, xdp, dev, xdp_xmit, +						  stats); +		else +			ret = XDP_ABORTED; +	}  	rcu_read_unlock();  	switch (ret) { diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index e595b0979a56..b3b00d324075 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1937,6 +1937,7 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)  	if (cmd_id == WMI_CMD_UNSUPPORTED) {  		ath10k_warn(ar, "wmi command %d is not supported by firmware\n",  			    cmd_id); +		dev_kfree_skb_any(skb);  		return ret;  	} diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 2810752260f2..812686173ac8 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -912,42 +912,84 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {  static const struct dmi_system_id ath11k_pm_quirk_table[] = {  	{  		.driver_data = (void *)ATH11K_PM_WOW, -		.matches = { +		.matches = { /* X13 G4 AMD #1 */ +			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), +			DMI_MATCH(DMI_PRODUCT_NAME, "21J3"), +		}, +	}, +	{ +		.driver_data = (void *)ATH11K_PM_WOW, +		.matches = { /* X13 G4 AMD #2 */  			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),  			DMI_MATCH(DMI_PRODUCT_NAME, "21J4"),  		},  	},  	{  		.driver_data = (void *)ATH11K_PM_WOW, -		.matches = { +		.matches = { /* T14 G4 AMD #1 */ +			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), +			DMI_MATCH(DMI_PRODUCT_NAME, "21K3"), +		}, +	}, +	{ +		.driver_data = (void *)ATH11K_PM_WOW, +		.matches = { /* T14 G4 AMD #2 */  			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),  			DMI_MATCH(DMI_PRODUCT_NAME, "21K4"),  		},  	},  	{  		.driver_data = (void *)ATH11K_PM_WOW, -		.matches = { +		.matches = { /* P14s G4 AMD #1 */ +			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), +			DMI_MATCH(DMI_PRODUCT_NAME, "21K5"), +		}, +	}, +	{ +		.driver_data = (void *)ATH11K_PM_WOW, +		.matches = { /* P14s G4 AMD #2 */  			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),  			DMI_MATCH(DMI_PRODUCT_NAME, "21K6"),  		},  	},  	{  		.driver_data = (void *)ATH11K_PM_WOW, -		.matches = { +		.matches = { /* T16 G2 AMD #1 */ +			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), +			DMI_MATCH(DMI_PRODUCT_NAME, "21K7"), +		}, +	}, +	{ +		.driver_data = (void *)ATH11K_PM_WOW, +		.matches = { /* T16 G2 AMD #2 */  			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),  			DMI_MATCH(DMI_PRODUCT_NAME, "21K8"),  		},  	},  	{  		.driver_data = (void *)ATH11K_PM_WOW, -		.matches = { +		.matches = { /* P16s G2 AMD #1 */ +			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), +			DMI_MATCH(DMI_PRODUCT_NAME, "21K9"), +		}, +	}, +	{ +		.driver_data = (void *)ATH11K_PM_WOW, +		.matches = { /* P16s G2 AMD #2 */  			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),  			DMI_MATCH(DMI_PRODUCT_NAME, "21KA"),  		},  	},  	{  		.driver_data = (void *)ATH11K_PM_WOW, -		.matches = { +		.matches = { /* T14s G4 AMD #1 */ +			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), +			DMI_MATCH(DMI_PRODUCT_NAME, "21F8"), +		}, +	}, +	{ +		.driver_data = (void *)ATH11K_PM_WOW, +		.matches = { /* T14s G4 AMD #2 */  			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),  			DMI_MATCH(DMI_PRODUCT_NAME, "21F9"),  		}, diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 106e2530b64e..0e41b5a91d66 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -1,7 +1,7 @@  // SPDX-License-Identifier: BSD-3-Clause-Clear  /*   * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.   */  #include <net/mac80211.h> @@ -4417,9 +4417,9 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  	}  	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) -		flags |= WMI_KEY_PAIRWISE; +		flags = WMI_KEY_PAIRWISE;  	else -		flags |= WMI_KEY_GROUP; +		flags = WMI_KEY_GROUP;  	ath11k_dbg(ar->ab, ATH11K_DBG_MAC,  		   "%s for peer %pM on vdev %d flags 0x%X, type = %d, num_sta %d\n", @@ -4456,7 +4456,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  	is_ap_with_no_sta = (vif->type == NL80211_IFTYPE_AP &&  			     !arvif->num_stations); -	if ((flags & WMI_KEY_PAIRWISE) || cmd == SET_KEY || is_ap_with_no_sta) { +	if (flags == WMI_KEY_PAIRWISE || cmd == SET_KEY || is_ap_with_no_sta) {  		ret = ath11k_install_key(arvif, key, cmd, peer_addr, flags);  		if (ret) {  			ath11k_warn(ab, "ath11k_install_key failed (%d)\n", ret); @@ -4470,7 +4470,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  			goto exit;  		} -		if ((flags & WMI_KEY_GROUP) && cmd == SET_KEY && is_ap_with_no_sta) +		if (flags == WMI_KEY_GROUP && cmd == SET_KEY && is_ap_with_no_sta)  			arvif->reinstall_group_keys = true;  	} diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 1d7b60aa5cb0..eacab798630a 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -8290,23 +8290,32 @@ static void ath12k_mgmt_over_wmi_tx_drop(struct ath12k *ar, struct sk_buff *skb)  		wake_up(&ar->txmgmt_empty_waitq);  } -int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) +static void ath12k_mac_tx_mgmt_free(struct ath12k *ar, int buf_id)  { -	struct sk_buff *msdu = skb; +	struct sk_buff *msdu;  	struct ieee80211_tx_info *info; -	struct ath12k *ar = ctx; -	struct ath12k_base *ab = ar->ab;  	spin_lock_bh(&ar->txmgmt_idr_lock); -	idr_remove(&ar->txmgmt_idr, buf_id); +	msdu = idr_remove(&ar->txmgmt_idr, buf_id);  	spin_unlock_bh(&ar->txmgmt_idr_lock); -	dma_unmap_single(ab->dev, ATH12K_SKB_CB(msdu)->paddr, msdu->len, + +	if (!msdu) +		return; + +	dma_unmap_single(ar->ab->dev, ATH12K_SKB_CB(msdu)->paddr, msdu->len,  			 DMA_TO_DEVICE);  	info = IEEE80211_SKB_CB(msdu);  	memset(&info->status, 0, sizeof(info->status)); -	ath12k_mgmt_over_wmi_tx_drop(ar, skb); +	ath12k_mgmt_over_wmi_tx_drop(ar, msdu); +} + +int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) +{ +	struct ath12k *ar = ctx; + +	ath12k_mac_tx_mgmt_free(ar, buf_id);  	return 0;  } @@ -8315,17 +8324,10 @@ static int ath12k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx)  {  	struct ieee80211_vif *vif = ctx;  	struct ath12k_skb_cb *skb_cb = ATH12K_SKB_CB(skb); -	struct sk_buff *msdu = skb;  	struct ath12k *ar = skb_cb->ar; -	struct ath12k_base *ab = ar->ab; -	if (skb_cb->vif == vif) { -		spin_lock_bh(&ar->txmgmt_idr_lock); -		idr_remove(&ar->txmgmt_idr, buf_id); -		spin_unlock_bh(&ar->txmgmt_idr_lock); -		dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, -				 DMA_TO_DEVICE); -	} +	if (skb_cb->vif == vif) +		ath12k_mac_tx_mgmt_free(ar, buf_id);  	return 0;  } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 8afaffe31031..bb96b87b2a6e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -5627,8 +5627,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,  			  *cookie, le16_to_cpu(action_frame->len),  			  le32_to_cpu(af_params->channel)); -		ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg), -						  af_params); +		ack = brcmf_p2p_send_action_frame(vif->ifp, af_params);  		cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,  					GFP_KERNEL); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c index 0dc9d28cd77b..e1752a513c73 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -1529,6 +1529,7 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,  /**   * brcmf_p2p_tx_action_frame() - send action frame over fil.   * + * @ifp: interface to transmit on.   * @p2p: p2p info struct for vif.   * @af_params: action frame data/info.   * @@ -1538,12 +1539,11 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,   * The WLC_E_ACTION_FRAME_COMPLETE event will be received when the action   * frame is transmitted.   */ -static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, +static s32 brcmf_p2p_tx_action_frame(struct brcmf_if *ifp, +				     struct brcmf_p2p_info *p2p,  				     struct brcmf_fil_af_params_le *af_params)  {  	struct brcmf_pub *drvr = p2p->cfg->pub; -	struct brcmf_cfg80211_vif *vif; -	struct brcmf_p2p_action_frame *p2p_af;  	s32 err = 0;  	brcmf_dbg(TRACE, "Enter\n"); @@ -1552,14 +1552,7 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p,  	clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status);  	clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status); -	/* check if it is a p2p_presence response */ -	p2p_af = (struct brcmf_p2p_action_frame *)af_params->action_frame.data; -	if (p2p_af->subtype == P2P_AF_PRESENCE_RSP) -		vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif; -	else -		vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; - -	err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params, +	err = brcmf_fil_bsscfg_data_set(ifp, "actframe", af_params,  					sizeof(*af_params));  	if (err) {  		bphy_err(drvr, " sending action frame has failed\n"); @@ -1711,16 +1704,14 @@ static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell,  /**   * brcmf_p2p_send_action_frame() - send action frame .   * - * @cfg: driver private data for cfg80211 interface. - * @ndev: net device to transmit on. + * @ifp: interface to transmit on.   * @af_params: configuration data for action frame.   */ -bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, -				 struct net_device *ndev, +bool brcmf_p2p_send_action_frame(struct brcmf_if *ifp,  				 struct brcmf_fil_af_params_le *af_params)  { +	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;  	struct brcmf_p2p_info *p2p = &cfg->p2p; -	struct brcmf_if *ifp = netdev_priv(ndev);  	struct brcmf_fil_action_frame_le *action_frame;  	struct brcmf_config_af_params config_af_params;  	struct afx_hdl *afx_hdl = &p2p->afx_hdl; @@ -1857,7 +1848,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg,  		if (af_params->channel)  			msleep(P2P_AF_RETRY_DELAY_TIME); -		ack = !brcmf_p2p_tx_action_frame(p2p, af_params); +		ack = !brcmf_p2p_tx_action_frame(ifp, p2p, af_params);  		tx_retry++;  		dwell_overflow = brcmf_p2p_check_dwell_overflow(requested_dwell,  								dwell_jiffies); @@ -2217,7 +2208,6 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,  	WARN_ON(p2p_ifp->bsscfgidx != bsscfgidx); -	init_completion(&p2p->send_af_done);  	INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);  	init_completion(&p2p->afx_hdl.act_frm_scan);  	init_completion(&p2p->wait_next_af); @@ -2513,6 +2503,8 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)  	pri_ifp = brcmf_get_ifp(cfg->pub, 0);  	p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif; +	init_completion(&p2p->send_af_done); +  	if (p2pdev_forced) {  		err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL);  		if (IS_ERR(err_ptr)) { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h index d2ecee565bf2..d3137ebd7158 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h @@ -168,8 +168,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,  int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,  					const struct brcmf_event_msg *e,  					void *data); -bool brcmf_p2p_send_action_frame(struct brcmf_cfg80211_info *cfg, -				 struct net_device *ndev, +bool brcmf_p2p_send_action_frame(struct brcmf_if *ifp,  				 struct brcmf_fil_af_params_le *af_params);  bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,  					   struct brcmf_bss_info_le *bi); diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.c b/drivers/net/wireless/intel/iwlwifi/mld/link.c index 738f80fe0c50..60d814bf5779 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/link.c @@ -501,6 +501,7 @@ void iwl_mld_remove_link(struct iwl_mld *mld,  	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif);  	struct iwl_mld_link *link = iwl_mld_link_from_mac80211(bss_conf);  	bool is_deflink = link == &mld_vif->deflink; +	u8 fw_id = link->fw_id;  	if (WARN_ON(!link || link->active))  		return; @@ -513,10 +514,10 @@ void iwl_mld_remove_link(struct iwl_mld *mld,  	RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL); -	if (WARN_ON(link->fw_id >= mld->fw->ucode_capa.num_links)) +	if (WARN_ON(fw_id >= mld->fw->ucode_capa.num_links))  		return; -	RCU_INIT_POINTER(mld->fw_id_to_bss_conf[link->fw_id], NULL); +	RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);  }  void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld, diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index c916176bd9f0..72fb675a696f 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1042,7 +1042,7 @@ static blk_status_t nvme_map_data(struct request *req)  	return nvme_pci_setup_data_prp(req, &iter);  } -static blk_status_t nvme_pci_setup_meta_sgls(struct request *req) +static blk_status_t nvme_pci_setup_meta_iter(struct request *req)  {  	struct nvme_queue *nvmeq = req->mq_hctx->driver_data;  	unsigned int entries = req->nr_integrity_segments; @@ -1072,8 +1072,12 @@ static blk_status_t nvme_pci_setup_meta_sgls(struct request *req)  	 * descriptor provides an explicit length, so we're relying on that  	 * mechanism to catch any misunderstandings between the application and  	 * device. +	 * +	 * P2P DMA also needs to use the blk_dma_iter method, so mptr setup +	 * leverages this routine when that happens.  	 */ -	if (entries == 1 && !(nvme_req(req)->flags & NVME_REQ_USERCMD)) { +	if (!nvme_ctrl_meta_sgl_supported(&dev->ctrl) || +	    (entries == 1 && !(nvme_req(req)->flags & NVME_REQ_USERCMD))) {  		iod->cmd.common.metadata = cpu_to_le64(iter.addr);  		iod->meta_total_len = iter.len;  		iod->meta_dma = iter.addr; @@ -1114,6 +1118,9 @@ static blk_status_t nvme_pci_setup_meta_mptr(struct request *req)  	struct nvme_queue *nvmeq = req->mq_hctx->driver_data;  	struct bio_vec bv = rq_integrity_vec(req); +	if (is_pci_p2pdma_page(bv.bv_page)) +		return nvme_pci_setup_meta_iter(req); +  	iod->meta_dma = dma_map_bvec(nvmeq->dev->dev, &bv, rq_dma_dir(req), 0);  	if (dma_mapping_error(nvmeq->dev->dev, iod->meta_dma))  		return BLK_STS_IOERR; @@ -1128,7 +1135,7 @@ static blk_status_t nvme_map_metadata(struct request *req)  	if ((iod->cmd.common.flags & NVME_CMD_SGL_METABUF) &&  	    nvme_pci_metadata_use_sgls(req)) -		return nvme_pci_setup_meta_sgls(req); +		return nvme_pci_setup_meta_iter(req);  	return nvme_pci_setup_meta_mptr(req);  } diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c index b340380f3892..ceba21684e82 100644 --- a/drivers/nvme/target/auth.c +++ b/drivers/nvme/target/auth.c @@ -298,7 +298,7 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response,  	const char *hash_name;  	u8 *challenge = req->sq->dhchap_c1;  	struct nvme_dhchap_key *transformed_key; -	u8 buf[4]; +	u8 buf[4], sc_c = ctrl->concat ? 1 : 0;  	int ret;  	hash_name = nvme_auth_hmac_name(ctrl->shash_id); @@ -367,13 +367,14 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response,  	ret = crypto_shash_update(shash, buf, 2);  	if (ret)  		goto out; -	memset(buf, 0, 4); +	*buf = sc_c;  	ret = crypto_shash_update(shash, buf, 1);  	if (ret)  		goto out;  	ret = crypto_shash_update(shash, "HostHost", 8);  	if (ret)  		goto out; +	memset(buf, 0, 4);  	ret = crypto_shash_update(shash, ctrl->hostnqn, strlen(ctrl->hostnqn));  	if (ret)  		goto out; diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index 6948824642dc..c48a20602d7f 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -247,6 +247,7 @@ struct qcom_pcie_ops {  	int (*get_resources)(struct qcom_pcie *pcie);  	int (*init)(struct qcom_pcie *pcie);  	int (*post_init)(struct qcom_pcie *pcie); +	void (*host_post_init)(struct qcom_pcie *pcie);  	void (*deinit)(struct qcom_pcie *pcie);  	void (*ltssm_enable)(struct qcom_pcie *pcie);  	int (*config_sid)(struct qcom_pcie *pcie); @@ -1038,6 +1039,25 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)  	return 0;  } +static int qcom_pcie_enable_aspm(struct pci_dev *pdev, void *userdata) +{ +	/* +	 * Downstream devices need to be in D0 state before enabling PCI PM +	 * substates. +	 */ +	pci_set_power_state_locked(pdev, PCI_D0); +	pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL); + +	return 0; +} + +static void qcom_pcie_host_post_init_2_7_0(struct qcom_pcie *pcie) +{ +	struct dw_pcie_rp *pp = &pcie->pci->pp; + +	pci_walk_bus(pp->bridge->bus, qcom_pcie_enable_aspm, NULL); +} +  static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie)  {  	struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0; @@ -1312,9 +1332,19 @@ static void qcom_pcie_host_deinit(struct dw_pcie_rp *pp)  	pcie->cfg->ops->deinit(pcie);  } +static void qcom_pcie_host_post_init(struct dw_pcie_rp *pp) +{ +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); +	struct qcom_pcie *pcie = to_qcom_pcie(pci); + +	if (pcie->cfg->ops->host_post_init) +		pcie->cfg->ops->host_post_init(pcie); +} +  static const struct dw_pcie_host_ops qcom_pcie_dw_ops = {  	.init		= qcom_pcie_host_init,  	.deinit		= qcom_pcie_host_deinit, +	.post_init	= qcom_pcie_host_post_init,  };  /* Qcom IP rev.: 2.1.0	Synopsys IP rev.: 4.01a */ @@ -1376,6 +1406,7 @@ static const struct qcom_pcie_ops ops_1_9_0 = {  	.get_resources = qcom_pcie_get_resources_2_7_0,  	.init = qcom_pcie_init_2_7_0,  	.post_init = qcom_pcie_post_init_2_7_0, +	.host_post_init = qcom_pcie_host_post_init_2_7_0,  	.deinit = qcom_pcie_deinit_2_7_0,  	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,  	.config_sid = qcom_pcie_config_sid_1_9_0, @@ -1386,6 +1417,7 @@ static const struct qcom_pcie_ops ops_1_21_0 = {  	.get_resources = qcom_pcie_get_resources_2_7_0,  	.init = qcom_pcie_init_2_7_0,  	.post_init = qcom_pcie_post_init_2_7_0, +	.host_post_init = qcom_pcie_host_post_init_2_7_0,  	.deinit = qcom_pcie_deinit_2_7_0,  	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,  }; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4a8735b275e4..3645f392a9fd 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1604,7 +1604,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, struct list_head *realloc_head)  		pbus_size_io(bus, realloc_head ? 0 : additional_io_size,  			     additional_io_size, realloc_head); -		if (pref) { +		if (pref && (pref->flags & IORESOURCE_PREFETCH)) {  			pbus_size_mem(bus,  				      IORESOURCE_MEM | IORESOURCE_PREFETCH |  				      (pref->flags & IORESOURCE_MEM_64), diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index 022d98f3c32a..ea9c4058ee6a 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -1613,6 +1613,8 @@ static int setup_feedback_loop(struct device *dev, struct device_node *np,  				step /= r1;  				new[j].min = min; +				new[j].min_sel = desc->linear_ranges[j].min_sel; +				new[j].max_sel = desc->linear_ranges[j].max_sel;  				new[j].step = step;  				dev_dbg(dev, "%s: old range min %d, step %d\n", diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index cc5d05dc395c..17173239301e 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -611,8 +611,9 @@ int scsi_host_busy(struct Scsi_Host *shost)  {  	int cnt = 0; -	blk_mq_tagset_busy_iter(&shost->tag_set, -				scsi_host_check_in_flight, &cnt); +	if (shost->tag_set.ops) +		blk_mq_tagset_busy_iter(&shost->tag_set, +					scsi_host_check_in_flight, &cnt);  	return cnt;  }  EXPORT_SYMBOL(scsi_host_busy); diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 746ff6a1f309..1c13812a3f03 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -554,9 +554,9 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)  		 * happened, even if someone else gets the sense data.  		 */  		if (sshdr.asc == 0x28) -			scmd->device->ua_new_media_ctr++; +			atomic_inc(&sdev->ua_new_media_ctr);  		else if (sshdr.asc == 0x29) -			scmd->device->ua_por_ctr++; +			atomic_inc(&sdev->ua_por_ctr);  	}  	if (scsi_sense_is_deferred(&sshdr)) diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c index 7765fb27c37c..b8c572394aac 100644 --- a/drivers/spi/spi-intel-pci.c +++ b/drivers/spi/spi-intel-pci.c @@ -80,6 +80,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = {  	{ PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info },  	{ PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info },  	{ PCI_VDEVICE(INTEL, 0x5794), (unsigned long)&cnl_info }, +	{ PCI_VDEVICE(INTEL, 0x5825), (unsigned long)&cnl_info },  	{ PCI_VDEVICE(INTEL, 0x7723), (unsigned long)&cnl_info },  	{ PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info },  	{ PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 8339fec975b9..9ca27de4767a 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -4282,8 +4282,8 @@ int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,  			get, UIC_GET_ATTR_ID(attr_sel),  			UFS_UIC_COMMAND_RETRIES - retries); -	if (mib_val && !ret) -		*mib_val = uic_cmd.argument3; +	if (mib_val) +		*mib_val = ret == 0 ? uic_cmd.argument3 : 0;  	if (peer && (hba->quirks & UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE)  	    && pwr_mode_change) @@ -4999,7 +4999,7 @@ EXPORT_SYMBOL_GPL(ufshcd_hba_enable);  static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer)  { -	int tx_lanes = 0, i, err = 0; +	int tx_lanes, i, err = 0;  	if (!peer)  		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), @@ -6673,6 +6673,20 @@ static void ufshcd_err_handler(struct work_struct *work)  		 hba->saved_uic_err, hba->force_reset,  		 ufshcd_is_link_broken(hba) ? "; link is broken" : ""); +	/* +	 * Use ufshcd_rpm_get_noresume() here to safely perform link recovery +	 * even if an error occurs during runtime suspend or runtime resume. +	 * This avoids potential deadlocks that could happen if we tried to +	 * resume the device while a PM operation is already in progress. +	 */ +	ufshcd_rpm_get_noresume(hba); +	if (hba->pm_op_in_progress) { +		ufshcd_link_recovery(hba); +		ufshcd_rpm_put(hba); +		return; +	} +	ufshcd_rpm_put(hba); +  	down(&hba->host_sem);  	spin_lock_irqsave(hba->host->host_lock, flags);  	if (ufshcd_err_handling_should_stop(hba)) { @@ -6684,14 +6698,6 @@ static void ufshcd_err_handler(struct work_struct *work)  	}  	spin_unlock_irqrestore(hba->host->host_lock, flags); -	ufshcd_rpm_get_noresume(hba); -	if (hba->pm_op_in_progress) { -		ufshcd_link_recovery(hba); -		ufshcd_rpm_put(hba); -		return; -	} -	ufshcd_rpm_put(hba); -  	ufshcd_err_handling_prepare(hba);  	spin_lock_irqsave(hba->host->host_lock, flags); diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 916cad80941c..5167bec14e36 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -38,6 +38,7 @@  #include <linux/workqueue.h>  #include <linux/notifier.h>  #include <linux/mm_inline.h> +#include <linux/overflow.h>  #include "vfio.h"  #define DRIVER_VERSION  "0.2" @@ -167,12 +168,14 @@ static struct vfio_dma *vfio_find_dma(struct vfio_iommu *iommu,  {  	struct rb_node *node = iommu->dma_list.rb_node; +	WARN_ON(!size); +  	while (node) {  		struct vfio_dma *dma = rb_entry(node, struct vfio_dma, node); -		if (start + size <= dma->iova) +		if (start + size - 1 < dma->iova)  			node = node->rb_left; -		else if (start >= dma->iova + dma->size) +		else if (start > dma->iova + dma->size - 1)  			node = node->rb_right;  		else  			return dma; @@ -182,16 +185,19 @@ static struct vfio_dma *vfio_find_dma(struct vfio_iommu *iommu,  }  static struct rb_node *vfio_find_dma_first_node(struct vfio_iommu *iommu, -						dma_addr_t start, u64 size) +						dma_addr_t start, +						dma_addr_t end)  {  	struct rb_node *res = NULL;  	struct rb_node *node = iommu->dma_list.rb_node;  	struct vfio_dma *dma_res = NULL; +	WARN_ON(end < start); +  	while (node) {  		struct vfio_dma *dma = rb_entry(node, struct vfio_dma, node); -		if (start < dma->iova + dma->size) { +		if (start <= dma->iova + dma->size - 1) {  			res = node;  			dma_res = dma;  			if (start >= dma->iova) @@ -201,7 +207,7 @@ static struct rb_node *vfio_find_dma_first_node(struct vfio_iommu *iommu,  			node = node->rb_right;  		}  	} -	if (res && size && dma_res->iova >= start + size) +	if (res && dma_res->iova > end)  		res = NULL;  	return res;  } @@ -211,11 +217,13 @@ static void vfio_link_dma(struct vfio_iommu *iommu, struct vfio_dma *new)  	struct rb_node **link = &iommu->dma_list.rb_node, *parent = NULL;  	struct vfio_dma *dma; +	WARN_ON(new->size != 0); +  	while (*link) {  		parent = *link;  		dma = rb_entry(parent, struct vfio_dma, node); -		if (new->iova + new->size <= dma->iova) +		if (new->iova <= dma->iova)  			link = &(*link)->rb_left;  		else  			link = &(*link)->rb_right; @@ -895,14 +903,20 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data,  	unsigned long remote_vaddr;  	struct vfio_dma *dma;  	bool do_accounting; +	dma_addr_t iova_end; +	size_t iova_size; -	if (!iommu || !pages) +	if (!iommu || !pages || npage <= 0)  		return -EINVAL;  	/* Supported for v2 version only */  	if (!iommu->v2)  		return -EACCES; +	if (check_mul_overflow(npage, PAGE_SIZE, &iova_size) || +	    check_add_overflow(user_iova, iova_size - 1, &iova_end)) +		return -EOVERFLOW; +  	mutex_lock(&iommu->lock);  	if (WARN_ONCE(iommu->vaddr_invalid_count, @@ -1008,12 +1022,21 @@ static void vfio_iommu_type1_unpin_pages(void *iommu_data,  {  	struct vfio_iommu *iommu = iommu_data;  	bool do_accounting; +	dma_addr_t iova_end; +	size_t iova_size;  	int i;  	/* Supported for v2 version only */  	if (WARN_ON(!iommu->v2))  		return; +	if (WARN_ON(npage <= 0)) +		return; + +	if (WARN_ON(check_mul_overflow(npage, PAGE_SIZE, &iova_size) || +		    check_add_overflow(user_iova, iova_size - 1, &iova_end))) +		return; +  	mutex_lock(&iommu->lock);  	do_accounting = list_empty(&iommu->domain_list); @@ -1067,7 +1090,7 @@ static long vfio_sync_unpin(struct vfio_dma *dma, struct vfio_domain *domain,  #define VFIO_IOMMU_TLB_SYNC_MAX		512  static size_t unmap_unpin_fast(struct vfio_domain *domain, -			       struct vfio_dma *dma, dma_addr_t *iova, +			       struct vfio_dma *dma, dma_addr_t iova,  			       size_t len, phys_addr_t phys, long *unlocked,  			       struct list_head *unmapped_list,  			       int *unmapped_cnt, @@ -1077,18 +1100,17 @@ static size_t unmap_unpin_fast(struct vfio_domain *domain,  	struct vfio_regions *entry = kzalloc(sizeof(*entry), GFP_KERNEL);  	if (entry) { -		unmapped = iommu_unmap_fast(domain->domain, *iova, len, +		unmapped = iommu_unmap_fast(domain->domain, iova, len,  					    iotlb_gather);  		if (!unmapped) {  			kfree(entry);  		} else { -			entry->iova = *iova; +			entry->iova = iova;  			entry->phys = phys;  			entry->len  = unmapped;  			list_add_tail(&entry->list, unmapped_list); -			*iova += unmapped;  			(*unmapped_cnt)++;  		}  	} @@ -1107,18 +1129,17 @@ static size_t unmap_unpin_fast(struct vfio_domain *domain,  }  static size_t unmap_unpin_slow(struct vfio_domain *domain, -			       struct vfio_dma *dma, dma_addr_t *iova, +			       struct vfio_dma *dma, dma_addr_t iova,  			       size_t len, phys_addr_t phys,  			       long *unlocked)  { -	size_t unmapped = iommu_unmap(domain->domain, *iova, len); +	size_t unmapped = iommu_unmap(domain->domain, iova, len);  	if (unmapped) { -		*unlocked += vfio_unpin_pages_remote(dma, *iova, +		*unlocked += vfio_unpin_pages_remote(dma, iova,  						     phys >> PAGE_SHIFT,  						     unmapped >> PAGE_SHIFT,  						     false); -		*iova += unmapped;  		cond_resched();  	}  	return unmapped; @@ -1127,12 +1148,12 @@ static size_t unmap_unpin_slow(struct vfio_domain *domain,  static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,  			     bool do_accounting)  { -	dma_addr_t iova = dma->iova, end = dma->iova + dma->size;  	struct vfio_domain *domain, *d;  	LIST_HEAD(unmapped_region_list);  	struct iommu_iotlb_gather iotlb_gather;  	int unmapped_region_cnt = 0;  	long unlocked = 0; +	size_t pos = 0;  	if (!dma->size)  		return 0; @@ -1156,13 +1177,14 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,  	}  	iommu_iotlb_gather_init(&iotlb_gather); -	while (iova < end) { +	while (pos < dma->size) {  		size_t unmapped, len;  		phys_addr_t phys, next; +		dma_addr_t iova = dma->iova + pos;  		phys = iommu_iova_to_phys(domain->domain, iova);  		if (WARN_ON(!phys)) { -			iova += PAGE_SIZE; +			pos += PAGE_SIZE;  			continue;  		} @@ -1171,7 +1193,7 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,  		 * may require hardware cache flushing, try to find the  		 * largest contiguous physical memory chunk to unmap.  		 */ -		for (len = PAGE_SIZE; iova + len < end; len += PAGE_SIZE) { +		for (len = PAGE_SIZE; pos + len < dma->size; len += PAGE_SIZE) {  			next = iommu_iova_to_phys(domain->domain, iova + len);  			if (next != phys + len)  				break; @@ -1181,16 +1203,18 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,  		 * First, try to use fast unmap/unpin. In case of failure,  		 * switch to slow unmap/unpin path.  		 */ -		unmapped = unmap_unpin_fast(domain, dma, &iova, len, phys, +		unmapped = unmap_unpin_fast(domain, dma, iova, len, phys,  					    &unlocked, &unmapped_region_list,  					    &unmapped_region_cnt,  					    &iotlb_gather);  		if (!unmapped) { -			unmapped = unmap_unpin_slow(domain, dma, &iova, len, +			unmapped = unmap_unpin_slow(domain, dma, iova, len,  						    phys, &unlocked);  			if (WARN_ON(!unmapped))  				break;  		} + +		pos += unmapped;  	}  	dma->iommu_mapped = false; @@ -1282,7 +1306,7 @@ static int update_user_bitmap(u64 __user *bitmap, struct vfio_iommu *iommu,  }  static int vfio_iova_dirty_bitmap(u64 __user *bitmap, struct vfio_iommu *iommu, -				  dma_addr_t iova, size_t size, size_t pgsize) +				  dma_addr_t iova, dma_addr_t iova_end, size_t pgsize)  {  	struct vfio_dma *dma;  	struct rb_node *n; @@ -1299,8 +1323,8 @@ static int vfio_iova_dirty_bitmap(u64 __user *bitmap, struct vfio_iommu *iommu,  	if (dma && dma->iova != iova)  		return -EINVAL; -	dma = vfio_find_dma(iommu, iova + size - 1, 0); -	if (dma && dma->iova + dma->size != iova + size) +	dma = vfio_find_dma(iommu, iova_end, 1); +	if (dma && dma->iova + dma->size - 1 != iova_end)  		return -EINVAL;  	for (n = rb_first(&iommu->dma_list); n; n = rb_next(n)) { @@ -1309,7 +1333,7 @@ static int vfio_iova_dirty_bitmap(u64 __user *bitmap, struct vfio_iommu *iommu,  		if (dma->iova < iova)  			continue; -		if (dma->iova > iova + size - 1) +		if (dma->iova > iova_end)  			break;  		ret = update_user_bitmap(bitmap, iommu, dma, iova, pgsize); @@ -1374,7 +1398,8 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,  	int ret = -EINVAL, retries = 0;  	unsigned long pgshift;  	dma_addr_t iova = unmap->iova; -	u64 size = unmap->size; +	dma_addr_t iova_end; +	size_t size = unmap->size;  	bool unmap_all = unmap->flags & VFIO_DMA_UNMAP_FLAG_ALL;  	bool invalidate_vaddr = unmap->flags & VFIO_DMA_UNMAP_FLAG_VADDR;  	struct rb_node *n, *first_n; @@ -1387,6 +1412,11 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,  		goto unlock;  	} +	if (iova != unmap->iova || size != unmap->size) { +		ret = -EOVERFLOW; +		goto unlock; +	} +  	pgshift = __ffs(iommu->pgsize_bitmap);  	pgsize = (size_t)1 << pgshift; @@ -1396,10 +1426,15 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,  	if (unmap_all) {  		if (iova || size)  			goto unlock; -		size = U64_MAX; -	} else if (!size || size & (pgsize - 1) || -		   iova + size - 1 < iova || size > SIZE_MAX) { -		goto unlock; +		iova_end = ~(dma_addr_t)0; +	} else { +		if (!size || size & (pgsize - 1)) +			goto unlock; + +		if (check_add_overflow(iova, size - 1, &iova_end)) { +			ret = -EOVERFLOW; +			goto unlock; +		}  	}  	/* When dirty tracking is enabled, allow only min supported pgsize */ @@ -1446,17 +1481,17 @@ again:  		if (dma && dma->iova != iova)  			goto unlock; -		dma = vfio_find_dma(iommu, iova + size - 1, 0); -		if (dma && dma->iova + dma->size != iova + size) +		dma = vfio_find_dma(iommu, iova_end, 1); +		if (dma && dma->iova + dma->size - 1 != iova_end)  			goto unlock;  	}  	ret = 0; -	n = first_n = vfio_find_dma_first_node(iommu, iova, size); +	n = first_n = vfio_find_dma_first_node(iommu, iova, iova_end);  	while (n) {  		dma = rb_entry(n, struct vfio_dma, node); -		if (dma->iova >= iova + size) +		if (dma->iova > iova_end)  			break;  		if (!iommu->v2 && iova > dma->iova) @@ -1648,7 +1683,9 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,  {  	bool set_vaddr = map->flags & VFIO_DMA_MAP_FLAG_VADDR;  	dma_addr_t iova = map->iova; +	dma_addr_t iova_end;  	unsigned long vaddr = map->vaddr; +	unsigned long vaddr_end;  	size_t size = map->size;  	int ret = 0, prot = 0;  	size_t pgsize; @@ -1656,8 +1693,15 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,  	/* Verify that none of our __u64 fields overflow */  	if (map->size != size || map->vaddr != vaddr || map->iova != iova) +		return -EOVERFLOW; + +	if (!size)  		return -EINVAL; +	if (check_add_overflow(iova, size - 1, &iova_end) || +	    check_add_overflow(vaddr, size - 1, &vaddr_end)) +		return -EOVERFLOW; +  	/* READ/WRITE from device perspective */  	if (map->flags & VFIO_DMA_MAP_FLAG_WRITE)  		prot |= IOMMU_WRITE; @@ -1673,13 +1717,7 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,  	WARN_ON((pgsize - 1) & PAGE_MASK); -	if (!size || (size | iova | vaddr) & (pgsize - 1)) { -		ret = -EINVAL; -		goto out_unlock; -	} - -	/* Don't allow IOVA or virtual address wrap */ -	if (iova + size - 1 < iova || vaddr + size - 1 < vaddr) { +	if ((size | iova | vaddr) & (pgsize - 1)) {  		ret = -EINVAL;  		goto out_unlock;  	} @@ -1710,7 +1748,7 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu,  		goto out_unlock;  	} -	if (!vfio_iommu_iova_dma_valid(iommu, iova, iova + size - 1)) { +	if (!vfio_iommu_iova_dma_valid(iommu, iova, iova_end)) {  		ret = -EINVAL;  		goto out_unlock;  	} @@ -1783,12 +1821,12 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,  	for (; n; n = rb_next(n)) {  		struct vfio_dma *dma; -		dma_addr_t iova; +		size_t pos = 0;  		dma = rb_entry(n, struct vfio_dma, node); -		iova = dma->iova; -		while (iova < dma->iova + dma->size) { +		while (pos < dma->size) { +			dma_addr_t iova = dma->iova + pos;  			phys_addr_t phys;  			size_t size; @@ -1804,14 +1842,14 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,  				phys = iommu_iova_to_phys(d->domain, iova);  				if (WARN_ON(!phys)) { -					iova += PAGE_SIZE; +					pos += PAGE_SIZE;  					continue;  				}  				size = PAGE_SIZE;  				p = phys + size;  				i = iova + size; -				while (i < dma->iova + dma->size && +				while (pos + size < dma->size &&  				       p == iommu_iova_to_phys(d->domain, i)) {  					size += PAGE_SIZE;  					p += PAGE_SIZE; @@ -1819,9 +1857,8 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,  				}  			} else {  				unsigned long pfn; -				unsigned long vaddr = dma->vaddr + -						     (iova - dma->iova); -				size_t n = dma->iova + dma->size - iova; +				unsigned long vaddr = dma->vaddr + pos; +				size_t n = dma->size - pos;  				long npage;  				npage = vfio_pin_pages_remote(dma, vaddr, @@ -1852,7 +1889,7 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,  				goto unwind;  			} -			iova += size; +			pos += size;  		}  	} @@ -1869,29 +1906,29 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,  unwind:  	for (; n; n = rb_prev(n)) {  		struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node); -		dma_addr_t iova; +		size_t pos = 0;  		if (dma->iommu_mapped) {  			iommu_unmap(domain->domain, dma->iova, dma->size);  			continue;  		} -		iova = dma->iova; -		while (iova < dma->iova + dma->size) { +		while (pos < dma->size) { +			dma_addr_t iova = dma->iova + pos;  			phys_addr_t phys, p;  			size_t size;  			dma_addr_t i;  			phys = iommu_iova_to_phys(domain->domain, iova);  			if (!phys) { -				iova += PAGE_SIZE; +				pos += PAGE_SIZE;  				continue;  			}  			size = PAGE_SIZE;  			p = phys + size;  			i = iova + size; -			while (i < dma->iova + dma->size && +			while (pos + size < dma->size &&  			       p == iommu_iova_to_phys(domain->domain, i)) {  				size += PAGE_SIZE;  				p += PAGE_SIZE; @@ -2977,7 +3014,8 @@ static int vfio_iommu_type1_dirty_pages(struct vfio_iommu *iommu,  		struct vfio_iommu_type1_dirty_bitmap_get range;  		unsigned long pgshift;  		size_t data_size = dirty.argsz - minsz; -		size_t iommu_pgsize; +		size_t size, iommu_pgsize; +		dma_addr_t iova, iova_end;  		if (!data_size || data_size < sizeof(range))  			return -EINVAL; @@ -2986,14 +3024,24 @@ static int vfio_iommu_type1_dirty_pages(struct vfio_iommu *iommu,  				   sizeof(range)))  			return -EFAULT; -		if (range.iova + range.size < range.iova) +		iova = range.iova; +		size = range.size; + +		if (iova != range.iova || size != range.size) +			return -EOVERFLOW; + +		if (!size)  			return -EINVAL; + +		if (check_add_overflow(iova, size - 1, &iova_end)) +			return -EOVERFLOW; +  		if (!access_ok((void __user *)range.bitmap.data,  			       range.bitmap.size))  			return -EINVAL;  		pgshift = __ffs(range.bitmap.pgsize); -		ret = verify_bitmap_size(range.size >> pgshift, +		ret = verify_bitmap_size(size >> pgshift,  					 range.bitmap.size);  		if (ret)  			return ret; @@ -3007,19 +3055,18 @@ static int vfio_iommu_type1_dirty_pages(struct vfio_iommu *iommu,  			ret = -EINVAL;  			goto out_unlock;  		} -		if (range.iova & (iommu_pgsize - 1)) { +		if (iova & (iommu_pgsize - 1)) {  			ret = -EINVAL;  			goto out_unlock;  		} -		if (!range.size || range.size & (iommu_pgsize - 1)) { +		if (size & (iommu_pgsize - 1)) {  			ret = -EINVAL;  			goto out_unlock;  		}  		if (iommu->dirty_page_tracking)  			ret = vfio_iova_dirty_bitmap(range.bitmap.data, -						     iommu, range.iova, -						     range.size, +						     iommu, iova, iova_end,  						     range.bitmap.pgsize);  		else  			ret = -EINVAL; diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 210fd3ac18a4..56ef1d88e003 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -2614,8 +2614,12 @@ static int aty_init(struct fb_info *info)  		pr_cont("\n");  	}  #endif -	if (par->pll_ops->init_pll) -		par->pll_ops->init_pll(info, &par->pll); +	if (par->pll_ops->init_pll) { +		ret = par->pll_ops->init_pll(info, &par->pll); +		if (ret) +			return ret; +	} +  	if (par->pll_ops->resume_pll)  		par->pll_ops->resume_pll(info, &par->pll); diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c index a9ec7f488522..dc5ad3fcc7be 100644 --- a/drivers/video/fbdev/core/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -79,12 +79,16 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,  				     struct fb_image *image, u8 *buf, u8 *dst)  {  	u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; +	unsigned int charcnt = vc->vc_font.charcount;  	u32 idx = vc->vc_font.width >> 3;  	u8 *src;  	while (cnt--) { -		src = vc->vc_font.data + (scr_readw(s++)& -					  charmask)*cellsize; +		u16 ch = scr_readw(s++) & charmask; + +		if (ch >= charcnt) +			ch = 0; +		src = vc->vc_font.data + (unsigned int)ch * cellsize;  		if (attr) {  			update_attr(buf, src, attr, vc); @@ -112,14 +116,18 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,  				       u8 *dst)  {  	u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; +	unsigned int charcnt = vc->vc_font.charcount;  	u32 shift_low = 0, mod = vc->vc_font.width % 8;  	u32 shift_high = 8;  	u32 idx = vc->vc_font.width >> 3;  	u8 *src;  	while (cnt--) { -		src = vc->vc_font.data + (scr_readw(s++)& -					  charmask)*cellsize; +		u16 ch = scr_readw(s++) & charmask; + +		if (ch >= charcnt) +			ch = 0; +		src = vc->vc_font.data + (unsigned int)ch * cellsize;  		if (attr) {  			update_attr(buf, src, attr, vc); diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 96cc9b389246..9bd3c3814b5c 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2810,6 +2810,25 @@ int fbcon_mode_deleted(struct fb_info *info,  	return found;  } +static void fbcon_delete_mode(struct fb_videomode *m) +{ +	struct fbcon_display *p; + +	for (int i = first_fb_vc; i <= last_fb_vc; i++) { +		p = &fb_display[i]; +		if (p->mode == m) +			p->mode = NULL; +	} +} + +void fbcon_delete_modelist(struct list_head *head) +{ +	struct fb_modelist *modelist; + +	list_for_each_entry(modelist, head, list) +		fbcon_delete_mode(&modelist->mode); +} +  #ifdef CONFIG_VT_HW_CONSOLE_BINDING  static void fbcon_unbind(void)  { diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 53f1719b1ae1..eff757ebbed1 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -544,6 +544,7 @@ static void do_unregister_framebuffer(struct fb_info *fb_info)  		fb_info->pixmap.addr = NULL;  	} +	fbcon_delete_modelist(&fb_info->modelist);  	fb_destroy_modelist(&fb_info->modelist);  	registered_fb[fb_info->node] = NULL;  	num_registered_fb--; diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index cbdb1caf61bd..0b8d23c12b77 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -192,7 +192,7 @@ static unsigned long pvr2fb_map;  #ifdef CONFIG_PVR2_DMA  static unsigned int shdma = PVR2_CASCADE_CHAN; -static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; +static unsigned int pvr2dma = CONFIG_NR_ONCHIP_DMA_CHANNELS;  #endif  static struct fb_videomode pvr2_modedb[] = { diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c index 91d070ef6989..6ff059ee1694 100644 --- a/drivers/video/fbdev/valkyriefb.c +++ b/drivers/video/fbdev/valkyriefb.c @@ -329,11 +329,13 @@ static int __init valkyriefb_init(void)  		if (of_address_to_resource(dp, 0, &r)) {  			printk(KERN_ERR "can't find address for valkyrie\n"); +			of_node_put(dp);  			return 0;  		}  		frame_buffer_phys = r.start;  		cmap_regs_phys = r.start + 0x304000; +		of_node_put(dp);  	}  #endif /* ppc (!CONFIG_MAC) */  | 
