This is the 6.6.50 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmbdPEMACgkQONu9yGCS
 aT5u+hAArItPr5guTO+Tmhde+THdW8rXWKMwLAyqITycwxE/FtApMvwMUnvTlDkm
 SLVHgvkq9gTD+e7grB1dxeBhyl+xHa+HV2GnpvsSnjt4X0UCDobOdzKDLU13AUO5
 nGUYazKP0dAHjuWHq/IRk+OfjDuGmz8SbnYywvOLQ0aN1J3KUSgH/ZBUxU4yBm98
 7fQks6W6KHbnd7DnOGA1ZMV/7zf/0R0W8I/dcoTXqhm2W8+OsE8ccgPVYYO/b1Dx
 viUBgbKY88AQAOh+WhR/YB920V2EdA/NK1t4n0OefAzCX1qBoB8mL2zxKDb5J2T3
 RNXRgutT7gcVAbIklfzf2PE+7yvGk2EZrxG2GnkRtcKOCvSHrH8fvt0dwwWFH9Mu
 26XIPHEsVgfHz3lDuCvOYJWKNr5Rm0u/DC/P/UdhgyPAom7nhxliDyBKS2EiSQRS
 mK7Hly9HqLVzRcBnfxERh1k2vn0+d0bx8iIF35RNq8odsBNK6gKzf3qBnBDUkHFY
 uMGDAb/dHZf0u+8NSAO4zHlnhexEudso+44SFsWZyrtF/Pnt5AwAk2iaqgN/buvP
 KBaBRkCTT2qwpC8wvpF6UqXxlGmcMvdw7zg0hF7dVA1fVdSsFIxfXDZkjFHef0em
 jK8CXrYZEm/bHX9mNWKzsoozjt1mcwmFZ+AV/GnmNTpGvixACkE=
 =vJxG
 -----END PGP SIGNATURE-----

Merge 6.6.50 into android15-6.6-lts

Changes in 6.6.50
	drm/fb-helper: Don't schedule_work() to flush frame buffer during panic()
	drm: panel-orientation-quirks: Add quirk for OrangePi Neo
	scsi: ufs: core: Check LSDBS cap when !mcq
	scsi: ufs: core: Bypass quick recovery if force reset is needed
	btrfs: tree-checker: validate dref root and objectid
	ALSA: hda/generic: Add a helper to mute speakers at suspend/shutdown
	ALSA: hda/conexant: Mute speakers at suspend / shutdown
	ALSA: ump: Transmit RPN/NRPN message at each MSB/LSB data reception
	ALSA: ump: Explicitly reset RPN with Null RPN
	ALSA: seq: ump: Use the common RPN/bank conversion context
	ALSA: seq: ump: Transmit RPN/NRPN message at each MSB/LSB data reception
	ALSA: seq: ump: Explicitly reset RPN with Null RPN
	net/mlx5: DR, Fix 'stack guard page was hit' error in dr_rule
	smb: client: fix FSCTL_GET_REPARSE_POINT against NetApp
	ASoC: amd: yc: Support mic on HP 14-em0002la
	spi: hisi-kunpeng: Add validation for the minimum value of speed_hz
	i2c: Fix conditional for substituting empty ACPI functions
	dma-debug: avoid deadlock between dma debug vs printk and netconsole
	net: usb: qmi_wwan: add MeiG Smart SRM825L
	ASoC: amd: yc: Support mic on Lenovo Thinkpad E14 Gen 6
	ASoC: codecs: ES8326: button detect issue
	mptcp: make pm_remove_addrs_and_subflows static
	mptcp: pm: fix RM_ADDR ID for the initial subflow
	selftests: mptcp: userspace pm create id 0 subflow
	selftests: mptcp: dump userspace addrs list
	selftests: mptcp: userspace pm get addr tests
	selftests: mptcp: declare event macros in mptcp_lib
	selftests: mptcp: join: cannot rm sf if closed
	selftests: mptcp: add explicit test case for remove/readd
	selftests: mptcp: join: check re-using ID of unused ADD_ADDR
	selftests: mptcp: join: check re-adding init endp with != id
	selftests: mptcp: add mptcp_lib_events helper
	selftests: mptcp: join: validate event numbers
	selftests: mptcp: join: check re-re-adding ID 0 signal
	selftests: mptcp: join: test for flush/re-add endpoints
	selftests: mptcp: join: disable get and dump addr checks
	selftests: mptcp: join: stop transfer when check is done (part 2.2)
	mptcp: avoid duplicated SUB_CLOSED events
	mptcp: pr_debug: add missing \n at the end
	drm/amdgpu: Fix uninitialized variable warning in amdgpu_afmt_acr
	drm/amd/display: Assign linear_pitch_alignment even for VM
	drm/amdgpu: fix overflowed array index read warning
	drm/amdgpu/pm: Check the return value of smum_send_msg_to_smc
	drm/amd/pm: fix uninitialized variable warning
	drm/amd/pm: fix uninitialized variable warning for smu8_hwmgr
	drm/amd/pm: fix warning using uninitialized value of max_vid_step
	drm/amd/pm: Fix negative array index read
	drm/amd/pm: fix the Out-of-bounds read warning
	drm/amd/pm: fix uninitialized variable warnings for vega10_hwmgr
	drm/amdgpu: avoid reading vf2pf info size from FB
	drm/amd/display: Check gpio_id before used as array index
	drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6
	drm/amd/display: Check index for aux_rd_interval before using
	drm/amd/display: Add array index check for hdcp ddc access
	drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[]
	drm/amd/display: Check msg_id before processing transcation
	drm/amd/display: Fix Coverity INTERGER_OVERFLOW within construct_integrated_info
	drm/amd/display: Fix Coverity INTEGER_OVERFLOW within dal_gpio_service_create
	drm/amd/display: Spinlock before reading event
	drm/amd/display: Fix Coverity INTEGER_OVERFLOW within decide_fallback_link_setting_max_bw_policy
	drm/amd/display: Ensure index calculation will not overflow
	drm/amd/display: Skip inactive planes within ModeSupportAndSystemConfiguration
	drm/amd/display: Fix index may exceed array range within fpu_update_bw_bounding_box
	drm/amd/amdgpu: Check tbo resource pointer
	drm/amd/pm: fix uninitialized variable warnings for vangogh_ppt
	drm/amdgpu/pm: Fix uninitialized variable warning for smu10
	drm/amdgpu/pm: Fix uninitialized variable agc_btc_response
	drm/amdgpu: Fix the uninitialized variable warning
	drm/amdgpu: Fix out-of-bounds write warning
	drm/amdkfd: Check debug trap enable before write dbg_ev_file
	drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number
	drm/amdgpu: fix ucode out-of-bounds read warning
	drm/amdgpu: fix mc_data out-of-bounds read warning
	drm/amdkfd: Reconcile the definition and use of oem_id in struct kfd_topology_device
	apparmor: fix possible NULL pointer dereference
	wifi: ath12k: initialize 'ret' in ath12k_qmi_load_file_target_mem()
	wifi: ath11k: initialize 'ret' in ath11k_qmi_load_file_target_mem()
	drm/amdgpu/pm: Check input value for CUSTOM profile mode setting on legacy SOCs
	drm/amdgpu: Fix the warning division or modulo by zero
	drm/amdgpu: fix dereference after null check
	drm/amdgpu: fix the waring dereferencing hive
	drm/amd/pm: check specific index for aldebaran
	drm/amd/pm: check specific index for smu13
	drm/amdgpu: the warning dereferencing obj for nbio_v7_4
	drm/amd/pm: check negtive return for table entries
	wifi: rtw89: ser: avoid multiple deinit on same CAM
	drm/kfd: Correct pinned buffer handling at kfd restore and validate process
	drm/amdgpu: update type of buf size to u32 for eeprom functions
	wifi: iwlwifi: remove fw_running op
	cpufreq: scmi: Avoid overflow of target_freq in fast switch
	PCI: al: Check IORESOURCE_BUS existence during probe
	wifi: mac80211: check ieee80211_bss_info_change_notify() against MLD
	hwspinlock: Introduce hwspin_lock_bust()
	soc: qcom: smem: Add qcom_smem_bust_hwspin_lock_by_host()
	RDMA/efa: Properly handle unexpected AQ completions
	ionic: fix potential irq name truncation
	pwm: xilinx: Fix u32 overflow issue in 32-bit width PWM mode.
	rcu/nocb: Remove buggy bypass lock contention mitigation
	media: v4l2-cci: Always assign *val
	usbip: Don't submit special requests twice
	usb: typec: ucsi: Fix null pointer dereference in trace
	fsnotify: clear PARENT_WATCHED flags lazily
	net: remove NULL-pointer net parameter in ip_metrics_convert
	drm/amdgu: fix Unintentional integer overflow for mall size
	regmap: spi: Fix potential off-by-one when calculating reserved size
	smack: tcp: ipv4, fix incorrect labeling
	platform/chrome: cros_ec_lpc: MEC access can use an AML mutex
	net/mlx5e: SHAMPO, Fix incorrect page release
	drm/meson: plane: Add error handling
	crypto: stm32/cryp - call finalize with bh disabled
	gfs2: Revert "Add quota_change type"
	drm/bridge: tc358767: Check if fully initialized before signalling HPD event via IRQ
	dmaengine: altera-msgdma: use irq variant of spin_lock/unlock while invoking callbacks
	dmaengine: altera-msgdma: properly free descriptor in msgdma_free_descriptor
	hwmon: (k10temp) Check return value of amd_smn_read()
	wifi: cfg80211: make hash table duplicates more survivable
	f2fs: fix to do sanity check on blocks for inline_data inode
	driver: iio: add missing checks on iio_info's callback access
	block: remove the blk_flush_integrity call in blk_integrity_unregister
	drm/amdgpu: add skip_hw_access checks for sriov
	drm/amdgpu: add lock in amdgpu_gart_invalidate_tlb
	drm/amdgpu: add lock in kfd_process_dequeue_from_device
	drm/amd/display: Don't use fsleep for PSR exit waits on dmub replay
	drm/amd/display: added NULL check at start of dc_validate_stream
	drm/amd/display: Correct the defined value for AMDGPU_DMUB_NOTIFICATION_MAX
	drm/amd/display: use preferred link settings for dp signal only
	drm/amd/display: Check BIOS images before it is used
	drm/amd/display: Skip wbscl_set_scaler_filter if filter is null
	media: uvcvideo: Enforce alignment of frame and interval
	virtio_net: Fix napi_skb_cache_put warning
	i2c: Use IS_REACHABLE() for substituting empty ACPI functions
	Linux 6.6.50

Change-Id: I0d10650643d671d01fa7df7782e6724c7da195a1
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2024-09-09 16:10:08 +00:00
commit ffff4c673c
137 changed files with 1592 additions and 567 deletions

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 6 VERSION = 6
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 49 SUBLEVEL = 50
EXTRAVERSION = EXTRAVERSION =
NAME = Hurr durr I'ma ninja sloth NAME = Hurr durr I'ma ninja sloth

View File

@ -396,8 +396,6 @@ void blk_integrity_unregister(struct gendisk *disk)
if (!bi->profile) if (!bi->profile)
return; return;
/* ensure all bios are off the integrity workqueue */
blk_flush_integrity();
blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue); blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
memset(bi, 0, sizeof(*bi)); memset(bi, 0, sizeof(*bi));
} }

View File

@ -122,8 +122,7 @@ static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
max_msg_size = spi_max_message_size(spi); max_msg_size = spi_max_message_size(spi);
reg_reserve_size = config->reg_bits / BITS_PER_BYTE reg_reserve_size = (config->reg_bits + config->pad_bits) / BITS_PER_BYTE;
+ config->pad_bits / BITS_PER_BYTE;
if (max_size + reg_reserve_size > max_msg_size) if (max_size + reg_reserve_size > max_msg_size)
max_size -= reg_reserve_size; max_size -= reg_reserve_size;

View File

@ -11,6 +11,7 @@
#include <crypto/internal/des.h> #include <crypto/internal/des.h>
#include <crypto/internal/skcipher.h> #include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h> #include <crypto/scatterwalk.h>
#include <linux/bottom_half.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
@ -1665,8 +1666,11 @@ static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg)
it_mask &= ~IMSCR_OUT; it_mask &= ~IMSCR_OUT;
stm32_cryp_write(cryp, cryp->caps->imsc, it_mask); stm32_cryp_write(cryp, cryp->caps->imsc, it_mask);
if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) {
local_bh_disable();
stm32_cryp_finish_req(cryp, 0); stm32_cryp_finish_req(cryp, 0);
local_bh_enable();
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -233,7 +233,7 @@ static void msgdma_free_descriptor(struct msgdma_device *mdev,
struct msgdma_sw_desc *child, *next; struct msgdma_sw_desc *child, *next;
mdev->desc_free_cnt++; mdev->desc_free_cnt++;
list_add_tail(&desc->node, &mdev->free_list); list_move_tail(&desc->node, &mdev->free_list);
list_for_each_entry_safe(child, next, &desc->tx_list, node) { list_for_each_entry_safe(child, next, &desc->tx_list, node) {
mdev->desc_free_cnt++; mdev->desc_free_cnt++;
list_move_tail(&child->node, &mdev->free_list); list_move_tail(&child->node, &mdev->free_list);
@ -583,17 +583,16 @@ static void msgdma_issue_pending(struct dma_chan *chan)
static void msgdma_chan_desc_cleanup(struct msgdma_device *mdev) static void msgdma_chan_desc_cleanup(struct msgdma_device *mdev)
{ {
struct msgdma_sw_desc *desc, *next; struct msgdma_sw_desc *desc, *next;
unsigned long irqflags;
list_for_each_entry_safe(desc, next, &mdev->done_list, node) { list_for_each_entry_safe(desc, next, &mdev->done_list, node) {
struct dmaengine_desc_callback cb; struct dmaengine_desc_callback cb;
list_del(&desc->node);
dmaengine_desc_get_callback(&desc->async_tx, &cb); dmaengine_desc_get_callback(&desc->async_tx, &cb);
if (dmaengine_desc_callback_valid(&cb)) { if (dmaengine_desc_callback_valid(&cb)) {
spin_unlock(&mdev->lock); spin_unlock_irqrestore(&mdev->lock, irqflags);
dmaengine_desc_callback_invoke(&cb, NULL); dmaengine_desc_callback_invoke(&cb, NULL);
spin_lock(&mdev->lock); spin_lock_irqsave(&mdev->lock, irqflags);
} }
/* Run any dependencies, then free the descriptor */ /* Run any dependencies, then free the descriptor */

View File

@ -100,6 +100,7 @@ struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock)
amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
res.clock = clock;
return res; return res;
} }

View File

@ -407,6 +407,10 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain,
"Called with userptr BO")) "Called with userptr BO"))
return -EINVAL; return -EINVAL;
/* bo has been pinned, not need validate it */
if (bo->tbo.pin_count)
return 0;
amdgpu_bo_placement_from_domain(bo, domain); amdgpu_bo_placement_from_domain(bo, domain);
ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
@ -2848,9 +2852,6 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
if (!attachment->is_mapped) if (!attachment->is_mapped)
continue; continue;
if (attachment->bo_va->base.bo->tbo.pin_count)
continue;
kfd_mem_dmaunmap_attachment(mem, attachment); kfd_mem_dmaunmap_attachment(mem, attachment);
ret = update_gpuvm_pte(mem, attachment, &sync_obj); ret = update_gpuvm_pte(mem, attachment, &sync_obj);
if (ret) { if (ret) {

View File

@ -1476,6 +1476,8 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev,
(u32)le32_to_cpu(*((u32 *)reg_data + j)); (u32)le32_to_cpu(*((u32 *)reg_data + j));
j++; j++;
} else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
if (i == 0)
continue;
reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = reg_table->mc_reg_table_entry[num_ranges].mc_data[i] =
reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1]; reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1];
} }

View File

@ -213,6 +213,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
struct amdgpu_firmware_info *ucode; struct amdgpu_firmware_info *ucode;
id = fw_type_convert(cgs_device, type); id = fw_type_convert(cgs_device, type);
if (id >= AMDGPU_UCODE_ID_MAXIMUM)
return -EINVAL;
ucode = &adev->firmware.ucode[id]; ucode = &adev->firmware.ucode[id];
if (ucode->fw == NULL) if (ucode->fw == NULL)
return -EINVAL; return -EINVAL;

View File

@ -4480,7 +4480,8 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev)
shadow = vmbo->shadow; shadow = vmbo->shadow;
/* No need to recover an evicted BO */ /* No need to recover an evicted BO */
if (shadow->tbo.resource->mem_type != TTM_PL_TT || if (!shadow->tbo.resource ||
shadow->tbo.resource->mem_type != TTM_PL_TT ||
shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET || shadow->tbo.resource->start == AMDGPU_BO_INVALID_OFFSET ||
shadow->parent->tbo.resource->mem_type != TTM_PL_VRAM) shadow->parent->tbo.resource->mem_type != TTM_PL_VRAM)
continue; continue;
@ -5235,7 +5236,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
* to put adev in the 1st position. * to put adev in the 1st position.
*/ */
INIT_LIST_HEAD(&device_list); INIT_LIST_HEAD(&device_list);
if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) { if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1) && hive) {
list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
list_add_tail(&tmp_adev->reset_list, &device_list); list_add_tail(&tmp_adev->reset_list, &device_list);
if (gpu_reset_for_dev_remove && adev->shutdown) if (gpu_reset_for_dev_remove && adev->shutdown)

View File

@ -1550,7 +1550,7 @@ static int amdgpu_discovery_get_mall_info(struct amdgpu_device *adev)
break; break;
case 2: case 2:
mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc); mall_size_per_umc = le32_to_cpu(mall_info->v2.mall_size_per_umc);
adev->gmc.mall_size = mall_size_per_umc * adev->gmc.num_umc; adev->gmc.mall_size = (uint64_t)mall_size_per_umc * adev->gmc.num_umc;
break; break;
default: default:
dev_err(adev->dev, dev_err(adev->dev,

View File

@ -179,7 +179,7 @@ static int __amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
* Returns the number of bytes read/written; -errno on error. * Returns the number of bytes read/written; -errno on error.
*/ */
static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr, static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
u8 *eeprom_buf, u16 buf_size, bool read) u8 *eeprom_buf, u32 buf_size, bool read)
{ {
const struct i2c_adapter_quirks *quirks = i2c_adap->quirks; const struct i2c_adapter_quirks *quirks = i2c_adap->quirks;
u16 limit; u16 limit;
@ -225,7 +225,7 @@ static int amdgpu_eeprom_xfer(struct i2c_adapter *i2c_adap, u32 eeprom_addr,
int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap, int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
u32 eeprom_addr, u8 *eeprom_buf, u32 eeprom_addr, u8 *eeprom_buf,
u16 bytes) u32 bytes)
{ {
return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes, return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes,
true); true);
@ -233,7 +233,7 @@ int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap, int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap,
u32 eeprom_addr, u8 *eeprom_buf, u32 eeprom_addr, u8 *eeprom_buf,
u16 bytes) u32 bytes)
{ {
return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes, return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes,
false); false);

View File

@ -28,10 +28,10 @@
int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap, int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
u32 eeprom_addr, u8 *eeprom_buf, u32 eeprom_addr, u8 *eeprom_buf,
u16 bytes); u32 bytes);
int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap, int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap,
u32 eeprom_addr, u8 *eeprom_buf, u32 eeprom_addr, u8 *eeprom_buf,
u16 bytes); u32 bytes);
#endif #endif

View File

@ -34,6 +34,7 @@
#include <asm/set_memory.h> #include <asm/set_memory.h>
#endif #endif
#include "amdgpu.h" #include "amdgpu.h"
#include "amdgpu_reset.h"
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/ttm/ttm_tt.h> #include <drm/ttm/ttm_tt.h>
@ -400,7 +401,10 @@ void amdgpu_gart_invalidate_tlb(struct amdgpu_device *adev)
return; return;
mb(); mb();
if (down_read_trylock(&adev->reset_domain->sem)) {
amdgpu_device_flush_hdp(adev, NULL); amdgpu_device_flush_hdp(adev, NULL);
up_read(&adev->reset_domain->sem);
}
for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS) for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS)
amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0); amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
} }

View File

@ -1336,6 +1336,9 @@ static void psp_xgmi_reflect_topology_info(struct psp_context *psp,
uint8_t dst_num_links = node_info.num_links; uint8_t dst_num_links = node_info.num_links;
hive = amdgpu_get_xgmi_hive(psp->adev); hive = amdgpu_get_xgmi_hive(psp->adev);
if (WARN_ON(!hive))
return;
list_for_each_entry(mirror_adev, &hive->device_list, gmc.xgmi.head) { list_for_each_entry(mirror_adev, &hive->device_list, gmc.xgmi.head) {
struct psp_xgmi_topology_info *mirror_top_info; struct psp_xgmi_topology_info *mirror_top_info;
int j; int j;

View File

@ -352,7 +352,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
ring->max_dw = max_dw; ring->max_dw = max_dw;
ring->hw_prio = hw_prio; ring->hw_prio = hw_prio;
if (!ring->no_scheduler) { if (!ring->no_scheduler && ring->funcs->type < AMDGPU_HW_IP_NUM) {
hw_ip = ring->funcs->type; hw_ip = ring->funcs->type;
num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds; num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds;
adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] = adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] =
@ -469,8 +469,9 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf,
size_t size, loff_t *pos) size_t size, loff_t *pos)
{ {
struct amdgpu_ring *ring = file_inode(f)->i_private; struct amdgpu_ring *ring = file_inode(f)->i_private;
int r, i;
uint32_t value, result, early[3]; uint32_t value, result, early[3];
loff_t i;
int r;
if (*pos & 3 || size & 3) if (*pos & 3 || size & 3)
return -EINVAL; return -EINVAL;

View File

@ -135,6 +135,10 @@ static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __u
mutex_unlock(&psp->securedisplay_context.mutex); mutex_unlock(&psp->securedisplay_context.mutex);
break; break;
case 2: case 2:
if (size < 3 || phy_id >= TA_SECUREDISPLAY_MAX_PHY) {
dev_err(adev->dev, "Invalid input: %s\n", str);
return -EINVAL;
}
mutex_lock(&psp->securedisplay_context.mutex); mutex_lock(&psp->securedisplay_context.mutex);
psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);

View File

@ -615,7 +615,7 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev)
vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr; vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr;
vf2pf_info->checksum = vf2pf_info->checksum =
amd_sriov_msg_checksum( amd_sriov_msg_checksum(
vf2pf_info, vf2pf_info->header.size, 0, 0); vf2pf_info, sizeof(*vf2pf_info), 0, 0);
return 0; return 0;
} }
@ -998,6 +998,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v
return 0; return 0;
} }
if (amdgpu_device_skip_hw_access(adev))
return 0;
reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id]; reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id];
scratch_reg0 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg0; scratch_reg0 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg0;
scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1;
@ -1073,6 +1076,9 @@ void amdgpu_sriov_wreg(struct amdgpu_device *adev,
{ {
u32 rlcg_flag; u32 rlcg_flag;
if (amdgpu_device_skip_hw_access(adev))
return;
if (!amdgpu_sriov_runtime(adev) && if (!amdgpu_sriov_runtime(adev) &&
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) { amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, true, &rlcg_flag)) {
amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag, xcc_id); amdgpu_virt_rlcg_reg_rw(adev, offset, value, rlcg_flag, xcc_id);
@ -1090,6 +1096,9 @@ u32 amdgpu_sriov_rreg(struct amdgpu_device *adev,
{ {
u32 rlcg_flag; u32 rlcg_flag;
if (amdgpu_device_skip_hw_access(adev))
return 0;
if (!amdgpu_sriov_runtime(adev) && if (!amdgpu_sriov_runtime(adev) &&
amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag)) amdgpu_virt_get_rlcg_reg_access_flag(adev, acc_flags, hwip, false, &rlcg_flag))
return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag, xcc_id); return amdgpu_virt_rlcg_reg_rw(adev, offset, 0, rlcg_flag, xcc_id);

View File

@ -500,6 +500,12 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
if (mode == AMDGPU_AUTO_COMPUTE_PARTITION_MODE) { if (mode == AMDGPU_AUTO_COMPUTE_PARTITION_MODE) {
mode = __aqua_vanjaram_get_auto_mode(xcp_mgr); mode = __aqua_vanjaram_get_auto_mode(xcp_mgr);
if (mode == AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE) {
dev_err(adev->dev,
"Invalid config, no compatible compute partition mode found, available memory partitions: %d",
adev->gmc.num_mem_partitions);
return -EINVAL;
}
} else if (!__aqua_vanjaram_is_valid_mode(xcp_mgr, mode)) { } else if (!__aqua_vanjaram_is_valid_mode(xcp_mgr, mode)) {
dev_err(adev->dev, dev_err(adev->dev,
"Invalid compute partition mode requested, requested: %s, available memory partitions: %d", "Invalid compute partition mode requested, requested: %s, available memory partitions: %d",

View File

@ -70,6 +70,8 @@ static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev)
int fb_channel_number; int fb_channel_number;
fb_channel_number = adev->df.funcs->get_fb_channel_number(adev); fb_channel_number = adev->df.funcs->get_fb_channel_number(adev);
if (fb_channel_number >= ARRAY_SIZE(df_v1_7_channel_number))
fb_channel_number = 0;
return df_v1_7_channel_number[fb_channel_number]; return df_v1_7_channel_number[fb_channel_number];
} }

View File

@ -384,7 +384,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device
else else
WREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl); WREG32_SOC15(NBIO, 0, mmBIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
if (!ras->disable_ras_err_cnt_harvest) { if (ras && !ras->disable_ras_err_cnt_harvest && obj) {
/* /*
* clear error status after ras_controller_intr * clear error status after ras_controller_intr
* according to hw team and count ue number * according to hw team and count ue number

View File

@ -42,8 +42,6 @@
#define CRAT_OEMTABLEID_LENGTH 8 #define CRAT_OEMTABLEID_LENGTH 8
#define CRAT_RESERVED_LENGTH 6 #define CRAT_RESERVED_LENGTH 6
#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1)
/* Compute Unit flags */ /* Compute Unit flags */
#define COMPUTE_UNIT_CPU (1 << 0) /* Create Virtual CRAT for CPU */ #define COMPUTE_UNIT_CPU (1 << 0) /* Create Virtual CRAT for CPU */
#define COMPUTE_UNIT_GPU (1 << 1) /* Create Virtual CRAT for GPU */ #define COMPUTE_UNIT_GPU (1 << 1) /* Create Virtual CRAT for GPU */

View File

@ -103,6 +103,7 @@ void debug_event_write_work_handler(struct work_struct *work)
struct kfd_process, struct kfd_process,
debug_event_workarea); debug_event_workarea);
if (process->debug_trap_enabled && process->dbg_ev_file)
kernel_write(process->dbg_ev_file, &write_data, 1, &pos); kernel_write(process->dbg_ev_file, &write_data, 1, &pos);
} }
@ -645,6 +646,7 @@ int kfd_dbg_trap_disable(struct kfd_process *target)
else if (target->runtime_info.runtime_state != DEBUG_RUNTIME_STATE_DISABLED) else if (target->runtime_info.runtime_state != DEBUG_RUNTIME_STATE_DISABLED)
target->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED; target->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED;
cancel_work_sync(&target->debug_event_workarea);
fput(target->dbg_ev_file); fput(target->dbg_ev_file);
target->dbg_ev_file = NULL; target->dbg_ev_file = NULL;

View File

@ -28,6 +28,7 @@
#include "kfd_priv.h" #include "kfd_priv.h"
#include "kfd_kernel_queue.h" #include "kfd_kernel_queue.h"
#include "amdgpu_amdkfd.h" #include "amdgpu_amdkfd.h"
#include "amdgpu_reset.h"
static inline struct process_queue_node *get_queue_by_qid( static inline struct process_queue_node *get_queue_by_qid(
struct process_queue_manager *pqm, unsigned int qid) struct process_queue_manager *pqm, unsigned int qid)
@ -87,8 +88,12 @@ void kfd_process_dequeue_from_device(struct kfd_process_device *pdd)
return; return;
dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd); dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd);
if (dev->kfd->shared_resources.enable_mes) if (dev->kfd->shared_resources.enable_mes &&
amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr); down_read_trylock(&dev->adev->reset_domain->sem)) {
amdgpu_mes_flush_shader_debugger(dev->adev,
pdd->proc_ctx_gpu_addr);
up_read(&dev->adev->reset_domain->sem);
}
pdd->already_dequeued = true; pdd->already_dequeued = true;
} }

View File

@ -958,8 +958,7 @@ static void kfd_update_system_properties(void)
dev = list_last_entry(&topology_device_list, dev = list_last_entry(&topology_device_list,
struct kfd_topology_device, list); struct kfd_topology_device, list);
if (dev) { if (dev) {
sys_props.platform_id = sys_props.platform_id = dev->oem_id64;
(*((uint64_t *)dev->oem_id)) & CRAT_OEMID_64BIT_MASK;
sys_props.platform_oem = *((uint64_t *)dev->oem_table_id); sys_props.platform_oem = *((uint64_t *)dev->oem_table_id);
sys_props.platform_rev = dev->oem_revision; sys_props.platform_rev = dev->oem_revision;
} }

View File

@ -154,7 +154,10 @@ struct kfd_topology_device {
struct attribute attr_gpuid; struct attribute attr_gpuid;
struct attribute attr_name; struct attribute attr_name;
struct attribute attr_props; struct attribute attr_props;
union {
uint8_t oem_id[CRAT_OEMID_LENGTH]; uint8_t oem_id[CRAT_OEMID_LENGTH];
uint64_t oem_id64;
};
uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH]; uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH];
uint32_t oem_revision; uint32_t oem_revision;
}; };

View File

@ -4357,7 +4357,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
/* There is one primary plane per CRTC */ /* There is one primary plane per CRTC */
primary_planes = dm->dc->caps.max_streams; primary_planes = dm->dc->caps.max_streams;
ASSERT(primary_planes <= AMDGPU_MAX_PLANES); if (primary_planes > AMDGPU_MAX_PLANES) {
DRM_ERROR("DM: Plane nums out of 6 planes\n");
return -EINVAL;
}
/* /*
* Initialize primary planes, implicit planes for legacy IOCTLS. * Initialize primary planes, implicit planes for legacy IOCTLS.
@ -8283,15 +8286,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
bundle->stream_update.vrr_infopacket = bundle->stream_update.vrr_infopacket =
&acrtc_state->stream->vrr_infopacket; &acrtc_state->stream->vrr_infopacket;
} }
} else if (cursor_update && acrtc_state->active_planes > 0 && } else if (cursor_update && acrtc_state->active_planes > 0) {
acrtc_attach->base.state->event) {
drm_crtc_vblank_get(pcrtc);
spin_lock_irqsave(&pcrtc->dev->event_lock, flags); spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
if (acrtc_attach->base.state->event) {
drm_crtc_vblank_get(pcrtc);
acrtc_attach->event = acrtc_attach->base.state->event; acrtc_attach->event = acrtc_attach->base.state->event;
acrtc_attach->base.state->event = NULL; acrtc_attach->base.state->event = NULL;
}
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
} }

View File

@ -49,7 +49,7 @@
#define AMDGPU_DM_MAX_NUM_EDP 2 #define AMDGPU_DM_MAX_NUM_EDP 2
#define AMDGPU_DMUB_NOTIFICATION_MAX 5 #define AMDGPU_DMUB_NOTIFICATION_MAX 6
#define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x00001A #define HDMI_AMD_VENDOR_SPECIFIC_DATA_BLOCK_IEEE_REGISTRATION_ID 0x00001A
#define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40 #define AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40

View File

@ -667,6 +667,9 @@ static enum bp_result get_ss_info_v3_1(
ss_table_header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, ss_table_header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base,
DATA_TABLES(ASIC_InternalSS_Info), DATA_TABLES(ASIC_InternalSS_Info),
struct_size(ss_table_header_include, asSpreadSpectrum, 1))); struct_size(ss_table_header_include, asSpreadSpectrum, 1)));
if (!ss_table_header_include)
return BP_RESULT_UNSUPPORTED;
table_size = table_size =
(le16_to_cpu(ss_table_header_include->sHeader.usStructureSize) (le16_to_cpu(ss_table_header_include->sHeader.usStructureSize)
- sizeof(ATOM_COMMON_TABLE_HEADER)) - sizeof(ATOM_COMMON_TABLE_HEADER))
@ -1036,6 +1039,8 @@ static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1(
&bp->base, &bp->base,
DATA_TABLES(ASIC_InternalSS_Info), DATA_TABLES(ASIC_InternalSS_Info),
struct_size(header, asSpreadSpectrum, 1))); struct_size(header, asSpreadSpectrum, 1)));
if (!header)
return result;
memset(info, 0, sizeof(struct spread_spectrum_info)); memset(info, 0, sizeof(struct spread_spectrum_info));
@ -1109,6 +1114,8 @@ static enum bp_result get_ss_info_from_ss_info_table(
get_atom_data_table_revision(header, &revision); get_atom_data_table_revision(header, &revision);
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info)); tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info));
if (!tbl)
return result;
if (1 != revision.major || 2 > revision.minor) if (1 != revision.major || 2 > revision.minor)
return result; return result;
@ -1636,6 +1643,8 @@ static uint32_t get_ss_entry_number_from_ss_info_tbl(
tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO,
DATA_TABLES(SS_Info)); DATA_TABLES(SS_Info));
if (!tbl)
return number;
if (1 != revision.major || 2 > revision.minor) if (1 != revision.major || 2 > revision.minor)
return number; return number;
@ -1718,6 +1727,8 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1(
&bp->base, &bp->base,
DATA_TABLES(ASIC_InternalSS_Info), DATA_TABLES(ASIC_InternalSS_Info),
struct_size(header_include, asSpreadSpectrum, 1))); struct_size(header_include, asSpreadSpectrum, 1)));
if (!header_include)
return 0;
size = (le16_to_cpu(header_include->sHeader.usStructureSize) size = (le16_to_cpu(header_include->sHeader.usStructureSize)
- sizeof(ATOM_COMMON_TABLE_HEADER)) - sizeof(ATOM_COMMON_TABLE_HEADER))
@ -1756,6 +1767,9 @@ static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1(
header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base, header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base,
DATA_TABLES(ASIC_InternalSS_Info), DATA_TABLES(ASIC_InternalSS_Info),
struct_size(header_include, asSpreadSpectrum, 1))); struct_size(header_include, asSpreadSpectrum, 1)));
if (!header_include)
return number;
size = (le16_to_cpu(header_include->sHeader.usStructureSize) - size = (le16_to_cpu(header_include->sHeader.usStructureSize) -
sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_COMMON_TABLE_HEADER)) /
sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
@ -2552,8 +2566,8 @@ static enum bp_result construct_integrated_info(
/* Sort voltage table from low to high*/ /* Sort voltage table from low to high*/
if (result == BP_RESULT_OK) { if (result == BP_RESULT_OK) {
uint32_t i; int32_t i;
uint32_t j; int32_t j;
for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
for (j = i; j > 0; --j) { for (j = i; j > 0; --j) {

View File

@ -2935,8 +2935,11 @@ static enum bp_result construct_integrated_info(
struct atom_common_table_header *header; struct atom_common_table_header *header;
struct atom_data_revision revision; struct atom_data_revision revision;
uint32_t i; int32_t i;
uint32_t j; int32_t j;
if (!info)
return result;
if (info && DATA_TABLES(integratedsysteminfo)) { if (info && DATA_TABLES(integratedsysteminfo)) {
header = GET_IMAGE(struct atom_common_table_header, header = GET_IMAGE(struct atom_common_table_header,

View File

@ -484,6 +484,7 @@ static void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_sm
ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
/* Modify previous watermark range to cover up to max */ /* Modify previous watermark range to cover up to max */
if (num_valid_sets > 0)
ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX;
} }
num_valid_sets++; num_valid_sets++;

View File

@ -1298,6 +1298,7 @@ struct dc *dc_create(const struct dc_init_data *init_params)
return NULL; return NULL;
if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) { if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) {
dc->caps.linear_pitch_alignment = 64;
if (!dc_construct_ctx(dc, init_params)) if (!dc_construct_ctx(dc, init_params))
goto destruct_dc; goto destruct_dc;
} else { } else {

View File

@ -3927,6 +3927,9 @@ void resource_build_bit_depth_reduction_params(struct dc_stream_state *stream,
enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream) enum dc_status dc_validate_stream(struct dc *dc, struct dc_stream_state *stream)
{ {
if (dc == NULL || stream == NULL)
return DC_ERROR_UNEXPECTED;
struct dc_link *link = stream->link; struct dc_link *link = stream->link;
struct timing_generator *tg = dc->res_pool->timing_generators[0]; struct timing_generator *tg = dc->res_pool->timing_generators[0];
enum dc_status res = DC_OK; enum dc_status res = DC_OK;

View File

@ -102,7 +102,8 @@ static void dmub_replay_enable(struct dmub_replay *dmub, bool enable, bool wait,
break; break;
} }
fsleep(500); /* must *not* be fsleep - this can be called from high irq levels */
udelay(500);
} }
/* assert if max retry hit */ /* assert if max retry hit */

View File

@ -690,6 +690,9 @@ static void wbscl_set_scaler_filter(
int pair; int pair;
uint16_t odd_coef, even_coef; uint16_t odd_coef, even_coef;
if (!filter)
return;
for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) {
for (pair = 0; pair < tap_pairs; pair++) { for (pair = 0; pair < tap_pairs; pair++) {
even_coef = filter[phase * taps + 2 * pair]; even_coef = filter[phase * taps + 2 * pair];

View File

@ -1453,10 +1453,9 @@ void dcn_bw_update_from_pplib_fclks(
ASSERT(fclks->num_levels); ASSERT(fclks->num_levels);
vmin0p65_idx = 0; vmin0p65_idx = 0;
vmid0p72_idx = fclks->num_levels - vmid0p72_idx = fclks->num_levels > 2 ? fclks->num_levels - 3 : 0;
(fclks->num_levels > 2 ? 3 : (fclks->num_levels > 1 ? 2 : 1)); vnom0p8_idx = fclks->num_levels > 1 ? fclks->num_levels - 2 : 0;
vnom0p8_idx = fclks->num_levels - (fclks->num_levels > 1 ? 2 : 1); vmax0p9_idx = fclks->num_levels > 0 ? fclks->num_levels - 1 : 0;
vmax0p9_idx = fclks->num_levels - 1;
dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 =
32 * (fclks->data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0; 32 * (fclks->data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0;

View File

@ -304,6 +304,16 @@ void dcn302_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
} }
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_02_soc.num_states = num_states; dcn3_02_soc.num_states = num_states;
for (i = 0; i < dcn3_02_soc.num_states; i++) { for (i = 0; i < dcn3_02_soc.num_states; i++) {
dcn3_02_soc.clock_limits[i].state = i; dcn3_02_soc.clock_limits[i].state = i;

View File

@ -299,6 +299,16 @@ void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
} }
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_03_soc.num_states = num_states; dcn3_03_soc.num_states = num_states;
for (i = 0; i < dcn3_03_soc.num_states; i++) { for (i = 0; i < dcn3_03_soc.num_states; i++) {
dcn3_03_soc.clock_limits[i].state = i; dcn3_03_soc.clock_limits[i].state = i;

View File

@ -2885,6 +2885,16 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
} }
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_2_soc.num_states = num_states; dcn3_2_soc.num_states = num_states;
for (i = 0; i < dcn3_2_soc.num_states; i++) { for (i = 0; i < dcn3_2_soc.num_states; i++) {
dcn3_2_soc.clock_limits[i].state = i; dcn3_2_soc.clock_limits[i].state = i;

View File

@ -789,6 +789,16 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p
dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16; dram_speed_mts[num_states++] = bw_params->clk_table.entries[j++].memclk_mhz * 16;
} }
/* bw_params->clk_table.entries[MAX_NUM_DPM_LVL].
* MAX_NUM_DPM_LVL is 8.
* dcn3_02_soc.clock_limits[DC__VOLTAGE_STATES].
* DC__VOLTAGE_STATES is 40.
*/
if (num_states > MAX_NUM_DPM_LVL) {
ASSERT(0);
return;
}
dcn3_21_soc.num_states = num_states; dcn3_21_soc.num_states = num_states;
for (i = 0; i < dcn3_21_soc.num_states; i++) { for (i = 0; i < dcn3_21_soc.num_states; i++) {
dcn3_21_soc.clock_limits[i].state = i; dcn3_21_soc.clock_limits[i].state = i;

View File

@ -1099,8 +1099,13 @@ void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib)
// Total Available Pipes Support Check // Total Available Pipes Support Check
for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) { for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
total_pipes += mode_lib->vba.DPPPerPlane[k];
pipe_idx = get_pipe_idx(mode_lib, k); pipe_idx = get_pipe_idx(mode_lib, k);
if (pipe_idx == -1) {
ASSERT(0);
continue; // skip inactive planes
}
total_pipes += mode_lib->vba.DPPPerPlane[k];
if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0) if (mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz > 0.0)
mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz; mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz;
else else

View File

@ -56,7 +56,7 @@ struct gpio_service *dal_gpio_service_create(
struct dc_context *ctx) struct dc_context *ctx)
{ {
struct gpio_service *service; struct gpio_service *service;
uint32_t index_of_id; int32_t index_of_id;
service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL); service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL);
@ -112,7 +112,7 @@ struct gpio_service *dal_gpio_service_create(
return service; return service;
failure_2: failure_2:
while (index_of_id) { while (index_of_id > 0) {
--index_of_id; --index_of_id;
kfree(service->busyness[index_of_id]); kfree(service->busyness[index_of_id]);
} }
@ -239,6 +239,9 @@ static bool is_pin_busy(
enum gpio_id id, enum gpio_id id,
uint32_t en) uint32_t en)
{ {
if (id == GPIO_ID_UNKNOWN)
return false;
return service->busyness[id][en]; return service->busyness[id][en];
} }
@ -247,6 +250,9 @@ static void set_pin_busy(
enum gpio_id id, enum gpio_id id,
uint32_t en) uint32_t en)
{ {
if (id == GPIO_ID_UNKNOWN)
return;
service->busyness[id][en] = true; service->busyness[id][en] = true;
} }
@ -255,6 +261,9 @@ static void set_pin_free(
enum gpio_id id, enum gpio_id id,
uint32_t en) uint32_t en)
{ {
if (id == GPIO_ID_UNKNOWN)
return;
service->busyness[id][en] = false; service->busyness[id][en] = false;
} }
@ -263,7 +272,7 @@ enum gpio_result dal_gpio_service_lock(
enum gpio_id id, enum gpio_id id,
uint32_t en) uint32_t en)
{ {
if (!service->busyness[id]) { if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) {
ASSERT_CRITICAL(false); ASSERT_CRITICAL(false);
return GPIO_RESULT_OPEN_FAILED; return GPIO_RESULT_OPEN_FAILED;
} }
@ -277,7 +286,7 @@ enum gpio_result dal_gpio_service_unlock(
enum gpio_id id, enum gpio_id id,
uint32_t en) uint32_t en)
{ {
if (!service->busyness[id]) { if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) {
ASSERT_CRITICAL(false); ASSERT_CRITICAL(false);
return GPIO_RESULT_OPEN_FAILED; return GPIO_RESULT_OPEN_FAILED;
} }

View File

@ -130,13 +130,21 @@ static bool hdmi_14_process_transaction(
const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/ const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/
const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/ const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/
struct i2c_command i2c_command; struct i2c_command i2c_command;
uint8_t offset = hdcp_i2c_offsets[message_info->msg_id]; uint8_t offset;
struct i2c_payload i2c_payloads[] = { struct i2c_payload i2c_payloads[] = {
{ true, 0, 1, &offset }, { true, 0, 1, 0 },
/* actual hdcp payload, will be filled later, zeroed for now*/ /* actual hdcp payload, will be filled later, zeroed for now*/
{ 0 } { 0 }
}; };
if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) {
DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id);
return false;
}
offset = hdcp_i2c_offsets[message_info->msg_id];
i2c_payloads[0].data = &offset;
switch (message_info->link) { switch (message_info->link) {
case HDCP_LINK_SECONDARY: case HDCP_LINK_SECONDARY:
i2c_payloads[0].address = hdcp_i2c_addr_link_secondary; i2c_payloads[0].address = hdcp_i2c_addr_link_secondary;
@ -310,6 +318,11 @@ static bool dp_11_process_transaction(
struct dc_link *link, struct dc_link *link,
struct hdcp_protection_message *message_info) struct hdcp_protection_message *message_info)
{ {
if (message_info->msg_id == HDCP_MESSAGE_ID_INVALID) {
DC_LOG_ERROR("%s: Invalid message_info msg_id - %d\n", __func__, message_info->msg_id);
return false;
}
return dpcd_access_helper( return dpcd_access_helper(
link, link,
message_info->length, message_info->length,

View File

@ -528,7 +528,7 @@ static bool decide_fallback_link_setting_max_bw_policy(
struct dc_link_settings *cur, struct dc_link_settings *cur,
enum link_training_result training_result) enum link_training_result training_result)
{ {
uint8_t cur_idx = 0, next_idx; uint32_t cur_idx = 0, next_idx;
bool found = false; bool found = false;
if (training_result == LINK_TRAINING_ABORT) if (training_result == LINK_TRAINING_ABORT)
@ -908,21 +908,17 @@ bool link_decide_link_settings(struct dc_stream_state *stream,
memset(link_setting, 0, sizeof(*link_setting)); memset(link_setting, 0, sizeof(*link_setting));
if (dc_is_dp_signal(stream->signal) &&
link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN &&
link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) {
/* if preferred is specified through AMDDP, use it, if it's enough /* if preferred is specified through AMDDP, use it, if it's enough
* to drive the mode * to drive the mode
*/ */
if (link->preferred_link_setting.lane_count !=
LANE_COUNT_UNKNOWN &&
link->preferred_link_setting.link_rate !=
LINK_RATE_UNKNOWN) {
*link_setting = link->preferred_link_setting; *link_setting = link->preferred_link_setting;
return true; } else if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
}
/* MST doesn't perform link training for now /* MST doesn't perform link training for now
* TODO: add MST specific link training routine * TODO: add MST specific link training routine
*/ */
if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
decide_mst_link_settings(link, link_setting); decide_mst_link_settings(link, link_setting);
} else if (link->connector_signal == SIGNAL_TYPE_EDP) { } else if (link->connector_signal == SIGNAL_TYPE_EDP) {
/* enable edp link optimization for DSC eDP case */ /* enable edp link optimization for DSC eDP case */

View File

@ -914,10 +914,10 @@ static enum dc_status configure_lttpr_mode_non_transparent(
/* Driver does not need to train the first hop. Skip DPCD read and clear /* Driver does not need to train the first hop. Skip DPCD read and clear
* AUX_RD_INTERVAL for DPTX-to-DPIA hop. * AUX_RD_INTERVAL for DPTX-to-DPIA hop.
*/ */
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA && repeater_cnt > 0 && repeater_cnt < MAX_REPEATER_CNT)
link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0; link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0;
for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) { for (repeater_id = repeater_cnt; repeater_id > 0 && repeater_id < MAX_REPEATER_CNT; repeater_id--) {
aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 + aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 +
((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1)); ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1));
core_link_read_dpcd( core_link_read_dpcd(

View File

@ -156,11 +156,16 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp,
uint32_t cur_size = 0; uint32_t cur_size = 0;
uint32_t data_offset = 0; uint32_t data_offset = 0;
if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
return MOD_HDCP_STATUS_DDC_FAILURE; return MOD_HDCP_STATUS_DDC_FAILURE;
}
if (is_dp_hdcp(hdcp)) { if (is_dp_hdcp(hdcp)) {
int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) /
sizeof(hdcp_dpcd_addrs[0]);
if (msg_id >= num_dpcd_addrs)
return MOD_HDCP_STATUS_DDC_FAILURE;
while (buf_len > 0) { while (buf_len > 0) {
cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle, success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
@ -175,6 +180,11 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp,
data_offset += cur_size; data_offset += cur_size;
} }
} else { } else {
int num_i2c_offsets = sizeof(hdcp_i2c_offsets) /
sizeof(hdcp_i2c_offsets[0]);
if (msg_id >= num_i2c_offsets)
return MOD_HDCP_STATUS_DDC_FAILURE;
success = hdcp->config.ddc.funcs.read_i2c( success = hdcp->config.ddc.funcs.read_i2c(
hdcp->config.ddc.handle, hdcp->config.ddc.handle,
HDCP_I2C_ADDR, HDCP_I2C_ADDR,
@ -219,11 +229,16 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp,
uint32_t cur_size = 0; uint32_t cur_size = 0;
uint32_t data_offset = 0; uint32_t data_offset = 0;
if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) { if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
return MOD_HDCP_STATUS_DDC_FAILURE; return MOD_HDCP_STATUS_DDC_FAILURE;
}
if (is_dp_hdcp(hdcp)) { if (is_dp_hdcp(hdcp)) {
int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) /
sizeof(hdcp_dpcd_addrs[0]);
if (msg_id >= num_dpcd_addrs)
return MOD_HDCP_STATUS_DDC_FAILURE;
while (buf_len > 0) { while (buf_len > 0) {
cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
success = hdcp->config.ddc.funcs.write_dpcd( success = hdcp->config.ddc.funcs.write_dpcd(
@ -239,6 +254,11 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp,
data_offset += cur_size; data_offset += cur_size;
} }
} else { } else {
int num_i2c_offsets = sizeof(hdcp_i2c_offsets) /
sizeof(hdcp_i2c_offsets[0]);
if (msg_id >= num_i2c_offsets)
return MOD_HDCP_STATUS_DDC_FAILURE;
hdcp->buf[0] = hdcp_i2c_offsets[msg_id]; hdcp->buf[0] = hdcp_i2c_offsets[msg_id];
memmove(&hdcp->buf[1], buf, buf_len); memmove(&hdcp->buf[1], buf, buf_len);
success = hdcp->config.ddc.funcs.write_i2c( success = hdcp->config.ddc.funcs.write_i2c(

View File

@ -99,7 +99,7 @@ static void pp_swctf_delayed_work_handler(struct work_struct *work)
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
struct amdgpu_dpm_thermal *range = struct amdgpu_dpm_thermal *range =
&adev->pm.dpm.thermal; &adev->pm.dpm.thermal;
uint32_t gpu_temperature, size; uint32_t gpu_temperature, size = sizeof(gpu_temperature);
int ret; int ret;
/* /*

View File

@ -30,9 +30,8 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr)
{ {
int result; int result;
unsigned int i; unsigned int i;
unsigned int table_entries;
struct pp_power_state *state; struct pp_power_state *state;
int size; int size, table_entries;
if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL) if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
return 0; return 0;
@ -40,15 +39,19 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr)
if (hwmgr->hwmgr_func->get_power_state_size == NULL) if (hwmgr->hwmgr_func->get_power_state_size == NULL)
return 0; return 0;
hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr); table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) + size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
sizeof(struct pp_power_state); sizeof(struct pp_power_state);
if (table_entries == 0 || size == 0) { if (table_entries <= 0 || size == 0) {
pr_warn("Please check whether power state management is supported on this asic\n"); pr_warn("Please check whether power state management is supported on this asic\n");
hwmgr->num_ps = 0;
hwmgr->ps_size = 0;
return 0; return 0;
} }
hwmgr->num_ps = table_entries;
hwmgr->ps_size = size;
hwmgr->ps = kcalloc(table_entries, size, GFP_KERNEL); hwmgr->ps = kcalloc(table_entries, size, GFP_KERNEL);
if (hwmgr->ps == NULL) if (hwmgr->ps == NULL)

View File

@ -73,6 +73,7 @@ static int atomctrl_retrieve_ac_timing(
j++; j++;
} else if ((table->mc_reg_address[i].uc_pre_reg_data & } else if ((table->mc_reg_address[i].uc_pre_reg_data &
LOW_NIBBLE_MASK) == DATA_EQU_PREV) { LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
if (i)
table->mc_reg_table_entry[num_ranges].mc_data[i] = table->mc_reg_table_entry[num_ranges].mc_data[i] =
table->mc_reg_table_entry[num_ranges].mc_data[i-1]; table->mc_reg_table_entry[num_ranges].mc_data[i-1];
} }

View File

@ -1036,7 +1036,9 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
switch (type) { switch (type) {
case PP_SCLK: case PP_SCLK:
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now);
if (ret)
return ret;
/* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */ /* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
if (now == data->gfx_max_freq_limit/100) if (now == data->gfx_max_freq_limit/100)
@ -1057,7 +1059,9 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
i == 2 ? "*" : ""); i == 2 ? "*" : "");
break; break;
case PP_MCLK: case PP_MCLK:
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency, &now);
if (ret)
return ret;
for (i = 0; i < mclk_table->count; i++) for (i = 0; i < mclk_table->count; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -1550,7 +1554,10 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr,
} }
if (input[0] == 0) { if (input[0] == 0) {
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq);
if (ret)
return ret;
if (input[1] < min_freq) { if (input[1] < min_freq) {
pr_err("Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", pr_err("Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
input[1], min_freq); input[1], min_freq);
@ -1558,7 +1565,10 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr,
} }
smu10_data->gfx_actual_soft_min_freq = input[1]; smu10_data->gfx_actual_soft_min_freq = input[1];
} else if (input[0] == 1) { } else if (input[0] == 1) {
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq);
if (ret)
return ret;
if (input[1] > max_freq) { if (input[1] > max_freq) {
pr_err("Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", pr_err("Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
input[1], max_freq); input[1], max_freq);
@ -1573,10 +1583,15 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr,
pr_err("Input parameter number not correct\n"); pr_err("Input parameter number not correct\n");
return -EINVAL; return -EINVAL;
} }
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq); if (ret)
return ret;
smu10_data->gfx_actual_soft_min_freq = min_freq; smu10_data->gfx_actual_soft_min_freq = min_freq;
ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq);
if (ret)
return ret;
smu10_data->gfx_actual_soft_max_freq = max_freq; smu10_data->gfx_actual_soft_max_freq = max_freq;
} else if (type == PP_OD_COMMIT_DPM_TABLE) { } else if (type == PP_OD_COMMIT_DPM_TABLE) {
if (size != 0) { if (size != 0) {

View File

@ -5641,7 +5641,7 @@ static int smu7_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint
mode = input[size]; mode = input[size];
switch (mode) { switch (mode) {
case PP_SMC_POWER_PROFILE_CUSTOM: case PP_SMC_POWER_PROFILE_CUSTOM:
if (size < 8 && size != 0) if (size != 8 && size != 0)
return -EINVAL; return -EINVAL;
/* If only CUSTOM is passed in, use the saved values. Check /* If only CUSTOM is passed in, use the saved values. Check
* that we actually have a CUSTOM profile by ensuring that * that we actually have a CUSTOM profile by ensuring that

View File

@ -584,6 +584,7 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr)
hwmgr->dyn_state.uvd_clock_voltage_dependency_table; hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
unsigned long clock = 0; unsigned long clock = 0;
uint32_t level; uint32_t level;
int ret;
if (NULL == table || table->count <= 0) if (NULL == table || table->count <= 0)
return -EINVAL; return -EINVAL;
@ -591,7 +592,9 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr)
data->uvd_dpm.soft_min_clk = 0; data->uvd_dpm.soft_min_clk = 0;
data->uvd_dpm.hard_min_clk = 0; data->uvd_dpm.hard_min_clk = 0;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxUvdLevel, &level); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxUvdLevel, &level);
if (ret)
return ret;
if (level < table->count) if (level < table->count)
clock = table->entries[level].vclk; clock = table->entries[level].vclk;
@ -611,6 +614,7 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr)
hwmgr->dyn_state.vce_clock_voltage_dependency_table; hwmgr->dyn_state.vce_clock_voltage_dependency_table;
unsigned long clock = 0; unsigned long clock = 0;
uint32_t level; uint32_t level;
int ret;
if (NULL == table || table->count <= 0) if (NULL == table || table->count <= 0)
return -EINVAL; return -EINVAL;
@ -618,7 +622,9 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr)
data->vce_dpm.soft_min_clk = 0; data->vce_dpm.soft_min_clk = 0;
data->vce_dpm.hard_min_clk = 0; data->vce_dpm.hard_min_clk = 0;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxEclkLevel, &level); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxEclkLevel, &level);
if (ret)
return ret;
if (level < table->count) if (level < table->count)
clock = table->entries[level].ecclk; clock = table->entries[level].ecclk;
@ -638,6 +644,7 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr)
hwmgr->dyn_state.acp_clock_voltage_dependency_table; hwmgr->dyn_state.acp_clock_voltage_dependency_table;
unsigned long clock = 0; unsigned long clock = 0;
uint32_t level; uint32_t level;
int ret;
if (NULL == table || table->count <= 0) if (NULL == table || table->count <= 0)
return -EINVAL; return -EINVAL;
@ -645,7 +652,9 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr)
data->acp_dpm.soft_min_clk = 0; data->acp_dpm.soft_min_clk = 0;
data->acp_dpm.hard_min_clk = 0; data->acp_dpm.hard_min_clk = 0;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxAclkLevel, &level); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxAclkLevel, &level);
if (ret)
return ret;
if (level < table->count) if (level < table->count)
clock = table->entries[level].acpclk; clock = table->entries[level].acpclk;

View File

@ -354,13 +354,13 @@ static int vega10_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
return 0; return 0;
} }
static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) static int vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
{ {
struct vega10_hwmgr *data = hwmgr->backend; struct vega10_hwmgr *data = hwmgr->backend;
int i;
uint32_t sub_vendor_id, hw_revision; uint32_t sub_vendor_id, hw_revision;
uint32_t top32, bottom32; uint32_t top32, bottom32;
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
int ret, i;
vega10_initialize_power_tune_defaults(hwmgr); vega10_initialize_power_tune_defaults(hwmgr);
@ -485,9 +485,12 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
if (data->registry_data.vr0hot_enabled) if (data->registry_data.vr0hot_enabled)
data->smu_features[GNLD_VR0HOT].supported = true; data->smu_features[GNLD_VR0HOT].supported = true;
smum_send_msg_to_smc(hwmgr, ret = smum_send_msg_to_smc(hwmgr,
PPSMC_MSG_GetSmuVersion, PPSMC_MSG_GetSmuVersion,
&hwmgr->smu_version); &hwmgr->smu_version);
if (ret)
return ret;
/* ACG firmware has major version 5 */ /* ACG firmware has major version 5 */
if ((hwmgr->smu_version & 0xff000000) == 0x5000000) if ((hwmgr->smu_version & 0xff000000) == 0x5000000)
data->smu_features[GNLD_ACG].supported = true; data->smu_features[GNLD_ACG].supported = true;
@ -505,10 +508,16 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
data->smu_features[GNLD_PCC_LIMIT].supported = true; data->smu_features[GNLD_PCC_LIMIT].supported = true;
/* Get the SN to turn into a Unique ID */ /* Get the SN to turn into a Unique ID */
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); if (ret)
return ret;
ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
if (ret)
return ret;
adev->unique_id = ((uint64_t)bottom32 << 32) | top32; adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
return 0;
} }
#ifdef PPLIB_VEGA10_EVV_SUPPORT #ifdef PPLIB_VEGA10_EVV_SUPPORT
@ -882,7 +891,9 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
vega10_set_features_platform_caps(hwmgr); vega10_set_features_platform_caps(hwmgr);
vega10_init_dpm_defaults(hwmgr); result = vega10_init_dpm_defaults(hwmgr);
if (result)
return result;
#ifdef PPLIB_VEGA10_EVV_SUPPORT #ifdef PPLIB_VEGA10_EVV_SUPPORT
/* Get leakage voltage based on leakage ID. */ /* Get leakage voltage based on leakage ID. */
@ -2350,15 +2361,20 @@ static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
{ {
struct vega10_hwmgr *data = hwmgr->backend; struct vega10_hwmgr *data = hwmgr->backend;
uint32_t agc_btc_response; uint32_t agc_btc_response;
int ret;
if (data->smu_features[GNLD_ACG].supported) { if (data->smu_features[GNLD_ACG].supported) {
if (0 == vega10_enable_smc_features(hwmgr, true, if (0 == vega10_enable_smc_features(hwmgr, true,
data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap)) data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap))
data->smu_features[GNLD_DPM_PREFETCHER].enabled = true; data->smu_features[GNLD_DPM_PREFETCHER].enabled = true;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg, NULL); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg, NULL);
if (ret)
return ret;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc, &agc_btc_response); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc, &agc_btc_response);
if (ret)
agc_btc_response = 0;
if (1 == agc_btc_response) { if (1 == agc_btc_response) {
if (1 == data->acg_loop_state) if (1 == data->acg_loop_state)
@ -2571,8 +2587,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
} }
} }
pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC, result = pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC,
VOLTAGE_OBJ_SVID2, &voltage_table); VOLTAGE_OBJ_SVID2, &voltage_table);
PP_ASSERT_WITH_CODE(!result,
"Failed to get voltage table!",
return result);
pp_table->MaxVidStep = voltage_table.max_vid_step; pp_table->MaxVidStep = voltage_table.max_vid_step;
pp_table->GfxDpmVoltageMode = pp_table->GfxDpmVoltageMode =
@ -3910,11 +3929,14 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
uint32_t *query) uint32_t *query)
{ {
uint32_t value; uint32_t value;
int ret;
if (!query) if (!query)
return -EINVAL; return -EINVAL;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr, &value); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr, &value);
if (ret)
return ret;
/* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */ /* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */
*query = value << 8; *query = value << 8;
@ -4810,14 +4832,16 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width; uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
PPTable_t *pptable = &(data->smc_state_table.pp_table); PPTable_t *pptable = &(data->smc_state_table.pp_table);
int i, now, size = 0, count = 0; int i, ret, now, size = 0, count = 0;
switch (type) { switch (type) {
case PP_SCLK: case PP_SCLK:
if (data->registry_data.sclk_dpm_key_disabled) if (data->registry_data.sclk_dpm_key_disabled)
break; break;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex, &now); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex, &now);
if (ret)
break;
if (hwmgr->pp_one_vf && if (hwmgr->pp_one_vf &&
(hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)) (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK))
@ -4833,7 +4857,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
if (data->registry_data.mclk_dpm_key_disabled) if (data->registry_data.mclk_dpm_key_disabled)
break; break;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now);
if (ret)
break;
for (i = 0; i < mclk_table->count; i++) for (i = 0; i < mclk_table->count; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -4844,7 +4870,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
if (data->registry_data.socclk_dpm_key_disabled) if (data->registry_data.socclk_dpm_key_disabled)
break; break;
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now);
if (ret)
break;
for (i = 0; i < soc_table->count; i++) for (i = 0; i < soc_table->count; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",
@ -4855,8 +4883,10 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
if (data->registry_data.dcefclk_dpm_key_disabled) if (data->registry_data.dcefclk_dpm_key_disabled)
break; break;
smum_send_msg_to_smc_with_parameter(hwmgr, ret = smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now); PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now);
if (ret)
break;
for (i = 0; i < dcef_table->count; i++) for (i = 0; i < dcef_table->count; i++)
size += sprintf(buf + size, "%d: %uMhz %s\n", size += sprintf(buf + size, "%d: %uMhz %s\n",

View File

@ -293,12 +293,12 @@ static int vega12_set_features_platform_caps(struct pp_hwmgr *hwmgr)
return 0; return 0;
} }
static void vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr) static int vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr)
{ {
struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
uint32_t top32, bottom32; uint32_t top32, bottom32;
int i; int i, ret;
data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id = data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
FEATURE_DPM_PREFETCHER_BIT; FEATURE_DPM_PREFETCHER_BIT;
@ -364,10 +364,16 @@ static void vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr)
} }
/* Get the SN to turn into a Unique ID */ /* Get the SN to turn into a Unique ID */
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); if (ret)
return ret;
ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
if (ret)
return ret;
adev->unique_id = ((uint64_t)bottom32 << 32) | top32; adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
return 0;
} }
static int vega12_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr) static int vega12_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
@ -410,7 +416,11 @@ static int vega12_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
vega12_set_features_platform_caps(hwmgr); vega12_set_features_platform_caps(hwmgr);
vega12_init_dpm_defaults(hwmgr); result = vega12_init_dpm_defaults(hwmgr);
if (result) {
pr_err("%s failed\n", __func__);
return result;
}
/* Parse pptable data read from VBIOS */ /* Parse pptable data read from VBIOS */
vega12_set_private_data_based_on_pptable(hwmgr); vega12_set_private_data_based_on_pptable(hwmgr);

View File

@ -328,12 +328,12 @@ static int vega20_set_features_platform_caps(struct pp_hwmgr *hwmgr)
return 0; return 0;
} }
static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr) static int vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr)
{ {
struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend);
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
uint32_t top32, bottom32; uint32_t top32, bottom32;
int i; int i, ret;
data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id = data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
FEATURE_DPM_PREFETCHER_BIT; FEATURE_DPM_PREFETCHER_BIT;
@ -404,10 +404,17 @@ static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr)
} }
/* Get the SN to turn into a Unique ID */ /* Get the SN to turn into a Unique ID */
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); if (ret)
return ret;
ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
if (ret)
return ret;
adev->unique_id = ((uint64_t)bottom32 << 32) | top32; adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
return 0;
} }
static int vega20_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr) static int vega20_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
@ -427,6 +434,7 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
{ {
struct vega20_hwmgr *data; struct vega20_hwmgr *data;
struct amdgpu_device *adev = hwmgr->adev; struct amdgpu_device *adev = hwmgr->adev;
int result;
data = kzalloc(sizeof(struct vega20_hwmgr), GFP_KERNEL); data = kzalloc(sizeof(struct vega20_hwmgr), GFP_KERNEL);
if (data == NULL) if (data == NULL)
@ -452,8 +460,11 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
vega20_set_features_platform_caps(hwmgr); vega20_set_features_platform_caps(hwmgr);
vega20_init_dpm_defaults(hwmgr); result = vega20_init_dpm_defaults(hwmgr);
if (result) {
pr_err("%s failed\n", __func__);
return result;
}
/* Parse pptable data read from VBIOS */ /* Parse pptable data read from VBIOS */
vega20_set_private_data_based_on_pptable(hwmgr); vega20_set_private_data_based_on_pptable(hwmgr);
@ -4091,9 +4102,11 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
struct vega20_hwmgr *data = struct vega20_hwmgr *data =
(struct vega20_hwmgr *)(hwmgr->backend); (struct vega20_hwmgr *)(hwmgr->backend);
if (size == 0 && !data->is_custom_profile_set)
if (size != 10 && size != 0)
return -EINVAL; return -EINVAL;
if (size < 10 && size != 0)
if (size == 0 && !data->is_custom_profile_set)
return -EINVAL; return -EINVAL;
result = vega20_get_activity_monitor_coeff(hwmgr, result = vega20_get_activity_monitor_coeff(hwmgr,
@ -4155,6 +4168,8 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
activity_monitor.Fclk_PD_Data_error_coeff = input[8]; activity_monitor.Fclk_PD_Data_error_coeff = input[8];
activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9]; activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9];
break; break;
default:
return -EINVAL;
} }
result = vega20_set_activity_monitor_coeff(hwmgr, result = vega20_set_activity_monitor_coeff(hwmgr,

View File

@ -130,13 +130,17 @@ int vega10_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
uint64_t *features_enabled) uint64_t *features_enabled)
{ {
uint32_t enabled_features; uint32_t enabled_features;
int ret;
if (features_enabled == NULL) if (features_enabled == NULL)
return -EINVAL; return -EINVAL;
smum_send_msg_to_smc(hwmgr, ret = smum_send_msg_to_smc(hwmgr,
PPSMC_MSG_GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures,
&enabled_features); &enabled_features);
if (ret)
return ret;
*features_enabled = enabled_features; *features_enabled = enabled_features;
return 0; return 0;

View File

@ -1222,19 +1222,22 @@ static int navi10_get_current_clk_freq_by_table(struct smu_context *smu,
value); value);
} }
static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type) static int navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type)
{ {
PPTable_t *pptable = smu->smu_table.driver_pptable; PPTable_t *pptable = smu->smu_table.driver_pptable;
DpmDescriptor_t *dpm_desc = NULL; DpmDescriptor_t *dpm_desc = NULL;
uint32_t clk_index = 0; int clk_index = 0;
clk_index = smu_cmn_to_asic_specific_index(smu, clk_index = smu_cmn_to_asic_specific_index(smu,
CMN2ASIC_MAPPING_CLK, CMN2ASIC_MAPPING_CLK,
clk_type); clk_type);
if (clk_index < 0)
return clk_index;
dpm_desc = &pptable->DpmDescriptor[clk_index]; dpm_desc = &pptable->DpmDescriptor[clk_index];
/* 0 - Fine grained DPM, 1 - Discrete DPM */ /* 0 - Fine grained DPM, 1 - Discrete DPM */
return dpm_desc->SnapToDiscrete == 0; return dpm_desc->SnapToDiscrete == 0 ? 1 : 0;
} }
static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap) static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap)
@ -1290,7 +1293,11 @@ static int navi10_emit_clk_levels(struct smu_context *smu,
if (ret) if (ret)
return ret; return ret;
if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
if (ret < 0)
return ret;
if (!ret) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ret = smu_v11_0_get_dpm_freq_by_index(smu, ret = smu_v11_0_get_dpm_freq_by_index(smu,
clk_type, i, &value); clk_type, i, &value);
@ -1499,7 +1506,11 @@ static int navi10_print_clk_levels(struct smu_context *smu,
if (ret) if (ret)
return size; return size;
if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
if (ret < 0)
return ret;
if (!ret) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value); ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
if (ret) if (ret)
@ -1668,7 +1679,11 @@ static int navi10_force_clk_levels(struct smu_context *smu,
case SMU_UCLK: case SMU_UCLK:
case SMU_FCLK: case SMU_FCLK:
/* There is only 2 levels for fine grained DPM */ /* There is only 2 levels for fine grained DPM */
if (navi10_is_support_fine_grained_dpm(smu, clk_type)) { ret = navi10_is_support_fine_grained_dpm(smu, clk_type);
if (ret < 0)
return ret;
if (ret) {
soft_max_level = (soft_max_level >= 1 ? 1 : 0); soft_max_level = (soft_max_level >= 1 ? 1 : 0);
soft_min_level = (soft_min_level >= 1 ? 1 : 0); soft_min_level = (soft_min_level >= 1 ? 1 : 0);
} }

View File

@ -1009,6 +1009,18 @@ static int vangogh_get_dpm_ultimate_freq(struct smu_context *smu,
} }
} }
if (min) { if (min) {
ret = vangogh_get_profiling_clk_mask(smu,
AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK,
NULL,
NULL,
&mclk_mask,
&fclk_mask,
&soc_mask);
if (ret)
goto failed;
vclk_mask = dclk_mask = 0;
switch (clk_type) { switch (clk_type) {
case SMU_UCLK: case SMU_UCLK:
case SMU_MCLK: case SMU_MCLK:
@ -2481,6 +2493,8 @@ static u32 vangogh_set_gfxoff_residency(struct smu_context *smu, bool start)
ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_LogGfxOffResidency, ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_LogGfxOffResidency,
start, &residency); start, &residency);
if (ret)
return ret;
if (!start) if (!start)
adev->gfx.gfx_off_residency = residency; adev->gfx.gfx_off_residency = residency;

View File

@ -1931,7 +1931,8 @@ static int aldebaran_mode2_reset(struct smu_context *smu)
index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
SMU_MSG_GfxDeviceDriverReset); SMU_MSG_GfxDeviceDriverReset);
if (index < 0 )
return -EINVAL;
mutex_lock(&smu->message_lock); mutex_lock(&smu->message_lock);
if (smu_version >= 0x00441400) { if (smu_version >= 0x00441400) {
ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, SMU_RESET_MODE_2); ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, SMU_RESET_MODE_2);

View File

@ -2058,6 +2058,8 @@ static int smu_v13_0_6_mode2_reset(struct smu_context *smu)
index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
SMU_MSG_GfxDeviceDriverReset); SMU_MSG_GfxDeviceDriverReset);
if (index < 0)
return index;
mutex_lock(&smu->message_lock); mutex_lock(&smu->message_lock);

View File

@ -2034,7 +2034,7 @@ static irqreturn_t tc_irq_handler(int irq, void *arg)
dev_err(tc->dev, "syserr %x\n", stat); dev_err(tc->dev, "syserr %x\n", stat);
} }
if (tc->hpd_pin >= 0 && tc->bridge.dev) { if (tc->hpd_pin >= 0 && tc->bridge.dev && tc->aux.drm_dev) {
/* /*
* H is triggered when the GPIO goes high. * H is triggered when the GPIO goes high.
* *

View File

@ -631,6 +631,17 @@ static void drm_fb_helper_add_damage_clip(struct drm_fb_helper *helper, u32 x, u
static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y, static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
u32 width, u32 height) u32 width, u32 height)
{ {
/*
* This function may be invoked by panic() to flush the frame
* buffer, where all CPUs except the panic CPU are stopped.
* During the following schedule_work(), the panic CPU needs
* the worker_pool lock, which might be held by a stopped CPU,
* causing schedule_work() and panic() to block. Return early on
* oops_in_progress to prevent this blocking.
*/
if (oops_in_progress)
return;
drm_fb_helper_add_damage_clip(helper, x, y, width, height); drm_fb_helper_add_damage_clip(helper, x, y, width, height);
schedule_work(&helper->damage_work); schedule_work(&helper->damage_work);

View File

@ -414,6 +414,12 @@ static const struct dmi_system_id orientation_data[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"),
}, },
.driver_data = (void *)&lcd1600x2560_leftside_up, .driver_data = (void *)&lcd1600x2560_leftside_up,
}, { /* OrangePi Neo */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "OrangePi"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "NEO-01"),
},
.driver_data = (void *)&lcd1200x1920_rightside_up,
}, { /* Samsung GalaxyBook 10.6 */ }, { /* Samsung GalaxyBook 10.6 */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),

View File

@ -534,6 +534,7 @@ int meson_plane_create(struct meson_drm *priv)
struct meson_plane *meson_plane; struct meson_plane *meson_plane;
struct drm_plane *plane; struct drm_plane *plane;
const uint64_t *format_modifiers = format_modifiers_default; const uint64_t *format_modifiers = format_modifiers_default;
int ret;
meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane), meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane),
GFP_KERNEL); GFP_KERNEL);
@ -548,12 +549,16 @@ int meson_plane_create(struct meson_drm *priv)
else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
format_modifiers = format_modifiers_afbc_g12a; format_modifiers = format_modifiers_afbc_g12a;
drm_universal_plane_init(priv->drm, plane, 0xFF, ret = drm_universal_plane_init(priv->drm, plane, 0xFF,
&meson_plane_funcs, &meson_plane_funcs,
supported_drm_formats, supported_drm_formats,
ARRAY_SIZE(supported_drm_formats), ARRAY_SIZE(supported_drm_formats),
format_modifiers, format_modifiers,
DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
if (ret) {
devm_kfree(priv->drm->dev, meson_plane);
return ret;
}
drm_plane_helper_add(plane, &meson_plane_helper_funcs); drm_plane_helper_add(plane, &meson_plane_helper_funcs);

View File

@ -153,8 +153,9 @@ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval) static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
{ {
amd_smn_read(amd_pci_dev_to_node_id(pdev), if (amd_smn_read(amd_pci_dev_to_node_id(pdev),
ZEN_REPORTED_TEMP_CTRL_BASE, regval); ZEN_REPORTED_TEMP_CTRL_BASE, regval))
*regval = 0;
} }
static long get_raw_temp(struct k10temp_data *data) static long get_raw_temp(struct k10temp_data *data)
@ -205,6 +206,7 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
long *val) long *val)
{ {
struct k10temp_data *data = dev_get_drvdata(dev); struct k10temp_data *data = dev_get_drvdata(dev);
int ret = -EOPNOTSUPP;
u32 regval; u32 regval;
switch (attr) { switch (attr) {
@ -221,13 +223,17 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
*val = 0; *val = 0;
break; break;
case 2 ... 13: /* Tccd{1-12} */ case 2 ... 13: /* Tccd{1-12} */
amd_smn_read(amd_pci_dev_to_node_id(data->pdev), ret = amd_smn_read(amd_pci_dev_to_node_id(data->pdev),
ZEN_CCD_TEMP(data->ccd_offset, channel - 2), ZEN_CCD_TEMP(data->ccd_offset, channel - 2),
&regval); &regval);
if (ret)
return ret;
*val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000; *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
break; break;
default: default:
return -EOPNOTSUPP; return ret;
} }
break; break;
case hwmon_temp_max: case hwmon_temp_max:
@ -243,7 +249,7 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
- ((regval >> 24) & 0xf)) * 500 + 52000; - ((regval >> 24) & 0xf)) * 500 + 52000;
break; break;
default: default:
return -EOPNOTSUPP; return ret;
} }
return 0; return 0;
} }
@ -381,8 +387,20 @@ static void k10temp_get_ccd_support(struct pci_dev *pdev,
int i; int i;
for (i = 0; i < limit; i++) { for (i = 0; i < limit; i++) {
amd_smn_read(amd_pci_dev_to_node_id(pdev), /*
ZEN_CCD_TEMP(data->ccd_offset, i), &regval); * Ignore inaccessible CCDs.
*
* Some systems will return a register value of 0, and the TEMP_VALID
* bit check below will naturally fail.
*
* Other systems will return a PCI_ERROR_RESPONSE (0xFFFFFFFF) for
* the register value. And this will incorrectly pass the TEMP_VALID
* bit check.
*/
if (amd_smn_read(amd_pci_dev_to_node_id(pdev),
ZEN_CCD_TEMP(data->ccd_offset, i), &regval))
continue;
if (regval & ZEN_CCD_TEMP_VALID) if (regval & ZEN_CCD_TEMP_VALID)
data->show_temp |= BIT(TCCD_BIT(i)); data->show_temp |= BIT(TCCD_BIT(i));
} }

View File

@ -752,9 +752,11 @@ static ssize_t iio_read_channel_info(struct device *dev,
INDIO_MAX_RAW_ELEMENTS, INDIO_MAX_RAW_ELEMENTS,
vals, &val_len, vals, &val_len,
this_attr->address); this_attr->address);
else else if (indio_dev->info->read_raw)
ret = indio_dev->info->read_raw(indio_dev, this_attr->c, ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
&vals[0], &vals[1], this_attr->address); &vals[0], &vals[1], this_attr->address);
else
return -EINVAL;
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -836,6 +838,9 @@ static ssize_t iio_read_channel_info_avail(struct device *dev,
int length; int length;
int type; int type;
if (!indio_dev->info->read_avail)
return -EINVAL;
ret = indio_dev->info->read_avail(indio_dev, this_attr->c, ret = indio_dev->info->read_avail(indio_dev, this_attr->c,
&vals, &type, &length, &vals, &type, &length,
this_attr->address); this_attr->address);

View File

@ -285,6 +285,9 @@ static ssize_t iio_ev_state_store(struct device *dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (!indio_dev->info->write_event_config)
return -EINVAL;
ret = indio_dev->info->write_event_config(indio_dev, ret = indio_dev->info->write_event_config(indio_dev,
this_attr->c, iio_ev_attr_type(this_attr), this_attr->c, iio_ev_attr_type(this_attr),
iio_ev_attr_dir(this_attr), val); iio_ev_attr_dir(this_attr), val);
@ -300,6 +303,9 @@ static ssize_t iio_ev_state_show(struct device *dev,
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
int val; int val;
if (!indio_dev->info->read_event_config)
return -EINVAL;
val = indio_dev->info->read_event_config(indio_dev, val = indio_dev->info->read_event_config(indio_dev,
this_attr->c, iio_ev_attr_type(this_attr), this_attr->c, iio_ev_attr_type(this_attr),
iio_ev_attr_dir(this_attr)); iio_ev_attr_dir(this_attr));
@ -318,6 +324,9 @@ static ssize_t iio_ev_value_show(struct device *dev,
int val, val2, val_arr[2]; int val, val2, val_arr[2];
int ret; int ret;
if (!indio_dev->info->read_event_value)
return -EINVAL;
ret = indio_dev->info->read_event_value(indio_dev, ret = indio_dev->info->read_event_value(indio_dev,
this_attr->c, iio_ev_attr_type(this_attr), this_attr->c, iio_ev_attr_type(this_attr),
iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr), iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),

View File

@ -562,6 +562,7 @@ EXPORT_SYMBOL_GPL(devm_iio_channel_get_all);
static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
enum iio_chan_info_enum info) enum iio_chan_info_enum info)
{ {
const struct iio_info *iio_info = chan->indio_dev->info;
int unused; int unused;
int vals[INDIO_MAX_RAW_ELEMENTS]; int vals[INDIO_MAX_RAW_ELEMENTS];
int ret; int ret;
@ -573,15 +574,18 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
if (!iio_channel_has_info(chan->channel, info)) if (!iio_channel_has_info(chan->channel, info))
return -EINVAL; return -EINVAL;
if (chan->indio_dev->info->read_raw_multi) { if (iio_info->read_raw_multi) {
ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, ret = iio_info->read_raw_multi(chan->indio_dev,
chan->channel, INDIO_MAX_RAW_ELEMENTS, chan->channel,
INDIO_MAX_RAW_ELEMENTS,
vals, &val_len, info); vals, &val_len, info);
*val = vals[0]; *val = vals[0];
*val2 = vals[1]; *val2 = vals[1];
} else { } else if (iio_info->read_raw) {
ret = chan->indio_dev->info->read_raw(chan->indio_dev, ret = iio_info->read_raw(chan->indio_dev,
chan->channel, val, val2, info); chan->channel, val, val2, info);
} else {
return -EINVAL;
} }
return ret; return ret;
@ -801,11 +805,15 @@ static int iio_channel_read_avail(struct iio_channel *chan,
const int **vals, int *type, int *length, const int **vals, int *type, int *length,
enum iio_chan_info_enum info) enum iio_chan_info_enum info)
{ {
const struct iio_info *iio_info = chan->indio_dev->info;
if (!iio_channel_has_available(chan->channel, info)) if (!iio_channel_has_available(chan->channel, info))
return -EINVAL; return -EINVAL;
return chan->indio_dev->info->read_avail(chan->indio_dev, chan->channel, if (iio_info->read_avail)
return iio_info->read_avail(chan->indio_dev, chan->channel,
vals, type, length, info); vals, type, length, info);
return -EINVAL;
} }
int iio_read_avail_channel_attribute(struct iio_channel *chan, int iio_read_avail_channel_attribute(struct iio_channel *chan,
@ -995,8 +1003,12 @@ EXPORT_SYMBOL_GPL(iio_get_channel_type);
static int iio_channel_write(struct iio_channel *chan, int val, int val2, static int iio_channel_write(struct iio_channel *chan, int val, int val2,
enum iio_chan_info_enum info) enum iio_chan_info_enum info)
{ {
return chan->indio_dev->info->write_raw(chan->indio_dev, const struct iio_info *iio_info = chan->indio_dev->info;
if (iio_info->write_raw)
return iio_info->write_raw(chan->indio_dev,
chan->channel, val, val2, info); chan->channel, val, val2, info);
return -EINVAL;
} }
int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2, int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
/* /*
* Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved. * Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved.
*/ */
#include "efa_com.h" #include "efa_com.h"
@ -406,7 +406,7 @@ static struct efa_comp_ctx *efa_com_submit_admin_cmd(struct efa_com_admin_queue
return comp_ctx; return comp_ctx;
} }
static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq, static int efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq,
struct efa_admin_acq_entry *cqe) struct efa_admin_acq_entry *cqe)
{ {
struct efa_comp_ctx *comp_ctx; struct efa_comp_ctx *comp_ctx;
@ -416,11 +416,11 @@ static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *a
EFA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID); EFA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID);
comp_ctx = efa_com_get_comp_ctx(aq, cmd_id, false); comp_ctx = efa_com_get_comp_ctx(aq, cmd_id, false);
if (!comp_ctx) { if (comp_ctx->status != EFA_CMD_SUBMITTED) {
ibdev_err(aq->efa_dev, ibdev_err(aq->efa_dev,
"comp_ctx is NULL. Changing the admin queue running state\n"); "Received completion with unexpected command id[%d], sq producer: %d, sq consumer: %d, cq consumer: %d\n",
clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state); cmd_id, aq->sq.pc, aq->sq.cc, aq->cq.cc);
return; return -EINVAL;
} }
comp_ctx->status = EFA_CMD_COMPLETED; comp_ctx->status = EFA_CMD_COMPLETED;
@ -428,14 +428,17 @@ static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *a
if (!test_bit(EFA_AQ_STATE_POLLING_BIT, &aq->state)) if (!test_bit(EFA_AQ_STATE_POLLING_BIT, &aq->state))
complete(&comp_ctx->wait_event); complete(&comp_ctx->wait_event);
return 0;
} }
static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq) static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq)
{ {
struct efa_admin_acq_entry *cqe; struct efa_admin_acq_entry *cqe;
u16 queue_size_mask; u16 queue_size_mask;
u16 comp_num = 0; u16 comp_cmds = 0;
u8 phase; u8 phase;
int err;
u16 ci; u16 ci;
queue_size_mask = aq->depth - 1; queue_size_mask = aq->depth - 1;
@ -453,10 +456,12 @@ static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq)
* phase bit was validated * phase bit was validated
*/ */
dma_rmb(); dma_rmb();
efa_com_handle_single_admin_completion(aq, cqe); err = efa_com_handle_single_admin_completion(aq, cqe);
if (!err)
comp_cmds++;
aq->cq.cc++;
ci++; ci++;
comp_num++;
if (ci == aq->depth) { if (ci == aq->depth) {
ci = 0; ci = 0;
phase = !phase; phase = !phase;
@ -465,10 +470,9 @@ static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq)
cqe = &aq->cq.entries[ci]; cqe = &aq->cq.entries[ci];
} }
aq->cq.cc += comp_num;
aq->cq.phase = phase; aq->cq.phase = phase;
aq->sq.cc += comp_num; aq->sq.cc += comp_cmds;
atomic64_add(comp_num, &aq->stats.completed_cmd); atomic64_add(comp_cmds, &aq->stats.completed_cmd);
} }
static int efa_com_comp_status_to_errno(u8 comp_status) static int efa_com_comp_status_to_errno(u8 comp_status)

View File

@ -687,16 +687,26 @@ static int uvc_parse_streaming(struct uvc_device *dev,
goto error; goto error;
} }
size = nformats * sizeof(*format) + nframes * sizeof(*frame) /*
* Allocate memory for the formats, the frames and the intervals,
* plus any required padding to guarantee that everything has the
* correct alignment.
*/
size = nformats * sizeof(*format);
size = ALIGN(size, __alignof__(*frame)) + nframes * sizeof(*frame);
size = ALIGN(size, __alignof__(*interval))
+ nintervals * sizeof(*interval); + nintervals * sizeof(*interval);
format = kzalloc(size, GFP_KERNEL); format = kzalloc(size, GFP_KERNEL);
if (format == NULL) { if (!format) {
ret = -ENOMEM; ret = -ENOMEM;
goto error; goto error;
} }
frame = (struct uvc_frame *)&format[nformats]; frame = (void *)format + nformats * sizeof(*format);
interval = (u32 *)&frame[nframes]; frame = PTR_ALIGN(frame, __alignof__(*frame));
interval = (void *)frame + nframes * sizeof(*frame);
interval = PTR_ALIGN(interval, __alignof__(*interval));
streaming->formats = format; streaming->formats = format;
streaming->nformats = 0; streaming->nformats = 0;

View File

@ -23,6 +23,15 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
u8 buf[8]; u8 buf[8];
int ret; int ret;
/*
* TODO: Fix smatch. Assign *val to 0 here in order to avoid
* failing a smatch check on caller when the caller proceeds to
* read *val without initialising it on caller's side. *val is set
* to a valid value whenever this function returns 0 but smatch
* can't figure that out currently.
*/
*val = 0;
if (err && *err) if (err && *err)
return *err; return *err;

View File

@ -2369,6 +2369,7 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq
if (flush) if (flush)
mlx5e_shampo_flush_skb(rq, cqe, match); mlx5e_shampo_flush_skb(rq, cqe, match);
free_hd_entry: free_hd_entry:
if (likely(head_size))
mlx5e_free_rx_shampo_hd_entry(rq, header_index); mlx5e_free_rx_shampo_hd_entry(rq, header_index);
mpwrq_cqe_out: mpwrq_cqe_out:
if (likely(wi->consumed_strides < rq->mpwqe.num_strides)) if (likely(wi->consumed_strides < rq->mpwqe.num_strides))

View File

@ -7,7 +7,7 @@
/* don't try to optimize STE allocation if the stack is too constaraining */ /* don't try to optimize STE allocation if the stack is too constaraining */
#define DR_RULE_MAX_STES_OPTIMIZED 0 #define DR_RULE_MAX_STES_OPTIMIZED 0
#else #else
#define DR_RULE_MAX_STES_OPTIMIZED 5 #define DR_RULE_MAX_STES_OPTIMIZED 2
#endif #endif
#define DR_RULE_MAX_STE_CHAIN_OPTIMIZED (DR_RULE_MAX_STES_OPTIMIZED + DR_ACTION_MAX_STES) #define DR_RULE_MAX_STE_CHAIN_OPTIMIZED (DR_RULE_MAX_STES_OPTIMIZED + DR_ACTION_MAX_STES)

View File

@ -234,7 +234,7 @@ static int ionic_request_irq(struct ionic_lif *lif, struct ionic_qcq *qcq)
name = dev_name(dev); name = dev_name(dev);
snprintf(intr->name, sizeof(intr->name), snprintf(intr->name, sizeof(intr->name),
"%s-%s-%s", IONIC_DRV_NAME, name, q->name); "%.5s-%.16s-%.8s", IONIC_DRV_NAME, name, q->name);
return devm_request_irq(dev, intr->vector, ionic_isr, return devm_request_irq(dev, intr->vector, ionic_isr,
0, intr->name, &qcq->napi); 0, intr->name, &qcq->napi);

View File

@ -1438,6 +1438,7 @@ static const struct usb_device_id products[] = {
{QMI_QUIRK_SET_DTR(0x1546, 0x1312, 4)}, /* u-blox LARA-R6 01B */ {QMI_QUIRK_SET_DTR(0x1546, 0x1312, 4)}, /* u-blox LARA-R6 01B */
{QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
{QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */ {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
{QMI_FIXED_INTF(0x2dee, 0x4d22, 5)}, /* MeiG Smart SRM825L */
/* 4. Gobi 1000 devices */ /* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */

View File

@ -2140,7 +2140,7 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
return packets; return packets;
} }
static void virtnet_poll_cleantx(struct receive_queue *rq) static void virtnet_poll_cleantx(struct receive_queue *rq, int budget)
{ {
struct virtnet_info *vi = rq->vq->vdev->priv; struct virtnet_info *vi = rq->vq->vdev->priv;
unsigned int index = vq2rxq(rq->vq); unsigned int index = vq2rxq(rq->vq);
@ -2158,7 +2158,7 @@ static void virtnet_poll_cleantx(struct receive_queue *rq)
do { do {
virtqueue_disable_cb(sq->vq); virtqueue_disable_cb(sq->vq);
free_old_xmit_skbs(sq, true); free_old_xmit_skbs(sq, !!budget);
} while (unlikely(!virtqueue_enable_cb_delayed(sq->vq))); } while (unlikely(!virtqueue_enable_cb_delayed(sq->vq)));
if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS)
@ -2177,7 +2177,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
unsigned int received; unsigned int received;
unsigned int xdp_xmit = 0; unsigned int xdp_xmit = 0;
virtnet_poll_cleantx(rq); virtnet_poll_cleantx(rq, budget);
received = virtnet_receive(rq, budget, &xdp_xmit); received = virtnet_receive(rq, budget, &xdp_xmit);
@ -2280,7 +2280,7 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget)
txq = netdev_get_tx_queue(vi->dev, index); txq = netdev_get_tx_queue(vi->dev, index);
__netif_tx_lock(txq, raw_smp_processor_id()); __netif_tx_lock(txq, raw_smp_processor_id());
virtqueue_disable_cb(sq->vq); virtqueue_disable_cb(sq->vq);
free_old_xmit_skbs(sq, true); free_old_xmit_skbs(sq, !!budget);
if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS)
netif_tx_wake_queue(txq); netif_tx_wake_queue(txq);

View File

@ -2293,7 +2293,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,
struct qmi_txn txn; struct qmi_txn txn;
const u8 *temp = data; const u8 *temp = data;
void __iomem *bdf_addr = NULL; void __iomem *bdf_addr = NULL;
int ret; int ret = 0;
u32 remaining = len; u32 remaining = len;
req = kzalloc(sizeof(*req), GFP_KERNEL); req = kzalloc(sizeof(*req), GFP_KERNEL);

View File

@ -2312,7 +2312,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp; struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
struct qmi_txn txn = {}; struct qmi_txn txn = {};
const u8 *temp = data; const u8 *temp = data;
int ret; int ret = 0;
u32 remaining = len; u32 remaining = len;
req = kzalloc(sizeof(*req), GFP_KERNEL); req = kzalloc(sizeof(*req), GFP_KERNEL);

View File

@ -230,8 +230,7 @@ static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf,
.data = { NULL, }, .data = { NULL, },
}; };
if (fwrt->ops && fwrt->ops->fw_running && if (!iwl_trans_fw_running(fwrt->trans))
!fwrt->ops->fw_running(fwrt->ops_ctx))
return -EIO; return -EIO;
if (count < header_size + 1 || count > 1024 * 4) if (count < header_size + 1 || count > 1024 * 4)

View File

@ -18,7 +18,6 @@
struct iwl_fw_runtime_ops { struct iwl_fw_runtime_ops {
void (*dump_start)(void *ctx); void (*dump_start)(void *ctx);
void (*dump_end)(void *ctx); void (*dump_end)(void *ctx);
bool (*fw_running)(void *ctx);
int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd); int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd);
bool (*d3_debug_enable)(void *ctx); bool (*d3_debug_enable)(void *ctx);
}; };

View File

@ -702,11 +702,6 @@ static void iwl_mvm_fwrt_dump_end(void *ctx)
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
} }
static bool iwl_mvm_fwrt_fw_running(void *ctx)
{
return iwl_mvm_firmware_running(ctx);
}
static int iwl_mvm_fwrt_send_hcmd(void *ctx, struct iwl_host_cmd *host_cmd) static int iwl_mvm_fwrt_send_hcmd(void *ctx, struct iwl_host_cmd *host_cmd)
{ {
struct iwl_mvm *mvm = (struct iwl_mvm *)ctx; struct iwl_mvm *mvm = (struct iwl_mvm *)ctx;
@ -727,7 +722,6 @@ static bool iwl_mvm_d3_debug_enable(void *ctx)
static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = {
.dump_start = iwl_mvm_fwrt_dump_start, .dump_start = iwl_mvm_fwrt_dump_start,
.dump_end = iwl_mvm_fwrt_dump_end, .dump_end = iwl_mvm_fwrt_dump_end,
.fw_running = iwl_mvm_fwrt_fw_running,
.send_hcmd = iwl_mvm_fwrt_send_hcmd, .send_hcmd = iwl_mvm_fwrt_send_hcmd,
.d3_debug_enable = iwl_mvm_d3_debug_enable, .d3_debug_enable = iwl_mvm_d3_debug_enable,
}; };

View File

@ -308,9 +308,13 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta) static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta)
{ {
struct rtw89_vif *rtwvif = (struct rtw89_vif *)data; struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data;
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
if (rtwvif != target_rtwvif)
return;
if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls) if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);

View File

@ -242,18 +242,24 @@ static struct pci_ops al_child_pci_ops = {
.write = pci_generic_config_write, .write = pci_generic_config_write,
}; };
static void al_pcie_config_prepare(struct al_pcie *pcie) static int al_pcie_config_prepare(struct al_pcie *pcie)
{ {
struct al_pcie_target_bus_cfg *target_bus_cfg; struct al_pcie_target_bus_cfg *target_bus_cfg;
struct dw_pcie_rp *pp = &pcie->pci->pp; struct dw_pcie_rp *pp = &pcie->pci->pp;
unsigned int ecam_bus_mask; unsigned int ecam_bus_mask;
struct resource_entry *ft;
u32 cfg_control_offset; u32 cfg_control_offset;
struct resource *bus;
u8 subordinate_bus; u8 subordinate_bus;
u8 secondary_bus; u8 secondary_bus;
u32 cfg_control; u32 cfg_control;
u32 reg; u32 reg;
struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
ft = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS);
if (!ft)
return -ENODEV;
bus = ft->res;
target_bus_cfg = &pcie->target_bus_cfg; target_bus_cfg = &pcie->target_bus_cfg;
ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1; ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1;
@ -287,6 +293,8 @@ static void al_pcie_config_prepare(struct al_pcie *pcie)
FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus); FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
al_pcie_controller_writel(pcie, cfg_control_offset, reg); al_pcie_controller_writel(pcie, cfg_control_offset, reg);
return 0;
} }
static int al_pcie_host_init(struct dw_pcie_rp *pp) static int al_pcie_host_init(struct dw_pcie_rp *pp)
@ -305,7 +313,9 @@ static int al_pcie_host_init(struct dw_pcie_rp *pp)
if (rc) if (rc)
return rc; return rc;
al_pcie_config_prepare(pcie); rc = al_pcie_config_prepare(pcie);
if (rc)
return rc;
return 0; return 0;
} }

View File

@ -10,13 +10,65 @@
#include "cros_ec_lpc_mec.h" #include "cros_ec_lpc_mec.h"
#define ACPI_LOCK_DELAY_MS 500
/* /*
* This mutex must be held while accessing the EMI unit. We can't rely on the * This mutex must be held while accessing the EMI unit. We can't rely on the
* EC mutex because memmap data may be accessed without it being held. * EC mutex because memmap data may be accessed without it being held.
*/ */
static DEFINE_MUTEX(io_mutex); static DEFINE_MUTEX(io_mutex);
/*
* An alternative mutex to be used when the ACPI AML code may also
* access memmap data. When set, this mutex is used in preference to
* io_mutex.
*/
static acpi_handle aml_mutex;
static u16 mec_emi_base, mec_emi_end; static u16 mec_emi_base, mec_emi_end;
/**
* cros_ec_lpc_mec_lock() - Acquire mutex for EMI
*
* @return: Negative error code, or zero for success
*/
static int cros_ec_lpc_mec_lock(void)
{
bool success;
if (!aml_mutex) {
mutex_lock(&io_mutex);
return 0;
}
success = ACPI_SUCCESS(acpi_acquire_mutex(aml_mutex,
NULL, ACPI_LOCK_DELAY_MS));
if (!success)
return -EBUSY;
return 0;
}
/**
* cros_ec_lpc_mec_unlock() - Release mutex for EMI
*
* @return: Negative error code, or zero for success
*/
static int cros_ec_lpc_mec_unlock(void)
{
bool success;
if (!aml_mutex) {
mutex_unlock(&io_mutex);
return 0;
}
success = ACPI_SUCCESS(acpi_release_mutex(aml_mutex, NULL));
if (!success)
return -EBUSY;
return 0;
}
/** /**
* cros_ec_lpc_mec_emi_write_address() - Initialize EMI at a given address. * cros_ec_lpc_mec_emi_write_address() - Initialize EMI at a given address.
* *
@ -77,6 +129,7 @@ u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type,
int io_addr; int io_addr;
u8 sum = 0; u8 sum = 0;
enum cros_ec_lpc_mec_emi_access_mode access, new_access; enum cros_ec_lpc_mec_emi_access_mode access, new_access;
int ret;
/* Return checksum of 0 if window is not initialized */ /* Return checksum of 0 if window is not initialized */
WARN_ON(mec_emi_base == 0 || mec_emi_end == 0); WARN_ON(mec_emi_base == 0 || mec_emi_end == 0);
@ -92,7 +145,9 @@ u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type,
else else
access = ACCESS_TYPE_LONG_AUTO_INCREMENT; access = ACCESS_TYPE_LONG_AUTO_INCREMENT;
mutex_lock(&io_mutex); ret = cros_ec_lpc_mec_lock();
if (ret)
return ret;
/* Initialize I/O at desired address */ /* Initialize I/O at desired address */
cros_ec_lpc_mec_emi_write_address(offset, access); cros_ec_lpc_mec_emi_write_address(offset, access);
@ -134,7 +189,9 @@ u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type,
} }
done: done:
mutex_unlock(&io_mutex); ret = cros_ec_lpc_mec_unlock();
if (ret)
return ret;
return sum; return sum;
} }
@ -146,3 +203,18 @@ void cros_ec_lpc_mec_init(unsigned int base, unsigned int end)
mec_emi_end = end; mec_emi_end = end;
} }
EXPORT_SYMBOL(cros_ec_lpc_mec_init); EXPORT_SYMBOL(cros_ec_lpc_mec_init);
int cros_ec_lpc_mec_acpi_mutex(struct acpi_device *adev, const char *pathname)
{
int status;
if (!adev)
return -ENOENT;
status = acpi_get_handle(adev->handle, pathname, &aml_mutex);
if (ACPI_FAILURE(status))
return -ENOENT;
return 0;
}
EXPORT_SYMBOL(cros_ec_lpc_mec_acpi_mutex);

View File

@ -8,6 +8,8 @@
#ifndef __CROS_EC_LPC_MEC_H #ifndef __CROS_EC_LPC_MEC_H
#define __CROS_EC_LPC_MEC_H #define __CROS_EC_LPC_MEC_H
#include <linux/acpi.h>
enum cros_ec_lpc_mec_emi_access_mode { enum cros_ec_lpc_mec_emi_access_mode {
/* 8-bit access */ /* 8-bit access */
ACCESS_TYPE_BYTE = 0x0, ACCESS_TYPE_BYTE = 0x0,
@ -45,6 +47,15 @@ enum cros_ec_lpc_mec_io_type {
*/ */
void cros_ec_lpc_mec_init(unsigned int base, unsigned int end); void cros_ec_lpc_mec_init(unsigned int base, unsigned int end);
/**
* cros_ec_lpc_mec_acpi_mutex() - Find and set ACPI mutex for MEC
*
* @adev: Parent ACPI device
* @pathname: Name of AML mutex
* @return: Negative error code, or zero for success
*/
int cros_ec_lpc_mec_acpi_mutex(struct acpi_device *adev, const char *pathname);
/** /**
* cros_ec_lpc_mec_in_range() - Determine if addresses are in MEC EMI range. * cros_ec_lpc_mec_in_range() - Determine if addresses are in MEC EMI range.
* *

View File

@ -359,6 +359,32 @@ static struct qcom_smem *__smem;
/* Timeout (ms) for the trylock of remote spinlocks */ /* Timeout (ms) for the trylock of remote spinlocks */
#define HWSPINLOCK_TIMEOUT 1000 #define HWSPINLOCK_TIMEOUT 1000
/* The qcom hwspinlock id is always plus one from the smem host id */
#define SMEM_HOST_ID_TO_HWSPINLOCK_ID(__x) ((__x) + 1)
/**
* qcom_smem_bust_hwspin_lock_by_host() - bust the smem hwspinlock for a host
* @host: remote processor id
*
* Busts the hwspin_lock for the given smem host id. This helper is intended
* for remoteproc drivers that manage remoteprocs with an equivalent smem
* driver instance in the remote firmware. Drivers can force a release of the
* smem hwspin_lock if the rproc unexpectedly goes into a bad state.
*
* Context: Process context.
*
* Returns: 0 on success, otherwise negative errno.
*/
int qcom_smem_bust_hwspin_lock_by_host(unsigned int host)
{
/* This function is for remote procs, so ignore SMEM_HOST_APPS */
if (host == SMEM_HOST_APPS || host >= SMEM_HOST_COUNT)
return -EINVAL;
return hwspin_lock_bust(__smem->hwlock, SMEM_HOST_ID_TO_HWSPINLOCK_ID(host));
}
EXPORT_SYMBOL_GPL(qcom_smem_bust_hwspin_lock_by_host);
/** /**
* qcom_smem_is_available() - Check if SMEM is available * qcom_smem_is_available() - Check if SMEM is available
* *

View File

@ -495,6 +495,7 @@ static int hisi_spi_probe(struct platform_device *pdev)
host->transfer_one = hisi_spi_transfer_one; host->transfer_one = hisi_spi_transfer_one;
host->handle_err = hisi_spi_handle_err; host->handle_err = hisi_spi_handle_err;
host->dev.fwnode = dev->fwnode; host->dev.fwnode = dev->fwnode;
host->min_speed_hz = DIV_ROUND_UP(host->max_speed_hz, CLK_DIV_MAX);
hisi_spi_hw_init(hs); hisi_spi_hw_init(hs);

View File

@ -2309,7 +2309,17 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba)
return err; return err;
} }
/*
* The UFSHCI 3.0 specification does not define MCQ_SUPPORT and
* LSDB_SUPPORT, but [31:29] as reserved bits with reset value 0s, which
* means we can simply read values regardless of version.
*/
hba->mcq_sup = FIELD_GET(MASK_MCQ_SUPPORT, hba->capabilities); hba->mcq_sup = FIELD_GET(MASK_MCQ_SUPPORT, hba->capabilities);
/*
* 0h: legacy single doorbell support is available
* 1h: indicate that legacy single doorbell support has been removed
*/
hba->lsdb_sup = !FIELD_GET(MASK_LSDB_SUPPORT, hba->capabilities);
if (!hba->mcq_sup) if (!hba->mcq_sup)
return 0; return 0;
@ -6506,7 +6516,8 @@ again:
if (ufshcd_err_handling_should_stop(hba)) if (ufshcd_err_handling_should_stop(hba))
goto skip_err_handling; goto skip_err_handling;
if (hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) { if ((hba->dev_quirks & UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) &&
!hba->force_reset) {
bool ret; bool ret;
spin_unlock_irqrestore(hba->host->host_lock, flags); spin_unlock_irqrestore(hba->host->host_lock, flags);
@ -10466,6 +10477,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
} }
if (!is_mcq_supported(hba)) { if (!is_mcq_supported(hba)) {
if (!hba->lsdb_sup) {
dev_err(hba->dev, "%s: failed to initialize (legacy doorbell mode not supported)\n",
__func__);
err = -EINVAL;
goto out_disable;
}
err = scsi_add_host(host, hba->dev); err = scsi_add_host(host, hba->dev);
if (err) { if (err) {
dev_err(hba->dev, "scsi_add_host failed\n"); dev_err(hba->dev, "scsi_add_host failed\n");

View File

@ -404,7 +404,7 @@ ucsi_register_displayport(struct ucsi_connector *con,
bool override, int offset, bool override, int offset,
struct typec_altmode_desc *desc) struct typec_altmode_desc *desc)
{ {
return NULL; return typec_port_register_altmode(con->port, desc);
} }
static inline void static inline void

View File

@ -144,53 +144,62 @@ static int tweak_set_configuration_cmd(struct urb *urb)
if (err && err != -ENODEV) if (err && err != -ENODEV)
dev_err(&sdev->udev->dev, "can't set config #%d, error %d\n", dev_err(&sdev->udev->dev, "can't set config #%d, error %d\n",
config, err); config, err);
return 0; return err;
} }
static int tweak_reset_device_cmd(struct urb *urb) static int tweak_reset_device_cmd(struct urb *urb)
{ {
struct stub_priv *priv = (struct stub_priv *) urb->context; struct stub_priv *priv = (struct stub_priv *) urb->context;
struct stub_device *sdev = priv->sdev; struct stub_device *sdev = priv->sdev;
int err;
dev_info(&urb->dev->dev, "usb_queue_reset_device\n"); dev_info(&urb->dev->dev, "usb_queue_reset_device\n");
if (usb_lock_device_for_reset(sdev->udev, NULL) < 0) { err = usb_lock_device_for_reset(sdev->udev, NULL);
if (err < 0) {
dev_err(&urb->dev->dev, "could not obtain lock to reset device\n"); dev_err(&urb->dev->dev, "could not obtain lock to reset device\n");
return 0; return err;
} }
usb_reset_device(sdev->udev); err = usb_reset_device(sdev->udev);
usb_unlock_device(sdev->udev); usb_unlock_device(sdev->udev);
return 0; return err;
} }
/* /*
* clear_halt, set_interface, and set_configuration require special tricks. * clear_halt, set_interface, and set_configuration require special tricks.
* Returns 1 if request was tweaked, 0 otherwise.
*/ */
static void tweak_special_requests(struct urb *urb) static int tweak_special_requests(struct urb *urb)
{ {
int err;
if (!urb || !urb->setup_packet) if (!urb || !urb->setup_packet)
return; return 0;
if (usb_pipetype(urb->pipe) != PIPE_CONTROL) if (usb_pipetype(urb->pipe) != PIPE_CONTROL)
return; return 0;
if (is_clear_halt_cmd(urb)) if (is_clear_halt_cmd(urb))
/* tweak clear_halt */ /* tweak clear_halt */
tweak_clear_halt_cmd(urb); err = tweak_clear_halt_cmd(urb);
else if (is_set_interface_cmd(urb)) else if (is_set_interface_cmd(urb))
/* tweak set_interface */ /* tweak set_interface */
tweak_set_interface_cmd(urb); err = tweak_set_interface_cmd(urb);
else if (is_set_configuration_cmd(urb)) else if (is_set_configuration_cmd(urb))
/* tweak set_configuration */ /* tweak set_configuration */
tweak_set_configuration_cmd(urb); err = tweak_set_configuration_cmd(urb);
else if (is_reset_device_cmd(urb)) else if (is_reset_device_cmd(urb))
tweak_reset_device_cmd(urb); err = tweak_reset_device_cmd(urb);
else else {
usbip_dbg_stub_rx("no need to tweak\n"); usbip_dbg_stub_rx("no need to tweak\n");
return 0;
}
return !err;
} }
/* /*
@ -468,6 +477,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
int support_sg = 1; int support_sg = 1;
int np = 0; int np = 0;
int ret, i; int ret, i;
int is_tweaked;
if (pipe == -1) if (pipe == -1)
return; return;
@ -580,8 +590,11 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
priv->urbs[i]->pipe = pipe; priv->urbs[i]->pipe = pipe;
priv->urbs[i]->complete = stub_complete; priv->urbs[i]->complete = stub_complete;
/* no need to submit an intercepted request, but harmless? */ /*
tweak_special_requests(priv->urbs[i]); * all URBs belong to a single PDU, so a global is_tweaked flag is
* enough
*/
is_tweaked = tweak_special_requests(priv->urbs[i]);
masking_bogus_flags(priv->urbs[i]); masking_bogus_flags(priv->urbs[i]);
} }
@ -594,6 +607,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
/* urb is now ready to submit */ /* urb is now ready to submit */
for (i = 0; i < priv->num_urbs; i++) { for (i = 0; i < priv->num_urbs; i++) {
if (!is_tweaked) {
ret = usb_submit_urb(priv->urbs[i], GFP_KERNEL); ret = usb_submit_urb(priv->urbs[i], GFP_KERNEL);
if (ret == 0) if (ret == 0)
@ -611,6 +625,15 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT); usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
break; break;
} }
} else {
/*
* An identical URB was already submitted in
* tweak_special_requests(). Skip submitting this URB to not
* duplicate the request.
*/
priv->urbs[i]->status = 0;
stub_complete(priv->urbs[i]);
}
} }
usbip_dbg_stub_rx("Leave\n"); usbip_dbg_stub_rx("Leave\n");

View File

@ -1266,6 +1266,19 @@ static void extent_err(const struct extent_buffer *eb, int slot,
va_end(args); va_end(args);
} }
static bool is_valid_dref_root(u64 rootid)
{
/*
* The following tree root objectids are allowed to have a data backref:
* - subvolume trees
* - data reloc tree
* - tree root
* For v1 space cache
*/
return is_fstree(rootid) || rootid == BTRFS_DATA_RELOC_TREE_OBJECTID ||
rootid == BTRFS_ROOT_TREE_OBJECTID;
}
static int check_extent_item(struct extent_buffer *leaf, static int check_extent_item(struct extent_buffer *leaf,
struct btrfs_key *key, int slot, struct btrfs_key *key, int slot,
struct btrfs_key *prev_key) struct btrfs_key *prev_key)
@ -1418,6 +1431,8 @@ static int check_extent_item(struct extent_buffer *leaf,
struct btrfs_extent_data_ref *dref; struct btrfs_extent_data_ref *dref;
struct btrfs_shared_data_ref *sref; struct btrfs_shared_data_ref *sref;
u64 seq; u64 seq;
u64 dref_root;
u64 dref_objectid;
u64 dref_offset; u64 dref_offset;
u64 inline_offset; u64 inline_offset;
u8 inline_type; u8 inline_type;
@ -1461,11 +1476,26 @@ static int check_extent_item(struct extent_buffer *leaf,
*/ */
case BTRFS_EXTENT_DATA_REF_KEY: case BTRFS_EXTENT_DATA_REF_KEY:
dref = (struct btrfs_extent_data_ref *)(&iref->offset); dref = (struct btrfs_extent_data_ref *)(&iref->offset);
dref_root = btrfs_extent_data_ref_root(leaf, dref);
dref_objectid = btrfs_extent_data_ref_objectid(leaf, dref);
dref_offset = btrfs_extent_data_ref_offset(leaf, dref); dref_offset = btrfs_extent_data_ref_offset(leaf, dref);
seq = hash_extent_data_ref( seq = hash_extent_data_ref(
btrfs_extent_data_ref_root(leaf, dref), btrfs_extent_data_ref_root(leaf, dref),
btrfs_extent_data_ref_objectid(leaf, dref), btrfs_extent_data_ref_objectid(leaf, dref),
btrfs_extent_data_ref_offset(leaf, dref)); btrfs_extent_data_ref_offset(leaf, dref));
if (unlikely(!is_valid_dref_root(dref_root))) {
extent_err(leaf, slot,
"invalid data ref root value %llu",
dref_root);
return -EUCLEAN;
}
if (unlikely(dref_objectid < BTRFS_FIRST_FREE_OBJECTID ||
dref_objectid > BTRFS_LAST_FREE_OBJECTID)) {
extent_err(leaf, slot,
"invalid data ref objectid value %llu",
dref_root);
return -EUCLEAN;
}
if (unlikely(!IS_ALIGNED(dref_offset, if (unlikely(!IS_ALIGNED(dref_offset,
fs_info->sectorsize))) { fs_info->sectorsize))) {
extent_err(leaf, slot, extent_err(leaf, slot,
@ -1601,6 +1631,8 @@ static int check_extent_data_ref(struct extent_buffer *leaf,
return -EUCLEAN; return -EUCLEAN;
} }
for (; ptr < end; ptr += sizeof(*dref)) { for (; ptr < end; ptr += sizeof(*dref)) {
u64 root;
u64 objectid;
u64 offset; u64 offset;
/* /*
@ -1608,7 +1640,22 @@ static int check_extent_data_ref(struct extent_buffer *leaf,
* overflow from the leaf due to hash collisions. * overflow from the leaf due to hash collisions.
*/ */
dref = (struct btrfs_extent_data_ref *)ptr; dref = (struct btrfs_extent_data_ref *)ptr;
root = btrfs_extent_data_ref_root(leaf, dref);
objectid = btrfs_extent_data_ref_objectid(leaf, dref);
offset = btrfs_extent_data_ref_offset(leaf, dref); offset = btrfs_extent_data_ref_offset(leaf, dref);
if (unlikely(!is_valid_dref_root(root))) {
extent_err(leaf, slot,
"invalid extent data backref root value %llu",
root);
return -EUCLEAN;
}
if (unlikely(objectid < BTRFS_FIRST_FREE_OBJECTID ||
objectid > BTRFS_LAST_FREE_OBJECTID)) {
extent_err(leaf, slot,
"invalid extent data backref objectid value %llu",
root);
return -EUCLEAN;
}
if (unlikely(!IS_ALIGNED(offset, leaf->fs_info->sectorsize))) { if (unlikely(!IS_ALIGNED(offset, leaf->fs_info->sectorsize))) {
extent_err(leaf, slot, extent_err(leaf, slot,
"invalid extent data backref offset, have %llu expect aligned to %u", "invalid extent data backref offset, have %llu expect aligned to %u",

View File

@ -75,9 +75,6 @@
#define GFS2_QD_HASH_SIZE BIT(GFS2_QD_HASH_SHIFT) #define GFS2_QD_HASH_SIZE BIT(GFS2_QD_HASH_SHIFT)
#define GFS2_QD_HASH_MASK (GFS2_QD_HASH_SIZE - 1) #define GFS2_QD_HASH_MASK (GFS2_QD_HASH_SIZE - 1)
#define QC_CHANGE 0
#define QC_SYNC 1
/* Lock order: qd_lock -> bucket lock -> qd->lockref.lock -> lru lock */ /* Lock order: qd_lock -> bucket lock -> qd->lockref.lock -> lru lock */
/* -> sd_bitmap_lock */ /* -> sd_bitmap_lock */
static DEFINE_SPINLOCK(qd_lock); static DEFINE_SPINLOCK(qd_lock);
@ -697,7 +694,7 @@ static int sort_qd(const void *a, const void *b)
return 0; return 0;
} }
static void do_qc(struct gfs2_quota_data *qd, s64 change, int qc_type) static void do_qc(struct gfs2_quota_data *qd, s64 change)
{ {
struct gfs2_sbd *sdp = qd->qd_sbd; struct gfs2_sbd *sdp = qd->qd_sbd;
struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode);
@ -722,18 +719,16 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change, int qc_type)
qd->qd_change = x; qd->qd_change = x;
spin_unlock(&qd_lock); spin_unlock(&qd_lock);
if (qc_type == QC_CHANGE) { if (!x) {
if (!test_and_set_bit(QDF_CHANGE, &qd->qd_flags)) {
qd_hold(qd);
slot_hold(qd);
}
} else {
gfs2_assert_warn(sdp, test_bit(QDF_CHANGE, &qd->qd_flags)); gfs2_assert_warn(sdp, test_bit(QDF_CHANGE, &qd->qd_flags));
clear_bit(QDF_CHANGE, &qd->qd_flags); clear_bit(QDF_CHANGE, &qd->qd_flags);
qc->qc_flags = 0; qc->qc_flags = 0;
qc->qc_id = 0; qc->qc_id = 0;
slot_put(qd); slot_put(qd);
qd_put(qd); qd_put(qd);
} else if (!test_and_set_bit(QDF_CHANGE, &qd->qd_flags)) {
qd_hold(qd);
slot_hold(qd);
} }
if (change < 0) /* Reset quiet flag if we freed some blocks */ if (change < 0) /* Reset quiet flag if we freed some blocks */
@ -978,7 +973,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
if (error) if (error)
goto out_end_trans; goto out_end_trans;
do_qc(qd, -qd->qd_change_sync, QC_SYNC); do_qc(qd, -qd->qd_change_sync);
set_bit(QDF_REFRESH, &qd->qd_flags); set_bit(QDF_REFRESH, &qd->qd_flags);
} }
@ -1300,7 +1295,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
if (qid_eq(qd->qd_id, make_kqid_uid(uid)) || if (qid_eq(qd->qd_id, make_kqid_uid(uid)) ||
qid_eq(qd->qd_id, make_kqid_gid(gid))) { qid_eq(qd->qd_id, make_kqid_gid(gid))) {
do_qc(qd, change, QC_CHANGE); do_qc(qd, change);
} }
} }
} }

View File

@ -99,12 +99,12 @@ out_unlock:
*/ */
int gfs2_freeze_lock_shared(struct gfs2_sbd *sdp) int gfs2_freeze_lock_shared(struct gfs2_sbd *sdp)
{ {
int flags = LM_FLAG_NOEXP | GL_EXACT;
int error; int error;
error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, flags,
LM_FLAG_NOEXP | GL_EXACT,
&sdp->sd_freeze_gh); &sdp->sd_freeze_gh);
if (error) if (error && error != GLR_TRYFAILED)
fs_err(sdp, "can't lock the freeze glock: %d\n", error); fs_err(sdp, "can't lock the freeze glock: %d\n", error);
return error; return error;
} }

View File

@ -103,17 +103,13 @@ void fsnotify_sb_delete(struct super_block *sb)
* parent cares. Thus when an event happens on a child it can quickly tell * parent cares. Thus when an event happens on a child it can quickly tell
* if there is a need to find a parent and send the event to the parent. * if there is a need to find a parent and send the event to the parent.
*/ */
void __fsnotify_update_child_dentry_flags(struct inode *inode) void fsnotify_set_children_dentry_flags(struct inode *inode)
{ {
struct dentry *alias; struct dentry *alias;
int watched;
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return; return;
/* determine if the children should tell inode about their events */
watched = fsnotify_inode_watches_children(inode);
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
/* run all of the dentries associated with this inode. Since this is a /* run all of the dentries associated with this inode. Since this is a
* directory, there damn well better only be one item on this list */ * directory, there damn well better only be one item on this list */
@ -129,10 +125,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
continue; continue;
spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED);
if (watched)
child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; child->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
else
child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
spin_unlock(&child->d_lock); spin_unlock(&child->d_lock);
} }
spin_unlock(&alias->d_lock); spin_unlock(&alias->d_lock);
@ -140,6 +133,24 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
} }
/*
* Lazily clear false positive PARENT_WATCHED flag for child whose parent had
* stopped watching children.
*/
static void fsnotify_clear_child_dentry_flag(struct inode *pinode,
struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
/*
* d_lock is a sufficient barrier to prevent observing a non-watched
* parent state from before the fsnotify_set_children_dentry_flags()
* or fsnotify_update_flags() call that had set PARENT_WATCHED.
*/
if (!fsnotify_inode_watches_children(pinode))
dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
spin_unlock(&dentry->d_lock);
}
/* Are inode/sb/mount interested in parent and name info with this event? */ /* Are inode/sb/mount interested in parent and name info with this event? */
static bool fsnotify_event_needs_parent(struct inode *inode, struct mount *mnt, static bool fsnotify_event_needs_parent(struct inode *inode, struct mount *mnt,
__u32 mask) __u32 mask)
@ -208,7 +219,7 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data,
p_inode = parent->d_inode; p_inode = parent->d_inode;
p_mask = fsnotify_inode_watches_children(p_inode); p_mask = fsnotify_inode_watches_children(p_inode);
if (unlikely(parent_watched && !p_mask)) if (unlikely(parent_watched && !p_mask))
__fsnotify_update_child_dentry_flags(p_inode); fsnotify_clear_child_dentry_flag(p_inode, dentry);
/* /*
* Include parent/name in notification either if some notification * Include parent/name in notification either if some notification

View File

@ -74,7 +74,7 @@ static inline void fsnotify_clear_marks_by_sb(struct super_block *sb)
* update the dentry->d_flags of all of inode's children to indicate if inode cares * update the dentry->d_flags of all of inode's children to indicate if inode cares
* about events that happen to its children. * about events that happen to its children.
*/ */
extern void __fsnotify_update_child_dentry_flags(struct inode *inode); extern void fsnotify_set_children_dentry_flags(struct inode *inode);
extern struct kmem_cache *fsnotify_mark_connector_cachep; extern struct kmem_cache *fsnotify_mark_connector_cachep;

View File

@ -176,6 +176,24 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
return fsnotify_update_iref(conn, want_iref); return fsnotify_update_iref(conn, want_iref);
} }
static bool fsnotify_conn_watches_children(
struct fsnotify_mark_connector *conn)
{
if (conn->type != FSNOTIFY_OBJ_TYPE_INODE)
return false;
return fsnotify_inode_watches_children(fsnotify_conn_inode(conn));
}
static void fsnotify_conn_set_children_dentry_flags(
struct fsnotify_mark_connector *conn)
{
if (conn->type != FSNOTIFY_OBJ_TYPE_INODE)
return;
fsnotify_set_children_dentry_flags(fsnotify_conn_inode(conn));
}
/* /*
* Calculate mask of events for a list of marks. The caller must make sure * Calculate mask of events for a list of marks. The caller must make sure
* connector and connector->obj cannot disappear under us. Callers achieve * connector and connector->obj cannot disappear under us. Callers achieve
@ -184,15 +202,23 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
*/ */
void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)
{ {
bool update_children;
if (!conn) if (!conn)
return; return;
spin_lock(&conn->lock); spin_lock(&conn->lock);
update_children = !fsnotify_conn_watches_children(conn);
__fsnotify_recalc_mask(conn); __fsnotify_recalc_mask(conn);
update_children &= fsnotify_conn_watches_children(conn);
spin_unlock(&conn->lock); spin_unlock(&conn->lock);
if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) /*
__fsnotify_update_child_dentry_flags( * Set children's PARENT_WATCHED flags only if parent started watching.
fsnotify_conn_inode(conn)); * When parent stops watching, we clear false positive PARENT_WATCHED
* flags lazily in __fsnotify_parent().
*/
if (update_children)
fsnotify_conn_set_children_dentry_flags(conn);
} }
/* Free all connectors queued for freeing once SRCU period ends */ /* Free all connectors queued for freeing once SRCU period ends */

View File

@ -950,7 +950,8 @@ int smb2_query_path_info(const unsigned int xid,
cmds[num_cmds++] = SMB2_OP_GET_REPARSE; cmds[num_cmds++] = SMB2_OP_GET_REPARSE;
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_READ_ATTRIBUTES |
FILE_READ_EA | SYNCHRONIZE,
FILE_OPEN, create_options | FILE_OPEN, create_options |
OPEN_REPARSE_POINT, ACL_NO_MODE); OPEN_REPARSE_POINT, ACL_NO_MODE);
cifs_get_readable_path(tcon, full_path, &cfile); cifs_get_readable_path(tcon, full_path, &cfile);
@ -1258,7 +1259,8 @@ int smb2_query_reparse_point(const unsigned int xid,
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path); cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
cifs_get_readable_path(tcon, full_path, &cfile); cifs_get_readable_path(tcon, full_path, &cfile);
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_READ_ATTRIBUTES, oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE,
FILE_OPEN, OPEN_REPARSE_POINT, ACL_NO_MODE); FILE_OPEN, OPEN_REPARSE_POINT, ACL_NO_MODE);
rc = smb2_compound_op(xid, tcon, cifs_sb, rc = smb2_compound_op(xid, tcon, cifs_sb,
full_path, &oparms, &in_iov, full_path, &oparms, &in_iov,

View File

@ -41,7 +41,7 @@ struct regmap;
struct xilinx_timer_priv { struct xilinx_timer_priv {
struct regmap *map; struct regmap *map;
struct clk *clk; struct clk *clk;
u32 max; u64 max;
}; };
/** /**

View File

@ -563,12 +563,14 @@ static inline __u32 fsnotify_parent_needed_mask(__u32 mask)
static inline int fsnotify_inode_watches_children(struct inode *inode) static inline int fsnotify_inode_watches_children(struct inode *inode)
{ {
__u32 parent_mask = READ_ONCE(inode->i_fsnotify_mask);
/* FS_EVENT_ON_CHILD is set if the inode may care */ /* FS_EVENT_ON_CHILD is set if the inode may care */
if (!(inode->i_fsnotify_mask & FS_EVENT_ON_CHILD)) if (!(parent_mask & FS_EVENT_ON_CHILD))
return 0; return 0;
/* this inode might care about child events, does it care about the /* this inode might care about child events, does it care about the
* specific set of events that can happen on a child? */ * specific set of events that can happen on a child? */
return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD; return parent_mask & FS_EVENTS_POSS_ON_CHILD;
} }
/* /*
@ -582,7 +584,7 @@ static inline void fsnotify_update_flags(struct dentry *dentry)
/* /*
* Serialisation of setting PARENT_WATCHED on the dentries is provided * Serialisation of setting PARENT_WATCHED on the dentries is provided
* by d_lock. If inotify_inode_watched changes after we have taken * by d_lock. If inotify_inode_watched changes after we have taken
* d_lock, the following __fsnotify_update_child_dentry_flags call will * d_lock, the following fsnotify_set_children_dentry_flags call will
* find our entry, so it will spin until we complete here, and update * find our entry, so it will spin until we complete here, and update
* us with the new state. * us with the new state.
*/ */

View File

@ -1033,7 +1033,7 @@ static inline int of_i2c_get_board_info(struct device *dev,
struct acpi_resource; struct acpi_resource;
struct acpi_resource_i2c_serialbus; struct acpi_resource_i2c_serialbus;
#if IS_ENABLED(CONFIG_ACPI) #if IS_REACHABLE(CONFIG_ACPI) && IS_REACHABLE(CONFIG_I2C)
bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
struct acpi_resource_i2c_serialbus **i2c); struct acpi_resource_i2c_serialbus **i2c);
int i2c_acpi_client_count(struct acpi_device *adev); int i2c_acpi_client_count(struct acpi_device *adev);

Some files were not shown because too many files have changed in this diff Show More